import { EvaluatedDefinitions, Hook } from '@ops-ai/toggly-hooks-types'; import { LocalGate } from '@ops-ai/toggly-local-gates'; interface VariantStatsAgg { checkCount: number; requestCount: number; usedCount: number; viewedCount: number; errorCount: number; durationSumMs: number; errorDurationSumMs: number; } interface UsageBatcherOptions { appKey: string; environment: string; instanceName?: string; appVersion?: string; processStartTime?: Date; maxUniqueHashesPerFeature?: number; maxApplicationUniqueHashes?: number; maxFeatures?: number; } interface FeatureStatPayload { appKey: string; environment: string; time: { seconds: number; nanos: number; }; stats: Array<{ feature: string; uniqueContextIdentifierEnabledCount: number; uniqueContextIdentifierDisabledCount: number; uniqueUsersUsedCount: number; uniqueUserHashes: number[]; uniqueViewedUserHashes: number[]; variantStats: Record; }>; totalUniqueUsers: number; uniqueUserHashes: number[]; instanceName?: string; appVersion?: string; processStartTime?: { seconds: number; nanos: number; }; /** Definition-refresh cache hits since last successful flush (optional proto field). */ definitionCacheHits?: number; /** Definition-refresh cache misses since last successful flush (optional proto field). */ definitionCacheMisses?: number; } /** * Wire payload plus uniqueness hash-set snapshots for soft-fail HTTPS restore. */ interface UsageFlushBundle { payload: FeatureStatPayload; uniqueUsersEnabled: Record; uniqueUsersDisabled: Record; uniqueUsersUsed: Record; } /** * In-memory feature usage aggregator. Prefer variantStats over legacy scalars * (matches .NET TogglyUsageStatsProvider send shape). */ declare class UsageBatcher { private readonly appKey; private readonly environment; private readonly instanceName?; private readonly appVersion?; private readonly processStartTime; private readonly maxUniqueHashesPerFeature; private readonly maxApplicationUniqueHashes; private readonly maxFeatures; private perFeature; private appUnique; private droppedFeatures; private definitionCacheHits; private definitionCacheMisses; constructor(options: UsageBatcherOptions); /** Count a definition-refresh outcome served from local/cache (not a new revision). */ recordDefinitionCacheHit(): void; /** Count a definition-refresh that applied a new revision from the network. */ recordDefinitionCacheMiss(): void; private get; private getVariant; private addHashCapped; private trackAppUnique; /** * Record a feature evaluation. * * `checkCount` increments on every call. `requestCount` maps to .NET * UniqueRequestEnabled/Disabled when `uniqueRequest` is true. */ recordCheck(feature: string, enabled: boolean, identity?: string, variant?: string, uniqueRequest?: boolean): void; recordUsage(feature: string, identity?: string, variant?: string): void; recordView(feature: string, identity?: string, variant?: string): void; recordUsageError(feature: string, _identity?: string, variant?: string, count?: number): void; recordUsageDuration(feature: string, durationMs: number, _identity?: string, variant?: string, failed?: boolean): void; recordUsageScopeOutcome(feature: string, outcome: { failed?: boolean; cancelled?: boolean; durationMs?: number; }, identity?: string, variant?: string): void; isEmpty(): boolean; hitFeatureCap(): boolean; featureCount(): number; buildAndReset(): UsageFlushBundle | null; private createBasePayload; private applyOptionalMetadata; restoreFromBundle(bundle: UsageFlushBundle): void; private mergeUniqueHashMap; } interface MetricsFeatureOptions { /** Optional feature key for experiment-style subcounts. */ feature?: string; /** Variant name (default: enabled). */ variant?: string; } interface MetricsBatcherOptions { appKey: string; environment: string; instanceName?: string; maxMetricKeys?: number; maxObservations?: number; } interface MetricStatPayload { appKey: string; environment: string; time: { seconds: number; nanos: number; }; stats: Array<{ metric: string; feature?: string; variantValues: Record; }>; counters: Array<{ metric: string; feature?: string; variantValues: Record; }>; observations: Array<{ time: { seconds: number; nanos: number; }; metric: string; feature?: string; variantValues: Record; }>; instanceName?: string; } /** * In-memory business metrics aggregator using variantValues maps (.NET parity). */ declare class MetricsBatcher { private readonly appKey; private readonly environment; private readonly instanceName?; private readonly maxMetricKeys; private readonly maxObservations; private readonly measures; private readonly counters; private observations; private droppedKeys; constructor(options: MetricsBatcherOptions); private key; private parseKey; private addToMap; measure(metric: string, value: number, options?: MetricsFeatureOptions): void; incrementCounter(metric: string, value?: number, options?: MetricsFeatureOptions): void; observe(metric: string, value: number, options?: MetricsFeatureOptions): void; private pushObservation; isEmpty(): boolean; hitCap(): boolean; private drainMap; buildAndReset(): MetricStatPayload | null; restoreFromPayload(payload: MetricStatPayload): void; } /** * Toggly Astro SDK - Type Definitions */ /** * Configuration options for Toggly integration */ interface TogglyConfig { /** Enable compact browser telemetry (default: true with an app key). */ enableTelemetry?: boolean; /** Browser telemetry interval, 30000–60000 ms (default: 45000). */ telemetryFlushIntervalMs?: number; /** Base URI for the Toggly definitions API (default: 'https://definitions.toggly.io') */ baseURI?: string; /** Whether signatures should be verified on signed responses */ verifySignatures?: boolean; /** * Optional allow-list of JWKS `kid` values when verifySignatures is enabled. * Empty/undefined accepts any key present in JWKS. */ allowedKeyIds?: string[]; /** * Reject envelopes whose `timestamp` is older than this many seconds. * Unset or <= 0 disables freshness checks. */ maxSignatureAgeSeconds?: number; /** Application key from Toggly */ appKey?: string; /** Environment name (e.g., 'Production', 'Staging') (default: 'Production') */ environment?: string; /** Default flag values to use when API is unavailable */ flagDefaults?: Record; /** Feature flags refresh interval in milliseconds (default: 180000 = 3 minutes) */ featureFlagsRefreshInterval?: number; /** * When true (default), the browser client connects to the definitions WebSocket * for live flag updates. Set false to rely on polling only. */ enableLiveUpdates?: boolean; /** Enable debug logging (default: false) */ isDebug?: boolean; /** Connection timeout in milliseconds (default: 5000) */ connectTimeout?: number; /** Host-minted browser instance token. Takes precedence over identity/groups/claims; never minted by this SDK. */ instanceId?: string; /** User identity for targeting and optional client-asserted browser telemetry (optional) */ identity?: string; /** User groups for targeting (optional) */ groups?: string[]; /** Custom claims for targeting (optional) */ claims?: Record; /** * When true, all features are enabled during build time (SSG). * This is useful when you have an edge worker (like Cloudflare Worker) that * filters content based on feature flags at runtime. * During dev server, actual feature flags from the API are still used. * (default: false) */ allFeaturesEnabledDuringBuild?: boolean; /** * When true, fetches from /evaluated-variants-signed and exposes variant APIs on the server client * and on the client store module. */ enableVariants?: boolean; /** Hooks to extend SDK behavior at key lifecycle points */ hooks?: Hook[]; /** Device-local gates applied as a read-time AND on worker-evaluated booleans */ localGates?: LocalGate[]; /** Optional SDK error callback for reporting fetch/cache/evaluation failures. */ onError?: (message: string, error?: unknown) => void; /** * When true, report usage stats (including definition cache hits/misses) via * HTTPS `POST api/usage/stats`. Defaults to true when `appKey` is set. * `TOGGLY_DISABLE_TELEMETRY=1` always wins over an explicit `true`. */ enableUsageTracking?: boolean; /** * When true, report business metrics (browser compact telemetry and/or * HTTPS `POST api/metrics` on the server client). * Defaults to true when `appKey` is set (same as usage). * `TOGGLY_DISABLE_TELEMETRY=1` always wins over an explicit `true`. */ enableMetrics?: boolean; /** * Opt-in Node process metrics on the server client (`CpuUsage`, `MemoryWorkingSet`, …). * Requires `enableMetrics`. Default false. */ systemMetrics?: boolean; /** Gateway base URL for usage/metrics flush (default: `https://metrics.toggly.io/`). */ metricsBaseUrl?: string; /** Usage flush interval in ms (default: 60000). Set `0` to disable the timer. */ usageFlushInterval?: number; /** Metrics flush interval in ms (default: 60000). Set `0` to disable the timer. */ metricsFlushInterval?: number; /** Optional instance name included on usage payloads. */ instanceName?: string; /** * Optional consuming-application version on usage payloads (heartbeat / * deployment identity). Omit when unset — do not confuse with SDK version * (sent via User-Agent / X-Toggly-Sdk-*). */ appVersion?: string; /** * When true (default for long-lived `TogglyServer`), attach process signal * flush handlers. Middleware-created request-scoped clients default this to * false and close at end of request. */ telemetryAttachProcessHandlers?: boolean; /** Optional fetch implementation for HTTPS usage flush (tests / edge). */ telemetryFetch?: typeof fetch; /** * Injected usage sender for tests. When unset and usage is enabled, the * server client builds a soft-fail HTTPS client to `api/usage/stats`. */ usageClient?: { sendStats(request: FeatureStatPayload): Promise; close?(): void; } | null; /** * Injected metrics sender for tests. When unset and metrics are enabled, the * server client builds a soft-fail HTTPS client to `api/metrics`. */ metricsClient?: { sendMetrics(request: MetricStatPayload): Promise; close?(): void; } | null; } /** * Assigned variant for a feature (from evaluated-variants-signed). */ interface VariantResult { name: string; configurationValue?: unknown; } /** * Raw evaluated entry from /evaluated-variants-signed `defs`. */ interface EvaluatedVariantDef { enabled: boolean; variant?: string; configurationValue?: unknown; } /** Feature flag definitions (boolean or entity gate per flag) */ type Flags = EvaluatedDefinitions; /** * Toggly client instance interface */ interface TogglyClient { /** * Get all feature flags as a map of key-value pairs * @returns Promise resolving to a map of flag keys to boolean values */ getFlags(): Promise; /** * Get a single feature flag value * @param key - The feature flag key * @param defaultValue - Optional default value if flag is not found (default: false) * @returns Promise resolving to the flag's boolean value */ getFlag(key: string, defaultValue?: boolean): Promise; /** * Evaluate a feature gate with multiple flags * @param keys - Array of feature flag keys to evaluate * @param requirement - 'all' requires all flags to be true, 'any' requires at least one * @param negate - If true, negates the result * @returns Promise resolving to boolean evaluation result */ evaluateGate(keys: string[], requirement?: 'all' | 'any', negate?: boolean): Promise; /** * Manually refresh the feature flags cache by fetching from the API * @returns Promise that resolves when flags have been refreshed */ refreshFlags(): Promise; /** * Current variant assignment for a feature (requires {@link TogglyConfig.enableVariants}). */ getVariant(featureKey: string): Promise; /** * Configuration payload for the assigned variant, if any. */ getVariantValue(featureKey: string, isT?: (v: unknown) => v is T): Promise; } /** * Page feature mapping for frontmatter extraction */ interface PageFeatureMapping { [routePath: string]: string; } /** * Props for Feature component */ interface FeatureProps { /** Single feature flag key to check */ flag?: string; /** Multiple feature flag keys to check */ flags?: string[]; /** Requirement for multiple flags: 'all' or 'any' (default: 'all') */ requirement?: 'all' | 'any'; /** If true, negates the result (default: false) */ negate?: boolean; } /** * Props for FeatureClient component */ interface FeatureClientProps { /** Feature flag key to check */ flag: string; /** Hydration strategy: 'load', 'idle', or 'visible' */ client?: 'load' | 'idle' | 'visible'; } /** * Augment Astro global types */ declare global { namespace App { interface Locals { toggly: TogglyClient; } } interface Window { __TOGGLY_CONFIG__?: TogglyConfig; __TOGGLY_PAGE_FEATURES__?: PageFeatureMapping; } } export { type EvaluatedVariantDef as E, type Flags as F, type MetricStatPayload as M, type PageFeatureMapping as P, type TogglyConfig as T, UsageBatcher as U, type VariantResult as V, type TogglyClient as a, type FeatureStatPayload as b, type MetricsFeatureOptions as c, MetricsBatcher as d, type UsageFlushBundle as e, type FeatureProps as f, type FeatureClientProps as g };