UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

290 lines 9.46 kB
/** * @beignet/core/flags * * Provider-neutral feature flag primitives for Beignet applications. */ type MaybePromise<T> = T | Promise<T>; /** * JSON-compatible value used by object flags and flag metadata. */ export type FlagJsonValue = null | boolean | number | string | readonly FlagJsonValue[] | { readonly [key: string]: FlagJsonValue; }; /** * Object-valued flags intentionally exclude scalar JSON values so the flag * kind remains predictable. */ export type FlagObjectValue = readonly FlagJsonValue[] | { readonly [key: string]: FlagJsonValue; }; /** * Value kinds supported by Beignet flags. */ export type FlagValue = boolean | string | number | FlagObjectValue; /** * Stable feature flag key. */ export type FlagKey = string; /** * Feature flag value kind. */ export type FlagValueKind = "boolean" | "string" | "number" | "object"; /** * Subject used for provider-neutral flag targeting. */ export type FlagSubject = { type: string; id: string; }; /** * Tenant or account used for provider-neutral flag targeting. */ export type FlagTenant = { id: string; slug?: string; }; /** * Attribute value accepted by the provider-neutral flag context. */ export type FlagAttributeValue = null | boolean | number | string | readonly FlagAttributeValue[] | { readonly [key: string]: FlagAttributeValue; }; /** * Context supplied to flag evaluations, exposure recording, and tracking. */ export type FlagEvaluationContext = { /** * Stable key used by providers for rollout bucketing and targeting. */ targetingKey: string; /** * Actor, user, service, tenant, or account being targeted. */ subject?: FlagSubject; /** * Tenant/account scope, when available. */ tenant?: FlagTenant; /** * Provider-neutral targeting attributes. Keep private data out unless the * selected provider and retention policy are approved for it. */ attributes?: Record<string, FlagAttributeValue>; /** * Attribute keys that should be treated as private by providers and * instrumentation. */ privateAttributes?: readonly string[]; requestId?: string; traceId?: string; spanId?: string; parentSpanId?: string; traceparent?: string; }; /** * Flag definition registered through `defineFlags(...)`. */ export type FlagDef<TValue extends FlagValue = FlagValue> = { kind: "flag"; key: FlagKey; valueKind: FlagValueKindForValue<TValue>; defaultValue: TValue; description?: string; metadata?: Record<string, unknown>; }; /** * Infer the flag value type from a flag definition. */ export type InferFlagValue<TFlag> = TFlag extends FlagDef<infer TValue> ? TValue : never; /** * Map a value type to its runtime flag kind. */ export type FlagValueKindForValue<TValue extends FlagValue> = TValue extends boolean ? "boolean" : TValue extends string ? "string" : TValue extends number ? "number" : "object"; /** * Options accepted when declaring a flag. */ export type DefineFlagOptions<TValue extends FlagValue> = { default: TValue; description?: string; metadata?: Record<string, unknown>; }; /** * Registry returned by `defineFlags(...)`. */ export type FlagRegistry = Record<string, FlagDef>; /** * Reason a flag received its value. */ export type FlagEvaluationReason = "static" | "targeting_match" | "default" | "error" | "unknown" | (string & {}); /** * Normalized error summary for failed flag provider evaluations. */ export type FlagEvaluationError = { message: string; code?: string; }; /** * Options accepted by flag evaluations. */ export type FlagEvaluationOptions<TValue extends FlagValue = FlagValue> = { context?: FlagEvaluationContext; /** * Override the flag declaration default for this call. */ defaultValue?: TValue; /** * Explicitly record an exposure after evaluation succeeds. Plain evaluation * does not record exposure by default. */ expose?: boolean; }; /** * Normalized flag evaluation details. */ export type FlagEvaluationDetails<TValue extends FlagValue = FlagValue> = { key: string; value: TValue; defaultValue: TValue; valueKind: FlagValueKindForValue<TValue>; reason: FlagEvaluationReason; defaulted: boolean; variant?: string; metadata?: Record<string, unknown>; error?: FlagEvaluationError; }; /** * Options accepted by explicit exposure recording. */ export type FlagExposureOptions = { context?: FlagEvaluationContext; value?: FlagValue; variant?: string; metadata?: Record<string, unknown>; }; /** * Options accepted by tracking calls. */ export type FlagTrackOptions = { context?: FlagEvaluationContext; value?: number; metadata?: Record<string, unknown>; }; /** * App-facing feature flag port. */ export type FlagsPort = { evaluate<TValue extends FlagValue>(flag: FlagDef<TValue>, options?: FlagEvaluationOptions<TValue>): Promise<TValue>; details<TValue extends FlagValue>(flag: FlagDef<TValue>, options?: FlagEvaluationOptions<TValue>): Promise<FlagEvaluationDetails<TValue>>; recordExposure<TValue extends FlagValue>(flag: FlagDef<TValue>, options?: FlagExposureOptions): Promise<void>; track(event: string, options?: FlagTrackOptions): Promise<void>; }; /** * Flag evaluation observation emitted by memory/static adapters. */ export type FlagEvaluationObservation<TValue extends FlagValue = FlagValue> = { source: "evaluate" | "details"; flag: FlagDef<TValue>; context?: FlagEvaluationContext; details: FlagEvaluationDetails<TValue>; durationMs: number; requestId?: string; traceId?: string; spanId?: string; parentSpanId?: string; traceparent?: string; }; /** * Explicit flag exposure observation. */ export type FlagExposureObservation<TValue extends FlagValue = FlagValue> = { flag: FlagDef<TValue>; context?: FlagEvaluationContext; value?: FlagValue; variant?: string; metadata?: Record<string, unknown>; requestId?: string; traceId?: string; spanId?: string; parentSpanId?: string; traceparent?: string; }; /** * Flag tracking observation. */ export type FlagTrackObservation = { event: string; context?: FlagEvaluationContext; value?: number; metadata?: Record<string, unknown>; requestId?: string; traceId?: string; spanId?: string; parentSpanId?: string; traceparent?: string; }; export type FlagEvaluationObserver = (observation: FlagEvaluationObservation) => MaybePromise<void>; export type FlagExposureObserver = (observation: FlagExposureObservation) => MaybePromise<void>; export type FlagTrackObserver = (observation: FlagTrackObservation) => MaybePromise<void>; /** * Options for memory/static flag adapters. */ export type CreateFlagsOptions = { onEvaluation?: FlagEvaluationObserver; onExposure?: FlagExposureObserver; onTrack?: FlagTrackObserver; }; /** * Static flag values keyed by flag key. */ export type StaticFlagValues = Record<string, FlagValue>; /** * Options for `createStaticFlags(...)`. */ export type CreateStaticFlagsOptions = CreateFlagsOptions & { values?: StaticFlagValues; }; /** * In-memory flags port with mutation helpers for tests and local development. */ export type MemoryFlagsPort = FlagsPort & { values: Map<string, FlagValue>; set<TValue extends FlagValue>(flag: FlagDef<TValue>, value: TValue): void; reset(flag?: FlagDef): void; }; declare function defineBooleanFlag(key: string, options: DefineFlagOptions<boolean>): FlagDef<boolean>; declare function defineStringFlag(key: string, options: DefineFlagOptions<string>): FlagDef<string>; declare function defineStringFlag<const TValue extends string>(key: string, options: DefineFlagOptions<TValue>): FlagDef<TValue>; declare function defineNumberFlag(key: string, options: DefineFlagOptions<number>): FlagDef<number>; declare function defineNumberFlag<const TValue extends number>(key: string, options: DefineFlagOptions<TValue>): FlagDef<TValue>; declare function defineObjectFlag<TValue extends FlagObjectValue>(key: string, options: DefineFlagOptions<TValue>): FlagDef<TValue>; /** * Define one feature flag declaration. */ export declare const defineFlag: { boolean: typeof defineBooleanFlag; string: typeof defineStringFlag; number: typeof defineNumberFlag; object: typeof defineObjectFlag; }; /** * Define a typed registry of feature flags. */ export declare function defineFlags<const TRegistry extends FlagRegistry>(registry: TRegistry): TRegistry; /** * Evaluate a flag through any `FlagsPort`. */ export declare function evaluateFlag<TValue extends FlagValue>(flags: FlagsPort, flag: FlagDef<TValue>, options?: FlagEvaluationOptions<TValue>): Promise<TValue>; /** * Return detailed flag evaluation information through any `FlagsPort`. */ export declare function getFlagDetails<TValue extends FlagValue>(flags: FlagsPort, flag: FlagDef<TValue>, options?: FlagEvaluationOptions<TValue>): Promise<FlagEvaluationDetails<TValue>>; /** * Create static flags backed by fixed values. */ export declare function createStaticFlags(options?: CreateStaticFlagsOptions): FlagsPort; /** * Create mutable in-memory flags for tests, examples, and local development. */ export declare function createMemoryFlags(options?: CreateStaticFlagsOptions): MemoryFlagsPort; export {}; //# sourceMappingURL=index.d.ts.map