@bluealba/pae-feature-flags
v1.0.0-feature-initial-feature-flags-poc-1238
Published
Feature flags client library for Blue Alba Platform
Maintainers
Readme
@bluealba/pae-feature-flags
Feature flags client library for Blue Alba Platform.
Installation
npm install @bluealba/pae-feature-flagsNestJS Usage
1. Import the Module
import { Module } from '@nestjs/common';
import { FeatureFlagsModule } from '@bluealba/pae-feature-flags';
@Module({
imports: [
FeatureFlagsModule.forRoot('http://gateway:3000'),
// Or with full configuration
FeatureFlagsModule.forRoot({
gatewayUrl: 'http://gateway:3000',
timeout: 5000,
maxRedirects: 5,
}),
],
})
export class MyServiceModule {}2. Use the Client
import { Injectable } from '@nestjs/common';
import { FeatureFlagsClient } from '@bluealba/pae-feature-flags';
@Injectable()
export class MyService {
constructor(private readonly featureFlagsClient: FeatureFlagsClient) {}
async doSomething() {
// Check if a feature is enabled
const isEnabled = await this.featureFlagsClient.isEnabled('my-feature');
if (isEnabled) {
// New implementation
} else {
// Old implementation
}
// Get variant for A/B testing
const variant = await this.featureFlagsClient.getVariant('ab-test', {
userId: '123',
tenantId: 'tenant-1',
});
if (variant?.name === 'variant-a') {
// Variant A logic
} else if (variant?.name === 'variant-b') {
// Variant B logic
}
// Evaluate multiple flags at once (more efficient)
const results = await this.featureFlagsClient.evaluateFlags(
['feature-a', 'feature-b', 'ab-test'],
{ userId: '123' }
);
const featureAEnabled = results.get('feature-a')?.enabled ?? false;
}
}React Usage
1. Setup the Provider
Wrap your application with the FeatureFlagsProvider:
import { FeatureFlagsProvider } from '@bluealba/pae-feature-flags';
function App() {
return (
<FeatureFlagsProvider
gatewayUrl="/api"
prefetchFlags={['new-ui', 'beta-feature']}
refreshInterval={60000}
>
<YourApp />
</FeatureFlagsProvider>
);
}Provider Props
gatewayUrl(string, optional): Base URL for the gateway API. Default:''prefetchFlags(string[], optional): Array of flag names to prefetch on mountrefreshInterval(number, optional): Interval in milliseconds for automatic refreshchildren(ReactNode): Child components
2. Use Feature Flags in Components
Simple Boolean Check with useFeatureFlag
import { useFeatureFlag } from '@bluealba/pae-feature-flags';
function MyComponent() {
const isNewUIEnabled = useFeatureFlag('new-ui', false);
return isNewUIEnabled ? <NewUI /> : <OldUI />;
}Conditional Rendering with FeatureFlagGuard
import { FeatureFlagGuard } from '@bluealba/pae-feature-flags';
function MyComponent() {
return (
<>
{/* Show feature if enabled */}
<FeatureFlagGuard flag="beta-feature">
<BetaFeature />
</FeatureFlagGuard>
{/* Show feature if enabled, fallback if disabled */}
<FeatureFlagGuard flag="new-ui" fallback={<OldUI />}>
<NewUI />
</FeatureFlagGuard>
{/* Inverted logic - show if disabled */}
<FeatureFlagGuard flag="maintenance-mode" invert>
<MainApp />
</FeatureFlagGuard>
</>
);
}Multivariant Flags with useVariant
For A/B testing and feature variants:
import { useVariant } from '@bluealba/pae-feature-flags';
function CheckoutFlow() {
const { variant, payload, isLoading } = useVariant('checkout-flow');
if (isLoading) {
return <Spinner />;
}
if (variant === 'new-checkout') {
return <NewCheckout config={payload} />;
}
if (variant === 'express-checkout') {
return <ExpressCheckout config={payload} />;
}
return <DefaultCheckout />;
}Access Full Context with useFeatureFlags
import { useFeatureFlags } from '@bluealba/pae-feature-flags';
function FlagsDebugPanel() {
const { flags, variants, isLoading, error, refresh } = useFeatureFlags();
const handleRefresh = async () => {
await refresh();
};
return (
<div>
<button onClick={handleRefresh} disabled={isLoading}>
Refresh Flags
</button>
{error && <div>Error: {error.message}</div>}
<div>Total flags loaded: {flags.size}</div>
<ul>
{Array.from(flags.entries()).map(([name, enabled]) => (
<li key={name}>
{name}: {enabled ? 'enabled' : 'disabled'}
</li>
))}
</ul>
</div>
);
}React Best Practices
- Prefetch Common Flags: Add frequently used flags to
prefetchFlagsfor better performance - Use FeatureFlagGuard: Cleaner than inline conditions for simple toggles
- Handle Loading States: Always handle
isLoadingwhen usinguseVariant - Provide Defaults: Always provide default values to
useFeatureFlag - Minimize Refresh: Don't set refresh intervals too low to avoid network overhead
API Reference
FeatureFlagsClient
isEnabled(flagName, defaultValue?, context?): Promise<boolean>
Evaluates if a feature flag is enabled.
flagName: Name of the feature flagdefaultValue: Default value if evaluation fails (default: false)context: Optional evaluation context (userId, tenantId, customProperties)
getVariant(flagName, context?): Promise<{name: string, payload: any} | null>
Gets the variant for a multivariant feature flag.
flagName: Name of the feature flagcontext: Optional evaluation context
evaluateFlags(flagNames, context?): Promise<Map<string, FlagEvaluationResult>>
Evaluates multiple feature flags in a single request.
flagNames: Array of feature flag namescontext: Optional evaluation context
License
PolyForm-Noncommercial-1.0.0
