@savvagent/sdk 1.0.0 → 1.1.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/README.md +49 -0
- package/dist/index.d.mts +199 -10
- package/dist/index.d.ts +199 -10
- package/dist/index.js +484 -64
- package/dist/index.mjs +484 -64
- package/package.json +16 -15
package/README.md
CHANGED
|
@@ -159,6 +159,9 @@ interface FlagClientConfig {
|
|
|
159
159
|
/** Base URL for the Savvagent API (default: production) */
|
|
160
160
|
baseUrl?: string;
|
|
161
161
|
|
|
162
|
+
/** Environment for flag evaluation (default: 'production') */
|
|
163
|
+
environment?: string;
|
|
164
|
+
|
|
162
165
|
/** Enable real-time flag updates via SSE (default: true) */
|
|
163
166
|
enableRealtime?: boolean;
|
|
164
167
|
|
|
@@ -182,6 +185,7 @@ interface FlagClientConfig {
|
|
|
182
185
|
const client = new FlagClient({
|
|
183
186
|
apiKey: 'sdk_dev_abc123',
|
|
184
187
|
baseUrl: 'https://api.savvagent.com',
|
|
188
|
+
environment: 'staging', // Use staging environment flags
|
|
185
189
|
enableRealtime: true,
|
|
186
190
|
cacheTtl: 30000, // 30 seconds
|
|
187
191
|
enableTelemetry: true,
|
|
@@ -196,6 +200,47 @@ const client = new FlagClient({
|
|
|
196
200
|
});
|
|
197
201
|
```
|
|
198
202
|
|
|
203
|
+
### Environment Configuration
|
|
204
|
+
|
|
205
|
+
The `environment` option controls which environment's flag values are used during evaluation. Common values include:
|
|
206
|
+
|
|
207
|
+
- `'production'` (default) - Production environment
|
|
208
|
+
- `'staging'` - Staging/pre-production environment
|
|
209
|
+
- `'development'` - Local development environment
|
|
210
|
+
- `'beta'` - Beta testing environment
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
// Production app
|
|
214
|
+
const client = new FlagClient({
|
|
215
|
+
apiKey: 'sdk_prod_...',
|
|
216
|
+
environment: 'production',
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// Staging/QA app
|
|
220
|
+
const client = new FlagClient({
|
|
221
|
+
apiKey: 'sdk_staging_...',
|
|
222
|
+
environment: 'staging',
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
// Development
|
|
226
|
+
const client = new FlagClient({
|
|
227
|
+
apiKey: 'sdk_dev_...',
|
|
228
|
+
environment: 'development',
|
|
229
|
+
});
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
You can also change the environment at runtime:
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
// Switch to beta environment
|
|
236
|
+
client.setEnvironment('beta');
|
|
237
|
+
|
|
238
|
+
// Get current environment
|
|
239
|
+
console.log(client.getEnvironment()); // 'beta'
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Note: Changing the environment clears the cache since flag values may differ between environments.
|
|
243
|
+
|
|
199
244
|
## Framework Integration
|
|
200
245
|
|
|
201
246
|
### React
|
|
@@ -408,6 +453,10 @@ const client = new FlagClient({
|
|
|
408
453
|
- `withFlag(flagKey, callback, context?)`: Execute code conditionally
|
|
409
454
|
- `trackError(flagKey, error, context?)`: Manually track an error
|
|
410
455
|
- `subscribe(flagKey, callback)`: Subscribe to flag updates
|
|
456
|
+
- `setEnvironment(environment)`: Set the environment for flag evaluation
|
|
457
|
+
- `getEnvironment()`: Get the current environment
|
|
458
|
+
- `setUserId(userId)`: Set the user ID for targeted rollouts
|
|
459
|
+
- `getUserId()`: Get the current user ID
|
|
411
460
|
- `getCachedFlags()`: Get all cached flag keys
|
|
412
461
|
- `clearCache()`: Clear the flag cache
|
|
413
462
|
- `isRealtimeConnected()`: Check real-time connection status
|
package/dist/index.d.mts
CHANGED
|
@@ -11,6 +11,8 @@ interface FlagClientConfig {
|
|
|
11
11
|
applicationId?: string;
|
|
12
12
|
/** Base URL for the Savvagent API (default: production URL) */
|
|
13
13
|
baseUrl?: string;
|
|
14
|
+
/** Environment for flag evaluation (e.g., "development", "staging", "production", "beta"). Default: "production" */
|
|
15
|
+
environment?: string;
|
|
14
16
|
/** Enable real-time flag updates via SSE (default: true) */
|
|
15
17
|
enableRealtime?: boolean;
|
|
16
18
|
/** Cache TTL in milliseconds (default: 60000 = 1 minute) */
|
|
@@ -25,25 +27,34 @@ interface FlagClientConfig {
|
|
|
25
27
|
defaultLanguage?: string;
|
|
26
28
|
/** Disable automatic browser language detection (default: false) */
|
|
27
29
|
disableLanguageDetection?: boolean;
|
|
30
|
+
/** Number of retry attempts for transient failures (default: 3) */
|
|
31
|
+
retryAttempts?: number;
|
|
32
|
+
/** Base delay between retries in milliseconds (default: 1000) */
|
|
33
|
+
retryDelay?: number;
|
|
34
|
+
/** Retry backoff strategy: 'linear' or 'exponential' (default: 'exponential') */
|
|
35
|
+
retryBackoff?: 'linear' | 'exponential';
|
|
28
36
|
}
|
|
29
37
|
/**
|
|
30
38
|
* Context passed to flag evaluation
|
|
39
|
+
* Per SDK Developer Guide: https://docs.savvagent.com/sdk-developer-guide
|
|
31
40
|
*/
|
|
32
41
|
interface FlagContext {
|
|
33
|
-
/** User ID for targeted rollouts (logged-in users) */
|
|
42
|
+
/** User ID for targeted rollouts (logged-in users) - required for percentage rollouts */
|
|
34
43
|
user_id?: string;
|
|
35
|
-
/** Anonymous ID for consistent rollouts (anonymous users) */
|
|
44
|
+
/** Anonymous ID for consistent rollouts (anonymous users) - alternative to user_id */
|
|
36
45
|
anonymous_id?: string;
|
|
37
46
|
/** Session ID as fallback identifier */
|
|
38
47
|
session_id?: string;
|
|
39
|
-
/**
|
|
48
|
+
/** Target environment (e.g., "production", "staging") */
|
|
49
|
+
environment?: string;
|
|
50
|
+
/** Organization ID for multi-tenant apps */
|
|
51
|
+
organization_id?: string;
|
|
52
|
+
/** Application ID for hierarchical flag lookup (auto-injected from config) */
|
|
40
53
|
application_id?: string;
|
|
41
|
-
/** User's language
|
|
54
|
+
/** User's language code (e.g., "en", "es") */
|
|
42
55
|
language?: string;
|
|
43
56
|
/** Custom attributes for targeting rules */
|
|
44
57
|
attributes?: Record<string, any>;
|
|
45
|
-
/** Environment (dev, staging, production) */
|
|
46
|
-
environment?: string;
|
|
47
58
|
}
|
|
48
59
|
/**
|
|
49
60
|
* Result from flag evaluation
|
|
@@ -105,6 +116,43 @@ interface FlagUpdateEvent {
|
|
|
105
116
|
flagKey: string;
|
|
106
117
|
data?: any;
|
|
107
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Flag definition returned from getAllFlags endpoint
|
|
121
|
+
* Per SDK Developer Guide: GET /api/sdk/flags
|
|
122
|
+
*/
|
|
123
|
+
interface FlagDefinition {
|
|
124
|
+
/** Flag key */
|
|
125
|
+
key: string;
|
|
126
|
+
/** Enabled state for the requested environment */
|
|
127
|
+
enabled: boolean;
|
|
128
|
+
/** Flag scope: "application" or "enterprise" */
|
|
129
|
+
scope: 'application' | 'enterprise';
|
|
130
|
+
/** Environment configuration with enabled state and rollout percentage */
|
|
131
|
+
environments: Record<string, {
|
|
132
|
+
enabled: boolean;
|
|
133
|
+
rollout_percentage?: number;
|
|
134
|
+
}>;
|
|
135
|
+
/** Variation definitions for A/B testing (if any) */
|
|
136
|
+
variations?: Record<string, any> | null;
|
|
137
|
+
/** Dynamic configuration attached to the flag */
|
|
138
|
+
configuration?: any;
|
|
139
|
+
/** Flag version for cache invalidation */
|
|
140
|
+
version: number;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Response from getAllFlags endpoint
|
|
144
|
+
* Per SDK Developer Guide: GET /api/sdk/flags
|
|
145
|
+
*/
|
|
146
|
+
interface FlagListResponse {
|
|
147
|
+
/** List of flag definitions */
|
|
148
|
+
flags: FlagDefinition[];
|
|
149
|
+
/** Total count of flags returned */
|
|
150
|
+
count: number;
|
|
151
|
+
/** Organization ID */
|
|
152
|
+
organization_id: string;
|
|
153
|
+
/** Application ID (present for SDK key auth) */
|
|
154
|
+
application_id?: string;
|
|
155
|
+
}
|
|
108
156
|
|
|
109
157
|
/**
|
|
110
158
|
* Savvagent Client for feature flag evaluation with AI-powered error detection
|
|
@@ -117,6 +165,9 @@ declare class FlagClient {
|
|
|
117
165
|
private anonymousId;
|
|
118
166
|
private userId;
|
|
119
167
|
private detectedLanguage;
|
|
168
|
+
private overrides;
|
|
169
|
+
private overrideListeners;
|
|
170
|
+
private authFailed;
|
|
120
171
|
constructor(config: FlagClientConfig);
|
|
121
172
|
/**
|
|
122
173
|
* Get or create an anonymous ID for consistent flag evaluation
|
|
@@ -139,6 +190,16 @@ declare class FlagClient {
|
|
|
139
190
|
* Get the current user ID
|
|
140
191
|
*/
|
|
141
192
|
getUserId(): string | null;
|
|
193
|
+
/**
|
|
194
|
+
* Set the environment for flag evaluation
|
|
195
|
+
* Useful for dynamically switching environments (e.g., dev tools)
|
|
196
|
+
* @param environment - The environment name (e.g., "development", "staging", "production", "beta")
|
|
197
|
+
*/
|
|
198
|
+
setEnvironment(environment: string): void;
|
|
199
|
+
/**
|
|
200
|
+
* Get the current environment
|
|
201
|
+
*/
|
|
202
|
+
getEnvironment(): string;
|
|
142
203
|
/**
|
|
143
204
|
* Get the current anonymous ID
|
|
144
205
|
*/
|
|
@@ -148,6 +209,23 @@ declare class FlagClient {
|
|
|
148
209
|
* @param overrides - Context overrides
|
|
149
210
|
*/
|
|
150
211
|
private buildContext;
|
|
212
|
+
/**
|
|
213
|
+
* Check if an error is retryable (transient failure)
|
|
214
|
+
* @param error - The error to check
|
|
215
|
+
* @param status - HTTP status code (if available)
|
|
216
|
+
*/
|
|
217
|
+
private isRetryableError;
|
|
218
|
+
/**
|
|
219
|
+
* Calculate delay for retry attempt
|
|
220
|
+
* @param attempt - Current attempt number (1-based)
|
|
221
|
+
*/
|
|
222
|
+
private getRetryDelay;
|
|
223
|
+
/**
|
|
224
|
+
* Execute a fetch request with retry logic
|
|
225
|
+
* @param requestFn - Function that returns a fetch promise
|
|
226
|
+
* @param operationName - Name of the operation for logging
|
|
227
|
+
*/
|
|
228
|
+
private fetchWithRetry;
|
|
151
229
|
/**
|
|
152
230
|
* Check if a feature flag is enabled
|
|
153
231
|
* @param flagKey - The flag key to evaluate
|
|
@@ -199,6 +277,110 @@ declare class FlagClient {
|
|
|
199
277
|
* Close the client and cleanup resources
|
|
200
278
|
*/
|
|
201
279
|
close(): void;
|
|
280
|
+
/**
|
|
281
|
+
* Set a local override for a flag.
|
|
282
|
+
* Overrides take precedence over server values and cache.
|
|
283
|
+
*
|
|
284
|
+
* @param flagKey - The flag key to override
|
|
285
|
+
* @param value - The override value (true/false)
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* ```typescript
|
|
289
|
+
* // Force a flag to be enabled locally
|
|
290
|
+
* client.setOverride('new-feature', true);
|
|
291
|
+
* ```
|
|
292
|
+
*/
|
|
293
|
+
setOverride(flagKey: string, value: boolean): void;
|
|
294
|
+
/**
|
|
295
|
+
* Clear a local override for a flag.
|
|
296
|
+
* The flag will return to using server/cached values.
|
|
297
|
+
*
|
|
298
|
+
* @param flagKey - The flag key to clear override for
|
|
299
|
+
*/
|
|
300
|
+
clearOverride(flagKey: string): void;
|
|
301
|
+
/**
|
|
302
|
+
* Clear all local overrides.
|
|
303
|
+
*/
|
|
304
|
+
clearAllOverrides(): void;
|
|
305
|
+
/**
|
|
306
|
+
* Check if a flag has a local override.
|
|
307
|
+
*
|
|
308
|
+
* @param flagKey - The flag key to check
|
|
309
|
+
* @returns true if the flag has an override
|
|
310
|
+
*/
|
|
311
|
+
hasOverride(flagKey: string): boolean;
|
|
312
|
+
/**
|
|
313
|
+
* Get the override value for a flag.
|
|
314
|
+
*
|
|
315
|
+
* @param flagKey - The flag key to get override for
|
|
316
|
+
* @returns The override value, or undefined if not set
|
|
317
|
+
*/
|
|
318
|
+
getOverride(flagKey: string): boolean | undefined;
|
|
319
|
+
/**
|
|
320
|
+
* Get all current overrides.
|
|
321
|
+
*
|
|
322
|
+
* @returns Record of flag keys to override values
|
|
323
|
+
*/
|
|
324
|
+
getOverrides(): Record<string, boolean>;
|
|
325
|
+
/**
|
|
326
|
+
* Set multiple overrides at once.
|
|
327
|
+
*
|
|
328
|
+
* @param overrides - Record of flag keys to override values
|
|
329
|
+
*/
|
|
330
|
+
setOverrides(overrides: Record<string, boolean>): void;
|
|
331
|
+
/**
|
|
332
|
+
* Subscribe to override changes.
|
|
333
|
+
* Useful for React components to re-render when overrides change.
|
|
334
|
+
*
|
|
335
|
+
* @param callback - Function to call when overrides change
|
|
336
|
+
* @returns Unsubscribe function
|
|
337
|
+
*/
|
|
338
|
+
onOverrideChange(callback: () => void): () => void;
|
|
339
|
+
/**
|
|
340
|
+
* Notify all override listeners of a change.
|
|
341
|
+
*/
|
|
342
|
+
private notifyOverrideListeners;
|
|
343
|
+
/**
|
|
344
|
+
* Get all flags for the application (and enterprise-scoped flags).
|
|
345
|
+
* Per SDK Developer Guide: GET /api/sdk/flags
|
|
346
|
+
*
|
|
347
|
+
* Use cases:
|
|
348
|
+
* - Local override UI: Display all available flags for developers to toggle
|
|
349
|
+
* - Offline mode: Pre-fetch flags for mobile/desktop apps
|
|
350
|
+
* - SDK initialization: Bootstrap SDK with all flag values on startup
|
|
351
|
+
* - DevTools integration: Show available flags in browser dev panels
|
|
352
|
+
*
|
|
353
|
+
* @param environment - Environment to evaluate enabled state for (default: 'development')
|
|
354
|
+
* @returns Promise<FlagDefinition[]> - List of flag definitions
|
|
355
|
+
*
|
|
356
|
+
* @example
|
|
357
|
+
* ```typescript
|
|
358
|
+
* // Fetch all flags for development
|
|
359
|
+
* const flags = await client.getAllFlags('development');
|
|
360
|
+
*
|
|
361
|
+
* // Bootstrap local cache
|
|
362
|
+
* flags.forEach(flag => {
|
|
363
|
+
* console.log(`${flag.key}: ${flag.enabled}`);
|
|
364
|
+
* });
|
|
365
|
+
* ```
|
|
366
|
+
*/
|
|
367
|
+
getAllFlags(environment?: string): Promise<FlagDefinition[]>;
|
|
368
|
+
/**
|
|
369
|
+
* Get only enterprise-scoped flags for the organization.
|
|
370
|
+
* Per SDK Developer Guide: GET /api/sdk/enterprise-flags
|
|
371
|
+
*
|
|
372
|
+
* Enterprise flags are shared across all applications in the organization.
|
|
373
|
+
*
|
|
374
|
+
* @param environment - Environment to evaluate enabled state for (default: 'development')
|
|
375
|
+
* @returns Promise<FlagDefinition[]> - List of enterprise flag definitions
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* ```typescript
|
|
379
|
+
* // Fetch enterprise-only flags
|
|
380
|
+
* const enterpriseFlags = await client.getEnterpriseFlags('production');
|
|
381
|
+
* ```
|
|
382
|
+
*/
|
|
383
|
+
getEnterpriseFlags(environment?: string): Promise<FlagDefinition[]>;
|
|
202
384
|
}
|
|
203
385
|
|
|
204
386
|
/**
|
|
@@ -260,10 +442,12 @@ declare class TelemetryService {
|
|
|
260
442
|
private flush;
|
|
261
443
|
/**
|
|
262
444
|
* Send evaluation events to backend
|
|
445
|
+
* Per SDK Developer Guide: POST /api/telemetry/evaluations with { "evaluations": [...] }
|
|
263
446
|
*/
|
|
264
447
|
private sendEvaluations;
|
|
265
448
|
/**
|
|
266
449
|
* Send error events to backend
|
|
450
|
+
* Per SDK Developer Guide: POST /api/telemetry/errors with { "errors": [...] }
|
|
267
451
|
*/
|
|
268
452
|
private sendErrors;
|
|
269
453
|
/**
|
|
@@ -278,20 +462,25 @@ declare class TelemetryService {
|
|
|
278
462
|
|
|
279
463
|
/**
|
|
280
464
|
* Real-time updates service using Server-Sent Events (SSE)
|
|
465
|
+
* Uses @microsoft/fetch-event-source to support custom headers for authentication
|
|
466
|
+
* (native EventSource doesn't support custom headers)
|
|
281
467
|
*/
|
|
282
468
|
declare class RealtimeService {
|
|
283
469
|
private baseUrl;
|
|
284
470
|
private apiKey;
|
|
285
|
-
private
|
|
471
|
+
private abortController;
|
|
286
472
|
private reconnectAttempts;
|
|
287
473
|
private maxReconnectAttempts;
|
|
288
474
|
private reconnectDelay;
|
|
289
475
|
private maxReconnectDelay;
|
|
290
476
|
private listeners;
|
|
291
477
|
private onConnectionChange?;
|
|
478
|
+
private connected;
|
|
479
|
+
private authFailed;
|
|
292
480
|
constructor(baseUrl: string, apiKey: string, onConnectionChange?: (connected: boolean) => void);
|
|
293
481
|
/**
|
|
294
|
-
* Connect to SSE stream
|
|
482
|
+
* Connect to SSE stream using header-based authentication
|
|
483
|
+
* Per SDK Developer Guide: "Never pass API keys as query parameters"
|
|
295
484
|
*/
|
|
296
485
|
connect(): void;
|
|
297
486
|
/**
|
|
@@ -299,7 +488,7 @@ declare class RealtimeService {
|
|
|
299
488
|
*/
|
|
300
489
|
private handleMessage;
|
|
301
490
|
/**
|
|
302
|
-
* Handle disconnection and attempt reconnect
|
|
491
|
+
* Handle disconnection and attempt reconnect with exponential backoff
|
|
303
492
|
*/
|
|
304
493
|
private handleDisconnect;
|
|
305
494
|
/**
|
|
@@ -596,4 +785,4 @@ interface components {
|
|
|
596
785
|
pathItems: never;
|
|
597
786
|
}
|
|
598
787
|
|
|
599
|
-
export { type components as ApiTypes, type CacheEntry, type ErrorEvent, type EvaluationEvent, FlagCache, FlagClient, type FlagClientConfig, type FlagContext, type FlagEvaluationResult, type FlagUpdateEvent, RealtimeService, TelemetryService, type components };
|
|
788
|
+
export { type components as ApiTypes, type CacheEntry, type ErrorEvent, type EvaluationEvent, FlagCache, FlagClient, type FlagClientConfig, type FlagContext, type FlagDefinition, type FlagEvaluationResult, type FlagListResponse, type FlagUpdateEvent, RealtimeService, TelemetryService, type components };
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ interface FlagClientConfig {
|
|
|
11
11
|
applicationId?: string;
|
|
12
12
|
/** Base URL for the Savvagent API (default: production URL) */
|
|
13
13
|
baseUrl?: string;
|
|
14
|
+
/** Environment for flag evaluation (e.g., "development", "staging", "production", "beta"). Default: "production" */
|
|
15
|
+
environment?: string;
|
|
14
16
|
/** Enable real-time flag updates via SSE (default: true) */
|
|
15
17
|
enableRealtime?: boolean;
|
|
16
18
|
/** Cache TTL in milliseconds (default: 60000 = 1 minute) */
|
|
@@ -25,25 +27,34 @@ interface FlagClientConfig {
|
|
|
25
27
|
defaultLanguage?: string;
|
|
26
28
|
/** Disable automatic browser language detection (default: false) */
|
|
27
29
|
disableLanguageDetection?: boolean;
|
|
30
|
+
/** Number of retry attempts for transient failures (default: 3) */
|
|
31
|
+
retryAttempts?: number;
|
|
32
|
+
/** Base delay between retries in milliseconds (default: 1000) */
|
|
33
|
+
retryDelay?: number;
|
|
34
|
+
/** Retry backoff strategy: 'linear' or 'exponential' (default: 'exponential') */
|
|
35
|
+
retryBackoff?: 'linear' | 'exponential';
|
|
28
36
|
}
|
|
29
37
|
/**
|
|
30
38
|
* Context passed to flag evaluation
|
|
39
|
+
* Per SDK Developer Guide: https://docs.savvagent.com/sdk-developer-guide
|
|
31
40
|
*/
|
|
32
41
|
interface FlagContext {
|
|
33
|
-
/** User ID for targeted rollouts (logged-in users) */
|
|
42
|
+
/** User ID for targeted rollouts (logged-in users) - required for percentage rollouts */
|
|
34
43
|
user_id?: string;
|
|
35
|
-
/** Anonymous ID for consistent rollouts (anonymous users) */
|
|
44
|
+
/** Anonymous ID for consistent rollouts (anonymous users) - alternative to user_id */
|
|
36
45
|
anonymous_id?: string;
|
|
37
46
|
/** Session ID as fallback identifier */
|
|
38
47
|
session_id?: string;
|
|
39
|
-
/**
|
|
48
|
+
/** Target environment (e.g., "production", "staging") */
|
|
49
|
+
environment?: string;
|
|
50
|
+
/** Organization ID for multi-tenant apps */
|
|
51
|
+
organization_id?: string;
|
|
52
|
+
/** Application ID for hierarchical flag lookup (auto-injected from config) */
|
|
40
53
|
application_id?: string;
|
|
41
|
-
/** User's language
|
|
54
|
+
/** User's language code (e.g., "en", "es") */
|
|
42
55
|
language?: string;
|
|
43
56
|
/** Custom attributes for targeting rules */
|
|
44
57
|
attributes?: Record<string, any>;
|
|
45
|
-
/** Environment (dev, staging, production) */
|
|
46
|
-
environment?: string;
|
|
47
58
|
}
|
|
48
59
|
/**
|
|
49
60
|
* Result from flag evaluation
|
|
@@ -105,6 +116,43 @@ interface FlagUpdateEvent {
|
|
|
105
116
|
flagKey: string;
|
|
106
117
|
data?: any;
|
|
107
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Flag definition returned from getAllFlags endpoint
|
|
121
|
+
* Per SDK Developer Guide: GET /api/sdk/flags
|
|
122
|
+
*/
|
|
123
|
+
interface FlagDefinition {
|
|
124
|
+
/** Flag key */
|
|
125
|
+
key: string;
|
|
126
|
+
/** Enabled state for the requested environment */
|
|
127
|
+
enabled: boolean;
|
|
128
|
+
/** Flag scope: "application" or "enterprise" */
|
|
129
|
+
scope: 'application' | 'enterprise';
|
|
130
|
+
/** Environment configuration with enabled state and rollout percentage */
|
|
131
|
+
environments: Record<string, {
|
|
132
|
+
enabled: boolean;
|
|
133
|
+
rollout_percentage?: number;
|
|
134
|
+
}>;
|
|
135
|
+
/** Variation definitions for A/B testing (if any) */
|
|
136
|
+
variations?: Record<string, any> | null;
|
|
137
|
+
/** Dynamic configuration attached to the flag */
|
|
138
|
+
configuration?: any;
|
|
139
|
+
/** Flag version for cache invalidation */
|
|
140
|
+
version: number;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Response from getAllFlags endpoint
|
|
144
|
+
* Per SDK Developer Guide: GET /api/sdk/flags
|
|
145
|
+
*/
|
|
146
|
+
interface FlagListResponse {
|
|
147
|
+
/** List of flag definitions */
|
|
148
|
+
flags: FlagDefinition[];
|
|
149
|
+
/** Total count of flags returned */
|
|
150
|
+
count: number;
|
|
151
|
+
/** Organization ID */
|
|
152
|
+
organization_id: string;
|
|
153
|
+
/** Application ID (present for SDK key auth) */
|
|
154
|
+
application_id?: string;
|
|
155
|
+
}
|
|
108
156
|
|
|
109
157
|
/**
|
|
110
158
|
* Savvagent Client for feature flag evaluation with AI-powered error detection
|
|
@@ -117,6 +165,9 @@ declare class FlagClient {
|
|
|
117
165
|
private anonymousId;
|
|
118
166
|
private userId;
|
|
119
167
|
private detectedLanguage;
|
|
168
|
+
private overrides;
|
|
169
|
+
private overrideListeners;
|
|
170
|
+
private authFailed;
|
|
120
171
|
constructor(config: FlagClientConfig);
|
|
121
172
|
/**
|
|
122
173
|
* Get or create an anonymous ID for consistent flag evaluation
|
|
@@ -139,6 +190,16 @@ declare class FlagClient {
|
|
|
139
190
|
* Get the current user ID
|
|
140
191
|
*/
|
|
141
192
|
getUserId(): string | null;
|
|
193
|
+
/**
|
|
194
|
+
* Set the environment for flag evaluation
|
|
195
|
+
* Useful for dynamically switching environments (e.g., dev tools)
|
|
196
|
+
* @param environment - The environment name (e.g., "development", "staging", "production", "beta")
|
|
197
|
+
*/
|
|
198
|
+
setEnvironment(environment: string): void;
|
|
199
|
+
/**
|
|
200
|
+
* Get the current environment
|
|
201
|
+
*/
|
|
202
|
+
getEnvironment(): string;
|
|
142
203
|
/**
|
|
143
204
|
* Get the current anonymous ID
|
|
144
205
|
*/
|
|
@@ -148,6 +209,23 @@ declare class FlagClient {
|
|
|
148
209
|
* @param overrides - Context overrides
|
|
149
210
|
*/
|
|
150
211
|
private buildContext;
|
|
212
|
+
/**
|
|
213
|
+
* Check if an error is retryable (transient failure)
|
|
214
|
+
* @param error - The error to check
|
|
215
|
+
* @param status - HTTP status code (if available)
|
|
216
|
+
*/
|
|
217
|
+
private isRetryableError;
|
|
218
|
+
/**
|
|
219
|
+
* Calculate delay for retry attempt
|
|
220
|
+
* @param attempt - Current attempt number (1-based)
|
|
221
|
+
*/
|
|
222
|
+
private getRetryDelay;
|
|
223
|
+
/**
|
|
224
|
+
* Execute a fetch request with retry logic
|
|
225
|
+
* @param requestFn - Function that returns a fetch promise
|
|
226
|
+
* @param operationName - Name of the operation for logging
|
|
227
|
+
*/
|
|
228
|
+
private fetchWithRetry;
|
|
151
229
|
/**
|
|
152
230
|
* Check if a feature flag is enabled
|
|
153
231
|
* @param flagKey - The flag key to evaluate
|
|
@@ -199,6 +277,110 @@ declare class FlagClient {
|
|
|
199
277
|
* Close the client and cleanup resources
|
|
200
278
|
*/
|
|
201
279
|
close(): void;
|
|
280
|
+
/**
|
|
281
|
+
* Set a local override for a flag.
|
|
282
|
+
* Overrides take precedence over server values and cache.
|
|
283
|
+
*
|
|
284
|
+
* @param flagKey - The flag key to override
|
|
285
|
+
* @param value - The override value (true/false)
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* ```typescript
|
|
289
|
+
* // Force a flag to be enabled locally
|
|
290
|
+
* client.setOverride('new-feature', true);
|
|
291
|
+
* ```
|
|
292
|
+
*/
|
|
293
|
+
setOverride(flagKey: string, value: boolean): void;
|
|
294
|
+
/**
|
|
295
|
+
* Clear a local override for a flag.
|
|
296
|
+
* The flag will return to using server/cached values.
|
|
297
|
+
*
|
|
298
|
+
* @param flagKey - The flag key to clear override for
|
|
299
|
+
*/
|
|
300
|
+
clearOverride(flagKey: string): void;
|
|
301
|
+
/**
|
|
302
|
+
* Clear all local overrides.
|
|
303
|
+
*/
|
|
304
|
+
clearAllOverrides(): void;
|
|
305
|
+
/**
|
|
306
|
+
* Check if a flag has a local override.
|
|
307
|
+
*
|
|
308
|
+
* @param flagKey - The flag key to check
|
|
309
|
+
* @returns true if the flag has an override
|
|
310
|
+
*/
|
|
311
|
+
hasOverride(flagKey: string): boolean;
|
|
312
|
+
/**
|
|
313
|
+
* Get the override value for a flag.
|
|
314
|
+
*
|
|
315
|
+
* @param flagKey - The flag key to get override for
|
|
316
|
+
* @returns The override value, or undefined if not set
|
|
317
|
+
*/
|
|
318
|
+
getOverride(flagKey: string): boolean | undefined;
|
|
319
|
+
/**
|
|
320
|
+
* Get all current overrides.
|
|
321
|
+
*
|
|
322
|
+
* @returns Record of flag keys to override values
|
|
323
|
+
*/
|
|
324
|
+
getOverrides(): Record<string, boolean>;
|
|
325
|
+
/**
|
|
326
|
+
* Set multiple overrides at once.
|
|
327
|
+
*
|
|
328
|
+
* @param overrides - Record of flag keys to override values
|
|
329
|
+
*/
|
|
330
|
+
setOverrides(overrides: Record<string, boolean>): void;
|
|
331
|
+
/**
|
|
332
|
+
* Subscribe to override changes.
|
|
333
|
+
* Useful for React components to re-render when overrides change.
|
|
334
|
+
*
|
|
335
|
+
* @param callback - Function to call when overrides change
|
|
336
|
+
* @returns Unsubscribe function
|
|
337
|
+
*/
|
|
338
|
+
onOverrideChange(callback: () => void): () => void;
|
|
339
|
+
/**
|
|
340
|
+
* Notify all override listeners of a change.
|
|
341
|
+
*/
|
|
342
|
+
private notifyOverrideListeners;
|
|
343
|
+
/**
|
|
344
|
+
* Get all flags for the application (and enterprise-scoped flags).
|
|
345
|
+
* Per SDK Developer Guide: GET /api/sdk/flags
|
|
346
|
+
*
|
|
347
|
+
* Use cases:
|
|
348
|
+
* - Local override UI: Display all available flags for developers to toggle
|
|
349
|
+
* - Offline mode: Pre-fetch flags for mobile/desktop apps
|
|
350
|
+
* - SDK initialization: Bootstrap SDK with all flag values on startup
|
|
351
|
+
* - DevTools integration: Show available flags in browser dev panels
|
|
352
|
+
*
|
|
353
|
+
* @param environment - Environment to evaluate enabled state for (default: 'development')
|
|
354
|
+
* @returns Promise<FlagDefinition[]> - List of flag definitions
|
|
355
|
+
*
|
|
356
|
+
* @example
|
|
357
|
+
* ```typescript
|
|
358
|
+
* // Fetch all flags for development
|
|
359
|
+
* const flags = await client.getAllFlags('development');
|
|
360
|
+
*
|
|
361
|
+
* // Bootstrap local cache
|
|
362
|
+
* flags.forEach(flag => {
|
|
363
|
+
* console.log(`${flag.key}: ${flag.enabled}`);
|
|
364
|
+
* });
|
|
365
|
+
* ```
|
|
366
|
+
*/
|
|
367
|
+
getAllFlags(environment?: string): Promise<FlagDefinition[]>;
|
|
368
|
+
/**
|
|
369
|
+
* Get only enterprise-scoped flags for the organization.
|
|
370
|
+
* Per SDK Developer Guide: GET /api/sdk/enterprise-flags
|
|
371
|
+
*
|
|
372
|
+
* Enterprise flags are shared across all applications in the organization.
|
|
373
|
+
*
|
|
374
|
+
* @param environment - Environment to evaluate enabled state for (default: 'development')
|
|
375
|
+
* @returns Promise<FlagDefinition[]> - List of enterprise flag definitions
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* ```typescript
|
|
379
|
+
* // Fetch enterprise-only flags
|
|
380
|
+
* const enterpriseFlags = await client.getEnterpriseFlags('production');
|
|
381
|
+
* ```
|
|
382
|
+
*/
|
|
383
|
+
getEnterpriseFlags(environment?: string): Promise<FlagDefinition[]>;
|
|
202
384
|
}
|
|
203
385
|
|
|
204
386
|
/**
|
|
@@ -260,10 +442,12 @@ declare class TelemetryService {
|
|
|
260
442
|
private flush;
|
|
261
443
|
/**
|
|
262
444
|
* Send evaluation events to backend
|
|
445
|
+
* Per SDK Developer Guide: POST /api/telemetry/evaluations with { "evaluations": [...] }
|
|
263
446
|
*/
|
|
264
447
|
private sendEvaluations;
|
|
265
448
|
/**
|
|
266
449
|
* Send error events to backend
|
|
450
|
+
* Per SDK Developer Guide: POST /api/telemetry/errors with { "errors": [...] }
|
|
267
451
|
*/
|
|
268
452
|
private sendErrors;
|
|
269
453
|
/**
|
|
@@ -278,20 +462,25 @@ declare class TelemetryService {
|
|
|
278
462
|
|
|
279
463
|
/**
|
|
280
464
|
* Real-time updates service using Server-Sent Events (SSE)
|
|
465
|
+
* Uses @microsoft/fetch-event-source to support custom headers for authentication
|
|
466
|
+
* (native EventSource doesn't support custom headers)
|
|
281
467
|
*/
|
|
282
468
|
declare class RealtimeService {
|
|
283
469
|
private baseUrl;
|
|
284
470
|
private apiKey;
|
|
285
|
-
private
|
|
471
|
+
private abortController;
|
|
286
472
|
private reconnectAttempts;
|
|
287
473
|
private maxReconnectAttempts;
|
|
288
474
|
private reconnectDelay;
|
|
289
475
|
private maxReconnectDelay;
|
|
290
476
|
private listeners;
|
|
291
477
|
private onConnectionChange?;
|
|
478
|
+
private connected;
|
|
479
|
+
private authFailed;
|
|
292
480
|
constructor(baseUrl: string, apiKey: string, onConnectionChange?: (connected: boolean) => void);
|
|
293
481
|
/**
|
|
294
|
-
* Connect to SSE stream
|
|
482
|
+
* Connect to SSE stream using header-based authentication
|
|
483
|
+
* Per SDK Developer Guide: "Never pass API keys as query parameters"
|
|
295
484
|
*/
|
|
296
485
|
connect(): void;
|
|
297
486
|
/**
|
|
@@ -299,7 +488,7 @@ declare class RealtimeService {
|
|
|
299
488
|
*/
|
|
300
489
|
private handleMessage;
|
|
301
490
|
/**
|
|
302
|
-
* Handle disconnection and attempt reconnect
|
|
491
|
+
* Handle disconnection and attempt reconnect with exponential backoff
|
|
303
492
|
*/
|
|
304
493
|
private handleDisconnect;
|
|
305
494
|
/**
|
|
@@ -596,4 +785,4 @@ interface components {
|
|
|
596
785
|
pathItems: never;
|
|
597
786
|
}
|
|
598
787
|
|
|
599
|
-
export { type components as ApiTypes, type CacheEntry, type ErrorEvent, type EvaluationEvent, FlagCache, FlagClient, type FlagClientConfig, type FlagContext, type FlagEvaluationResult, type FlagUpdateEvent, RealtimeService, TelemetryService, type components };
|
|
788
|
+
export { type components as ApiTypes, type CacheEntry, type ErrorEvent, type EvaluationEvent, FlagCache, FlagClient, type FlagClientConfig, type FlagContext, type FlagDefinition, type FlagEvaluationResult, type FlagListResponse, type FlagUpdateEvent, RealtimeService, TelemetryService, type components };
|