@sparkleideas/integration 3.0.1
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 +270 -0
- package/package.json +55 -0
- package/src/__tests__/agent-adapter.test.ts +271 -0
- package/src/__tests__/agentic-flow-agent.test.ts +176 -0
- package/src/__tests__/token-optimizer.test.ts +176 -0
- package/src/agent-adapter.ts +651 -0
- package/src/agentic-flow-agent.ts +802 -0
- package/src/agentic-flow-bridge.ts +803 -0
- package/src/attention-coordinator.ts +679 -0
- package/src/feature-flags.ts +485 -0
- package/src/index.ts +466 -0
- package/src/long-running-worker.ts +871 -0
- package/src/multi-model-router.ts +1079 -0
- package/src/provider-adapter.ts +1168 -0
- package/src/sdk-bridge.ts +435 -0
- package/src/sona-adapter.ts +824 -0
- package/src/specialized-worker.ts +864 -0
- package/src/swarm-adapter.ts +1112 -0
- package/src/token-optimizer.ts +306 -0
- package/src/types.ts +494 -0
- package/src/worker-base.ts +822 -0
- package/src/worker-pool.ts +933 -0
- package/tmp.json +0 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature Flags Configuration System
|
|
3
|
+
*
|
|
4
|
+
* Provides runtime feature flag management for v3 integration,
|
|
5
|
+
* enabling gradual rollout, A/B testing, and environment-specific
|
|
6
|
+
* feature enablement.
|
|
7
|
+
*
|
|
8
|
+
* @module v3/integration/feature-flags
|
|
9
|
+
* @version 3.0.0-alpha.1
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { EventEmitter } from 'events';
|
|
13
|
+
import type { FeatureFlags, DEFAULT_FEATURE_FLAGS } from './types.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Feature flag metadata
|
|
17
|
+
*/
|
|
18
|
+
interface FeatureFlagInfo {
|
|
19
|
+
/** Flag name */
|
|
20
|
+
name: keyof FeatureFlags;
|
|
21
|
+
/** Human-readable description */
|
|
22
|
+
description: string;
|
|
23
|
+
/** Default value */
|
|
24
|
+
defaultValue: boolean;
|
|
25
|
+
/** Whether the flag is experimental */
|
|
26
|
+
experimental: boolean;
|
|
27
|
+
/** Performance impact if enabled */
|
|
28
|
+
performanceImpact: 'none' | 'low' | 'medium' | 'high';
|
|
29
|
+
/** Dependencies on other flags */
|
|
30
|
+
dependencies: (keyof FeatureFlags)[];
|
|
31
|
+
/** Minimum SDK version required */
|
|
32
|
+
minSDKVersion?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Feature flag definitions with metadata
|
|
37
|
+
*/
|
|
38
|
+
const FEATURE_FLAG_DEFINITIONS: Record<keyof FeatureFlags, FeatureFlagInfo> = {
|
|
39
|
+
enableSONA: {
|
|
40
|
+
name: 'enableSONA',
|
|
41
|
+
description: 'Enable SONA (Self-Optimizing Neural Architecture) learning system',
|
|
42
|
+
defaultValue: true,
|
|
43
|
+
experimental: false,
|
|
44
|
+
performanceImpact: 'low',
|
|
45
|
+
dependencies: [],
|
|
46
|
+
},
|
|
47
|
+
enableFlashAttention: {
|
|
48
|
+
name: 'enableFlashAttention',
|
|
49
|
+
description: 'Enable Flash Attention for 2.49x-7.47x speedup',
|
|
50
|
+
defaultValue: true,
|
|
51
|
+
experimental: false,
|
|
52
|
+
performanceImpact: 'none',
|
|
53
|
+
dependencies: [],
|
|
54
|
+
},
|
|
55
|
+
enableAgentDB: {
|
|
56
|
+
name: 'enableAgentDB',
|
|
57
|
+
description: 'Enable AgentDB vector search with HNSW indexing',
|
|
58
|
+
defaultValue: true,
|
|
59
|
+
experimental: false,
|
|
60
|
+
performanceImpact: 'low',
|
|
61
|
+
dependencies: [],
|
|
62
|
+
},
|
|
63
|
+
enableTrajectoryTracking: {
|
|
64
|
+
name: 'enableTrajectoryTracking',
|
|
65
|
+
description: 'Enable trajectory tracking for experience replay',
|
|
66
|
+
defaultValue: true,
|
|
67
|
+
experimental: false,
|
|
68
|
+
performanceImpact: 'low',
|
|
69
|
+
dependencies: ['enableSONA'],
|
|
70
|
+
},
|
|
71
|
+
enableGNN: {
|
|
72
|
+
name: 'enableGNN',
|
|
73
|
+
description: 'Enable GNN query refinement for +12.4% recall improvement',
|
|
74
|
+
defaultValue: true,
|
|
75
|
+
experimental: false,
|
|
76
|
+
performanceImpact: 'medium',
|
|
77
|
+
dependencies: ['enableAgentDB'],
|
|
78
|
+
minSDKVersion: '2.0.0',
|
|
79
|
+
},
|
|
80
|
+
enableIntelligenceBridge: {
|
|
81
|
+
name: 'enableIntelligenceBridge',
|
|
82
|
+
description: 'Enable intelligence bridge tools for pattern management',
|
|
83
|
+
defaultValue: true,
|
|
84
|
+
experimental: false,
|
|
85
|
+
performanceImpact: 'low',
|
|
86
|
+
dependencies: ['enableSONA'],
|
|
87
|
+
},
|
|
88
|
+
enableQUICTransport: {
|
|
89
|
+
name: 'enableQUICTransport',
|
|
90
|
+
description: 'Enable QUIC transport for faster agent communication',
|
|
91
|
+
defaultValue: false,
|
|
92
|
+
experimental: true,
|
|
93
|
+
performanceImpact: 'low',
|
|
94
|
+
dependencies: [],
|
|
95
|
+
minSDKVersion: '2.0.1',
|
|
96
|
+
},
|
|
97
|
+
enableNightlyLearning: {
|
|
98
|
+
name: 'enableNightlyLearning',
|
|
99
|
+
description: 'Enable automated nightly learning cycles',
|
|
100
|
+
defaultValue: false,
|
|
101
|
+
experimental: true,
|
|
102
|
+
performanceImpact: 'high',
|
|
103
|
+
dependencies: ['enableSONA', 'enableTrajectoryTracking'],
|
|
104
|
+
minSDKVersion: '2.0.1',
|
|
105
|
+
},
|
|
106
|
+
enableAutoConsolidation: {
|
|
107
|
+
name: 'enableAutoConsolidation',
|
|
108
|
+
description: 'Enable automatic pattern consolidation',
|
|
109
|
+
defaultValue: true,
|
|
110
|
+
experimental: false,
|
|
111
|
+
performanceImpact: 'low',
|
|
112
|
+
dependencies: ['enableSONA'],
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Feature flag source (where the value came from)
|
|
118
|
+
*/
|
|
119
|
+
type FlagSource = 'default' | 'config' | 'environment' | 'runtime';
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* FeatureFlagManager - Runtime feature flag management
|
|
123
|
+
*/
|
|
124
|
+
export class FeatureFlagManager extends EventEmitter {
|
|
125
|
+
private flags: FeatureFlags;
|
|
126
|
+
private sources: Map<keyof FeatureFlags, FlagSource> = new Map();
|
|
127
|
+
private overrides: Map<keyof FeatureFlags, boolean> = new Map();
|
|
128
|
+
private initialized: boolean = false;
|
|
129
|
+
|
|
130
|
+
constructor(initialFlags?: Partial<FeatureFlags>) {
|
|
131
|
+
super();
|
|
132
|
+
this.flags = this.initializeFlags(initialFlags);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Initialize the feature flag manager
|
|
137
|
+
*/
|
|
138
|
+
async initialize(): Promise<void> {
|
|
139
|
+
if (this.initialized) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Load from environment variables
|
|
144
|
+
this.loadFromEnvironment();
|
|
145
|
+
|
|
146
|
+
// Validate dependencies
|
|
147
|
+
this.validateDependencies();
|
|
148
|
+
|
|
149
|
+
this.initialized = true;
|
|
150
|
+
this.emit('initialized', { flags: this.getAllFlags() });
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Get all feature flags
|
|
155
|
+
*/
|
|
156
|
+
getAllFlags(): FeatureFlags {
|
|
157
|
+
const result = { ...this.flags };
|
|
158
|
+
|
|
159
|
+
// Apply overrides
|
|
160
|
+
for (const [flag, value] of this.overrides) {
|
|
161
|
+
result[flag] = value;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Check if a feature is enabled
|
|
169
|
+
*/
|
|
170
|
+
isEnabled(flag: keyof FeatureFlags): boolean {
|
|
171
|
+
// Check override first
|
|
172
|
+
if (this.overrides.has(flag)) {
|
|
173
|
+
return this.overrides.get(flag)!;
|
|
174
|
+
}
|
|
175
|
+
return this.flags[flag];
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Enable a feature
|
|
180
|
+
*/
|
|
181
|
+
enable(flag: keyof FeatureFlags, runtime: boolean = true): void {
|
|
182
|
+
const previousValue = this.isEnabled(flag);
|
|
183
|
+
|
|
184
|
+
// Check dependencies
|
|
185
|
+
const info = FEATURE_FLAG_DEFINITIONS[flag];
|
|
186
|
+
for (const dep of info.dependencies) {
|
|
187
|
+
if (!this.isEnabled(dep)) {
|
|
188
|
+
throw new Error(
|
|
189
|
+
`Cannot enable '${flag}': dependency '${dep}' is not enabled`
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (runtime) {
|
|
195
|
+
this.overrides.set(flag, true);
|
|
196
|
+
this.sources.set(flag, 'runtime');
|
|
197
|
+
} else {
|
|
198
|
+
this.flags[flag] = true;
|
|
199
|
+
this.sources.set(flag, 'config');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (!previousValue) {
|
|
203
|
+
this.emit('flag-changed', { flag, previousValue, newValue: true });
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Disable a feature
|
|
209
|
+
*/
|
|
210
|
+
disable(flag: keyof FeatureFlags, runtime: boolean = true): void {
|
|
211
|
+
const previousValue = this.isEnabled(flag);
|
|
212
|
+
|
|
213
|
+
// Check for dependent features
|
|
214
|
+
const dependents = this.getDependentFlags(flag);
|
|
215
|
+
for (const dep of dependents) {
|
|
216
|
+
if (this.isEnabled(dep)) {
|
|
217
|
+
console.warn(
|
|
218
|
+
`Warning: Disabling '${flag}' may affect '${dep}' which depends on it`
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (runtime) {
|
|
224
|
+
this.overrides.set(flag, false);
|
|
225
|
+
this.sources.set(flag, 'runtime');
|
|
226
|
+
} else {
|
|
227
|
+
this.flags[flag] = false;
|
|
228
|
+
this.sources.set(flag, 'config');
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (previousValue) {
|
|
232
|
+
this.emit('flag-changed', { flag, previousValue, newValue: false });
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Toggle a feature
|
|
238
|
+
*/
|
|
239
|
+
toggle(flag: keyof FeatureFlags): boolean {
|
|
240
|
+
const current = this.isEnabled(flag);
|
|
241
|
+
if (current) {
|
|
242
|
+
this.disable(flag);
|
|
243
|
+
} else {
|
|
244
|
+
this.enable(flag);
|
|
245
|
+
}
|
|
246
|
+
return !current;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Reset a feature to its default value
|
|
251
|
+
*/
|
|
252
|
+
reset(flag: keyof FeatureFlags): void {
|
|
253
|
+
const info = FEATURE_FLAG_DEFINITIONS[flag];
|
|
254
|
+
const previousValue = this.isEnabled(flag);
|
|
255
|
+
|
|
256
|
+
this.overrides.delete(flag);
|
|
257
|
+
this.flags[flag] = info.defaultValue;
|
|
258
|
+
this.sources.set(flag, 'default');
|
|
259
|
+
|
|
260
|
+
if (previousValue !== info.defaultValue) {
|
|
261
|
+
this.emit('flag-changed', {
|
|
262
|
+
flag,
|
|
263
|
+
previousValue,
|
|
264
|
+
newValue: info.defaultValue
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Reset all features to default values
|
|
271
|
+
*/
|
|
272
|
+
resetAll(): void {
|
|
273
|
+
this.overrides.clear();
|
|
274
|
+
for (const [flag, info] of Object.entries(FEATURE_FLAG_DEFINITIONS)) {
|
|
275
|
+
this.flags[flag as keyof FeatureFlags] = info.defaultValue;
|
|
276
|
+
this.sources.set(flag as keyof FeatureFlags, 'default');
|
|
277
|
+
}
|
|
278
|
+
this.emit('flags-reset');
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Get feature flag information
|
|
283
|
+
*/
|
|
284
|
+
getFlagInfo(flag: keyof FeatureFlags): FeatureFlagInfo & {
|
|
285
|
+
currentValue: boolean;
|
|
286
|
+
source: FlagSource;
|
|
287
|
+
} {
|
|
288
|
+
return {
|
|
289
|
+
...FEATURE_FLAG_DEFINITIONS[flag],
|
|
290
|
+
currentValue: this.isEnabled(flag),
|
|
291
|
+
source: this.sources.get(flag) || 'default',
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Get all flag information
|
|
297
|
+
*/
|
|
298
|
+
getAllFlagInfo(): Array<FeatureFlagInfo & {
|
|
299
|
+
currentValue: boolean;
|
|
300
|
+
source: FlagSource;
|
|
301
|
+
}> {
|
|
302
|
+
return Object.keys(FEATURE_FLAG_DEFINITIONS).map(
|
|
303
|
+
flag => this.getFlagInfo(flag as keyof FeatureFlags)
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Get enabled experimental features
|
|
309
|
+
*/
|
|
310
|
+
getEnabledExperimentalFeatures(): (keyof FeatureFlags)[] {
|
|
311
|
+
return Object.entries(FEATURE_FLAG_DEFINITIONS)
|
|
312
|
+
.filter(([flag, info]) => info.experimental && this.isEnabled(flag as keyof FeatureFlags))
|
|
313
|
+
.map(([flag]) => flag as keyof FeatureFlags);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Get performance impact of enabled features
|
|
318
|
+
*/
|
|
319
|
+
getPerformanceImpact(): {
|
|
320
|
+
none: (keyof FeatureFlags)[];
|
|
321
|
+
low: (keyof FeatureFlags)[];
|
|
322
|
+
medium: (keyof FeatureFlags)[];
|
|
323
|
+
high: (keyof FeatureFlags)[];
|
|
324
|
+
overall: 'none' | 'low' | 'medium' | 'high';
|
|
325
|
+
} {
|
|
326
|
+
const result = {
|
|
327
|
+
none: [] as (keyof FeatureFlags)[],
|
|
328
|
+
low: [] as (keyof FeatureFlags)[],
|
|
329
|
+
medium: [] as (keyof FeatureFlags)[],
|
|
330
|
+
high: [] as (keyof FeatureFlags)[],
|
|
331
|
+
overall: 'none' as 'none' | 'low' | 'medium' | 'high',
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
for (const [flag, info] of Object.entries(FEATURE_FLAG_DEFINITIONS)) {
|
|
335
|
+
if (this.isEnabled(flag as keyof FeatureFlags)) {
|
|
336
|
+
result[info.performanceImpact].push(flag as keyof FeatureFlags);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Determine overall impact
|
|
341
|
+
if (result.high.length > 0) {
|
|
342
|
+
result.overall = 'high';
|
|
343
|
+
} else if (result.medium.length > 0) {
|
|
344
|
+
result.overall = 'medium';
|
|
345
|
+
} else if (result.low.length > 0) {
|
|
346
|
+
result.overall = 'low';
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
return result;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Create feature flags from profile
|
|
354
|
+
*/
|
|
355
|
+
static fromProfile(profile: 'minimal' | 'standard' | 'full' | 'experimental'): FeatureFlags {
|
|
356
|
+
const profiles: Record<string, Partial<FeatureFlags>> = {
|
|
357
|
+
minimal: {
|
|
358
|
+
enableSONA: false,
|
|
359
|
+
enableFlashAttention: true,
|
|
360
|
+
enableAgentDB: true,
|
|
361
|
+
enableTrajectoryTracking: false,
|
|
362
|
+
enableGNN: false,
|
|
363
|
+
enableIntelligenceBridge: false,
|
|
364
|
+
enableQUICTransport: false,
|
|
365
|
+
enableNightlyLearning: false,
|
|
366
|
+
enableAutoConsolidation: false,
|
|
367
|
+
},
|
|
368
|
+
standard: {
|
|
369
|
+
enableSONA: true,
|
|
370
|
+
enableFlashAttention: true,
|
|
371
|
+
enableAgentDB: true,
|
|
372
|
+
enableTrajectoryTracking: true,
|
|
373
|
+
enableGNN: true,
|
|
374
|
+
enableIntelligenceBridge: true,
|
|
375
|
+
enableQUICTransport: false,
|
|
376
|
+
enableNightlyLearning: false,
|
|
377
|
+
enableAutoConsolidation: true,
|
|
378
|
+
},
|
|
379
|
+
full: {
|
|
380
|
+
enableSONA: true,
|
|
381
|
+
enableFlashAttention: true,
|
|
382
|
+
enableAgentDB: true,
|
|
383
|
+
enableTrajectoryTracking: true,
|
|
384
|
+
enableGNN: true,
|
|
385
|
+
enableIntelligenceBridge: true,
|
|
386
|
+
enableQUICTransport: true,
|
|
387
|
+
enableNightlyLearning: true,
|
|
388
|
+
enableAutoConsolidation: true,
|
|
389
|
+
},
|
|
390
|
+
experimental: {
|
|
391
|
+
enableSONA: true,
|
|
392
|
+
enableFlashAttention: true,
|
|
393
|
+
enableAgentDB: true,
|
|
394
|
+
enableTrajectoryTracking: true,
|
|
395
|
+
enableGNN: true,
|
|
396
|
+
enableIntelligenceBridge: true,
|
|
397
|
+
enableQUICTransport: true,
|
|
398
|
+
enableNightlyLearning: true,
|
|
399
|
+
enableAutoConsolidation: true,
|
|
400
|
+
},
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
const base: Record<string, boolean> = {};
|
|
404
|
+
for (const [flag, info] of Object.entries(FEATURE_FLAG_DEFINITIONS)) {
|
|
405
|
+
base[flag] = info.defaultValue;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return { ...base, ...profiles[profile] } as FeatureFlags;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// ===== Private Methods =====
|
|
412
|
+
|
|
413
|
+
private initializeFlags(initial?: Partial<FeatureFlags>): FeatureFlags {
|
|
414
|
+
const flags = {} as FeatureFlags;
|
|
415
|
+
|
|
416
|
+
for (const [flag, info] of Object.entries(FEATURE_FLAG_DEFINITIONS)) {
|
|
417
|
+
const key = flag as keyof FeatureFlags;
|
|
418
|
+
flags[key] = initial?.[key] ?? info.defaultValue;
|
|
419
|
+
this.sources.set(key, initial?.[key] !== undefined ? 'config' : 'default');
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return flags;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
private loadFromEnvironment(): void {
|
|
426
|
+
for (const flag of Object.keys(FEATURE_FLAG_DEFINITIONS)) {
|
|
427
|
+
const envVar = `CLAUDE_FLOW_${flag.replace(/([A-Z])/g, '_$1').toUpperCase()}`;
|
|
428
|
+
const envValue = process.env[envVar];
|
|
429
|
+
|
|
430
|
+
if (envValue !== undefined) {
|
|
431
|
+
const boolValue = envValue.toLowerCase() === 'true' || envValue === '1';
|
|
432
|
+
this.flags[flag as keyof FeatureFlags] = boolValue;
|
|
433
|
+
this.sources.set(flag as keyof FeatureFlags, 'environment');
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
private validateDependencies(): void {
|
|
439
|
+
for (const [flag, info] of Object.entries(FEATURE_FLAG_DEFINITIONS)) {
|
|
440
|
+
if (this.isEnabled(flag as keyof FeatureFlags)) {
|
|
441
|
+
for (const dep of info.dependencies) {
|
|
442
|
+
if (!this.isEnabled(dep)) {
|
|
443
|
+
console.warn(
|
|
444
|
+
`Warning: '${flag}' depends on '${dep}' which is disabled. ` +
|
|
445
|
+
`'${flag}' may not work correctly.`
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
private getDependentFlags(flag: keyof FeatureFlags): (keyof FeatureFlags)[] {
|
|
454
|
+
return Object.entries(FEATURE_FLAG_DEFINITIONS)
|
|
455
|
+
.filter(([_, info]) => info.dependencies.includes(flag))
|
|
456
|
+
.map(([name]) => name as keyof FeatureFlags);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Create and initialize a feature flag manager
|
|
462
|
+
*/
|
|
463
|
+
export async function createFeatureFlagManager(
|
|
464
|
+
initialFlags?: Partial<FeatureFlags>
|
|
465
|
+
): Promise<FeatureFlagManager> {
|
|
466
|
+
const manager = new FeatureFlagManager(initialFlags);
|
|
467
|
+
await manager.initialize();
|
|
468
|
+
return manager;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Default feature flag manager instance
|
|
473
|
+
*/
|
|
474
|
+
let defaultManager: FeatureFlagManager | null = null;
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Get the default feature flag manager
|
|
478
|
+
*/
|
|
479
|
+
export async function getDefaultFeatureFlagManager(): Promise<FeatureFlagManager> {
|
|
480
|
+
if (!defaultManager) {
|
|
481
|
+
defaultManager = new FeatureFlagManager();
|
|
482
|
+
await defaultManager.initialize();
|
|
483
|
+
}
|
|
484
|
+
return defaultManager;
|
|
485
|
+
}
|