/** * Feature flags — provider-neutral interface + an in-memory implementation. * * Vendor SDKs (LaunchDarkly, Flagsmith, Statsig, GrowthBook, OpenFeature) all * expose roughly the same shape: `isEnabled / variation / refresh`. The * `FeatureFlagAdapter` interface here is the common-denominator surface, and * `fromVendor()` wraps any duck-typed SDK into it without us depending on the * SDK package. */ export interface FlagContext { /** Stable user id when known. Used by sticky bucketing. */ userId?: string; /** Free-form attributes for vendor-side targeting (locale, plan, etc.). */ attributes?: Record; } export interface FeatureFlagAdapter { /** Boolean flag. */ isEnabled(flag: string, ctx?: FlagContext): boolean; /** Multi-variate / typed variation. */ variation(flag: string, defaultValue: T, ctx?: FlagContext): T; /** Optional async refresh (poll vendor, swap manifest). */ refresh?(): Promise; /** Subscribe to flag-set updates. Returns unsubscribe. */ subscribe?(listener: () => void): () => void; } export type InMemoryFlagsValue = boolean | string | number | Record; export interface InMemoryFlagsOptions { flags?: Record; /** Optional per-user override map: userId → { flag → value }. */ overrides?: Record>; } export declare class InMemoryFlags implements FeatureFlagAdapter { private flags; private overrides; private listeners; constructor(opts?: InMemoryFlagsOptions); set(flag: string, value: InMemoryFlagsValue): void; setOverride(userId: string, flag: string, value: InMemoryFlagsValue): void; clearOverride(userId: string, flag?: string): void; replaceAll(flags: Record): void; isEnabled(flag: string, ctx?: FlagContext): boolean; variation(flag: string, defaultValue: T, ctx?: FlagContext): T; subscribe(listener: () => void): () => void; private resolve; private notify; } /** * Wrap a vendor SDK client into `FeatureFlagAdapter`. We use a *duck-typed* * `client` so JORVEL doesn't take a hard dependency on any vendor package. * * Expected duck: * - `variation(flag, ctx?, defaultValue?)` returning any * - or `boolVariation(flag, ctx?, defaultValue?)` for the boolean fast path * * Provide your own `toClientContext` if the SDK takes a custom user shape. */ export interface VendorClientLike { variation?: (flag: string, ctxOrDefault?: unknown, maybeDefault?: unknown) => unknown; boolVariation?: (flag: string, ctxOrDefault?: unknown, maybeDefault?: unknown) => boolean; } export interface FromVendorOptions { /** Convert JORVEL context to whatever the SDK expects (e.g. `{ kind: 'user', key }`). */ toClientContext?: (ctx: FlagContext | undefined) => unknown; } export declare function fromVendor(client: VendorClientLike, opts?: FromVendorOptions): FeatureFlagAdapter; export declare function setFeatureFlags(adapter: FeatureFlagAdapter): void; export declare function getFeatureFlags(): FeatureFlagAdapter | undefined; /** Convenience — returns `false` when no adapter is registered. */ export declare function isFeatureEnabled(flag: string, ctx?: FlagContext): boolean; /** Convenience — returns `defaultValue` when no adapter is registered. */ export declare function featureVariation(flag: string, defaultValue: T, ctx?: FlagContext): T; /** @internal — testing */ export declare function _resetFeatureFlags(): void; //# sourceMappingURL=feature-flags.d.ts.map