import { BulkEvent } from '../bulkQueue'; import { ReflagContext } from '../context'; import { HttpClient } from '../httpClient'; import { Logger } from '../logger'; import { default as RateLimiter } from '../rateLimiter'; import { StorageAdapter } from '../storage'; import { FlagCache } from './flagCache'; export type RawFlagOptIn = { /** * Whether the current user has opted into the flag. */ userOptedIn: boolean; /** * Whether the current company has opted into the flag. */ companyOptedIn: boolean; /** * Whether either the current user or company has opted into the flag. */ isOptedIn: boolean; /** * Display name of the opt-in flag. */ name: string; /** * SDK-facing opt-in description. */ description: string | null; }; export type OptInFlag = RawFlagOptIn & { /** * Flag key. */ key: string; /** * Result of flag evaluation. */ isEnabled: boolean; }; /** * A flag fetched from the server. */ export type RawFlag = { /** * Flag key. */ key: string; /** * Result of flag evaluation. * Note: does not take local overrides into account. */ isEnabled: boolean; /** * If not null or undefined, the result is being overridden locally */ isEnabledOverride?: boolean | null; /** * Version of targeting rules. */ targetingVersion?: number; /** * Rule evaluation results. */ ruleEvaluationResults?: boolean[]; /** * Missing context fields. * @deprecated Use `evaluationErrors` and check for `MISSING_CONTEXT_FIELD`. */ missingContextFields?: string[]; /** * Non-fatal diagnostics produced while evaluating targeting rules. */ evaluationErrors?: Array<{ code: string; field: string; operator?: string; message: string; }>; /** * Whether end-user opt-in is enabled for this flag. */ optInEnabled?: boolean; /** * Opt-in metadata for this flag and the current context. */ optIn?: RawFlagOptIn | null; /** * Optional user-defined dynamic configuration. */ config?: { /** * The key of the matched configuration value. */ key: string; /** * The version of the matched configuration value. */ version?: number; /** * The optional user-supplied payload data. */ payload?: any; /** * The rule evaluation results. */ ruleEvaluationResults?: boolean[]; /** * The missing context fields. * @deprecated Use `evaluationErrors` and check for `MISSING_CONTEXT_FIELD`. */ missingContextFields?: string[]; /** * Non-fatal diagnostics produced while evaluating targeting rules. */ evaluationErrors?: RawFlag["evaluationErrors"]; }; }; export type RawFlags = Record; export type FallbackFlagOverride = { key: string; payload: any; } | true; type Config = { timeoutMs: number; staleTimeMs: number; staleWhileRevalidate: boolean; expireTimeMs: number; offline: boolean; }; export declare const DEFAULT_FLAGS_CONFIG: Config; export type FetchedFlagsResult = { flags: RawFlags; flagStateVersion?: number; }; export type FlagsFetchResult = FetchedFlagsResult & { success: boolean; }; export declare function validateFlagsResponse(response: any): FlagsFetchResult | undefined; export declare function flattenJSON(obj: Record): Record; /** * Event representing checking the flag evaluation result */ export interface CheckEvent { /** * `check-is-enabled` means `isEnabled` was checked, `check-config` means `config` was checked. */ action: "check-is-enabled" | "check-config"; /** * Flag key. */ key: string; /** * Result of flag or configuration evaluation. * If `action` is `check-is-enabled`, this is the result of the flag evaluation and `value` is a boolean. * If `action` is `check-config`, this is the result of the configuration evaluation. */ value?: boolean | { key: string; payload: any; }; /** * Version of targeting rules. */ version?: number; /** * Rule evaluation results. */ ruleEvaluationResults?: boolean[]; /** * Missing context fields. * @deprecated Use `evaluationErrors` and check for `MISSING_CONTEXT_FIELD`. */ missingContextFields?: string[]; /** * Non-fatal diagnostics produced while evaluating the flag. */ evaluationErrors?: RawFlag["evaluationErrors"]; } export type FlagOverrides = Record; type BootstrappedState = { flags: RawFlags; flagStateVersion?: number; }; type FlagsClientOptions = Partial & { bootstrappedState?: BootstrappedState; bootstrappedFlags?: RawFlags; fallbackFlags?: Record | string[]; cache?: FlagCache; rateLimiter?: RateLimiter; storage?: StorageAdapter; enqueueBulkEvent?: (event: BulkEvent) => Promise; }; /** * @internal */ export declare class FlagsClient { private httpClient; private context; private initialized; private bootstrapped; private initializationComplete; private rateLimiter; private readonly logger; private cache; private fetchedFlags; private fetchedFlagStateVersion; private fetchedFlagsContextVersion; private flagOverrides; private flags; private fallbackFlags; private contextFetchVersion; private optInFlagsRequested; private optInFlagsLoading; private optInFlagsLoadingGeneration; private optInMetadataRefreshAttemptContextVersion; private optInMetadataRefresh; private storage; private refreshEvents; private enqueueBulkEvent?; private config; private eventTarget; private abortController; constructor(httpClient: HttpClient, context: ReflagContext, logger: Logger, { bootstrappedState, bootstrappedFlags, cache, rateLimiter, fallbackFlags, storage, enqueueBulkEvent, ...config }?: FlagsClientOptions); initialize(): Promise; /** * Stop the client. */ stop(): void; getFlags(): RawFlags; getFetchedFlags(): RawFlags; requestOptInFlags(): void; getIsLoadingOptInFlags(): boolean; onOptInFlagsLoadingUpdated(callback: (isLoading: boolean) => void): void; resetOptInMetadataRefresh(): void; markBootstrappedStateApplied(): void; refreshOptInMetadataIfNeeded(): Promise; setContextWithoutFetch(context: ReflagContext, invalidatePendingFetches?: boolean): void; setFetchedFlags(fetchedFlags: RawFlags, triggerEvent?: boolean, flagStateVersion?: number): void; private shouldApplyFetchedFlagsResult; private applyFetchedFlagsResult; setContext(context: ReflagContext): Promise; updateFlags(triggerEvent?: boolean): void; setFlagOverride(key: string, isEnabled: boolean | null): void; getFlagOverride(key: string): boolean | null; /** * Register a callback to be called when the flags are updated. * Flags are not guaranteed to have actually changed when the callback is called. * * @param callback this will be called when the flags are updated. * @returns a function that can be called to remove the listener */ onUpdated(callback: () => void): void; /** * Send a flag "check" event. * * * @param checkEvent - The flag to send the event for. * @param cb - Callback to call after the event is sent. Might be skipped if the event was rate limited. */ sendCheckEvent(checkEvent: CheckEvent, cb: () => void): Promise; getFlagStateVersion(): number | undefined; fetchFlags(waitForVersion?: number): Promise; /** * Force refresh flags from the API, bypassing cache. */ refreshFlags(waitForVersion?: number): Promise; private setOverridesCache; private getOverridesCache; private maybeFetchFlags; private hasOptInMetadataForCurrentContext; private ensureOptInFlagsLoading; private startOptInFlagsLoading; private finishOptInFlagsLoading; private supersedeOptInFlagsLoading; private setOptInFlagsLoading; private mergeFlags; private triggerFlagsUpdated; private setupCache; private setupFallbackFlags; private fetchParams; private warnMissingFlagContextFields; } export {}; //# sourceMappingURL=flags.d.ts.map