@featureflare/sdk-js 0.0.34 → 0.0.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -105,6 +105,20 @@ var FeatureFlareClient = class {
105
105
  pollTimer = null;
106
106
  reconnectTimer = null;
107
107
  eventSource = null;
108
+ visibilityListenersAttached = false;
109
+ realtimePausedByVisibility = false;
110
+ handleRealtimeVisibilityChange = () => {
111
+ if (!this.realtimeEnabled) return;
112
+ const shouldPause = !this.isRealtimeWindowActive();
113
+ if (shouldPause === this.realtimePausedByVisibility) return;
114
+ this.realtimePausedByVisibility = shouldPause;
115
+ if (shouldPause) {
116
+ this.clearRealtimeTransport();
117
+ this.emit("connectionState", { state: "offline", transport: "none" });
118
+ return;
119
+ }
120
+ this.connectSse(0);
121
+ };
108
122
  constructor(options = {}) {
109
123
  this.apiBaseUrl = getApiBaseUrl(options.apiBaseUrl).replace(/\/$/, "");
110
124
  this.sdkKey = options.sdkKey?.trim() || getSdkKeyFromEnv();
@@ -644,7 +658,7 @@ var FeatureFlareClient = class {
644
658
  }
645
659
  }
646
660
  if (message.type === "snapshot.invalidate" && this.lastUser) {
647
- void this.revalidate(this.lastUser, this.lastDefaultValue);
661
+ void this.fetchFlagsFromNetwork(this.lastUser, this.lastDefaultValue, "network");
648
662
  }
649
663
  const eventLagMs = Math.max(0, Date.now() - (message.timestamp ?? Date.now()));
650
664
  this.emitMetric("ff_realtime_lag_ms", eventLagMs, {
@@ -656,12 +670,67 @@ var FeatureFlareClient = class {
656
670
  void this.persistCache();
657
671
  }
658
672
  }
673
+ isRealtimeWindowActive() {
674
+ if (typeof document !== "undefined" && document.hidden) {
675
+ return false;
676
+ }
677
+ if (typeof document !== "undefined" && typeof document.hasFocus === "function") {
678
+ return document.hasFocus();
679
+ }
680
+ return true;
681
+ }
682
+ attachRealtimeVisibilityListeners() {
683
+ if (this.visibilityListenersAttached) return;
684
+ if (typeof document !== "undefined" && typeof document.addEventListener === "function") {
685
+ document.addEventListener("visibilitychange", this.handleRealtimeVisibilityChange);
686
+ this.visibilityListenersAttached = true;
687
+ }
688
+ if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
689
+ window.addEventListener("focus", this.handleRealtimeVisibilityChange);
690
+ window.addEventListener("blur", this.handleRealtimeVisibilityChange);
691
+ this.visibilityListenersAttached = true;
692
+ }
693
+ if (this.visibilityListenersAttached) {
694
+ this.handleRealtimeVisibilityChange();
695
+ }
696
+ }
697
+ detachRealtimeVisibilityListeners() {
698
+ if (!this.visibilityListenersAttached) return;
699
+ if (typeof document !== "undefined" && typeof document.removeEventListener === "function") {
700
+ document.removeEventListener("visibilitychange", this.handleRealtimeVisibilityChange);
701
+ }
702
+ if (typeof window !== "undefined" && typeof window.removeEventListener === "function") {
703
+ window.removeEventListener("focus", this.handleRealtimeVisibilityChange);
704
+ window.removeEventListener("blur", this.handleRealtimeVisibilityChange);
705
+ }
706
+ this.visibilityListenersAttached = false;
707
+ this.realtimePausedByVisibility = false;
708
+ }
709
+ clearRealtimeTransport() {
710
+ if (this.eventSource) {
711
+ this.eventSource.close();
712
+ this.eventSource = null;
713
+ }
714
+ if (this.pollTimer) {
715
+ clearTimeout(this.pollTimer);
716
+ this.pollTimer = null;
717
+ }
718
+ if (this.reconnectTimer) {
719
+ clearTimeout(this.reconnectTimer);
720
+ this.reconnectTimer = null;
721
+ }
722
+ }
659
723
  startPolling() {
724
+ if (this.realtimePausedByVisibility) return;
660
725
  if (this.pollTimer) {
661
726
  clearTimeout(this.pollTimer);
662
727
  this.pollTimer = null;
663
728
  }
664
729
  const tick = async () => {
730
+ if (this.realtimePausedByVisibility || !this.realtimeEnabled) {
731
+ this.pollTimer = null;
732
+ return;
733
+ }
665
734
  if (!this.lastUser) {
666
735
  this.pollTimer = setTimeout(tick, this.realtimePollingMs);
667
736
  return;
@@ -672,6 +741,9 @@ var FeatureFlareClient = class {
672
741
  this.pollTimer = setTimeout(tick, this.realtimePollingMs);
673
742
  }
674
743
  connectSse(attempt = 0) {
744
+ if (this.realtimePausedByVisibility || !this.realtimeEnabled) {
745
+ return;
746
+ }
675
747
  const EventSourceImpl = typeof EventSource !== "undefined" ? EventSource : null;
676
748
  if (!EventSourceImpl || !this.sdkKey) {
677
749
  this.emit("connectionState", { state: "degraded", transport: "polling" });
@@ -699,6 +771,11 @@ var FeatureFlareClient = class {
699
771
  }
700
772
  };
701
773
  this.eventSource.onerror = () => {
774
+ if (this.realtimePausedByVisibility || !this.realtimeEnabled) {
775
+ this.clearRealtimeTransport();
776
+ this.emit("connectionState", { state: "offline", transport: "none" });
777
+ return;
778
+ }
702
779
  this.emit("connectionState", { state: "degraded", transport: "polling" });
703
780
  this.eventSource?.close();
704
781
  this.eventSource = null;
@@ -714,22 +791,17 @@ var FeatureFlareClient = class {
714
791
  }
715
792
  startRealtime() {
716
793
  this.realtimeEnabled = true;
794
+ this.attachRealtimeVisibilityListeners();
795
+ if (this.realtimePausedByVisibility) {
796
+ this.emit("connectionState", { state: "offline", transport: "none" });
797
+ return;
798
+ }
717
799
  this.connectSse(0);
718
800
  }
719
801
  stopRealtime() {
720
802
  this.realtimeEnabled = false;
721
- if (this.eventSource) {
722
- this.eventSource.close();
723
- this.eventSource = null;
724
- }
725
- if (this.pollTimer) {
726
- clearTimeout(this.pollTimer);
727
- this.pollTimer = null;
728
- }
729
- if (this.reconnectTimer) {
730
- clearTimeout(this.reconnectTimer);
731
- this.reconnectTimer = null;
732
- }
803
+ this.detachRealtimeVisibilityListeners();
804
+ this.clearRealtimeTransport();
733
805
  this.emit("connectionState", { state: "offline", transport: "none" });
734
806
  }
735
807
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["metadata"],"mappings":"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","file":"index.cjs","sourcesContent":["export type FeatureFlareUserPayload = {\n /** Unique user identifier (preferred). */\n id?: string;\n /** Legacy alias for id. */\n key?: string;\n email?: string;\n name?: string;\n country?: string;\n /** Queryable attributes. */\n meta?: Record<string, string | number | boolean | null>;\n /** Legacy alias for meta. */\n custom?: Record<string, string | number | boolean | null>;\n};\n\ntype FeatureFlareUser = {\n key: string;\n email?: string;\n name?: string;\n country?: string;\n custom?: Record<string, string | number | boolean | null>;\n};\n\nconst DEFAULT_FEATUREFLARE_API_BASE_URL =\n 'https://shipit-api-392444455847.us-central1.run.app';\n\nfunction getApiBaseUrlFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_API_BASE_URL?.trim() ||\n process.env.SHIPIT_API_BASE_URL?.trim() ||\n null\n );\n }\n return null;\n}\n\nfunction getApiBaseUrl(explicit?: string): string {\n const fromOptions = explicit?.trim();\n if (fromOptions) return fromOptions;\n\n const fromEnv = getApiBaseUrlFromEnv();\n if (fromEnv) return fromEnv;\n\n return DEFAULT_FEATUREFLARE_API_BASE_URL;\n}\n\nexport type FeatureFlareCacheSource = 'bootstrap' | 'network' | 'realtime' | 'persistent';\nexport type FeatureFlareEvaluationReason = 'fresh_cache' | 'stale_cache' | 'bootstrap' | 'default' | 'network' | 'kill_switch';\n\nexport type FeatureFlareEvaluationMetadata = {\n reason: FeatureFlareEvaluationReason;\n isStale: boolean;\n latencyMs: number;\n source: FeatureFlareCacheSource | 'default' | 'kill_switch';\n updatedAt?: number;\n staleAt?: number;\n expiresAt?: number;\n};\n\nexport type FeatureFlareEvaluationResult = {\n value: boolean;\n metadata: FeatureFlareEvaluationMetadata;\n};\n\nexport type FeatureFlareMetricName =\n | 'ff_eval_latency_ms'\n | 'ff_cache_hit_ratio'\n | 'ff_revalidate_latency_ms'\n | 'ff_realtime_lag_ms'\n | 'ff_killswitch_apply_latency_ms';\n\nexport type FeatureFlareMetricTags = Record<string, string | number | boolean | undefined>;\n\nexport type FeatureFlareErrorReport = {\n /** The flag key being evaluated when the error was observed. */\n flagKey: string;\n /** Observed error rate as a fraction from 0 to 1 (e.g. 0.05 = 5%). */\n errorRate: number;\n /** Observed p99 latency in milliseconds. */\n latencyMs?: number;\n /** ISO-8601 timestamp of the observation window end. Defaults to now. */\n observedAt?: string;\n /** Optional free-form context about the error (e.g. HTTP status, exception name). */\n context?: Record<string, string | number | boolean>;\n};\n\nexport type FeatureFlarePersistentSnapshot = {\n revision?: number;\n killSwitches?: string[];\n flags: Record<\n string,\n {\n value: boolean;\n updatedAt: number;\n staleAt: number;\n expiresAt: number;\n source?: FeatureFlareCacheSource;\n revision?: number;\n }\n >;\n};\n\nexport type FeatureFlarePersistentCacheAdapter = {\n load: (envKey: string) => Promise<FeatureFlarePersistentSnapshot | null> | FeatureFlarePersistentSnapshot | null;\n save: (envKey: string, snapshot: FeatureFlarePersistentSnapshot) => Promise<void> | void;\n};\n\nexport type FeatureFlareBootstrapPayload = {\n revision?: number;\n killSwitches?: string[];\n flags?:\n | Record<string, boolean>\n | Array<{ key: string; value: boolean; revision?: number; updatedAt?: number }>;\n};\n\nexport type FeatureFlareClientOptions = {\n apiBaseUrl?: string;\n sdkKey?: string;\n projectKey?: string;\n envKey?: string;\n timeoutMs?: number;\n maxRetries?: number;\n backoffMs?: number;\n jitter?: number;\n cacheTtlMs?: number;\n staleTtlMs?: number;\n bootstrap?: FeatureFlareBootstrapPayload;\n persistentCache?: FeatureFlarePersistentCacheAdapter;\n onMetric?: (metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags) => void;\n realtime?: {\n enabled?: boolean;\n pollingIntervalMs?: number;\n ssePath?: string;\n };\n};\n\ntype CacheItem = {\n envKey: string;\n flagKey: string;\n value: boolean;\n updatedAt: number;\n staleAt: number;\n expiresAt: number;\n source: FeatureFlareCacheSource;\n revision: number;\n};\n\ntype RealtimeEventPayload = {\n type: 'flag.updated' | 'flag.deleted' | 'env.kill_switch.updated' | 'snapshot.invalidate';\n timestamp?: number;\n revision?: number;\n data?: Record<string, unknown>;\n};\n\ntype FeatureFlareClientEvents = {\n update: { changedKeys: string[]; source: FeatureFlareCacheSource | 'network' };\n circuitOpen: { envKey: string; reason: string };\n circuitClose: { envKey: string };\n connectionState: { state: 'connected' | 'degraded' | 'offline'; transport: 'sse' | 'polling' | 'none' };\n};\n\nfunction getEnvKeyFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_ENV_KEY?.trim() ||\n process.env.SHIPIT_ENV_KEY?.trim() ||\n null\n );\n }\n return null;\n}\n\nfunction getSdkKeyFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_CLIENT_KEY?.trim() ||\n process.env.FEATUREFLARE_SERVER_KEY?.trim() ||\n process.env.SHIPIT_CLIENT_KEY?.trim() ||\n process.env.SHIPIT_SERVER_KEY?.trim() ||\n null\n );\n }\n return null;\n}\n\nfunction monotonicNow(): number {\n if (typeof performance !== 'undefined' && typeof performance.now === 'function') {\n return performance.now();\n }\n return Date.now();\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nfunction isRetriableStatus(status: number): boolean {\n return status === 408 || status === 425 || status === 429 || status >= 500;\n}\n\nfunction normalizeBoolMap(\n input: { flags?: Array<{ key: string; value: boolean }>; values?: Record<string, boolean> }\n): Array<{ key: string; value: boolean }> {\n if (Array.isArray(input.flags)) {\n return input.flags\n .filter((entry): entry is { key: string; value: boolean } =>\n Boolean(entry) && typeof entry.key === 'string' && typeof entry.value === 'boolean'\n )\n .map((entry) => ({ key: entry.key, value: entry.value }));\n }\n\n const values = input.values ?? {};\n return Object.entries(values).map(([key, value]) => ({ key, value: Boolean(value) }));\n}\n\nexport class InMemoryMetricsCollector {\n private readonly buckets = new Map<string, number[]>();\n\n record = (metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags) => {\n const key = `${metricName}:${JSON.stringify(tags ?? {})}`;\n const list = this.buckets.get(key) ?? [];\n list.push(value);\n this.buckets.set(key, list);\n };\n\n get(metricName: FeatureFlareMetricName): Array<{ tags: FeatureFlareMetricTags; values: number[] }> {\n const rows: Array<{ tags: FeatureFlareMetricTags; values: number[] }> = [];\n for (const [key, values] of this.buckets.entries()) {\n if (!key.startsWith(`${metricName}:`)) continue;\n rows.push({\n tags: JSON.parse(key.slice(metricName.length + 1)) as FeatureFlareMetricTags,\n values: [...values]\n });\n }\n return rows;\n }\n}\n\nexport class FeatureFlareClient {\n private readonly apiBaseUrl: string;\n private readonly sdkKey: string | null;\n private readonly projectKey: string | null;\n private readonly envKey: string;\n private readonly expectedEnvKey: string | null;\n private readonly timeoutMs: number;\n private readonly maxRetries: number;\n private readonly backoffMs: number;\n private readonly jitter: number;\n private readonly cacheTtlMs: number;\n private readonly staleTtlMs: number;\n private readonly persistentCache: FeatureFlarePersistentCacheAdapter | undefined;\n private readonly onMetric?: (metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags) => void;\n private readonly listeners: {\n [K in keyof FeatureFlareClientEvents]: Set<(payload: FeatureFlareClientEvents[K]) => void>;\n } = {\n update: new Set(),\n circuitOpen: new Set(),\n circuitClose: new Set(),\n connectionState: new Set()\n };\n\n private readonly cache = new Map<string, CacheItem>();\n private readonly diagnostics = new Map<string, FeatureFlareEvaluationMetadata>();\n private readonly killSwitches = new Set<string>();\n\n private revision = 0;\n private circuitOpen = false;\n private persistentLoadPromise: Promise<void> | null = null;\n private readonly inFlightRevalidate = new Map<string, Promise<Array<{ key: string; value: boolean }> | null>>();\n private lastUser: FeatureFlareUser | null = null;\n private lastDefaultValue = false;\n\n private realtimeEnabled = true;\n private realtimePollingMs = 15000;\n private realtimeSsePath = '/api/v1/sdk/stream';\n private pollTimer: ReturnType<typeof setTimeout> | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private eventSource: EventSource | null = null;\n\n constructor(options: FeatureFlareClientOptions = {}) {\n this.apiBaseUrl = getApiBaseUrl(options.apiBaseUrl).replace(/\\/$/, '');\n this.sdkKey = options.sdkKey?.trim() || getSdkKeyFromEnv();\n this.projectKey = options.projectKey?.trim() ? options.projectKey.trim() : null;\n const explicitOrEnvKey = options.envKey?.trim() || getEnvKeyFromEnv() || null;\n this.envKey = explicitOrEnvKey ?? 'production';\n this.expectedEnvKey = explicitOrEnvKey;\n\n if (!this.sdkKey && !this.projectKey) {\n throw new Error(\n 'FeatureFlareClient requires either sdkKey (recommended) or projectKey (legacy). Set FEATUREFLARE_CLIENT_KEY or FEATUREFLARE_SERVER_KEY env var, or pass sdkKey in options.'\n );\n }\n\n this.timeoutMs = Number.isFinite(options.timeoutMs) && (options.timeoutMs ?? 0) > 0 ? Number(options.timeoutMs) : 3000;\n this.maxRetries = Number.isFinite(options.maxRetries) && (options.maxRetries ?? 0) >= 0 ? Number(options.maxRetries) : 2;\n this.backoffMs = Number.isFinite(options.backoffMs) && (options.backoffMs ?? 0) > 0 ? Number(options.backoffMs) : 200;\n this.jitter = Number.isFinite(options.jitter) && (options.jitter ?? 0) >= 0 ? Number(options.jitter) : 0.25;\n\n this.cacheTtlMs = Number.isFinite(options.cacheTtlMs) && (options.cacheTtlMs ?? 0) > 0 ? Number(options.cacheTtlMs) : 60000;\n const configuredStaleTtlMs =\n Number.isFinite(options.staleTtlMs) && (options.staleTtlMs ?? 0) > 0 ? Number(options.staleTtlMs) : 10000;\n this.staleTtlMs = Math.min(configuredStaleTtlMs, this.cacheTtlMs);\n\n this.persistentCache = options.persistentCache;\n this.onMetric = options.onMetric;\n\n this.realtimeEnabled = options.realtime?.enabled ?? true;\n this.realtimePollingMs =\n Number.isFinite(options.realtime?.pollingIntervalMs) && (options.realtime?.pollingIntervalMs ?? 0) > 0\n ? Number(options.realtime?.pollingIntervalMs)\n : 15000;\n this.realtimeSsePath = options.realtime?.ssePath ?? '/api/v1/sdk/stream';\n\n this.applyBootstrap(options.bootstrap);\n this.persistentLoadPromise = this.loadPersistentCache();\n\n if (this.realtimeEnabled && this.sdkKey) {\n this.startRealtime();\n }\n }\n\n private getCacheKey(flagKey: string): string {\n return `${this.envKey}:${flagKey}`;\n }\n\n private normalizeUser(input: FeatureFlareUserPayload): FeatureFlareUser {\n const key = (input.id ?? input.key ?? '').trim();\n if (!key) throw new Error('FeatureFlareClient requires user.id (or legacy user.key).');\n return {\n key,\n email: input.email,\n name: input.name,\n country: input.country,\n custom: input.meta ?? input.custom\n };\n }\n\n private emit<K extends keyof FeatureFlareClientEvents>(event: K, payload: FeatureFlareClientEvents[K]): void {\n for (const listener of this.listeners[event]) {\n listener(payload);\n }\n }\n\n on<K extends keyof FeatureFlareClientEvents>(\n event: K,\n listener: (payload: FeatureFlareClientEvents[K]) => void\n ): () => void {\n this.listeners[event].add(listener);\n return () => {\n this.listeners[event].delete(listener);\n };\n }\n\n private emitMetric(metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags): void {\n this.onMetric?.(metricName, value, tags);\n }\n\n private async ensurePersistentLoaded(): Promise<void> {\n if (!this.persistentLoadPromise) return;\n await this.persistentLoadPromise;\n }\n\n private async loadPersistentCache(): Promise<void> {\n if (!this.persistentCache) return;\n try {\n const snapshot = await this.persistentCache.load(this.envKey);\n if (!snapshot) return;\n this.revision = Math.max(this.revision, snapshot.revision ?? 0);\n for (const killSwitchKey of snapshot.killSwitches ?? []) {\n this.killSwitches.add(killSwitchKey);\n }\n\n for (const [flagKey, item] of Object.entries(snapshot.flags ?? {})) {\n const existing = this.cache.get(this.getCacheKey(flagKey));\n if (existing && existing.source === 'bootstrap') continue;\n this.cache.set(this.getCacheKey(flagKey), {\n envKey: this.envKey,\n flagKey,\n value: Boolean(item.value),\n updatedAt: Number(item.updatedAt) || Date.now(),\n staleAt: Number(item.staleAt) || Date.now(),\n expiresAt: Number(item.expiresAt) || Date.now(),\n source: item.source ?? 'persistent',\n revision: item.revision ?? 0\n });\n }\n } catch {\n // Ignore persistent cache failures; runtime must stay non-throwing for outage semantics.\n }\n }\n\n private async persistCache(): Promise<void> {\n if (!this.persistentCache) return;\n const snapshot: FeatureFlarePersistentSnapshot = {\n revision: this.revision,\n killSwitches: [...this.killSwitches],\n flags: {}\n };\n\n for (const [key, item] of this.cache.entries()) {\n if (!key.startsWith(`${this.envKey}:`)) continue;\n snapshot.flags[item.flagKey] = {\n value: item.value,\n updatedAt: item.updatedAt,\n staleAt: item.staleAt,\n expiresAt: item.expiresAt,\n source: item.source,\n revision: item.revision\n };\n }\n\n try {\n await this.persistentCache.save(this.envKey, snapshot);\n } catch {\n // Persistent errors must not break evaluation.\n }\n }\n\n private makeCacheWindow(at = Date.now()): Pick<CacheItem, 'updatedAt' | 'staleAt' | 'expiresAt'> {\n return {\n updatedAt: at,\n staleAt: at + this.staleTtlMs,\n expiresAt: at + this.cacheTtlMs\n };\n }\n\n private setCacheItem(\n flagKey: string,\n value: boolean,\n source: FeatureFlareCacheSource,\n revision = this.revision,\n at = Date.now()\n ): void {\n this.cache.set(this.getCacheKey(flagKey), {\n envKey: this.envKey,\n flagKey,\n value,\n source,\n revision,\n ...this.makeCacheWindow(at)\n });\n }\n\n private applyBootstrap(bootstrap?: FeatureFlareBootstrapPayload): void {\n if (!bootstrap) return;\n this.revision = Math.max(this.revision, bootstrap.revision ?? 0);\n for (const killSwitchKey of bootstrap.killSwitches ?? []) {\n this.killSwitches.add(killSwitchKey);\n }\n\n const apply = (flagKey: string, value: boolean, revision?: number, updatedAt?: number) => {\n this.setCacheItem(flagKey, value, 'bootstrap', revision ?? this.revision, updatedAt ?? Date.now());\n };\n\n if (Array.isArray(bootstrap.flags)) {\n for (const item of bootstrap.flags) {\n if (!item || typeof item.key !== 'string') continue;\n apply(item.key, Boolean(item.value), item.revision, item.updatedAt);\n }\n return;\n }\n\n for (const [flagKey, value] of Object.entries(bootstrap.flags ?? {})) {\n apply(flagKey, Boolean(value));\n }\n }\n\n private getCacheState(item: CacheItem | undefined, now = Date.now()): 'fresh' | 'stale' | 'expired' | 'missing' {\n if (!item) return 'missing';\n if (now <= item.staleAt) return 'fresh';\n if (now <= item.expiresAt) return 'stale';\n return 'expired';\n }\n\n private setCircuitState(isOpen: boolean, reason = ''): void {\n if (this.circuitOpen === isOpen) return;\n this.circuitOpen = isOpen;\n if (isOpen) {\n this.emit('circuitOpen', { envKey: this.envKey, reason });\n return;\n }\n this.emit('circuitClose', { envKey: this.envKey });\n }\n\n private async fetchWithRetry(url: string, init: RequestInit, transport: 'network' | 'polling') {\n let lastError: unknown = null;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n const ac = typeof AbortController !== 'undefined' ? new AbortController() : null;\n const timeout =\n ac !== null\n ? setTimeout(() => {\n ac.abort();\n }, this.timeoutMs)\n : null;\n\n try {\n const response = await fetch(url, {\n ...init,\n signal: ac?.signal\n });\n\n if (timeout) clearTimeout(timeout);\n\n if (!response.ok && isRetriableStatus(response.status) && attempt < this.maxRetries) {\n lastError = new Error(`HTTP ${response.status}`);\n const jitterOffset = this.backoffMs * this.jitter * Math.random();\n await sleep(this.backoffMs * (attempt + 1) + jitterOffset);\n continue;\n }\n\n return response;\n } catch (error) {\n if (timeout) clearTimeout(timeout);\n lastError = error;\n if (attempt >= this.maxRetries) break;\n const jitterOffset = this.backoffMs * this.jitter * Math.random();\n await sleep(this.backoffMs * (attempt + 1) + jitterOffset);\n }\n }\n\n this.setCircuitState(true, transport);\n throw lastError;\n }\n\n private collectCachedFlags(): Array<{ key: string; value: boolean }> {\n const now = Date.now();\n const flags: Array<{ key: string; value: boolean }> = [];\n\n for (const [cacheKey, item] of this.cache.entries()) {\n if (!cacheKey.startsWith(`${this.envKey}:`)) continue;\n if (this.killSwitches.has(item.flagKey)) {\n flags.push({ key: item.flagKey, value: false });\n continue;\n }\n\n const state = this.getCacheState(item, now);\n if (state === 'missing' || state === 'expired') continue;\n flags.push({ key: item.flagKey, value: item.value });\n }\n\n return flags.sort((a, b) => a.key.localeCompare(b.key));\n }\n\n getCachedFlags(): {\n flags: Array<{ key: string; value: boolean }>;\n hasData: boolean;\n } {\n const flags = this.collectCachedFlags();\n return { flags, hasData: flags.length > 0 };\n }\n\n getFlagDiagnostics(flagKey: string): FeatureFlareEvaluationMetadata | null {\n return this.diagnostics.get(this.getCacheKey(flagKey)) ?? null;\n }\n\n setKillSwitch(flagKey: string, enabled: boolean): void {\n const started = monotonicNow();\n if (enabled) {\n this.killSwitches.add(flagKey);\n } else {\n this.killSwitches.delete(flagKey);\n }\n const elapsed = monotonicNow() - started;\n this.emitMetric('ff_killswitch_apply_latency_ms', elapsed, {\n env: this.envKey,\n result: enabled ? 'enabled' : 'disabled'\n });\n this.emit('update', { changedKeys: [flagKey], source: 'realtime' });\n void this.persistCache();\n }\n\n private async fetchEvalFromNetwork(\n flagKey: string,\n normalizedUser: FeatureFlareUser,\n defaultValue: boolean\n ): Promise<boolean | null> {\n const response = this.sdkKey\n ? await this.fetchWithRetry(\n `${this.apiBaseUrl}/api/v1/sdk/eval`,\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-featureflare-sdk-key': this.sdkKey\n },\n body: JSON.stringify({\n flagKey,\n user: normalizedUser,\n defaultValue,\n expectedEnvKey: this.expectedEnvKey ?? undefined\n })\n },\n 'network'\n )\n : await this.fetchWithRetry(\n `${this.apiBaseUrl}/api/v1/eval`,\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n projectKey: this.projectKey,\n envKey: this.envKey,\n flagKey,\n user: normalizedUser,\n defaultValue\n })\n },\n 'network'\n );\n\n if (!response.ok) {\n if (!isRetriableStatus(response.status)) {\n this.setCircuitState(true, `http_${response.status}`);\n }\n return null;\n }\n\n const json = (await response.json()) as { value?: boolean; revision?: number; killSwitch?: boolean };\n const value = typeof json.value === 'boolean' ? json.value : defaultValue;\n\n if (json.killSwitch === true) {\n this.killSwitches.add(flagKey);\n }\n\n const revision = json.revision ?? this.revision;\n this.revision = Math.max(this.revision, revision);\n this.setCacheItem(flagKey, value, 'network', revision);\n this.setCircuitState(false);\n void this.persistCache();\n this.emit('update', { changedKeys: [flagKey], source: 'network' });\n return value;\n }\n\n private async fetchFlagsFromNetwork(\n normalizedUser: FeatureFlareUser,\n defaultValue: boolean,\n transport: 'network' | 'polling'\n ): Promise<Array<{ key: string; value: boolean }> | null> {\n if (!this.sdkKey) {\n return null;\n }\n\n const started = monotonicNow();\n\n try {\n const response = await this.fetchWithRetry(\n `${this.apiBaseUrl}/api/v1/sdk/flags`,\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-featureflare-sdk-key': this.sdkKey\n },\n body: JSON.stringify({\n user: normalizedUser,\n defaultValue,\n expectedEnvKey: this.expectedEnvKey ?? undefined\n })\n },\n transport\n );\n\n if (!response.ok) {\n if (!isRetriableStatus(response.status)) {\n this.setCircuitState(true, `http_${response.status}`);\n }\n return null;\n }\n\n const json = (await response.json()) as {\n flags?: Array<{ key: string; value: boolean }>;\n values?: Record<string, boolean>;\n revision?: number;\n killSwitches?: string[];\n };\n\n const list = normalizeBoolMap(json);\n const revision = json.revision ?? this.revision;\n this.revision = Math.max(this.revision, revision);\n\n if (Array.isArray(json.killSwitches)) {\n for (const key of json.killSwitches) {\n this.killSwitches.add(key);\n }\n }\n\n const changed = new Set<string>();\n for (const entry of list) {\n const existing = this.cache.get(this.getCacheKey(entry.key));\n if (!existing || existing.value !== entry.value || existing.revision !== revision) {\n changed.add(entry.key);\n }\n this.setCacheItem(entry.key, entry.value, 'network', revision);\n }\n\n if (changed.size > 0) {\n this.emit('update', { changedKeys: [...changed], source: 'network' });\n }\n\n this.setCircuitState(false);\n void this.persistCache();\n this.emitMetric('ff_revalidate_latency_ms', monotonicNow() - started, {\n env: this.envKey,\n transport\n });\n return list;\n } catch {\n this.emitMetric('ff_revalidate_latency_ms', monotonicNow() - started, {\n env: this.envKey,\n transport,\n result: 'error'\n });\n return null;\n }\n }\n\n private revalidate(normalizedUser: FeatureFlareUser, defaultValue: boolean): Promise<Array<{ key: string; value: boolean }> | null> {\n const existing = this.inFlightRevalidate.get(this.envKey);\n if (existing) return existing;\n\n const promise = this.fetchFlagsFromNetwork(normalizedUser, defaultValue, 'network').finally(() => {\n this.inFlightRevalidate.delete(this.envKey);\n });\n\n this.inFlightRevalidate.set(this.envKey, promise);\n return promise;\n }\n\n async evaluate(\n flagKey: string,\n user: FeatureFlareUserPayload,\n defaultValue = false\n ): Promise<FeatureFlareEvaluationResult> {\n const started = monotonicNow();\n await this.ensurePersistentLoaded();\n\n const normalizedUser = this.normalizeUser(user);\n this.lastUser = normalizedUser;\n this.lastDefaultValue = defaultValue;\n\n if (this.killSwitches.has(flagKey)) {\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'kill_switch',\n isStale: false,\n latencyMs: monotonicNow() - started,\n source: 'kill_switch'\n };\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'disabled'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: false, metadata };\n }\n\n const cacheItem = this.cache.get(this.getCacheKey(flagKey));\n const cacheState = this.getCacheState(cacheItem);\n\n if (cacheItem && cacheState === 'fresh') {\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: cacheItem.source === 'bootstrap' || cacheItem.source === 'persistent' ? 'bootstrap' : 'fresh_cache',\n isStale: false,\n latencyMs: monotonicNow() - started,\n source: cacheItem.source,\n updatedAt: cacheItem.updatedAt,\n staleAt: cacheItem.staleAt,\n expiresAt: cacheItem.expiresAt\n };\n this.emitMetric('ff_cache_hit_ratio', 1, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'cache_hit'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: cacheItem.value, metadata };\n }\n\n if (cacheItem && cacheState === 'stale') {\n void this.revalidate(normalizedUser, defaultValue);\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'stale_cache',\n isStale: true,\n latencyMs: monotonicNow() - started,\n source: cacheItem.source,\n updatedAt: cacheItem.updatedAt,\n staleAt: cacheItem.staleAt,\n expiresAt: cacheItem.expiresAt\n };\n this.emitMetric('ff_cache_hit_ratio', 1, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'stale'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: cacheItem.value, metadata };\n }\n\n if (cacheItem && (cacheItem.source === 'bootstrap' || cacheItem.source === 'persistent')) {\n void this.revalidate(normalizedUser, defaultValue);\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'bootstrap',\n isStale: true,\n latencyMs: monotonicNow() - started,\n source: cacheItem.source,\n updatedAt: cacheItem.updatedAt,\n staleAt: cacheItem.staleAt,\n expiresAt: cacheItem.expiresAt\n };\n this.emitMetric('ff_cache_hit_ratio', 1, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'bootstrap'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: cacheItem.value, metadata };\n }\n\n try {\n const networkValue = await this.fetchEvalFromNetwork(flagKey, normalizedUser, defaultValue);\n if (networkValue !== null) {\n const item = this.cache.get(this.getCacheKey(flagKey));\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'network',\n isStale: false,\n latencyMs: monotonicNow() - started,\n source: 'network',\n updatedAt: item?.updatedAt,\n staleAt: item?.staleAt,\n expiresAt: item?.expiresAt\n };\n this.emitMetric('ff_cache_hit_ratio', 0, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'network'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: networkValue, metadata };\n }\n } catch {\n // Fall through to deterministic default for outage semantics.\n }\n\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'default',\n isStale: false,\n latencyMs: monotonicNow() - started,\n source: 'default'\n };\n this.emitMetric('ff_cache_hit_ratio', 0, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'default'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: defaultValue, metadata };\n }\n\n async bool(flagKey: string, user: FeatureFlareUserPayload, defaultValue = false): Promise<boolean> {\n const result = await this.evaluate(flagKey, user, defaultValue);\n return result.value;\n }\n\n async flags(user: FeatureFlareUserPayload, defaultValue = false): Promise<Array<{ key: string; value: boolean }>> {\n await this.ensurePersistentLoaded();\n const normalizedUser = this.normalizeUser(user);\n this.lastUser = normalizedUser;\n this.lastDefaultValue = defaultValue;\n\n const list = await this.revalidate(normalizedUser, defaultValue);\n if (list && list.length > 0) {\n return list.map((entry) => ({\n key: entry.key,\n value: this.killSwitches.has(entry.key) ? false : entry.value\n }));\n }\n\n const cached = this.collectCachedFlags();\n if (cached.length > 0) return cached;\n return [];\n }\n\n private applyRealtimeMessage(message: RealtimeEventPayload): void {\n if (typeof message.revision === 'number' && message.revision < this.revision) {\n return;\n }\n\n if (typeof message.revision === 'number') {\n this.revision = message.revision;\n }\n\n const changed = new Set<string>();\n const now = Date.now();\n\n if (message.type === 'flag.updated') {\n const flagKey = typeof message.data?.flagKey === 'string' ? message.data.flagKey : null;\n const value = typeof message.data?.value === 'boolean' ? message.data.value : null;\n if (flagKey !== null && value !== null) {\n this.setCacheItem(flagKey, value, 'realtime', message.revision ?? this.revision, now);\n changed.add(flagKey);\n }\n }\n\n if (message.type === 'flag.deleted') {\n const flagKey = typeof message.data?.flagKey === 'string' ? message.data.flagKey : null;\n if (flagKey !== null) {\n this.cache.delete(this.getCacheKey(flagKey));\n changed.add(flagKey);\n }\n }\n\n if (message.type === 'env.kill_switch.updated') {\n const started = monotonicNow();\n const flagKey = typeof message.data?.flagKey === 'string' ? message.data.flagKey : null;\n const enabled = typeof message.data?.enabled === 'boolean' ? message.data.enabled : true;\n if (flagKey !== null) {\n if (enabled) {\n this.killSwitches.add(flagKey);\n } else {\n this.killSwitches.delete(flagKey);\n }\n changed.add(flagKey);\n this.emitMetric('ff_killswitch_apply_latency_ms', monotonicNow() - started, {\n env: this.envKey,\n transport: this.eventSource ? 'sse' : 'polling',\n result: enabled ? 'enabled' : 'disabled'\n });\n }\n }\n\n if (message.type === 'snapshot.invalidate' && this.lastUser) {\n void this.revalidate(this.lastUser, this.lastDefaultValue);\n }\n\n const eventLagMs = Math.max(0, Date.now() - (message.timestamp ?? Date.now()));\n this.emitMetric('ff_realtime_lag_ms', eventLagMs, {\n env: this.envKey,\n transport: this.eventSource ? 'sse' : 'polling'\n });\n\n if (changed.size > 0) {\n this.emit('update', { changedKeys: [...changed], source: 'realtime' });\n void this.persistCache();\n }\n }\n\n private startPolling(): void {\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n\n const tick = async () => {\n if (!this.lastUser) {\n this.pollTimer = setTimeout(tick, this.realtimePollingMs);\n return;\n }\n await this.fetchFlagsFromNetwork(this.lastUser, this.lastDefaultValue, 'polling');\n this.pollTimer = setTimeout(tick, this.realtimePollingMs);\n };\n\n this.pollTimer = setTimeout(tick, this.realtimePollingMs);\n }\n\n private connectSse(attempt = 0): void {\n const EventSourceImpl = typeof EventSource !== 'undefined' ? EventSource : null;\n if (!EventSourceImpl || !this.sdkKey) {\n this.emit('connectionState', { state: 'degraded', transport: 'polling' });\n this.startPolling();\n return;\n }\n\n const url = new URL(this.realtimeSsePath, this.apiBaseUrl);\n url.searchParams.set('sdkKey', this.sdkKey);\n if (this.expectedEnvKey) {\n url.searchParams.set('expectedEnvKey', this.expectedEnvKey);\n }\n\n this.eventSource = new EventSourceImpl(url.toString());\n\n this.eventSource.onopen = () => {\n this.emit('connectionState', { state: 'connected', transport: 'sse' });\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n };\n\n this.eventSource.onmessage = (event: MessageEvent) => {\n try {\n const payload = JSON.parse(String(event.data)) as RealtimeEventPayload;\n this.applyRealtimeMessage(payload);\n } catch {\n // Ignore malformed realtime messages.\n }\n };\n\n this.eventSource.onerror = () => {\n this.emit('connectionState', { state: 'degraded', transport: 'polling' });\n this.eventSource?.close();\n this.eventSource = null;\n this.startPolling();\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n }\n const backoff = Math.min(this.backoffMs * (attempt + 1), 30000);\n this.reconnectTimer = setTimeout(() => {\n this.connectSse(attempt + 1);\n }, backoff);\n };\n }\n\n startRealtime(): void {\n this.realtimeEnabled = true;\n this.connectSse(0);\n }\n\n stopRealtime(): void {\n this.realtimeEnabled = false;\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.emit('connectionState', { state: 'offline', transport: 'none' });\n }\n\n /**\n * Report observed error metrics (error rate, latency) for a flag back to the FeatureFlare API.\n * The API evaluates the report against active rollback policies and may trigger an automated\n * rollback if configured thresholds are breached.\n *\n * Errors from this call are silently swallowed so that reporting never disrupts the host application.\n */\n async reportError(report: FeatureFlareErrorReport): Promise<void> {\n if (!this.sdkKey) return;\n try {\n await fetch(`${this.apiBaseUrl}/api/v1/sdk/report`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-featureflare-sdk-key': this.sdkKey\n },\n body: JSON.stringify({\n flagKey: report.flagKey,\n errorRate: report.errorRate,\n latencyMs: report.latencyMs,\n observedAt: report.observedAt ?? new Date().toISOString(),\n envKey: this.envKey,\n context: report.context\n })\n });\n } catch {\n // Reporting failures must never surface to the caller.\n }\n }\n\n dispose(): void {\n this.stopRealtime();\n this.listeners.update.clear();\n this.listeners.circuitOpen.clear();\n this.listeners.circuitClose.clear();\n this.listeners.connectionState.clear();\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":["metadata"],"mappings":"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","file":"index.cjs","sourcesContent":["export type FeatureFlareUserPayload = {\n /** Unique user identifier (preferred). */\n id?: string;\n /** Legacy alias for id. */\n key?: string;\n email?: string;\n name?: string;\n country?: string;\n /** Queryable attributes. */\n meta?: Record<string, string | number | boolean | null>;\n /** Legacy alias for meta. */\n custom?: Record<string, string | number | boolean | null>;\n};\n\ntype FeatureFlareUser = {\n key: string;\n email?: string;\n name?: string;\n country?: string;\n custom?: Record<string, string | number | boolean | null>;\n};\n\nconst DEFAULT_FEATUREFLARE_API_BASE_URL =\n 'https://shipit-api-392444455847.us-central1.run.app';\n\nfunction getApiBaseUrlFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_API_BASE_URL?.trim() ||\n process.env.SHIPIT_API_BASE_URL?.trim() ||\n null\n );\n }\n return null;\n}\n\nfunction getApiBaseUrl(explicit?: string): string {\n const fromOptions = explicit?.trim();\n if (fromOptions) return fromOptions;\n\n const fromEnv = getApiBaseUrlFromEnv();\n if (fromEnv) return fromEnv;\n\n return DEFAULT_FEATUREFLARE_API_BASE_URL;\n}\n\nexport type FeatureFlareCacheSource = 'bootstrap' | 'network' | 'realtime' | 'persistent';\nexport type FeatureFlareEvaluationReason = 'fresh_cache' | 'stale_cache' | 'bootstrap' | 'default' | 'network' | 'kill_switch';\n\nexport type FeatureFlareEvaluationMetadata = {\n reason: FeatureFlareEvaluationReason;\n isStale: boolean;\n latencyMs: number;\n source: FeatureFlareCacheSource | 'default' | 'kill_switch';\n updatedAt?: number;\n staleAt?: number;\n expiresAt?: number;\n};\n\nexport type FeatureFlareEvaluationResult = {\n value: boolean;\n metadata: FeatureFlareEvaluationMetadata;\n};\n\nexport type FeatureFlareMetricName =\n | 'ff_eval_latency_ms'\n | 'ff_cache_hit_ratio'\n | 'ff_revalidate_latency_ms'\n | 'ff_realtime_lag_ms'\n | 'ff_killswitch_apply_latency_ms';\n\nexport type FeatureFlareMetricTags = Record<string, string | number | boolean | undefined>;\n\nexport type FeatureFlareErrorReport = {\n /** The flag key being evaluated when the error was observed. */\n flagKey: string;\n /** Observed error rate as a fraction from 0 to 1 (e.g. 0.05 = 5%). */\n errorRate: number;\n /** Observed p99 latency in milliseconds. */\n latencyMs?: number;\n /** ISO-8601 timestamp of the observation window end. Defaults to now. */\n observedAt?: string;\n /** Optional free-form context about the error (e.g. HTTP status, exception name). */\n context?: Record<string, string | number | boolean>;\n};\n\nexport type FeatureFlarePersistentSnapshot = {\n revision?: number;\n killSwitches?: string[];\n flags: Record<\n string,\n {\n value: boolean;\n updatedAt: number;\n staleAt: number;\n expiresAt: number;\n source?: FeatureFlareCacheSource;\n revision?: number;\n }\n >;\n};\n\nexport type FeatureFlarePersistentCacheAdapter = {\n load: (envKey: string) => Promise<FeatureFlarePersistentSnapshot | null> | FeatureFlarePersistentSnapshot | null;\n save: (envKey: string, snapshot: FeatureFlarePersistentSnapshot) => Promise<void> | void;\n};\n\nexport type FeatureFlareBootstrapPayload = {\n revision?: number;\n killSwitches?: string[];\n flags?:\n | Record<string, boolean>\n | Array<{ key: string; value: boolean; revision?: number; updatedAt?: number }>;\n};\n\nexport type FeatureFlareClientOptions = {\n apiBaseUrl?: string;\n sdkKey?: string;\n projectKey?: string;\n envKey?: string;\n timeoutMs?: number;\n maxRetries?: number;\n backoffMs?: number;\n jitter?: number;\n cacheTtlMs?: number;\n staleTtlMs?: number;\n bootstrap?: FeatureFlareBootstrapPayload;\n persistentCache?: FeatureFlarePersistentCacheAdapter;\n onMetric?: (metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags) => void;\n realtime?: {\n enabled?: boolean;\n pollingIntervalMs?: number;\n ssePath?: string;\n };\n};\n\ntype CacheItem = {\n envKey: string;\n flagKey: string;\n value: boolean;\n updatedAt: number;\n staleAt: number;\n expiresAt: number;\n source: FeatureFlareCacheSource;\n revision: number;\n};\n\ntype RealtimeEventPayload = {\n type: 'flag.updated' | 'flag.deleted' | 'env.kill_switch.updated' | 'snapshot.invalidate';\n timestamp?: number;\n revision?: number;\n data?: Record<string, unknown>;\n};\n\ntype FeatureFlareClientEvents = {\n update: { changedKeys: string[]; source: FeatureFlareCacheSource | 'network' };\n circuitOpen: { envKey: string; reason: string };\n circuitClose: { envKey: string };\n connectionState: { state: 'connected' | 'degraded' | 'offline'; transport: 'sse' | 'polling' | 'none' };\n};\n\nfunction getEnvKeyFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_ENV_KEY?.trim() ||\n process.env.SHIPIT_ENV_KEY?.trim() ||\n null\n );\n }\n return null;\n}\n\nfunction getSdkKeyFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_CLIENT_KEY?.trim() ||\n process.env.FEATUREFLARE_SERVER_KEY?.trim() ||\n process.env.SHIPIT_CLIENT_KEY?.trim() ||\n process.env.SHIPIT_SERVER_KEY?.trim() ||\n null\n );\n }\n return null;\n}\n\nfunction monotonicNow(): number {\n if (typeof performance !== 'undefined' && typeof performance.now === 'function') {\n return performance.now();\n }\n return Date.now();\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nfunction isRetriableStatus(status: number): boolean {\n return status === 408 || status === 425 || status === 429 || status >= 500;\n}\n\nfunction normalizeBoolMap(\n input: { flags?: Array<{ key: string; value: boolean }>; values?: Record<string, boolean> }\n): Array<{ key: string; value: boolean }> {\n if (Array.isArray(input.flags)) {\n return input.flags\n .filter((entry): entry is { key: string; value: boolean } =>\n Boolean(entry) && typeof entry.key === 'string' && typeof entry.value === 'boolean'\n )\n .map((entry) => ({ key: entry.key, value: entry.value }));\n }\n\n const values = input.values ?? {};\n return Object.entries(values).map(([key, value]) => ({ key, value: Boolean(value) }));\n}\n\nexport class InMemoryMetricsCollector {\n private readonly buckets = new Map<string, number[]>();\n\n record = (metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags) => {\n const key = `${metricName}:${JSON.stringify(tags ?? {})}`;\n const list = this.buckets.get(key) ?? [];\n list.push(value);\n this.buckets.set(key, list);\n };\n\n get(metricName: FeatureFlareMetricName): Array<{ tags: FeatureFlareMetricTags; values: number[] }> {\n const rows: Array<{ tags: FeatureFlareMetricTags; values: number[] }> = [];\n for (const [key, values] of this.buckets.entries()) {\n if (!key.startsWith(`${metricName}:`)) continue;\n rows.push({\n tags: JSON.parse(key.slice(metricName.length + 1)) as FeatureFlareMetricTags,\n values: [...values]\n });\n }\n return rows;\n }\n}\n\nexport class FeatureFlareClient {\n private readonly apiBaseUrl: string;\n private readonly sdkKey: string | null;\n private readonly projectKey: string | null;\n private readonly envKey: string;\n private readonly expectedEnvKey: string | null;\n private readonly timeoutMs: number;\n private readonly maxRetries: number;\n private readonly backoffMs: number;\n private readonly jitter: number;\n private readonly cacheTtlMs: number;\n private readonly staleTtlMs: number;\n private readonly persistentCache: FeatureFlarePersistentCacheAdapter | undefined;\n private readonly onMetric?: (metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags) => void;\n private readonly listeners: {\n [K in keyof FeatureFlareClientEvents]: Set<(payload: FeatureFlareClientEvents[K]) => void>;\n } = {\n update: new Set(),\n circuitOpen: new Set(),\n circuitClose: new Set(),\n connectionState: new Set()\n };\n\n private readonly cache = new Map<string, CacheItem>();\n private readonly diagnostics = new Map<string, FeatureFlareEvaluationMetadata>();\n private readonly killSwitches = new Set<string>();\n\n private revision = 0;\n private circuitOpen = false;\n private persistentLoadPromise: Promise<void> | null = null;\n private readonly inFlightRevalidate = new Map<string, Promise<Array<{ key: string; value: boolean }> | null>>();\n private lastUser: FeatureFlareUser | null = null;\n private lastDefaultValue = false;\n\n private realtimeEnabled = true;\n private realtimePollingMs = 15000;\n private realtimeSsePath = '/api/v1/sdk/stream';\n private pollTimer: ReturnType<typeof setTimeout> | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private eventSource: EventSource | null = null;\n private visibilityListenersAttached = false;\n private realtimePausedByVisibility = false;\n\n private readonly handleRealtimeVisibilityChange = () => {\n if (!this.realtimeEnabled) return;\n\n const shouldPause = !this.isRealtimeWindowActive();\n if (shouldPause === this.realtimePausedByVisibility) return;\n\n this.realtimePausedByVisibility = shouldPause;\n if (shouldPause) {\n this.clearRealtimeTransport();\n this.emit('connectionState', { state: 'offline', transport: 'none' });\n return;\n }\n\n this.connectSse(0);\n };\n\n constructor(options: FeatureFlareClientOptions = {}) {\n this.apiBaseUrl = getApiBaseUrl(options.apiBaseUrl).replace(/\\/$/, '');\n this.sdkKey = options.sdkKey?.trim() || getSdkKeyFromEnv();\n this.projectKey = options.projectKey?.trim() ? options.projectKey.trim() : null;\n const explicitOrEnvKey = options.envKey?.trim() || getEnvKeyFromEnv() || null;\n this.envKey = explicitOrEnvKey ?? 'production';\n this.expectedEnvKey = explicitOrEnvKey;\n\n if (!this.sdkKey && !this.projectKey) {\n throw new Error(\n 'FeatureFlareClient requires either sdkKey (recommended) or projectKey (legacy). Set FEATUREFLARE_CLIENT_KEY or FEATUREFLARE_SERVER_KEY env var, or pass sdkKey in options.'\n );\n }\n\n this.timeoutMs = Number.isFinite(options.timeoutMs) && (options.timeoutMs ?? 0) > 0 ? Number(options.timeoutMs) : 3000;\n this.maxRetries = Number.isFinite(options.maxRetries) && (options.maxRetries ?? 0) >= 0 ? Number(options.maxRetries) : 2;\n this.backoffMs = Number.isFinite(options.backoffMs) && (options.backoffMs ?? 0) > 0 ? Number(options.backoffMs) : 200;\n this.jitter = Number.isFinite(options.jitter) && (options.jitter ?? 0) >= 0 ? Number(options.jitter) : 0.25;\n\n this.cacheTtlMs = Number.isFinite(options.cacheTtlMs) && (options.cacheTtlMs ?? 0) > 0 ? Number(options.cacheTtlMs) : 60000;\n const configuredStaleTtlMs =\n Number.isFinite(options.staleTtlMs) && (options.staleTtlMs ?? 0) > 0 ? Number(options.staleTtlMs) : 10000;\n this.staleTtlMs = Math.min(configuredStaleTtlMs, this.cacheTtlMs);\n\n this.persistentCache = options.persistentCache;\n this.onMetric = options.onMetric;\n\n this.realtimeEnabled = options.realtime?.enabled ?? true;\n this.realtimePollingMs =\n Number.isFinite(options.realtime?.pollingIntervalMs) && (options.realtime?.pollingIntervalMs ?? 0) > 0\n ? Number(options.realtime?.pollingIntervalMs)\n : 15000;\n this.realtimeSsePath = options.realtime?.ssePath ?? '/api/v1/sdk/stream';\n\n this.applyBootstrap(options.bootstrap);\n this.persistentLoadPromise = this.loadPersistentCache();\n\n if (this.realtimeEnabled && this.sdkKey) {\n this.startRealtime();\n }\n }\n\n private getCacheKey(flagKey: string): string {\n return `${this.envKey}:${flagKey}`;\n }\n\n private normalizeUser(input: FeatureFlareUserPayload): FeatureFlareUser {\n const key = (input.id ?? input.key ?? '').trim();\n if (!key) throw new Error('FeatureFlareClient requires user.id (or legacy user.key).');\n return {\n key,\n email: input.email,\n name: input.name,\n country: input.country,\n custom: input.meta ?? input.custom\n };\n }\n\n private emit<K extends keyof FeatureFlareClientEvents>(event: K, payload: FeatureFlareClientEvents[K]): void {\n for (const listener of this.listeners[event]) {\n listener(payload);\n }\n }\n\n on<K extends keyof FeatureFlareClientEvents>(\n event: K,\n listener: (payload: FeatureFlareClientEvents[K]) => void\n ): () => void {\n this.listeners[event].add(listener);\n return () => {\n this.listeners[event].delete(listener);\n };\n }\n\n private emitMetric(metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags): void {\n this.onMetric?.(metricName, value, tags);\n }\n\n private async ensurePersistentLoaded(): Promise<void> {\n if (!this.persistentLoadPromise) return;\n await this.persistentLoadPromise;\n }\n\n private async loadPersistentCache(): Promise<void> {\n if (!this.persistentCache) return;\n try {\n const snapshot = await this.persistentCache.load(this.envKey);\n if (!snapshot) return;\n this.revision = Math.max(this.revision, snapshot.revision ?? 0);\n for (const killSwitchKey of snapshot.killSwitches ?? []) {\n this.killSwitches.add(killSwitchKey);\n }\n\n for (const [flagKey, item] of Object.entries(snapshot.flags ?? {})) {\n const existing = this.cache.get(this.getCacheKey(flagKey));\n if (existing && existing.source === 'bootstrap') continue;\n this.cache.set(this.getCacheKey(flagKey), {\n envKey: this.envKey,\n flagKey,\n value: Boolean(item.value),\n updatedAt: Number(item.updatedAt) || Date.now(),\n staleAt: Number(item.staleAt) || Date.now(),\n expiresAt: Number(item.expiresAt) || Date.now(),\n source: item.source ?? 'persistent',\n revision: item.revision ?? 0\n });\n }\n } catch {\n // Ignore persistent cache failures; runtime must stay non-throwing for outage semantics.\n }\n }\n\n private async persistCache(): Promise<void> {\n if (!this.persistentCache) return;\n const snapshot: FeatureFlarePersistentSnapshot = {\n revision: this.revision,\n killSwitches: [...this.killSwitches],\n flags: {}\n };\n\n for (const [key, item] of this.cache.entries()) {\n if (!key.startsWith(`${this.envKey}:`)) continue;\n snapshot.flags[item.flagKey] = {\n value: item.value,\n updatedAt: item.updatedAt,\n staleAt: item.staleAt,\n expiresAt: item.expiresAt,\n source: item.source,\n revision: item.revision\n };\n }\n\n try {\n await this.persistentCache.save(this.envKey, snapshot);\n } catch {\n // Persistent errors must not break evaluation.\n }\n }\n\n private makeCacheWindow(at = Date.now()): Pick<CacheItem, 'updatedAt' | 'staleAt' | 'expiresAt'> {\n return {\n updatedAt: at,\n staleAt: at + this.staleTtlMs,\n expiresAt: at + this.cacheTtlMs\n };\n }\n\n private setCacheItem(\n flagKey: string,\n value: boolean,\n source: FeatureFlareCacheSource,\n revision = this.revision,\n at = Date.now()\n ): void {\n this.cache.set(this.getCacheKey(flagKey), {\n envKey: this.envKey,\n flagKey,\n value,\n source,\n revision,\n ...this.makeCacheWindow(at)\n });\n }\n\n private applyBootstrap(bootstrap?: FeatureFlareBootstrapPayload): void {\n if (!bootstrap) return;\n this.revision = Math.max(this.revision, bootstrap.revision ?? 0);\n for (const killSwitchKey of bootstrap.killSwitches ?? []) {\n this.killSwitches.add(killSwitchKey);\n }\n\n const apply = (flagKey: string, value: boolean, revision?: number, updatedAt?: number) => {\n this.setCacheItem(flagKey, value, 'bootstrap', revision ?? this.revision, updatedAt ?? Date.now());\n };\n\n if (Array.isArray(bootstrap.flags)) {\n for (const item of bootstrap.flags) {\n if (!item || typeof item.key !== 'string') continue;\n apply(item.key, Boolean(item.value), item.revision, item.updatedAt);\n }\n return;\n }\n\n for (const [flagKey, value] of Object.entries(bootstrap.flags ?? {})) {\n apply(flagKey, Boolean(value));\n }\n }\n\n private getCacheState(item: CacheItem | undefined, now = Date.now()): 'fresh' | 'stale' | 'expired' | 'missing' {\n if (!item) return 'missing';\n if (now <= item.staleAt) return 'fresh';\n if (now <= item.expiresAt) return 'stale';\n return 'expired';\n }\n\n private setCircuitState(isOpen: boolean, reason = ''): void {\n if (this.circuitOpen === isOpen) return;\n this.circuitOpen = isOpen;\n if (isOpen) {\n this.emit('circuitOpen', { envKey: this.envKey, reason });\n return;\n }\n this.emit('circuitClose', { envKey: this.envKey });\n }\n\n private async fetchWithRetry(url: string, init: RequestInit, transport: 'network' | 'polling') {\n let lastError: unknown = null;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n const ac = typeof AbortController !== 'undefined' ? new AbortController() : null;\n const timeout =\n ac !== null\n ? setTimeout(() => {\n ac.abort();\n }, this.timeoutMs)\n : null;\n\n try {\n const response = await fetch(url, {\n ...init,\n signal: ac?.signal\n });\n\n if (timeout) clearTimeout(timeout);\n\n if (!response.ok && isRetriableStatus(response.status) && attempt < this.maxRetries) {\n lastError = new Error(`HTTP ${response.status}`);\n const jitterOffset = this.backoffMs * this.jitter * Math.random();\n await sleep(this.backoffMs * (attempt + 1) + jitterOffset);\n continue;\n }\n\n return response;\n } catch (error) {\n if (timeout) clearTimeout(timeout);\n lastError = error;\n if (attempt >= this.maxRetries) break;\n const jitterOffset = this.backoffMs * this.jitter * Math.random();\n await sleep(this.backoffMs * (attempt + 1) + jitterOffset);\n }\n }\n\n this.setCircuitState(true, transport);\n throw lastError;\n }\n\n private collectCachedFlags(): Array<{ key: string; value: boolean }> {\n const now = Date.now();\n const flags: Array<{ key: string; value: boolean }> = [];\n\n for (const [cacheKey, item] of this.cache.entries()) {\n if (!cacheKey.startsWith(`${this.envKey}:`)) continue;\n if (this.killSwitches.has(item.flagKey)) {\n flags.push({ key: item.flagKey, value: false });\n continue;\n }\n\n const state = this.getCacheState(item, now);\n if (state === 'missing' || state === 'expired') continue;\n flags.push({ key: item.flagKey, value: item.value });\n }\n\n return flags.sort((a, b) => a.key.localeCompare(b.key));\n }\n\n getCachedFlags(): {\n flags: Array<{ key: string; value: boolean }>;\n hasData: boolean;\n } {\n const flags = this.collectCachedFlags();\n return { flags, hasData: flags.length > 0 };\n }\n\n getFlagDiagnostics(flagKey: string): FeatureFlareEvaluationMetadata | null {\n return this.diagnostics.get(this.getCacheKey(flagKey)) ?? null;\n }\n\n setKillSwitch(flagKey: string, enabled: boolean): void {\n const started = monotonicNow();\n if (enabled) {\n this.killSwitches.add(flagKey);\n } else {\n this.killSwitches.delete(flagKey);\n }\n const elapsed = monotonicNow() - started;\n this.emitMetric('ff_killswitch_apply_latency_ms', elapsed, {\n env: this.envKey,\n result: enabled ? 'enabled' : 'disabled'\n });\n this.emit('update', { changedKeys: [flagKey], source: 'realtime' });\n void this.persistCache();\n }\n\n private async fetchEvalFromNetwork(\n flagKey: string,\n normalizedUser: FeatureFlareUser,\n defaultValue: boolean\n ): Promise<boolean | null> {\n const response = this.sdkKey\n ? await this.fetchWithRetry(\n `${this.apiBaseUrl}/api/v1/sdk/eval`,\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-featureflare-sdk-key': this.sdkKey\n },\n body: JSON.stringify({\n flagKey,\n user: normalizedUser,\n defaultValue,\n expectedEnvKey: this.expectedEnvKey ?? undefined\n })\n },\n 'network'\n )\n : await this.fetchWithRetry(\n `${this.apiBaseUrl}/api/v1/eval`,\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n projectKey: this.projectKey,\n envKey: this.envKey,\n flagKey,\n user: normalizedUser,\n defaultValue\n })\n },\n 'network'\n );\n\n if (!response.ok) {\n if (!isRetriableStatus(response.status)) {\n this.setCircuitState(true, `http_${response.status}`);\n }\n return null;\n }\n\n const json = (await response.json()) as { value?: boolean; revision?: number; killSwitch?: boolean };\n const value = typeof json.value === 'boolean' ? json.value : defaultValue;\n\n if (json.killSwitch === true) {\n this.killSwitches.add(flagKey);\n }\n\n const revision = json.revision ?? this.revision;\n this.revision = Math.max(this.revision, revision);\n this.setCacheItem(flagKey, value, 'network', revision);\n this.setCircuitState(false);\n void this.persistCache();\n this.emit('update', { changedKeys: [flagKey], source: 'network' });\n return value;\n }\n\n private async fetchFlagsFromNetwork(\n normalizedUser: FeatureFlareUser,\n defaultValue: boolean,\n transport: 'network' | 'polling'\n ): Promise<Array<{ key: string; value: boolean }> | null> {\n if (!this.sdkKey) {\n return null;\n }\n\n const started = monotonicNow();\n\n try {\n const response = await this.fetchWithRetry(\n `${this.apiBaseUrl}/api/v1/sdk/flags`,\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-featureflare-sdk-key': this.sdkKey\n },\n body: JSON.stringify({\n user: normalizedUser,\n defaultValue,\n expectedEnvKey: this.expectedEnvKey ?? undefined\n })\n },\n transport\n );\n\n if (!response.ok) {\n if (!isRetriableStatus(response.status)) {\n this.setCircuitState(true, `http_${response.status}`);\n }\n return null;\n }\n\n const json = (await response.json()) as {\n flags?: Array<{ key: string; value: boolean }>;\n values?: Record<string, boolean>;\n revision?: number;\n killSwitches?: string[];\n };\n\n const list = normalizeBoolMap(json);\n const revision = json.revision ?? this.revision;\n this.revision = Math.max(this.revision, revision);\n\n if (Array.isArray(json.killSwitches)) {\n for (const key of json.killSwitches) {\n this.killSwitches.add(key);\n }\n }\n\n const changed = new Set<string>();\n for (const entry of list) {\n const existing = this.cache.get(this.getCacheKey(entry.key));\n if (!existing || existing.value !== entry.value || existing.revision !== revision) {\n changed.add(entry.key);\n }\n this.setCacheItem(entry.key, entry.value, 'network', revision);\n }\n\n if (changed.size > 0) {\n this.emit('update', { changedKeys: [...changed], source: 'network' });\n }\n\n this.setCircuitState(false);\n void this.persistCache();\n this.emitMetric('ff_revalidate_latency_ms', monotonicNow() - started, {\n env: this.envKey,\n transport\n });\n return list;\n } catch {\n this.emitMetric('ff_revalidate_latency_ms', monotonicNow() - started, {\n env: this.envKey,\n transport,\n result: 'error'\n });\n return null;\n }\n }\n\n private revalidate(normalizedUser: FeatureFlareUser, defaultValue: boolean): Promise<Array<{ key: string; value: boolean }> | null> {\n const existing = this.inFlightRevalidate.get(this.envKey);\n if (existing) return existing;\n\n const promise = this.fetchFlagsFromNetwork(normalizedUser, defaultValue, 'network').finally(() => {\n this.inFlightRevalidate.delete(this.envKey);\n });\n\n this.inFlightRevalidate.set(this.envKey, promise);\n return promise;\n }\n\n async evaluate(\n flagKey: string,\n user: FeatureFlareUserPayload,\n defaultValue = false\n ): Promise<FeatureFlareEvaluationResult> {\n const started = monotonicNow();\n await this.ensurePersistentLoaded();\n\n const normalizedUser = this.normalizeUser(user);\n this.lastUser = normalizedUser;\n this.lastDefaultValue = defaultValue;\n\n if (this.killSwitches.has(flagKey)) {\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'kill_switch',\n isStale: false,\n latencyMs: monotonicNow() - started,\n source: 'kill_switch'\n };\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'disabled'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: false, metadata };\n }\n\n const cacheItem = this.cache.get(this.getCacheKey(flagKey));\n const cacheState = this.getCacheState(cacheItem);\n\n if (cacheItem && cacheState === 'fresh') {\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: cacheItem.source === 'bootstrap' || cacheItem.source === 'persistent' ? 'bootstrap' : 'fresh_cache',\n isStale: false,\n latencyMs: monotonicNow() - started,\n source: cacheItem.source,\n updatedAt: cacheItem.updatedAt,\n staleAt: cacheItem.staleAt,\n expiresAt: cacheItem.expiresAt\n };\n this.emitMetric('ff_cache_hit_ratio', 1, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'cache_hit'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: cacheItem.value, metadata };\n }\n\n if (cacheItem && cacheState === 'stale') {\n void this.revalidate(normalizedUser, defaultValue);\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'stale_cache',\n isStale: true,\n latencyMs: monotonicNow() - started,\n source: cacheItem.source,\n updatedAt: cacheItem.updatedAt,\n staleAt: cacheItem.staleAt,\n expiresAt: cacheItem.expiresAt\n };\n this.emitMetric('ff_cache_hit_ratio', 1, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'stale'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: cacheItem.value, metadata };\n }\n\n if (cacheItem && (cacheItem.source === 'bootstrap' || cacheItem.source === 'persistent')) {\n void this.revalidate(normalizedUser, defaultValue);\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'bootstrap',\n isStale: true,\n latencyMs: monotonicNow() - started,\n source: cacheItem.source,\n updatedAt: cacheItem.updatedAt,\n staleAt: cacheItem.staleAt,\n expiresAt: cacheItem.expiresAt\n };\n this.emitMetric('ff_cache_hit_ratio', 1, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'bootstrap'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: cacheItem.value, metadata };\n }\n\n try {\n const networkValue = await this.fetchEvalFromNetwork(flagKey, normalizedUser, defaultValue);\n if (networkValue !== null) {\n const item = this.cache.get(this.getCacheKey(flagKey));\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'network',\n isStale: false,\n latencyMs: monotonicNow() - started,\n source: 'network',\n updatedAt: item?.updatedAt,\n staleAt: item?.staleAt,\n expiresAt: item?.expiresAt\n };\n this.emitMetric('ff_cache_hit_ratio', 0, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'network'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: networkValue, metadata };\n }\n } catch {\n // Fall through to deterministic default for outage semantics.\n }\n\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'default',\n isStale: false,\n latencyMs: monotonicNow() - started,\n source: 'default'\n };\n this.emitMetric('ff_cache_hit_ratio', 0, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'default'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: defaultValue, metadata };\n }\n\n async bool(flagKey: string, user: FeatureFlareUserPayload, defaultValue = false): Promise<boolean> {\n const result = await this.evaluate(flagKey, user, defaultValue);\n return result.value;\n }\n\n async flags(user: FeatureFlareUserPayload, defaultValue = false): Promise<Array<{ key: string; value: boolean }>> {\n await this.ensurePersistentLoaded();\n const normalizedUser = this.normalizeUser(user);\n this.lastUser = normalizedUser;\n this.lastDefaultValue = defaultValue;\n\n const list = await this.revalidate(normalizedUser, defaultValue);\n if (list && list.length > 0) {\n return list.map((entry) => ({\n key: entry.key,\n value: this.killSwitches.has(entry.key) ? false : entry.value\n }));\n }\n\n const cached = this.collectCachedFlags();\n if (cached.length > 0) return cached;\n return [];\n }\n\n private applyRealtimeMessage(message: RealtimeEventPayload): void {\n if (typeof message.revision === 'number' && message.revision < this.revision) {\n return;\n }\n\n if (typeof message.revision === 'number') {\n this.revision = message.revision;\n }\n\n const changed = new Set<string>();\n const now = Date.now();\n\n if (message.type === 'flag.updated') {\n const flagKey = typeof message.data?.flagKey === 'string' ? message.data.flagKey : null;\n const value = typeof message.data?.value === 'boolean' ? message.data.value : null;\n if (flagKey !== null && value !== null) {\n this.setCacheItem(flagKey, value, 'realtime', message.revision ?? this.revision, now);\n changed.add(flagKey);\n }\n }\n\n if (message.type === 'flag.deleted') {\n const flagKey = typeof message.data?.flagKey === 'string' ? message.data.flagKey : null;\n if (flagKey !== null) {\n this.cache.delete(this.getCacheKey(flagKey));\n changed.add(flagKey);\n }\n }\n\n if (message.type === 'env.kill_switch.updated') {\n const started = monotonicNow();\n const flagKey = typeof message.data?.flagKey === 'string' ? message.data.flagKey : null;\n const enabled = typeof message.data?.enabled === 'boolean' ? message.data.enabled : true;\n if (flagKey !== null) {\n if (enabled) {\n this.killSwitches.add(flagKey);\n } else {\n this.killSwitches.delete(flagKey);\n }\n changed.add(flagKey);\n this.emitMetric('ff_killswitch_apply_latency_ms', monotonicNow() - started, {\n env: this.envKey,\n transport: this.eventSource ? 'sse' : 'polling',\n result: enabled ? 'enabled' : 'disabled'\n });\n }\n }\n\n if (message.type === 'snapshot.invalidate' && this.lastUser) {\n void this.fetchFlagsFromNetwork(this.lastUser, this.lastDefaultValue, 'network');\n }\n\n const eventLagMs = Math.max(0, Date.now() - (message.timestamp ?? Date.now()));\n this.emitMetric('ff_realtime_lag_ms', eventLagMs, {\n env: this.envKey,\n transport: this.eventSource ? 'sse' : 'polling'\n });\n\n if (changed.size > 0) {\n this.emit('update', { changedKeys: [...changed], source: 'realtime' });\n void this.persistCache();\n }\n }\n\n private isRealtimeWindowActive(): boolean {\n if (typeof document !== 'undefined' && document.hidden) {\n return false;\n }\n\n if (typeof document !== 'undefined' && typeof document.hasFocus === 'function') {\n return document.hasFocus();\n }\n\n return true;\n }\n\n private attachRealtimeVisibilityListeners(): void {\n if (this.visibilityListenersAttached) return;\n\n if (typeof document !== 'undefined' && typeof document.addEventListener === 'function') {\n document.addEventListener('visibilitychange', this.handleRealtimeVisibilityChange);\n this.visibilityListenersAttached = true;\n }\n\n if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {\n window.addEventListener('focus', this.handleRealtimeVisibilityChange);\n window.addEventListener('blur', this.handleRealtimeVisibilityChange);\n this.visibilityListenersAttached = true;\n }\n\n if (this.visibilityListenersAttached) {\n this.handleRealtimeVisibilityChange();\n }\n }\n\n private detachRealtimeVisibilityListeners(): void {\n if (!this.visibilityListenersAttached) return;\n\n if (typeof document !== 'undefined' && typeof document.removeEventListener === 'function') {\n document.removeEventListener('visibilitychange', this.handleRealtimeVisibilityChange);\n }\n\n if (typeof window !== 'undefined' && typeof window.removeEventListener === 'function') {\n window.removeEventListener('focus', this.handleRealtimeVisibilityChange);\n window.removeEventListener('blur', this.handleRealtimeVisibilityChange);\n }\n\n this.visibilityListenersAttached = false;\n this.realtimePausedByVisibility = false;\n }\n\n private clearRealtimeTransport(): void {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n }\n\n private startPolling(): void {\n if (this.realtimePausedByVisibility) return;\n\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n\n const tick = async () => {\n if (this.realtimePausedByVisibility || !this.realtimeEnabled) {\n this.pollTimer = null;\n return;\n }\n if (!this.lastUser) {\n this.pollTimer = setTimeout(tick, this.realtimePollingMs);\n return;\n }\n await this.fetchFlagsFromNetwork(this.lastUser, this.lastDefaultValue, 'polling');\n this.pollTimer = setTimeout(tick, this.realtimePollingMs);\n };\n\n this.pollTimer = setTimeout(tick, this.realtimePollingMs);\n }\n\n private connectSse(attempt = 0): void {\n if (this.realtimePausedByVisibility || !this.realtimeEnabled) {\n return;\n }\n\n const EventSourceImpl = typeof EventSource !== 'undefined' ? EventSource : null;\n if (!EventSourceImpl || !this.sdkKey) {\n this.emit('connectionState', { state: 'degraded', transport: 'polling' });\n this.startPolling();\n return;\n }\n\n const url = new URL(this.realtimeSsePath, this.apiBaseUrl);\n url.searchParams.set('sdkKey', this.sdkKey);\n if (this.expectedEnvKey) {\n url.searchParams.set('expectedEnvKey', this.expectedEnvKey);\n }\n\n this.eventSource = new EventSourceImpl(url.toString());\n\n this.eventSource.onopen = () => {\n this.emit('connectionState', { state: 'connected', transport: 'sse' });\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n };\n\n this.eventSource.onmessage = (event: MessageEvent) => {\n try {\n const payload = JSON.parse(String(event.data)) as RealtimeEventPayload;\n this.applyRealtimeMessage(payload);\n } catch {\n // Ignore malformed realtime messages.\n }\n };\n\n this.eventSource.onerror = () => {\n if (this.realtimePausedByVisibility || !this.realtimeEnabled) {\n this.clearRealtimeTransport();\n this.emit('connectionState', { state: 'offline', transport: 'none' });\n return;\n }\n\n this.emit('connectionState', { state: 'degraded', transport: 'polling' });\n this.eventSource?.close();\n this.eventSource = null;\n this.startPolling();\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n }\n const backoff = Math.min(this.backoffMs * (attempt + 1), 30000);\n this.reconnectTimer = setTimeout(() => {\n this.connectSse(attempt + 1);\n }, backoff);\n };\n }\n\n startRealtime(): void {\n this.realtimeEnabled = true;\n this.attachRealtimeVisibilityListeners();\n if (this.realtimePausedByVisibility) {\n this.emit('connectionState', { state: 'offline', transport: 'none' });\n return;\n }\n this.connectSse(0);\n }\n\n stopRealtime(): void {\n this.realtimeEnabled = false;\n this.detachRealtimeVisibilityListeners();\n this.clearRealtimeTransport();\n this.emit('connectionState', { state: 'offline', transport: 'none' });\n }\n\n /**\n * Report observed error metrics (error rate, latency) for a flag back to the FeatureFlare API.\n * The API evaluates the report against active rollback policies and may trigger an automated\n * rollback if configured thresholds are breached.\n *\n * Errors from this call are silently swallowed so that reporting never disrupts the host application.\n */\n async reportError(report: FeatureFlareErrorReport): Promise<void> {\n if (!this.sdkKey) return;\n try {\n await fetch(`${this.apiBaseUrl}/api/v1/sdk/report`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-featureflare-sdk-key': this.sdkKey\n },\n body: JSON.stringify({\n flagKey: report.flagKey,\n errorRate: report.errorRate,\n latencyMs: report.latencyMs,\n observedAt: report.observedAt ?? new Date().toISOString(),\n envKey: this.envKey,\n context: report.context\n })\n });\n } catch {\n // Reporting failures must never surface to the caller.\n }\n }\n\n dispose(): void {\n this.stopRealtime();\n this.listeners.update.clear();\n this.listeners.circuitOpen.clear();\n this.listeners.circuitClose.clear();\n this.listeners.connectionState.clear();\n }\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -141,6 +141,9 @@ declare class FeatureFlareClient {
141
141
  private pollTimer;
142
142
  private reconnectTimer;
143
143
  private eventSource;
144
+ private visibilityListenersAttached;
145
+ private realtimePausedByVisibility;
146
+ private readonly handleRealtimeVisibilityChange;
144
147
  constructor(options?: FeatureFlareClientOptions);
145
148
  private getCacheKey;
146
149
  private normalizeUser;
@@ -176,6 +179,10 @@ declare class FeatureFlareClient {
176
179
  value: boolean;
177
180
  }>>;
178
181
  private applyRealtimeMessage;
182
+ private isRealtimeWindowActive;
183
+ private attachRealtimeVisibilityListeners;
184
+ private detachRealtimeVisibilityListeners;
185
+ private clearRealtimeTransport;
179
186
  private startPolling;
180
187
  private connectSse;
181
188
  startRealtime(): void;
package/dist/index.d.ts CHANGED
@@ -141,6 +141,9 @@ declare class FeatureFlareClient {
141
141
  private pollTimer;
142
142
  private reconnectTimer;
143
143
  private eventSource;
144
+ private visibilityListenersAttached;
145
+ private realtimePausedByVisibility;
146
+ private readonly handleRealtimeVisibilityChange;
144
147
  constructor(options?: FeatureFlareClientOptions);
145
148
  private getCacheKey;
146
149
  private normalizeUser;
@@ -176,6 +179,10 @@ declare class FeatureFlareClient {
176
179
  value: boolean;
177
180
  }>>;
178
181
  private applyRealtimeMessage;
182
+ private isRealtimeWindowActive;
183
+ private attachRealtimeVisibilityListeners;
184
+ private detachRealtimeVisibilityListeners;
185
+ private clearRealtimeTransport;
179
186
  private startPolling;
180
187
  private connectSse;
181
188
  startRealtime(): void;
package/dist/index.js CHANGED
@@ -103,6 +103,20 @@ var FeatureFlareClient = class {
103
103
  pollTimer = null;
104
104
  reconnectTimer = null;
105
105
  eventSource = null;
106
+ visibilityListenersAttached = false;
107
+ realtimePausedByVisibility = false;
108
+ handleRealtimeVisibilityChange = () => {
109
+ if (!this.realtimeEnabled) return;
110
+ const shouldPause = !this.isRealtimeWindowActive();
111
+ if (shouldPause === this.realtimePausedByVisibility) return;
112
+ this.realtimePausedByVisibility = shouldPause;
113
+ if (shouldPause) {
114
+ this.clearRealtimeTransport();
115
+ this.emit("connectionState", { state: "offline", transport: "none" });
116
+ return;
117
+ }
118
+ this.connectSse(0);
119
+ };
106
120
  constructor(options = {}) {
107
121
  this.apiBaseUrl = getApiBaseUrl(options.apiBaseUrl).replace(/\/$/, "");
108
122
  this.sdkKey = options.sdkKey?.trim() || getSdkKeyFromEnv();
@@ -642,7 +656,7 @@ var FeatureFlareClient = class {
642
656
  }
643
657
  }
644
658
  if (message.type === "snapshot.invalidate" && this.lastUser) {
645
- void this.revalidate(this.lastUser, this.lastDefaultValue);
659
+ void this.fetchFlagsFromNetwork(this.lastUser, this.lastDefaultValue, "network");
646
660
  }
647
661
  const eventLagMs = Math.max(0, Date.now() - (message.timestamp ?? Date.now()));
648
662
  this.emitMetric("ff_realtime_lag_ms", eventLagMs, {
@@ -654,12 +668,67 @@ var FeatureFlareClient = class {
654
668
  void this.persistCache();
655
669
  }
656
670
  }
671
+ isRealtimeWindowActive() {
672
+ if (typeof document !== "undefined" && document.hidden) {
673
+ return false;
674
+ }
675
+ if (typeof document !== "undefined" && typeof document.hasFocus === "function") {
676
+ return document.hasFocus();
677
+ }
678
+ return true;
679
+ }
680
+ attachRealtimeVisibilityListeners() {
681
+ if (this.visibilityListenersAttached) return;
682
+ if (typeof document !== "undefined" && typeof document.addEventListener === "function") {
683
+ document.addEventListener("visibilitychange", this.handleRealtimeVisibilityChange);
684
+ this.visibilityListenersAttached = true;
685
+ }
686
+ if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
687
+ window.addEventListener("focus", this.handleRealtimeVisibilityChange);
688
+ window.addEventListener("blur", this.handleRealtimeVisibilityChange);
689
+ this.visibilityListenersAttached = true;
690
+ }
691
+ if (this.visibilityListenersAttached) {
692
+ this.handleRealtimeVisibilityChange();
693
+ }
694
+ }
695
+ detachRealtimeVisibilityListeners() {
696
+ if (!this.visibilityListenersAttached) return;
697
+ if (typeof document !== "undefined" && typeof document.removeEventListener === "function") {
698
+ document.removeEventListener("visibilitychange", this.handleRealtimeVisibilityChange);
699
+ }
700
+ if (typeof window !== "undefined" && typeof window.removeEventListener === "function") {
701
+ window.removeEventListener("focus", this.handleRealtimeVisibilityChange);
702
+ window.removeEventListener("blur", this.handleRealtimeVisibilityChange);
703
+ }
704
+ this.visibilityListenersAttached = false;
705
+ this.realtimePausedByVisibility = false;
706
+ }
707
+ clearRealtimeTransport() {
708
+ if (this.eventSource) {
709
+ this.eventSource.close();
710
+ this.eventSource = null;
711
+ }
712
+ if (this.pollTimer) {
713
+ clearTimeout(this.pollTimer);
714
+ this.pollTimer = null;
715
+ }
716
+ if (this.reconnectTimer) {
717
+ clearTimeout(this.reconnectTimer);
718
+ this.reconnectTimer = null;
719
+ }
720
+ }
657
721
  startPolling() {
722
+ if (this.realtimePausedByVisibility) return;
658
723
  if (this.pollTimer) {
659
724
  clearTimeout(this.pollTimer);
660
725
  this.pollTimer = null;
661
726
  }
662
727
  const tick = async () => {
728
+ if (this.realtimePausedByVisibility || !this.realtimeEnabled) {
729
+ this.pollTimer = null;
730
+ return;
731
+ }
663
732
  if (!this.lastUser) {
664
733
  this.pollTimer = setTimeout(tick, this.realtimePollingMs);
665
734
  return;
@@ -670,6 +739,9 @@ var FeatureFlareClient = class {
670
739
  this.pollTimer = setTimeout(tick, this.realtimePollingMs);
671
740
  }
672
741
  connectSse(attempt = 0) {
742
+ if (this.realtimePausedByVisibility || !this.realtimeEnabled) {
743
+ return;
744
+ }
673
745
  const EventSourceImpl = typeof EventSource !== "undefined" ? EventSource : null;
674
746
  if (!EventSourceImpl || !this.sdkKey) {
675
747
  this.emit("connectionState", { state: "degraded", transport: "polling" });
@@ -697,6 +769,11 @@ var FeatureFlareClient = class {
697
769
  }
698
770
  };
699
771
  this.eventSource.onerror = () => {
772
+ if (this.realtimePausedByVisibility || !this.realtimeEnabled) {
773
+ this.clearRealtimeTransport();
774
+ this.emit("connectionState", { state: "offline", transport: "none" });
775
+ return;
776
+ }
700
777
  this.emit("connectionState", { state: "degraded", transport: "polling" });
701
778
  this.eventSource?.close();
702
779
  this.eventSource = null;
@@ -712,22 +789,17 @@ var FeatureFlareClient = class {
712
789
  }
713
790
  startRealtime() {
714
791
  this.realtimeEnabled = true;
792
+ this.attachRealtimeVisibilityListeners();
793
+ if (this.realtimePausedByVisibility) {
794
+ this.emit("connectionState", { state: "offline", transport: "none" });
795
+ return;
796
+ }
715
797
  this.connectSse(0);
716
798
  }
717
799
  stopRealtime() {
718
800
  this.realtimeEnabled = false;
719
- if (this.eventSource) {
720
- this.eventSource.close();
721
- this.eventSource = null;
722
- }
723
- if (this.pollTimer) {
724
- clearTimeout(this.pollTimer);
725
- this.pollTimer = null;
726
- }
727
- if (this.reconnectTimer) {
728
- clearTimeout(this.reconnectTimer);
729
- this.reconnectTimer = null;
730
- }
801
+ this.detachRealtimeVisibilityListeners();
802
+ this.clearRealtimeTransport();
731
803
  this.emit("connectionState", { state: "offline", transport: "none" });
732
804
  }
733
805
  /**
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["metadata"],"mappings":";AAsBA,IAAM,iCAAA,GACJ,qDAAA;AAEF,SAAS,oBAAA,GAAsC;AAC7C,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,EAAK;AACjD,IAAA,OACE,OAAA,CAAQ,IAAI,yBAAA,EAA2B,IAAA,MACvC,OAAA,CAAQ,GAAA,CAAI,mBAAA,EAAqB,IAAA,EAAK,IACtC,IAAA;AAAA,EAEJ;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,cAAc,QAAA,EAA2B;AAChD,EAAA,MAAM,WAAA,GAAc,UAAU,IAAA,EAAK;AACnC,EAAA,IAAI,aAAa,OAAO,WAAA;AAExB,EAAA,MAAM,UAAU,oBAAA,EAAqB;AACrC,EAAA,IAAI,SAAS,OAAO,OAAA;AAEpB,EAAA,OAAO,iCAAA;AACT;AAqHA,SAAS,gBAAA,GAAkC;AACzC,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,EAAK;AACjD,IAAA,OACE,OAAA,CAAQ,IAAI,oBAAA,EAAsB,IAAA,MAClC,OAAA,CAAQ,GAAA,CAAI,cAAA,EAAgB,IAAA,EAAK,IACjC,IAAA;AAAA,EAEJ;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,gBAAA,GAAkC;AACzC,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,EAAK;AACjD,IAAA,OACE,QAAQ,GAAA,CAAI,uBAAA,EAAyB,MAAK,IAC1C,OAAA,CAAQ,IAAI,uBAAA,EAAyB,IAAA,MACrC,OAAA,CAAQ,GAAA,CAAI,mBAAmB,IAAA,EAAK,IACpC,QAAQ,GAAA,CAAI,iBAAA,EAAmB,MAAK,IACpC,IAAA;AAAA,EAEJ;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,YAAA,GAAuB;AAC9B,EAAA,IAAI,OAAO,WAAA,KAAgB,WAAA,IAAe,OAAO,WAAA,CAAY,QAAQ,UAAA,EAAY;AAC/E,IAAA,OAAO,YAAY,GAAA,EAAI;AAAA,EACzB;AACA,EAAA,OAAO,KAAK,GAAA,EAAI;AAClB;AAEA,SAAS,MAAM,EAAA,EAA2B;AACxC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9B,IAAA,UAAA,CAAW,SAAS,EAAE,CAAA;AAAA,EACxB,CAAC,CAAA;AACH;AAEA,SAAS,kBAAkB,MAAA,EAAyB;AAClD,EAAA,OAAO,WAAW,GAAA,IAAO,MAAA,KAAW,GAAA,IAAO,MAAA,KAAW,OAAO,MAAA,IAAU,GAAA;AACzE;AAEA,SAAS,iBACP,KAAA,EACwC;AACxC,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA,EAAG;AAC9B,IAAA,OAAO,MAAM,KAAA,CACV,MAAA;AAAA,MAAO,CAAC,KAAA,KACP,OAAA,CAAQ,KAAK,CAAA,IAAK,OAAO,KAAA,CAAM,GAAA,KAAQ,QAAA,IAAY,OAAO,KAAA,CAAM,KAAA,KAAU;AAAA,KAC5E,CACC,GAAA,CAAI,CAAC,KAAA,MAAW,EAAE,GAAA,EAAK,KAAA,CAAM,GAAA,EAAK,KAAA,EAAO,KAAA,CAAM,KAAA,EAAM,CAAE,CAAA;AAAA,EAC5D;AAEA,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,MAAA,IAAU,EAAC;AAChC,EAAA,OAAO,OAAO,OAAA,CAAQ,MAAM,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,MAAO,EAAE,GAAA,EAAK,KAAA,EAAO,OAAA,CAAQ,KAAK,GAAE,CAAE,CAAA;AACtF;AAEO,IAAM,2BAAN,MAA+B;AAAA,EACnB,OAAA,uBAAc,GAAA,EAAsB;AAAA,EAErD,MAAA,GAAS,CAAC,UAAA,EAAoC,KAAA,EAAe,IAAA,KAAkC;AAC7F,IAAA,MAAM,GAAA,GAAM,GAAG,UAAU,CAAA,CAAA,EAAI,KAAK,SAAA,CAAU,IAAA,IAAQ,EAAE,CAAC,CAAA,CAAA;AACvD,IAAA,MAAM,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,GAAG,KAAK,EAAC;AACvC,IAAA,IAAA,CAAK,KAAK,KAAK,CAAA;AACf,IAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,IAAI,CAAA;AAAA,EAC5B,CAAA;AAAA,EAEA,IAAI,UAAA,EAA+F;AACjG,IAAA,MAAM,OAAkE,EAAC;AACzE,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,MAAM,KAAK,IAAA,CAAK,OAAA,CAAQ,SAAQ,EAAG;AAClD,MAAA,IAAI,CAAC,GAAA,CAAI,UAAA,CAAW,CAAA,EAAG,UAAU,GAAG,CAAA,EAAG;AACvC,MAAA,IAAA,CAAK,IAAA,CAAK;AAAA,QACR,IAAA,EAAM,KAAK,KAAA,CAAM,GAAA,CAAI,MAAM,UAAA,CAAW,MAAA,GAAS,CAAC,CAAC,CAAA;AAAA,QACjD,MAAA,EAAQ,CAAC,GAAG,MAAM;AAAA,OACnB,CAAA;AAAA,IACH;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEO,IAAM,qBAAN,MAAyB;AAAA,EACb,UAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,cAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,eAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA,GAEb;AAAA,IACF,MAAA,sBAAY,GAAA,EAAI;AAAA,IAChB,WAAA,sBAAiB,GAAA,EAAI;AAAA,IACrB,YAAA,sBAAkB,GAAA,EAAI;AAAA,IACtB,eAAA,sBAAqB,GAAA;AAAI,GAC3B;AAAA,EAEiB,KAAA,uBAAY,GAAA,EAAuB;AAAA,EACnC,WAAA,uBAAkB,GAAA,EAA4C;AAAA,EAC9D,YAAA,uBAAmB,GAAA,EAAY;AAAA,EAExC,QAAA,GAAW,CAAA;AAAA,EACX,WAAA,GAAc,KAAA;AAAA,EACd,qBAAA,GAA8C,IAAA;AAAA,EACrC,kBAAA,uBAAyB,GAAA,EAAoE;AAAA,EACtG,QAAA,GAAoC,IAAA;AAAA,EACpC,gBAAA,GAAmB,KAAA;AAAA,EAEnB,eAAA,GAAkB,IAAA;AAAA,EAClB,iBAAA,GAAoB,IAAA;AAAA,EACpB,eAAA,GAAkB,oBAAA;AAAA,EAClB,SAAA,GAAkD,IAAA;AAAA,EAClD,cAAA,GAAuD,IAAA;AAAA,EACvD,WAAA,GAAkC,IAAA;AAAA,EAE1C,WAAA,CAAY,OAAA,GAAqC,EAAC,EAAG;AACnD,IAAA,IAAA,CAAK,aAAa,aAAA,CAAc,OAAA,CAAQ,UAAU,CAAA,CAAE,OAAA,CAAQ,OAAO,EAAE,CAAA;AACrE,IAAA,IAAA,CAAK,MAAA,GAAS,OAAA,CAAQ,MAAA,EAAQ,IAAA,MAAU,gBAAA,EAAiB;AACzD,IAAA,IAAA,CAAK,UAAA,GAAa,QAAQ,UAAA,EAAY,IAAA,KAAS,OAAA,CAAQ,UAAA,CAAW,MAAK,GAAI,IAAA;AAC3E,IAAA,MAAM,mBAAmB,OAAA,CAAQ,MAAA,EAAQ,IAAA,EAAK,IAAK,kBAAiB,IAAK,IAAA;AACzE,IAAA,IAAA,CAAK,SAAS,gBAAA,IAAoB,YAAA;AAClC,IAAA,IAAA,CAAK,cAAA,GAAiB,gBAAA;AAEtB,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,IAAU,CAAC,KAAK,UAAA,EAAY;AACpC,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,SAAA,GAAY,MAAA,CAAO,QAAA,CAAS,OAAA,CAAQ,SAAS,CAAA,IAAA,CAAM,OAAA,CAAQ,SAAA,IAAa,CAAA,IAAK,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,GAAI,GAAA;AAClH,IAAA,IAAA,CAAK,UAAA,GAAa,MAAA,CAAO,QAAA,CAAS,OAAA,CAAQ,UAAU,CAAA,IAAA,CAAM,OAAA,CAAQ,UAAA,IAAc,CAAA,KAAM,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,GAAI,CAAA;AACvH,IAAA,IAAA,CAAK,SAAA,GAAY,MAAA,CAAO,QAAA,CAAS,OAAA,CAAQ,SAAS,CAAA,IAAA,CAAM,OAAA,CAAQ,SAAA,IAAa,CAAA,IAAK,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,GAAI,GAAA;AAClH,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA,CAAO,QAAA,CAAS,OAAA,CAAQ,MAAM,CAAA,IAAA,CAAM,OAAA,CAAQ,MAAA,IAAU,CAAA,KAAM,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,GAAI,IAAA;AAEvG,IAAA,IAAA,CAAK,UAAA,GAAa,MAAA,CAAO,QAAA,CAAS,OAAA,CAAQ,UAAU,CAAA,IAAA,CAAM,OAAA,CAAQ,UAAA,IAAc,CAAA,IAAK,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,GAAI,GAAA;AACtH,IAAA,MAAM,oBAAA,GACJ,MAAA,CAAO,QAAA,CAAS,OAAA,CAAQ,UAAU,CAAA,IAAA,CAAM,OAAA,CAAQ,UAAA,IAAc,CAAA,IAAK,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,GAAI,GAAA;AACtG,IAAA,IAAA,CAAK,UAAA,GAAa,IAAA,CAAK,GAAA,CAAI,oBAAA,EAAsB,KAAK,UAAU,CAAA;AAEhE,IAAA,IAAA,CAAK,kBAAkB,OAAA,CAAQ,eAAA;AAC/B,IAAA,IAAA,CAAK,WAAW,OAAA,CAAQ,QAAA;AAExB,IAAA,IAAA,CAAK,eAAA,GAAkB,OAAA,CAAQ,QAAA,EAAU,OAAA,IAAW,IAAA;AACpD,IAAA,IAAA,CAAK,oBACH,MAAA,CAAO,QAAA,CAAS,OAAA,CAAQ,QAAA,EAAU,iBAAiB,CAAA,IAAA,CAAM,OAAA,CAAQ,QAAA,EAAU,iBAAA,IAAqB,KAAK,CAAA,GACjG,MAAA,CAAO,OAAA,CAAQ,QAAA,EAAU,iBAAiB,CAAA,GAC1C,IAAA;AACN,IAAA,IAAA,CAAK,eAAA,GAAkB,OAAA,CAAQ,QAAA,EAAU,OAAA,IAAW,oBAAA;AAEpD,IAAA,IAAA,CAAK,cAAA,CAAe,QAAQ,SAAS,CAAA;AACrC,IAAA,IAAA,CAAK,qBAAA,GAAwB,KAAK,mBAAA,EAAoB;AAEtD,IAAA,IAAI,IAAA,CAAK,eAAA,IAAmB,IAAA,CAAK,MAAA,EAAQ;AACvC,MAAA,IAAA,CAAK,aAAA,EAAc;AAAA,IACrB;AAAA,EACF;AAAA,EAEQ,YAAY,OAAA,EAAyB;AAC3C,IAAA,OAAO,CAAA,EAAG,IAAA,CAAK,MAAM,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA;AAAA,EAClC;AAAA,EAEQ,cAAc,KAAA,EAAkD;AACtE,IAAA,MAAM,OAAO,KAAA,CAAM,EAAA,IAAM,KAAA,CAAM,GAAA,IAAO,IAAI,IAAA,EAAK;AAC/C,IAAA,IAAI,CAAC,GAAA,EAAK,MAAM,IAAI,MAAM,2DAA2D,CAAA;AACrF,IAAA,OAAO;AAAA,MACL,GAAA;AAAA,MACA,OAAO,KAAA,CAAM,KAAA;AAAA,MACb,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,MAAA,EAAQ,KAAA,CAAM,IAAA,IAAQ,KAAA,CAAM;AAAA,KAC9B;AAAA,EACF;AAAA,EAEQ,IAAA,CAA+C,OAAU,OAAA,EAA4C;AAC3G,IAAA,KAAA,MAAW,QAAA,IAAY,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA,EAAG;AAC5C,MAAA,QAAA,CAAS,OAAO,CAAA;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,EAAA,CACE,OACA,QAAA,EACY;AACZ,IAAA,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA,CAAE,GAAA,CAAI,QAAQ,CAAA;AAClC,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA,CAAE,MAAA,CAAO,QAAQ,CAAA;AAAA,IACvC,CAAA;AAAA,EACF;AAAA,EAEQ,UAAA,CAAW,UAAA,EAAoC,KAAA,EAAe,IAAA,EAAqC;AACzG,IAAA,IAAA,CAAK,QAAA,GAAW,UAAA,EAAY,KAAA,EAAO,IAAI,CAAA;AAAA,EACzC;AAAA,EAEA,MAAc,sBAAA,GAAwC;AACpD,IAAA,IAAI,CAAC,KAAK,qBAAA,EAAuB;AACjC,IAAA,MAAM,IAAA,CAAK,qBAAA;AAAA,EACb;AAAA,EAEA,MAAc,mBAAA,GAAqC;AACjD,IAAA,IAAI,CAAC,KAAK,eAAA,EAAiB;AAC3B,IAAA,IAAI;AACF,MAAA,MAAM,WAAW,MAAM,IAAA,CAAK,eAAA,CAAgB,IAAA,CAAK,KAAK,MAAM,CAAA;AAC5D,MAAA,IAAI,CAAC,QAAA,EAAU;AACf,MAAA,IAAA,CAAK,WAAW,IAAA,CAAK,GAAA,CAAI,KAAK,QAAA,EAAU,QAAA,CAAS,YAAY,CAAC,CAAA;AAC9D,MAAA,KAAA,MAAW,aAAA,IAAiB,QAAA,CAAS,YAAA,IAAgB,EAAC,EAAG;AACvD,QAAA,IAAA,CAAK,YAAA,CAAa,IAAI,aAAa,CAAA;AAAA,MACrC;AAEA,MAAA,KAAA,MAAW,CAAC,OAAA,EAAS,IAAI,CAAA,IAAK,MAAA,CAAO,QAAQ,QAAA,CAAS,KAAA,IAAS,EAAE,CAAA,EAAG;AAClE,QAAA,MAAM,WAAW,IAAA,CAAK,KAAA,CAAM,IAAI,IAAA,CAAK,WAAA,CAAY,OAAO,CAAC,CAAA;AACzD,QAAA,IAAI,QAAA,IAAY,QAAA,CAAS,MAAA,KAAW,WAAA,EAAa;AACjD,QAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAA,CAAK,WAAA,CAAY,OAAO,CAAA,EAAG;AAAA,UACxC,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb,OAAA;AAAA,UACA,KAAA,EAAO,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA;AAAA,UACzB,WAAW,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,IAAK,KAAK,GAAA,EAAI;AAAA,UAC9C,SAAS,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA,IAAK,KAAK,GAAA,EAAI;AAAA,UAC1C,WAAW,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,IAAK,KAAK,GAAA,EAAI;AAAA,UAC9C,MAAA,EAAQ,KAAK,MAAA,IAAU,YAAA;AAAA,UACvB,QAAA,EAAU,KAAK,QAAA,IAAY;AAAA,SAC5B,CAAA;AAAA,MACH;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,MAAc,YAAA,GAA8B;AAC1C,IAAA,IAAI,CAAC,KAAK,eAAA,EAAiB;AAC3B,IAAA,MAAM,QAAA,GAA2C;AAAA,MAC/C,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,YAAA,EAAc,CAAC,GAAG,IAAA,CAAK,YAAY,CAAA;AAAA,MACnC,OAAO;AAAC,KACV;AAEA,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,IAAI,KAAK,IAAA,CAAK,KAAA,CAAM,SAAQ,EAAG;AAC9C,MAAA,IAAI,CAAC,GAAA,CAAI,UAAA,CAAW,GAAG,IAAA,CAAK,MAAM,GAAG,CAAA,EAAG;AACxC,MAAA,QAAA,CAAS,KAAA,CAAM,IAAA,CAAK,OAAO,CAAA,GAAI;AAAA,QAC7B,OAAO,IAAA,CAAK,KAAA;AAAA,QACZ,WAAW,IAAA,CAAK,SAAA;AAAA,QAChB,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,WAAW,IAAA,CAAK,SAAA;AAAA,QAChB,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,UAAU,IAAA,CAAK;AAAA,OACjB;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,eAAA,CAAgB,IAAA,CAAK,IAAA,CAAK,QAAQ,QAAQ,CAAA;AAAA,IACvD,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEQ,eAAA,CAAgB,EAAA,GAAK,IAAA,CAAK,GAAA,EAAI,EAA2D;AAC/F,IAAA,OAAO;AAAA,MACL,SAAA,EAAW,EAAA;AAAA,MACX,OAAA,EAAS,KAAK,IAAA,CAAK,UAAA;AAAA,MACnB,SAAA,EAAW,KAAK,IAAA,CAAK;AAAA,KACvB;AAAA,EACF;AAAA,EAEQ,YAAA,CACN,OAAA,EACA,KAAA,EACA,MAAA,EACA,QAAA,GAAW,KAAK,QAAA,EAChB,EAAA,GAAK,IAAA,CAAK,GAAA,EAAI,EACR;AACN,IAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAA,CAAK,WAAA,CAAY,OAAO,CAAA,EAAG;AAAA,MACxC,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,OAAA;AAAA,MACA,KAAA;AAAA,MACA,MAAA;AAAA,MACA,QAAA;AAAA,MACA,GAAG,IAAA,CAAK,eAAA,CAAgB,EAAE;AAAA,KAC3B,CAAA;AAAA,EACH;AAAA,EAEQ,eAAe,SAAA,EAAgD;AACrE,IAAA,IAAI,CAAC,SAAA,EAAW;AAChB,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,GAAA,CAAI,KAAK,QAAA,EAAU,SAAA,CAAU,YAAY,CAAC,CAAA;AAC/D,IAAA,KAAA,MAAW,aAAA,IAAiB,SAAA,CAAU,YAAA,IAAgB,EAAC,EAAG;AACxD,MAAA,IAAA,CAAK,YAAA,CAAa,IAAI,aAAa,CAAA;AAAA,IACrC;AAEA,IAAA,MAAM,KAAA,GAAQ,CAAC,OAAA,EAAiB,KAAA,EAAgB,UAAmB,SAAA,KAAuB;AACxF,MAAA,IAAA,CAAK,YAAA,CAAa,OAAA,EAAS,KAAA,EAAO,WAAA,EAAa,QAAA,IAAY,KAAK,QAAA,EAAU,SAAA,IAAa,IAAA,CAAK,GAAA,EAAK,CAAA;AAAA,IACnG,CAAA;AAEA,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,SAAA,CAAU,KAAK,CAAA,EAAG;AAClC,MAAA,KAAA,MAAW,IAAA,IAAQ,UAAU,KAAA,EAAO;AAClC,QAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,CAAK,QAAQ,QAAA,EAAU;AAC3C,QAAA,KAAA,CAAM,IAAA,CAAK,KAAK,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA,EAAG,IAAA,CAAK,QAAA,EAAU,IAAA,CAAK,SAAS,CAAA;AAAA,MACpE;AACA,MAAA;AAAA,IACF;AAEA,IAAA,KAAA,MAAW,CAAC,OAAA,EAAS,KAAK,CAAA,IAAK,MAAA,CAAO,QAAQ,SAAA,CAAU,KAAA,IAAS,EAAE,CAAA,EAAG;AACpE,MAAA,KAAA,CAAM,OAAA,EAAS,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAC/B;AAAA,EACF;AAAA,EAEQ,aAAA,CAAc,IAAA,EAA6B,GAAA,GAAM,IAAA,CAAK,KAAI,EAA8C;AAC9G,IAAA,IAAI,CAAC,MAAM,OAAO,SAAA;AAClB,IAAA,IAAI,GAAA,IAAO,IAAA,CAAK,OAAA,EAAS,OAAO,OAAA;AAChC,IAAA,IAAI,GAAA,IAAO,IAAA,CAAK,SAAA,EAAW,OAAO,OAAA;AAClC,IAAA,OAAO,SAAA;AAAA,EACT;AAAA,EAEQ,eAAA,CAAgB,MAAA,EAAiB,MAAA,GAAS,EAAA,EAAU;AAC1D,IAAA,IAAI,IAAA,CAAK,gBAAgB,MAAA,EAAQ;AACjC,IAAA,IAAA,CAAK,WAAA,GAAc,MAAA;AACnB,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,IAAA,CAAK,KAAK,aAAA,EAAe,EAAE,QAAQ,IAAA,CAAK,MAAA,EAAQ,QAAQ,CAAA;AACxD,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,KAAK,cAAA,EAAgB,EAAE,MAAA,EAAQ,IAAA,CAAK,QAAQ,CAAA;AAAA,EACnD;AAAA,EAEA,MAAc,cAAA,CAAe,GAAA,EAAa,IAAA,EAAmB,SAAA,EAAkC;AAC7F,IAAA,IAAI,SAAA,GAAqB,IAAA;AAEzB,IAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,IAAA,CAAK,YAAY,OAAA,EAAA,EAAW;AAC3D,MAAA,MAAM,KAAK,OAAO,eAAA,KAAoB,WAAA,GAAc,IAAI,iBAAgB,GAAI,IAAA;AAC5E,MAAA,MAAM,OAAA,GACJ,EAAA,KAAO,IAAA,GACH,UAAA,CAAW,MAAM;AACf,QAAA,EAAA,CAAG,KAAA,EAAM;AAAA,MACX,CAAA,EAAG,IAAA,CAAK,SAAS,CAAA,GACjB,IAAA;AAEN,MAAA,IAAI;AACF,QAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,UAChC,GAAG,IAAA;AAAA,UACH,QAAQ,EAAA,EAAI;AAAA,SACb,CAAA;AAED,QAAA,IAAI,OAAA,eAAsB,OAAO,CAAA;AAEjC,QAAA,IAAI,CAAC,SAAS,EAAA,IAAM,iBAAA,CAAkB,SAAS,MAAM,CAAA,IAAK,OAAA,GAAU,IAAA,CAAK,UAAA,EAAY;AACnF,UAAA,SAAA,GAAY,IAAI,KAAA,CAAM,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAC/C,UAAA,MAAM,eAAe,IAAA,CAAK,SAAA,GAAY,IAAA,CAAK,MAAA,GAAS,KAAK,MAAA,EAAO;AAChE,UAAA,MAAM,KAAA,CAAM,IAAA,CAAK,SAAA,IAAa,OAAA,GAAU,KAAK,YAAY,CAAA;AACzD,UAAA;AAAA,QACF;AAEA,QAAA,OAAO,QAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,OAAA,eAAsB,OAAO,CAAA;AACjC,QAAA,SAAA,GAAY,KAAA;AACZ,QAAA,IAAI,OAAA,IAAW,KAAK,UAAA,EAAY;AAChC,QAAA,MAAM,eAAe,IAAA,CAAK,SAAA,GAAY,IAAA,CAAK,MAAA,GAAS,KAAK,MAAA,EAAO;AAChE,QAAA,MAAM,KAAA,CAAM,IAAA,CAAK,SAAA,IAAa,OAAA,GAAU,KAAK,YAAY,CAAA;AAAA,MAC3D;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,eAAA,CAAgB,MAAM,SAAS,CAAA;AACpC,IAAA,MAAM,SAAA;AAAA,EACR;AAAA,EAEQ,kBAAA,GAA6D;AACnE,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,MAAM,QAAgD,EAAC;AAEvD,IAAA,KAAA,MAAW,CAAC,QAAA,EAAU,IAAI,KAAK,IAAA,CAAK,KAAA,CAAM,SAAQ,EAAG;AACnD,MAAA,IAAI,CAAC,QAAA,CAAS,UAAA,CAAW,GAAG,IAAA,CAAK,MAAM,GAAG,CAAA,EAAG;AAC7C,MAAA,IAAI,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,IAAA,CAAK,OAAO,CAAA,EAAG;AACvC,QAAA,KAAA,CAAM,KAAK,EAAE,GAAA,EAAK,KAAK,OAAA,EAAS,KAAA,EAAO,OAAO,CAAA;AAC9C,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,aAAA,CAAc,IAAA,EAAM,GAAG,CAAA;AAC1C,MAAA,IAAI,KAAA,KAAU,SAAA,IAAa,KAAA,KAAU,SAAA,EAAW;AAChD,MAAA,KAAA,CAAM,IAAA,CAAK,EAAE,GAAA,EAAK,IAAA,CAAK,SAAS,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA;AAAA,IACrD;AAEA,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,GAAA,CAAI,aAAA,CAAc,CAAA,CAAE,GAAG,CAAC,CAAA;AAAA,EACxD;AAAA,EAEA,cAAA,GAGE;AACA,IAAA,MAAM,KAAA,GAAQ,KAAK,kBAAA,EAAmB;AACtC,IAAA,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,KAAA,CAAM,SAAS,CAAA,EAAE;AAAA,EAC5C;AAAA,EAEA,mBAAmB,OAAA,EAAwD;AACzE,IAAA,OAAO,KAAK,WAAA,CAAY,GAAA,CAAI,KAAK,WAAA,CAAY,OAAO,CAAC,CAAA,IAAK,IAAA;AAAA,EAC5D;AAAA,EAEA,aAAA,CAAc,SAAiB,OAAA,EAAwB;AACrD,IAAA,MAAM,UAAU,YAAA,EAAa;AAC7B,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,IAAA,CAAK,YAAA,CAAa,IAAI,OAAO,CAAA;AAAA,IAC/B,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,YAAA,CAAa,OAAO,OAAO,CAAA;AAAA,IAClC;AACA,IAAA,MAAM,OAAA,GAAU,cAAa,GAAI,OAAA;AACjC,IAAA,IAAA,CAAK,UAAA,CAAW,kCAAkC,OAAA,EAAS;AAAA,MACzD,KAAK,IAAA,CAAK,MAAA;AAAA,MACV,MAAA,EAAQ,UAAU,SAAA,GAAY;AAAA,KAC/B,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,CAAK,UAAU,EAAE,WAAA,EAAa,CAAC,OAAO,CAAA,EAAG,MAAA,EAAQ,UAAA,EAAY,CAAA;AAClE,IAAA,KAAK,KAAK,YAAA,EAAa;AAAA,EACzB;AAAA,EAEA,MAAc,oBAAA,CACZ,OAAA,EACA,cAAA,EACA,YAAA,EACyB;AACzB,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,GAClB,MAAM,IAAA,CAAK,cAAA;AAAA,MACT,CAAA,EAAG,KAAK,UAAU,CAAA,gBAAA,CAAA;AAAA,MAClB;AAAA,QACE,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB,kBAAA;AAAA,UAChB,0BAA0B,IAAA,CAAK;AAAA,SACjC;AAAA,QACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,UACnB,OAAA;AAAA,UACA,IAAA,EAAM,cAAA;AAAA,UACN,YAAA;AAAA,UACA,cAAA,EAAgB,KAAK,cAAA,IAAkB;AAAA,SACxC;AAAA,OACH;AAAA,MACA;AAAA,KACF,GACA,MAAM,IAAA,CAAK,cAAA;AAAA,MACT,CAAA,EAAG,KAAK,UAAU,CAAA,YAAA,CAAA;AAAA,MAClB;AAAA,QACE,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,QAC9C,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,UACnB,YAAY,IAAA,CAAK,UAAA;AAAA,UACjB,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb,OAAA;AAAA,UACA,IAAA,EAAM,cAAA;AAAA,UACN;AAAA,SACD;AAAA,OACH;AAAA,MACA;AAAA,KACF;AAEJ,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,IAAI,CAAC,iBAAA,CAAkB,QAAA,CAAS,MAAM,CAAA,EAAG;AACvC,QAAA,IAAA,CAAK,eAAA,CAAgB,IAAA,EAAM,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,MACtD;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,IAAA,MAAM,QAAQ,OAAO,IAAA,CAAK,KAAA,KAAU,SAAA,GAAY,KAAK,KAAA,GAAQ,YAAA;AAE7D,IAAA,IAAI,IAAA,CAAK,eAAe,IAAA,EAAM;AAC5B,MAAA,IAAA,CAAK,YAAA,CAAa,IAAI,OAAO,CAAA;AAAA,IAC/B;AAEA,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,QAAA;AACvC,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,UAAU,QAAQ,CAAA;AAChD,IAAA,IAAA,CAAK,YAAA,CAAa,OAAA,EAAS,KAAA,EAAO,SAAA,EAAW,QAAQ,CAAA;AACrD,IAAA,IAAA,CAAK,gBAAgB,KAAK,CAAA;AAC1B,IAAA,KAAK,KAAK,YAAA,EAAa;AACvB,IAAA,IAAA,CAAK,IAAA,CAAK,UAAU,EAAE,WAAA,EAAa,CAAC,OAAO,CAAA,EAAG,MAAA,EAAQ,SAAA,EAAW,CAAA;AACjE,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEA,MAAc,qBAAA,CACZ,cAAA,EACA,YAAA,EACA,SAAA,EACwD;AACxD,IAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AAChB,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,UAAU,YAAA,EAAa;AAE7B,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,cAAA;AAAA,QAC1B,CAAA,EAAG,KAAK,UAAU,CAAA,iBAAA,CAAA;AAAA,QAClB;AAAA,UACE,MAAA,EAAQ,MAAA;AAAA,UACR,OAAA,EAAS;AAAA,YACP,cAAA,EAAgB,kBAAA;AAAA,YAChB,0BAA0B,IAAA,CAAK;AAAA,WACjC;AAAA,UACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,YACnB,IAAA,EAAM,cAAA;AAAA,YACN,YAAA;AAAA,YACA,cAAA,EAAgB,KAAK,cAAA,IAAkB,KAAA;AAAA,WACxC;AAAA,SACH;AAAA,QACA;AAAA,OACF;AAEA,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,IAAI,CAAC,iBAAA,CAAkB,QAAA,CAAS,MAAM,CAAA,EAAG;AACvC,UAAA,IAAA,CAAK,eAAA,CAAgB,IAAA,EAAM,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,QACtD;AACA,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAOlC,MAAA,MAAM,IAAA,GAAO,iBAAiB,IAAI,CAAA;AAClC,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,QAAA;AACvC,MAAA,IAAA,CAAK,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,UAAU,QAAQ,CAAA;AAEhD,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,YAAY,CAAA,EAAG;AACpC,QAAA,KAAA,MAAW,GAAA,IAAO,KAAK,YAAA,EAAc;AACnC,UAAA,IAAA,CAAK,YAAA,CAAa,IAAI,GAAG,CAAA;AAAA,QAC3B;AAAA,MACF;AAEA,MAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,MAAA,KAAA,MAAW,SAAS,IAAA,EAAM;AACxB,QAAA,MAAM,QAAA,GAAW,KAAK,KAAA,CAAM,GAAA,CAAI,KAAK,WAAA,CAAY,KAAA,CAAM,GAAG,CAAC,CAAA;AAC3D,QAAA,IAAI,CAAC,YAAY,QAAA,CAAS,KAAA,KAAU,MAAM,KAAA,IAAS,QAAA,CAAS,aAAa,QAAA,EAAU;AACjF,UAAA,OAAA,CAAQ,GAAA,CAAI,MAAM,GAAG,CAAA;AAAA,QACvB;AACA,QAAA,IAAA,CAAK,aAAa,KAAA,CAAM,GAAA,EAAK,KAAA,CAAM,KAAA,EAAO,WAAW,QAAQ,CAAA;AAAA,MAC/D;AAEA,MAAA,IAAI,OAAA,CAAQ,OAAO,CAAA,EAAG;AACpB,QAAA,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,EAAE,WAAA,EAAa,CAAC,GAAG,OAAO,CAAA,EAAG,MAAA,EAAQ,SAAA,EAAW,CAAA;AAAA,MACtE;AAEA,MAAA,IAAA,CAAK,gBAAgB,KAAK,CAAA;AAC1B,MAAA,KAAK,KAAK,YAAA,EAAa;AACvB,MAAA,IAAA,CAAK,UAAA,CAAW,0BAAA,EAA4B,YAAA,EAAa,GAAI,OAAA,EAAS;AAAA,QACpE,KAAK,IAAA,CAAK,MAAA;AAAA,QACV;AAAA,OACD,CAAA;AACD,MAAA,OAAO,IAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AACN,MAAA,IAAA,CAAK,UAAA,CAAW,0BAAA,EAA4B,YAAA,EAAa,GAAI,OAAA,EAAS;AAAA,QACpE,KAAK,IAAA,CAAK,MAAA;AAAA,QACV,SAAA;AAAA,QACA,MAAA,EAAQ;AAAA,OACT,CAAA;AACD,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,UAAA,CAAW,gBAAkC,YAAA,EAA+E;AAClI,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,kBAAA,CAAmB,GAAA,CAAI,KAAK,MAAM,CAAA;AACxD,IAAA,IAAI,UAAU,OAAO,QAAA;AAErB,IAAA,MAAM,OAAA,GAAU,KAAK,qBAAA,CAAsB,cAAA,EAAgB,cAAc,SAAS,CAAA,CAAE,QAAQ,MAAM;AAChG,MAAA,IAAA,CAAK,kBAAA,CAAmB,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA;AAAA,IAC5C,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,kBAAA,CAAmB,GAAA,CAAI,IAAA,CAAK,MAAA,EAAQ,OAAO,CAAA;AAChD,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAM,QAAA,CACJ,OAAA,EACA,IAAA,EACA,eAAe,KAAA,EACwB;AACvC,IAAA,MAAM,UAAU,YAAA,EAAa;AAC7B,IAAA,MAAM,KAAK,sBAAA,EAAuB;AAElC,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,aAAA,CAAc,IAAI,CAAA;AAC9C,IAAA,IAAA,CAAK,QAAA,GAAW,cAAA;AAChB,IAAA,IAAA,CAAK,gBAAA,GAAmB,YAAA;AAExB,IAAA,IAAI,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,OAAO,CAAA,EAAG;AAClC,MAAA,MAAMA,SAAAA,GAA2C;AAAA,QAC/C,MAAA,EAAQ,aAAA;AAAA,QACR,OAAA,EAAS,KAAA;AAAA,QACT,SAAA,EAAW,cAAa,GAAI,OAAA;AAAA,QAC5B,MAAA,EAAQ;AAAA,OACV;AACA,MAAA,IAAA,CAAK,UAAA,CAAW,oBAAA,EAAsBA,SAAAA,CAAS,SAAA,EAAW;AAAA,QACxD,KAAK,IAAA,CAAK,MAAA;AAAA,QACV,QAAQA,SAAAA,CAAS,MAAA;AAAA,QACjB,MAAA,EAAQ;AAAA,OACT,CAAA;AACD,MAAA,IAAA,CAAK,YAAY,GAAA,CAAI,IAAA,CAAK,WAAA,CAAY,OAAO,GAAGA,SAAQ,CAAA;AACxD,MAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,QAAA,EAAAA,SAAAA,EAAS;AAAA,IAClC;AAEA,IAAA,MAAM,YAAY,IAAA,CAAK,KAAA,CAAM,IAAI,IAAA,CAAK,WAAA,CAAY,OAAO,CAAC,CAAA;AAC1D,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,aAAA,CAAc,SAAS,CAAA;AAE/C,IAAA,IAAI,SAAA,IAAa,eAAe,OAAA,EAAS;AACvC,MAAA,MAAMA,SAAAA,GAA2C;AAAA,QAC/C,QAAQ,SAAA,CAAU,MAAA,KAAW,eAAe,SAAA,CAAU,MAAA,KAAW,eAAe,WAAA,GAAc,aAAA;AAAA,QAC9F,OAAA,EAAS,KAAA;AAAA,QACT,SAAA,EAAW,cAAa,GAAI,OAAA;AAAA,QAC5B,QAAQ,SAAA,CAAU,MAAA;AAAA,QAClB,WAAW,SAAA,CAAU,SAAA;AAAA,QACrB,SAAS,SAAA,CAAU,OAAA;AAAA,QACnB,WAAW,SAAA,CAAU;AAAA,OACvB;AACA,MAAA,IAAA,CAAK,UAAA,CAAW,oBAAA,EAAsB,CAAA,EAAG,EAAE,GAAA,EAAK,KAAK,MAAA,EAAQ,MAAA,EAAQA,SAAAA,CAAS,MAAA,EAAQ,CAAA;AACtF,MAAA,IAAA,CAAK,UAAA,CAAW,oBAAA,EAAsBA,SAAAA,CAAS,SAAA,EAAW;AAAA,QACxD,KAAK,IAAA,CAAK,MAAA;AAAA,QACV,QAAQA,SAAAA,CAAS,MAAA;AAAA,QACjB,MAAA,EAAQ;AAAA,OACT,CAAA;AACD,MAAA,IAAA,CAAK,YAAY,GAAA,CAAI,IAAA,CAAK,WAAA,CAAY,OAAO,GAAGA,SAAQ,CAAA;AACxD,MAAA,OAAO,EAAE,KAAA,EAAO,SAAA,CAAU,KAAA,EAAO,UAAAA,SAAAA,EAAS;AAAA,IAC5C;AAEA,IAAA,IAAI,SAAA,IAAa,eAAe,OAAA,EAAS;AACvC,MAAA,KAAK,IAAA,CAAK,UAAA,CAAW,cAAA,EAAgB,YAAY,CAAA;AACjD,MAAA,MAAMA,SAAAA,GAA2C;AAAA,QAC/C,MAAA,EAAQ,aAAA;AAAA,QACR,OAAA,EAAS,IAAA;AAAA,QACT,SAAA,EAAW,cAAa,GAAI,OAAA;AAAA,QAC5B,QAAQ,SAAA,CAAU,MAAA;AAAA,QAClB,WAAW,SAAA,CAAU,SAAA;AAAA,QACrB,SAAS,SAAA,CAAU,OAAA;AAAA,QACnB,WAAW,SAAA,CAAU;AAAA,OACvB;AACA,MAAA,IAAA,CAAK,UAAA,CAAW,oBAAA,EAAsB,CAAA,EAAG,EAAE,GAAA,EAAK,KAAK,MAAA,EAAQ,MAAA,EAAQA,SAAAA,CAAS,MAAA,EAAQ,CAAA;AACtF,MAAA,IAAA,CAAK,UAAA,CAAW,oBAAA,EAAsBA,SAAAA,CAAS,SAAA,EAAW;AAAA,QACxD,KAAK,IAAA,CAAK,MAAA;AAAA,QACV,QAAQA,SAAAA,CAAS,MAAA;AAAA,QACjB,MAAA,EAAQ;AAAA,OACT,CAAA;AACD,MAAA,IAAA,CAAK,YAAY,GAAA,CAAI,IAAA,CAAK,WAAA,CAAY,OAAO,GAAGA,SAAQ,CAAA;AACxD,MAAA,OAAO,EAAE,KAAA,EAAO,SAAA,CAAU,KAAA,EAAO,UAAAA,SAAAA,EAAS;AAAA,IAC5C;AAEA,IAAA,IAAI,cAAc,SAAA,CAAU,MAAA,KAAW,WAAA,IAAe,SAAA,CAAU,WAAW,YAAA,CAAA,EAAe;AACxF,MAAA,KAAK,IAAA,CAAK,UAAA,CAAW,cAAA,EAAgB,YAAY,CAAA;AACjD,MAAA,MAAMA,SAAAA,GAA2C;AAAA,QAC/C,MAAA,EAAQ,WAAA;AAAA,QACR,OAAA,EAAS,IAAA;AAAA,QACT,SAAA,EAAW,cAAa,GAAI,OAAA;AAAA,QAC5B,QAAQ,SAAA,CAAU,MAAA;AAAA,QAClB,WAAW,SAAA,CAAU,SAAA;AAAA,QACrB,SAAS,SAAA,CAAU,OAAA;AAAA,QACnB,WAAW,SAAA,CAAU;AAAA,OACvB;AACA,MAAA,IAAA,CAAK,UAAA,CAAW,oBAAA,EAAsB,CAAA,EAAG,EAAE,GAAA,EAAK,KAAK,MAAA,EAAQ,MAAA,EAAQA,SAAAA,CAAS,MAAA,EAAQ,CAAA;AACtF,MAAA,IAAA,CAAK,UAAA,CAAW,oBAAA,EAAsBA,SAAAA,CAAS,SAAA,EAAW;AAAA,QACxD,KAAK,IAAA,CAAK,MAAA;AAAA,QACV,QAAQA,SAAAA,CAAS,MAAA;AAAA,QACjB,MAAA,EAAQ;AAAA,OACT,CAAA;AACD,MAAA,IAAA,CAAK,YAAY,GAAA,CAAI,IAAA,CAAK,WAAA,CAAY,OAAO,GAAGA,SAAQ,CAAA;AACxD,MAAA,OAAO,EAAE,KAAA,EAAO,SAAA,CAAU,KAAA,EAAO,UAAAA,SAAAA,EAAS;AAAA,IAC5C;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,eAAe,MAAM,IAAA,CAAK,oBAAA,CAAqB,OAAA,EAAS,gBAAgB,YAAY,CAAA;AAC1F,MAAA,IAAI,iBAAiB,IAAA,EAAM;AACzB,QAAA,MAAM,OAAO,IAAA,CAAK,KAAA,CAAM,IAAI,IAAA,CAAK,WAAA,CAAY,OAAO,CAAC,CAAA;AACrD,QAAA,MAAMA,SAAAA,GAA2C;AAAA,UAC/C,MAAA,EAAQ,SAAA;AAAA,UACR,OAAA,EAAS,KAAA;AAAA,UACT,SAAA,EAAW,cAAa,GAAI,OAAA;AAAA,UAC5B,MAAA,EAAQ,SAAA;AAAA,UACR,WAAW,IAAA,EAAM,SAAA;AAAA,UACjB,SAAS,IAAA,EAAM,OAAA;AAAA,UACf,WAAW,IAAA,EAAM;AAAA,SACnB;AACA,QAAA,IAAA,CAAK,UAAA,CAAW,oBAAA,EAAsB,CAAA,EAAG,EAAE,GAAA,EAAK,KAAK,MAAA,EAAQ,MAAA,EAAQA,SAAAA,CAAS,MAAA,EAAQ,CAAA;AACtF,QAAA,IAAA,CAAK,UAAA,CAAW,oBAAA,EAAsBA,SAAAA,CAAS,SAAA,EAAW;AAAA,UACxD,KAAK,IAAA,CAAK,MAAA;AAAA,UACV,QAAQA,SAAAA,CAAS,MAAA;AAAA,UACjB,MAAA,EAAQ;AAAA,SACT,CAAA;AACD,QAAA,IAAA,CAAK,YAAY,GAAA,CAAI,IAAA,CAAK,WAAA,CAAY,OAAO,GAAGA,SAAQ,CAAA;AACxD,QAAA,OAAO,EAAE,KAAA,EAAO,YAAA,EAAc,QAAA,EAAAA,SAAAA,EAAS;AAAA,MACzC;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,MAAM,QAAA,GAA2C;AAAA,MAC/C,MAAA,EAAQ,SAAA;AAAA,MACR,OAAA,EAAS,KAAA;AAAA,MACT,SAAA,EAAW,cAAa,GAAI,OAAA;AAAA,MAC5B,MAAA,EAAQ;AAAA,KACV;AACA,IAAA,IAAA,CAAK,UAAA,CAAW,oBAAA,EAAsB,CAAA,EAAG,EAAE,GAAA,EAAK,KAAK,MAAA,EAAQ,MAAA,EAAQ,QAAA,CAAS,MAAA,EAAQ,CAAA;AACtF,IAAA,IAAA,CAAK,UAAA,CAAW,oBAAA,EAAsB,QAAA,CAAS,SAAA,EAAW;AAAA,MACxD,KAAK,IAAA,CAAK,MAAA;AAAA,MACV,QAAQ,QAAA,CAAS,MAAA;AAAA,MACjB,MAAA,EAAQ;AAAA,KACT,CAAA;AACD,IAAA,IAAA,CAAK,YAAY,GAAA,CAAI,IAAA,CAAK,WAAA,CAAY,OAAO,GAAG,QAAQ,CAAA;AACxD,IAAA,OAAO,EAAE,KAAA,EAAO,YAAA,EAAc,QAAA,EAAS;AAAA,EACzC;AAAA,EAEA,MAAM,IAAA,CAAK,OAAA,EAAiB,IAAA,EAA+B,eAAe,KAAA,EAAyB;AACjG,IAAA,MAAM,SAAS,MAAM,IAAA,CAAK,QAAA,CAAS,OAAA,EAAS,MAAM,YAAY,CAAA;AAC9D,IAAA,OAAO,MAAA,CAAO,KAAA;AAAA,EAChB;AAAA,EAEA,MAAM,KAAA,CAAM,IAAA,EAA+B,YAAA,GAAe,KAAA,EAAwD;AAChH,IAAA,MAAM,KAAK,sBAAA,EAAuB;AAClC,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,aAAA,CAAc,IAAI,CAAA;AAC9C,IAAA,IAAA,CAAK,QAAA,GAAW,cAAA;AAChB,IAAA,IAAA,CAAK,gBAAA,GAAmB,YAAA;AAExB,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,UAAA,CAAW,gBAAgB,YAAY,CAAA;AAC/D,IAAA,IAAI,IAAA,IAAQ,IAAA,CAAK,MAAA,GAAS,CAAA,EAAG;AAC3B,MAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAC,KAAA,MAAW;AAAA,QAC1B,KAAK,KAAA,CAAM,GAAA;AAAA,QACX,KAAA,EAAO,KAAK,YAAA,CAAa,GAAA,CAAI,MAAM,GAAG,CAAA,GAAI,QAAQ,KAAA,CAAM;AAAA,OAC1D,CAAE,CAAA;AAAA,IACJ;AAEA,IAAA,MAAM,MAAA,GAAS,KAAK,kBAAA,EAAmB;AACvC,IAAA,IAAI,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG,OAAO,MAAA;AAC9B,IAAA,OAAO,EAAC;AAAA,EACV;AAAA,EAEQ,qBAAqB,OAAA,EAAqC;AAChE,IAAA,IAAI,OAAO,OAAA,CAAQ,QAAA,KAAa,YAAY,OAAA,CAAQ,QAAA,GAAW,KAAK,QAAA,EAAU;AAC5E,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,OAAO,OAAA,CAAQ,QAAA,KAAa,QAAA,EAAU;AACxC,MAAA,IAAA,CAAK,WAAW,OAAA,CAAQ,QAAA;AAAA,IAC1B;AAEA,IAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAErB,IAAA,IAAI,OAAA,CAAQ,SAAS,cAAA,EAAgB;AACnC,MAAA,MAAM,OAAA,GAAU,OAAO,OAAA,CAAQ,IAAA,EAAM,YAAY,QAAA,GAAW,OAAA,CAAQ,KAAK,OAAA,GAAU,IAAA;AACnF,MAAA,MAAM,KAAA,GAAQ,OAAO,OAAA,CAAQ,IAAA,EAAM,UAAU,SAAA,GAAY,OAAA,CAAQ,KAAK,KAAA,GAAQ,IAAA;AAC9E,MAAA,IAAI,OAAA,KAAY,IAAA,IAAQ,KAAA,KAAU,IAAA,EAAM;AACtC,QAAA,IAAA,CAAK,YAAA,CAAa,SAAS,KAAA,EAAO,UAAA,EAAY,QAAQ,QAAA,IAAY,IAAA,CAAK,UAAU,GAAG,CAAA;AACpF,QAAA,OAAA,CAAQ,IAAI,OAAO,CAAA;AAAA,MACrB;AAAA,IACF;AAEA,IAAA,IAAI,OAAA,CAAQ,SAAS,cAAA,EAAgB;AACnC,MAAA,MAAM,OAAA,GAAU,OAAO,OAAA,CAAQ,IAAA,EAAM,YAAY,QAAA,GAAW,OAAA,CAAQ,KAAK,OAAA,GAAU,IAAA;AACnF,MAAA,IAAI,YAAY,IAAA,EAAM;AACpB,QAAA,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,IAAA,CAAK,WAAA,CAAY,OAAO,CAAC,CAAA;AAC3C,QAAA,OAAA,CAAQ,IAAI,OAAO,CAAA;AAAA,MACrB;AAAA,IACF;AAEA,IAAA,IAAI,OAAA,CAAQ,SAAS,yBAAA,EAA2B;AAC9C,MAAA,MAAM,UAAU,YAAA,EAAa;AAC7B,MAAA,MAAM,OAAA,GAAU,OAAO,OAAA,CAAQ,IAAA,EAAM,YAAY,QAAA,GAAW,OAAA,CAAQ,KAAK,OAAA,GAAU,IAAA;AACnF,MAAA,MAAM,OAAA,GAAU,OAAO,OAAA,CAAQ,IAAA,EAAM,YAAY,SAAA,GAAY,OAAA,CAAQ,KAAK,OAAA,GAAU,IAAA;AACpF,MAAA,IAAI,YAAY,IAAA,EAAM;AACpB,QAAA,IAAI,OAAA,EAAS;AACX,UAAA,IAAA,CAAK,YAAA,CAAa,IAAI,OAAO,CAAA;AAAA,QAC/B,CAAA,MAAO;AACL,UAAA,IAAA,CAAK,YAAA,CAAa,OAAO,OAAO,CAAA;AAAA,QAClC;AACA,QAAA,OAAA,CAAQ,IAAI,OAAO,CAAA;AACnB,QAAA,IAAA,CAAK,UAAA,CAAW,gCAAA,EAAkC,YAAA,EAAa,GAAI,OAAA,EAAS;AAAA,UAC1E,KAAK,IAAA,CAAK,MAAA;AAAA,UACV,SAAA,EAAW,IAAA,CAAK,WAAA,GAAc,KAAA,GAAQ,SAAA;AAAA,UACtC,MAAA,EAAQ,UAAU,SAAA,GAAY;AAAA,SAC/B,CAAA;AAAA,MACH;AAAA,IACF;AAEA,IAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,qBAAA,IAAyB,IAAA,CAAK,QAAA,EAAU;AAC3D,MAAA,KAAK,IAAA,CAAK,UAAA,CAAW,IAAA,CAAK,QAAA,EAAU,KAAK,gBAAgB,CAAA;AAAA,IAC3D;AAEA,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,EAAI,IAAK,OAAA,CAAQ,SAAA,IAAa,IAAA,CAAK,GAAA,EAAI,CAAE,CAAA;AAC7E,IAAA,IAAA,CAAK,UAAA,CAAW,sBAAsB,UAAA,EAAY;AAAA,MAChD,KAAK,IAAA,CAAK,MAAA;AAAA,MACV,SAAA,EAAW,IAAA,CAAK,WAAA,GAAc,KAAA,GAAQ;AAAA,KACvC,CAAA;AAED,IAAA,IAAI,OAAA,CAAQ,OAAO,CAAA,EAAG;AACpB,MAAA,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,EAAE,WAAA,EAAa,CAAC,GAAG,OAAO,CAAA,EAAG,MAAA,EAAQ,UAAA,EAAY,CAAA;AACrE,MAAA,KAAK,KAAK,YAAA,EAAa;AAAA,IACzB;AAAA,EACF;AAAA,EAEQ,YAAA,GAAqB;AAC3B,IAAA,IAAI,KAAK,SAAA,EAAW;AAClB,MAAA,YAAA,CAAa,KAAK,SAAS,CAAA;AAC3B,MAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,IACnB;AAEA,IAAA,MAAM,OAAO,YAAY;AACvB,MAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AAClB,QAAA,IAAA,CAAK,SAAA,GAAY,UAAA,CAAW,IAAA,EAAM,IAAA,CAAK,iBAAiB,CAAA;AACxD,QAAA;AAAA,MACF;AACA,MAAA,MAAM,KAAK,qBAAA,CAAsB,IAAA,CAAK,QAAA,EAAU,IAAA,CAAK,kBAAkB,SAAS,CAAA;AAChF,MAAA,IAAA,CAAK,SAAA,GAAY,UAAA,CAAW,IAAA,EAAM,IAAA,CAAK,iBAAiB,CAAA;AAAA,IAC1D,CAAA;AAEA,IAAA,IAAA,CAAK,SAAA,GAAY,UAAA,CAAW,IAAA,EAAM,IAAA,CAAK,iBAAiB,CAAA;AAAA,EAC1D;AAAA,EAEQ,UAAA,CAAW,UAAU,CAAA,EAAS;AACpC,IAAA,MAAM,eAAA,GAAkB,OAAO,WAAA,KAAgB,WAAA,GAAc,WAAA,GAAc,IAAA;AAC3E,IAAA,IAAI,CAAC,eAAA,IAAmB,CAAC,IAAA,CAAK,MAAA,EAAQ;AACpC,MAAA,IAAA,CAAK,KAAK,iBAAA,EAAmB,EAAE,OAAO,UAAA,EAAY,SAAA,EAAW,WAAW,CAAA;AACxE,MAAA,IAAA,CAAK,YAAA,EAAa;AAClB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,MAAM,IAAI,GAAA,CAAI,IAAA,CAAK,eAAA,EAAiB,KAAK,UAAU,CAAA;AACzD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,QAAA,EAAU,IAAA,CAAK,MAAM,CAAA;AAC1C,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,gBAAA,EAAkB,IAAA,CAAK,cAAc,CAAA;AAAA,IAC5D;AAEA,IAAA,IAAA,CAAK,WAAA,GAAc,IAAI,eAAA,CAAgB,GAAA,CAAI,UAAU,CAAA;AAErD,IAAA,IAAA,CAAK,WAAA,CAAY,SAAS,MAAM;AAC9B,MAAA,IAAA,CAAK,KAAK,iBAAA,EAAmB,EAAE,OAAO,WAAA,EAAa,SAAA,EAAW,OAAO,CAAA;AACrE,MAAA,IAAI,KAAK,SAAA,EAAW;AAClB,QAAA,YAAA,CAAa,KAAK,SAAS,CAAA;AAC3B,QAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,MACnB;AAAA,IACF,CAAA;AAEA,IAAA,IAAA,CAAK,WAAA,CAAY,SAAA,GAAY,CAAC,KAAA,KAAwB;AACpD,MAAA,IAAI;AACF,QAAA,MAAM,UAAU,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,KAAA,CAAM,IAAI,CAAC,CAAA;AAC7C,QAAA,IAAA,CAAK,qBAAqB,OAAO,CAAA;AAAA,MACnC,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAA;AAEA,IAAA,IAAA,CAAK,WAAA,CAAY,UAAU,MAAM;AAC/B,MAAA,IAAA,CAAK,KAAK,iBAAA,EAAmB,EAAE,OAAO,UAAA,EAAY,SAAA,EAAW,WAAW,CAAA;AACxE,MAAA,IAAA,CAAK,aAAa,KAAA,EAAM;AACxB,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,MAAA,IAAA,CAAK,YAAA,EAAa;AAElB,MAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,QAAA,YAAA,CAAa,KAAK,cAAc,CAAA;AAAA,MAClC;AACA,MAAA,MAAM,UAAU,IAAA,CAAK,GAAA,CAAI,KAAK,SAAA,IAAa,OAAA,GAAU,IAAI,GAAK,CAAA;AAC9D,MAAA,IAAA,CAAK,cAAA,GAAiB,WAAW,MAAM;AACrC,QAAA,IAAA,CAAK,UAAA,CAAW,UAAU,CAAC,CAAA;AAAA,MAC7B,GAAG,OAAO,CAAA;AAAA,IACZ,CAAA;AAAA,EACF;AAAA,EAEA,aAAA,GAAsB;AACpB,IAAA,IAAA,CAAK,eAAA,GAAkB,IAAA;AACvB,IAAA,IAAA,CAAK,WAAW,CAAC,CAAA;AAAA,EACnB;AAAA,EAEA,YAAA,GAAqB;AACnB,IAAA,IAAA,CAAK,eAAA,GAAkB,KAAA;AACvB,IAAA,IAAI,KAAK,WAAA,EAAa;AACpB,MAAA,IAAA,CAAK,YAAY,KAAA,EAAM;AACvB,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,IACrB;AACA,IAAA,IAAI,KAAK,SAAA,EAAW;AAClB,MAAA,YAAA,CAAa,KAAK,SAAS,CAAA;AAC3B,MAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,IACnB;AACA,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,YAAA,CAAa,KAAK,cAAc,CAAA;AAChC,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AAAA,IACxB;AACA,IAAA,IAAA,CAAK,KAAK,iBAAA,EAAmB,EAAE,OAAO,SAAA,EAAW,SAAA,EAAW,QAAQ,CAAA;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,YAAY,MAAA,EAAgD;AAChE,IAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AAClB,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,UAAU,CAAA,kBAAA,CAAA,EAAsB;AAAA,QAClD,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB,kBAAA;AAAA,UAChB,0BAA0B,IAAA,CAAK;AAAA,SACjC;AAAA,QACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,UACnB,SAAS,MAAA,CAAO,OAAA;AAAA,UAChB,WAAW,MAAA,CAAO,SAAA;AAAA,UAClB,WAAW,MAAA,CAAO,SAAA;AAAA,UAClB,YAAY,MAAA,CAAO,UAAA,IAAA,iBAAc,IAAI,IAAA,IAAO,WAAA,EAAY;AAAA,UACxD,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb,SAAS,MAAA,CAAO;AAAA,SACjB;AAAA,OACF,CAAA;AAAA,IACH,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,YAAA,EAAa;AAClB,IAAA,IAAA,CAAK,SAAA,CAAU,OAAO,KAAA,EAAM;AAC5B,IAAA,IAAA,CAAK,SAAA,CAAU,YAAY,KAAA,EAAM;AACjC,IAAA,IAAA,CAAK,SAAA,CAAU,aAAa,KAAA,EAAM;AAClC,IAAA,IAAA,CAAK,SAAA,CAAU,gBAAgB,KAAA,EAAM;AAAA,EACvC;AACF","file":"index.js","sourcesContent":["export type FeatureFlareUserPayload = {\n /** Unique user identifier (preferred). */\n id?: string;\n /** Legacy alias for id. */\n key?: string;\n email?: string;\n name?: string;\n country?: string;\n /** Queryable attributes. */\n meta?: Record<string, string | number | boolean | null>;\n /** Legacy alias for meta. */\n custom?: Record<string, string | number | boolean | null>;\n};\n\ntype FeatureFlareUser = {\n key: string;\n email?: string;\n name?: string;\n country?: string;\n custom?: Record<string, string | number | boolean | null>;\n};\n\nconst DEFAULT_FEATUREFLARE_API_BASE_URL =\n 'https://shipit-api-392444455847.us-central1.run.app';\n\nfunction getApiBaseUrlFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_API_BASE_URL?.trim() ||\n process.env.SHIPIT_API_BASE_URL?.trim() ||\n null\n );\n }\n return null;\n}\n\nfunction getApiBaseUrl(explicit?: string): string {\n const fromOptions = explicit?.trim();\n if (fromOptions) return fromOptions;\n\n const fromEnv = getApiBaseUrlFromEnv();\n if (fromEnv) return fromEnv;\n\n return DEFAULT_FEATUREFLARE_API_BASE_URL;\n}\n\nexport type FeatureFlareCacheSource = 'bootstrap' | 'network' | 'realtime' | 'persistent';\nexport type FeatureFlareEvaluationReason = 'fresh_cache' | 'stale_cache' | 'bootstrap' | 'default' | 'network' | 'kill_switch';\n\nexport type FeatureFlareEvaluationMetadata = {\n reason: FeatureFlareEvaluationReason;\n isStale: boolean;\n latencyMs: number;\n source: FeatureFlareCacheSource | 'default' | 'kill_switch';\n updatedAt?: number;\n staleAt?: number;\n expiresAt?: number;\n};\n\nexport type FeatureFlareEvaluationResult = {\n value: boolean;\n metadata: FeatureFlareEvaluationMetadata;\n};\n\nexport type FeatureFlareMetricName =\n | 'ff_eval_latency_ms'\n | 'ff_cache_hit_ratio'\n | 'ff_revalidate_latency_ms'\n | 'ff_realtime_lag_ms'\n | 'ff_killswitch_apply_latency_ms';\n\nexport type FeatureFlareMetricTags = Record<string, string | number | boolean | undefined>;\n\nexport type FeatureFlareErrorReport = {\n /** The flag key being evaluated when the error was observed. */\n flagKey: string;\n /** Observed error rate as a fraction from 0 to 1 (e.g. 0.05 = 5%). */\n errorRate: number;\n /** Observed p99 latency in milliseconds. */\n latencyMs?: number;\n /** ISO-8601 timestamp of the observation window end. Defaults to now. */\n observedAt?: string;\n /** Optional free-form context about the error (e.g. HTTP status, exception name). */\n context?: Record<string, string | number | boolean>;\n};\n\nexport type FeatureFlarePersistentSnapshot = {\n revision?: number;\n killSwitches?: string[];\n flags: Record<\n string,\n {\n value: boolean;\n updatedAt: number;\n staleAt: number;\n expiresAt: number;\n source?: FeatureFlareCacheSource;\n revision?: number;\n }\n >;\n};\n\nexport type FeatureFlarePersistentCacheAdapter = {\n load: (envKey: string) => Promise<FeatureFlarePersistentSnapshot | null> | FeatureFlarePersistentSnapshot | null;\n save: (envKey: string, snapshot: FeatureFlarePersistentSnapshot) => Promise<void> | void;\n};\n\nexport type FeatureFlareBootstrapPayload = {\n revision?: number;\n killSwitches?: string[];\n flags?:\n | Record<string, boolean>\n | Array<{ key: string; value: boolean; revision?: number; updatedAt?: number }>;\n};\n\nexport type FeatureFlareClientOptions = {\n apiBaseUrl?: string;\n sdkKey?: string;\n projectKey?: string;\n envKey?: string;\n timeoutMs?: number;\n maxRetries?: number;\n backoffMs?: number;\n jitter?: number;\n cacheTtlMs?: number;\n staleTtlMs?: number;\n bootstrap?: FeatureFlareBootstrapPayload;\n persistentCache?: FeatureFlarePersistentCacheAdapter;\n onMetric?: (metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags) => void;\n realtime?: {\n enabled?: boolean;\n pollingIntervalMs?: number;\n ssePath?: string;\n };\n};\n\ntype CacheItem = {\n envKey: string;\n flagKey: string;\n value: boolean;\n updatedAt: number;\n staleAt: number;\n expiresAt: number;\n source: FeatureFlareCacheSource;\n revision: number;\n};\n\ntype RealtimeEventPayload = {\n type: 'flag.updated' | 'flag.deleted' | 'env.kill_switch.updated' | 'snapshot.invalidate';\n timestamp?: number;\n revision?: number;\n data?: Record<string, unknown>;\n};\n\ntype FeatureFlareClientEvents = {\n update: { changedKeys: string[]; source: FeatureFlareCacheSource | 'network' };\n circuitOpen: { envKey: string; reason: string };\n circuitClose: { envKey: string };\n connectionState: { state: 'connected' | 'degraded' | 'offline'; transport: 'sse' | 'polling' | 'none' };\n};\n\nfunction getEnvKeyFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_ENV_KEY?.trim() ||\n process.env.SHIPIT_ENV_KEY?.trim() ||\n null\n );\n }\n return null;\n}\n\nfunction getSdkKeyFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_CLIENT_KEY?.trim() ||\n process.env.FEATUREFLARE_SERVER_KEY?.trim() ||\n process.env.SHIPIT_CLIENT_KEY?.trim() ||\n process.env.SHIPIT_SERVER_KEY?.trim() ||\n null\n );\n }\n return null;\n}\n\nfunction monotonicNow(): number {\n if (typeof performance !== 'undefined' && typeof performance.now === 'function') {\n return performance.now();\n }\n return Date.now();\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nfunction isRetriableStatus(status: number): boolean {\n return status === 408 || status === 425 || status === 429 || status >= 500;\n}\n\nfunction normalizeBoolMap(\n input: { flags?: Array<{ key: string; value: boolean }>; values?: Record<string, boolean> }\n): Array<{ key: string; value: boolean }> {\n if (Array.isArray(input.flags)) {\n return input.flags\n .filter((entry): entry is { key: string; value: boolean } =>\n Boolean(entry) && typeof entry.key === 'string' && typeof entry.value === 'boolean'\n )\n .map((entry) => ({ key: entry.key, value: entry.value }));\n }\n\n const values = input.values ?? {};\n return Object.entries(values).map(([key, value]) => ({ key, value: Boolean(value) }));\n}\n\nexport class InMemoryMetricsCollector {\n private readonly buckets = new Map<string, number[]>();\n\n record = (metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags) => {\n const key = `${metricName}:${JSON.stringify(tags ?? {})}`;\n const list = this.buckets.get(key) ?? [];\n list.push(value);\n this.buckets.set(key, list);\n };\n\n get(metricName: FeatureFlareMetricName): Array<{ tags: FeatureFlareMetricTags; values: number[] }> {\n const rows: Array<{ tags: FeatureFlareMetricTags; values: number[] }> = [];\n for (const [key, values] of this.buckets.entries()) {\n if (!key.startsWith(`${metricName}:`)) continue;\n rows.push({\n tags: JSON.parse(key.slice(metricName.length + 1)) as FeatureFlareMetricTags,\n values: [...values]\n });\n }\n return rows;\n }\n}\n\nexport class FeatureFlareClient {\n private readonly apiBaseUrl: string;\n private readonly sdkKey: string | null;\n private readonly projectKey: string | null;\n private readonly envKey: string;\n private readonly expectedEnvKey: string | null;\n private readonly timeoutMs: number;\n private readonly maxRetries: number;\n private readonly backoffMs: number;\n private readonly jitter: number;\n private readonly cacheTtlMs: number;\n private readonly staleTtlMs: number;\n private readonly persistentCache: FeatureFlarePersistentCacheAdapter | undefined;\n private readonly onMetric?: (metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags) => void;\n private readonly listeners: {\n [K in keyof FeatureFlareClientEvents]: Set<(payload: FeatureFlareClientEvents[K]) => void>;\n } = {\n update: new Set(),\n circuitOpen: new Set(),\n circuitClose: new Set(),\n connectionState: new Set()\n };\n\n private readonly cache = new Map<string, CacheItem>();\n private readonly diagnostics = new Map<string, FeatureFlareEvaluationMetadata>();\n private readonly killSwitches = new Set<string>();\n\n private revision = 0;\n private circuitOpen = false;\n private persistentLoadPromise: Promise<void> | null = null;\n private readonly inFlightRevalidate = new Map<string, Promise<Array<{ key: string; value: boolean }> | null>>();\n private lastUser: FeatureFlareUser | null = null;\n private lastDefaultValue = false;\n\n private realtimeEnabled = true;\n private realtimePollingMs = 15000;\n private realtimeSsePath = '/api/v1/sdk/stream';\n private pollTimer: ReturnType<typeof setTimeout> | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private eventSource: EventSource | null = null;\n\n constructor(options: FeatureFlareClientOptions = {}) {\n this.apiBaseUrl = getApiBaseUrl(options.apiBaseUrl).replace(/\\/$/, '');\n this.sdkKey = options.sdkKey?.trim() || getSdkKeyFromEnv();\n this.projectKey = options.projectKey?.trim() ? options.projectKey.trim() : null;\n const explicitOrEnvKey = options.envKey?.trim() || getEnvKeyFromEnv() || null;\n this.envKey = explicitOrEnvKey ?? 'production';\n this.expectedEnvKey = explicitOrEnvKey;\n\n if (!this.sdkKey && !this.projectKey) {\n throw new Error(\n 'FeatureFlareClient requires either sdkKey (recommended) or projectKey (legacy). Set FEATUREFLARE_CLIENT_KEY or FEATUREFLARE_SERVER_KEY env var, or pass sdkKey in options.'\n );\n }\n\n this.timeoutMs = Number.isFinite(options.timeoutMs) && (options.timeoutMs ?? 0) > 0 ? Number(options.timeoutMs) : 3000;\n this.maxRetries = Number.isFinite(options.maxRetries) && (options.maxRetries ?? 0) >= 0 ? Number(options.maxRetries) : 2;\n this.backoffMs = Number.isFinite(options.backoffMs) && (options.backoffMs ?? 0) > 0 ? Number(options.backoffMs) : 200;\n this.jitter = Number.isFinite(options.jitter) && (options.jitter ?? 0) >= 0 ? Number(options.jitter) : 0.25;\n\n this.cacheTtlMs = Number.isFinite(options.cacheTtlMs) && (options.cacheTtlMs ?? 0) > 0 ? Number(options.cacheTtlMs) : 60000;\n const configuredStaleTtlMs =\n Number.isFinite(options.staleTtlMs) && (options.staleTtlMs ?? 0) > 0 ? Number(options.staleTtlMs) : 10000;\n this.staleTtlMs = Math.min(configuredStaleTtlMs, this.cacheTtlMs);\n\n this.persistentCache = options.persistentCache;\n this.onMetric = options.onMetric;\n\n this.realtimeEnabled = options.realtime?.enabled ?? true;\n this.realtimePollingMs =\n Number.isFinite(options.realtime?.pollingIntervalMs) && (options.realtime?.pollingIntervalMs ?? 0) > 0\n ? Number(options.realtime?.pollingIntervalMs)\n : 15000;\n this.realtimeSsePath = options.realtime?.ssePath ?? '/api/v1/sdk/stream';\n\n this.applyBootstrap(options.bootstrap);\n this.persistentLoadPromise = this.loadPersistentCache();\n\n if (this.realtimeEnabled && this.sdkKey) {\n this.startRealtime();\n }\n }\n\n private getCacheKey(flagKey: string): string {\n return `${this.envKey}:${flagKey}`;\n }\n\n private normalizeUser(input: FeatureFlareUserPayload): FeatureFlareUser {\n const key = (input.id ?? input.key ?? '').trim();\n if (!key) throw new Error('FeatureFlareClient requires user.id (or legacy user.key).');\n return {\n key,\n email: input.email,\n name: input.name,\n country: input.country,\n custom: input.meta ?? input.custom\n };\n }\n\n private emit<K extends keyof FeatureFlareClientEvents>(event: K, payload: FeatureFlareClientEvents[K]): void {\n for (const listener of this.listeners[event]) {\n listener(payload);\n }\n }\n\n on<K extends keyof FeatureFlareClientEvents>(\n event: K,\n listener: (payload: FeatureFlareClientEvents[K]) => void\n ): () => void {\n this.listeners[event].add(listener);\n return () => {\n this.listeners[event].delete(listener);\n };\n }\n\n private emitMetric(metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags): void {\n this.onMetric?.(metricName, value, tags);\n }\n\n private async ensurePersistentLoaded(): Promise<void> {\n if (!this.persistentLoadPromise) return;\n await this.persistentLoadPromise;\n }\n\n private async loadPersistentCache(): Promise<void> {\n if (!this.persistentCache) return;\n try {\n const snapshot = await this.persistentCache.load(this.envKey);\n if (!snapshot) return;\n this.revision = Math.max(this.revision, snapshot.revision ?? 0);\n for (const killSwitchKey of snapshot.killSwitches ?? []) {\n this.killSwitches.add(killSwitchKey);\n }\n\n for (const [flagKey, item] of Object.entries(snapshot.flags ?? {})) {\n const existing = this.cache.get(this.getCacheKey(flagKey));\n if (existing && existing.source === 'bootstrap') continue;\n this.cache.set(this.getCacheKey(flagKey), {\n envKey: this.envKey,\n flagKey,\n value: Boolean(item.value),\n updatedAt: Number(item.updatedAt) || Date.now(),\n staleAt: Number(item.staleAt) || Date.now(),\n expiresAt: Number(item.expiresAt) || Date.now(),\n source: item.source ?? 'persistent',\n revision: item.revision ?? 0\n });\n }\n } catch {\n // Ignore persistent cache failures; runtime must stay non-throwing for outage semantics.\n }\n }\n\n private async persistCache(): Promise<void> {\n if (!this.persistentCache) return;\n const snapshot: FeatureFlarePersistentSnapshot = {\n revision: this.revision,\n killSwitches: [...this.killSwitches],\n flags: {}\n };\n\n for (const [key, item] of this.cache.entries()) {\n if (!key.startsWith(`${this.envKey}:`)) continue;\n snapshot.flags[item.flagKey] = {\n value: item.value,\n updatedAt: item.updatedAt,\n staleAt: item.staleAt,\n expiresAt: item.expiresAt,\n source: item.source,\n revision: item.revision\n };\n }\n\n try {\n await this.persistentCache.save(this.envKey, snapshot);\n } catch {\n // Persistent errors must not break evaluation.\n }\n }\n\n private makeCacheWindow(at = Date.now()): Pick<CacheItem, 'updatedAt' | 'staleAt' | 'expiresAt'> {\n return {\n updatedAt: at,\n staleAt: at + this.staleTtlMs,\n expiresAt: at + this.cacheTtlMs\n };\n }\n\n private setCacheItem(\n flagKey: string,\n value: boolean,\n source: FeatureFlareCacheSource,\n revision = this.revision,\n at = Date.now()\n ): void {\n this.cache.set(this.getCacheKey(flagKey), {\n envKey: this.envKey,\n flagKey,\n value,\n source,\n revision,\n ...this.makeCacheWindow(at)\n });\n }\n\n private applyBootstrap(bootstrap?: FeatureFlareBootstrapPayload): void {\n if (!bootstrap) return;\n this.revision = Math.max(this.revision, bootstrap.revision ?? 0);\n for (const killSwitchKey of bootstrap.killSwitches ?? []) {\n this.killSwitches.add(killSwitchKey);\n }\n\n const apply = (flagKey: string, value: boolean, revision?: number, updatedAt?: number) => {\n this.setCacheItem(flagKey, value, 'bootstrap', revision ?? this.revision, updatedAt ?? Date.now());\n };\n\n if (Array.isArray(bootstrap.flags)) {\n for (const item of bootstrap.flags) {\n if (!item || typeof item.key !== 'string') continue;\n apply(item.key, Boolean(item.value), item.revision, item.updatedAt);\n }\n return;\n }\n\n for (const [flagKey, value] of Object.entries(bootstrap.flags ?? {})) {\n apply(flagKey, Boolean(value));\n }\n }\n\n private getCacheState(item: CacheItem | undefined, now = Date.now()): 'fresh' | 'stale' | 'expired' | 'missing' {\n if (!item) return 'missing';\n if (now <= item.staleAt) return 'fresh';\n if (now <= item.expiresAt) return 'stale';\n return 'expired';\n }\n\n private setCircuitState(isOpen: boolean, reason = ''): void {\n if (this.circuitOpen === isOpen) return;\n this.circuitOpen = isOpen;\n if (isOpen) {\n this.emit('circuitOpen', { envKey: this.envKey, reason });\n return;\n }\n this.emit('circuitClose', { envKey: this.envKey });\n }\n\n private async fetchWithRetry(url: string, init: RequestInit, transport: 'network' | 'polling') {\n let lastError: unknown = null;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n const ac = typeof AbortController !== 'undefined' ? new AbortController() : null;\n const timeout =\n ac !== null\n ? setTimeout(() => {\n ac.abort();\n }, this.timeoutMs)\n : null;\n\n try {\n const response = await fetch(url, {\n ...init,\n signal: ac?.signal\n });\n\n if (timeout) clearTimeout(timeout);\n\n if (!response.ok && isRetriableStatus(response.status) && attempt < this.maxRetries) {\n lastError = new Error(`HTTP ${response.status}`);\n const jitterOffset = this.backoffMs * this.jitter * Math.random();\n await sleep(this.backoffMs * (attempt + 1) + jitterOffset);\n continue;\n }\n\n return response;\n } catch (error) {\n if (timeout) clearTimeout(timeout);\n lastError = error;\n if (attempt >= this.maxRetries) break;\n const jitterOffset = this.backoffMs * this.jitter * Math.random();\n await sleep(this.backoffMs * (attempt + 1) + jitterOffset);\n }\n }\n\n this.setCircuitState(true, transport);\n throw lastError;\n }\n\n private collectCachedFlags(): Array<{ key: string; value: boolean }> {\n const now = Date.now();\n const flags: Array<{ key: string; value: boolean }> = [];\n\n for (const [cacheKey, item] of this.cache.entries()) {\n if (!cacheKey.startsWith(`${this.envKey}:`)) continue;\n if (this.killSwitches.has(item.flagKey)) {\n flags.push({ key: item.flagKey, value: false });\n continue;\n }\n\n const state = this.getCacheState(item, now);\n if (state === 'missing' || state === 'expired') continue;\n flags.push({ key: item.flagKey, value: item.value });\n }\n\n return flags.sort((a, b) => a.key.localeCompare(b.key));\n }\n\n getCachedFlags(): {\n flags: Array<{ key: string; value: boolean }>;\n hasData: boolean;\n } {\n const flags = this.collectCachedFlags();\n return { flags, hasData: flags.length > 0 };\n }\n\n getFlagDiagnostics(flagKey: string): FeatureFlareEvaluationMetadata | null {\n return this.diagnostics.get(this.getCacheKey(flagKey)) ?? null;\n }\n\n setKillSwitch(flagKey: string, enabled: boolean): void {\n const started = monotonicNow();\n if (enabled) {\n this.killSwitches.add(flagKey);\n } else {\n this.killSwitches.delete(flagKey);\n }\n const elapsed = monotonicNow() - started;\n this.emitMetric('ff_killswitch_apply_latency_ms', elapsed, {\n env: this.envKey,\n result: enabled ? 'enabled' : 'disabled'\n });\n this.emit('update', { changedKeys: [flagKey], source: 'realtime' });\n void this.persistCache();\n }\n\n private async fetchEvalFromNetwork(\n flagKey: string,\n normalizedUser: FeatureFlareUser,\n defaultValue: boolean\n ): Promise<boolean | null> {\n const response = this.sdkKey\n ? await this.fetchWithRetry(\n `${this.apiBaseUrl}/api/v1/sdk/eval`,\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-featureflare-sdk-key': this.sdkKey\n },\n body: JSON.stringify({\n flagKey,\n user: normalizedUser,\n defaultValue,\n expectedEnvKey: this.expectedEnvKey ?? undefined\n })\n },\n 'network'\n )\n : await this.fetchWithRetry(\n `${this.apiBaseUrl}/api/v1/eval`,\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n projectKey: this.projectKey,\n envKey: this.envKey,\n flagKey,\n user: normalizedUser,\n defaultValue\n })\n },\n 'network'\n );\n\n if (!response.ok) {\n if (!isRetriableStatus(response.status)) {\n this.setCircuitState(true, `http_${response.status}`);\n }\n return null;\n }\n\n const json = (await response.json()) as { value?: boolean; revision?: number; killSwitch?: boolean };\n const value = typeof json.value === 'boolean' ? json.value : defaultValue;\n\n if (json.killSwitch === true) {\n this.killSwitches.add(flagKey);\n }\n\n const revision = json.revision ?? this.revision;\n this.revision = Math.max(this.revision, revision);\n this.setCacheItem(flagKey, value, 'network', revision);\n this.setCircuitState(false);\n void this.persistCache();\n this.emit('update', { changedKeys: [flagKey], source: 'network' });\n return value;\n }\n\n private async fetchFlagsFromNetwork(\n normalizedUser: FeatureFlareUser,\n defaultValue: boolean,\n transport: 'network' | 'polling'\n ): Promise<Array<{ key: string; value: boolean }> | null> {\n if (!this.sdkKey) {\n return null;\n }\n\n const started = monotonicNow();\n\n try {\n const response = await this.fetchWithRetry(\n `${this.apiBaseUrl}/api/v1/sdk/flags`,\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-featureflare-sdk-key': this.sdkKey\n },\n body: JSON.stringify({\n user: normalizedUser,\n defaultValue,\n expectedEnvKey: this.expectedEnvKey ?? undefined\n })\n },\n transport\n );\n\n if (!response.ok) {\n if (!isRetriableStatus(response.status)) {\n this.setCircuitState(true, `http_${response.status}`);\n }\n return null;\n }\n\n const json = (await response.json()) as {\n flags?: Array<{ key: string; value: boolean }>;\n values?: Record<string, boolean>;\n revision?: number;\n killSwitches?: string[];\n };\n\n const list = normalizeBoolMap(json);\n const revision = json.revision ?? this.revision;\n this.revision = Math.max(this.revision, revision);\n\n if (Array.isArray(json.killSwitches)) {\n for (const key of json.killSwitches) {\n this.killSwitches.add(key);\n }\n }\n\n const changed = new Set<string>();\n for (const entry of list) {\n const existing = this.cache.get(this.getCacheKey(entry.key));\n if (!existing || existing.value !== entry.value || existing.revision !== revision) {\n changed.add(entry.key);\n }\n this.setCacheItem(entry.key, entry.value, 'network', revision);\n }\n\n if (changed.size > 0) {\n this.emit('update', { changedKeys: [...changed], source: 'network' });\n }\n\n this.setCircuitState(false);\n void this.persistCache();\n this.emitMetric('ff_revalidate_latency_ms', monotonicNow() - started, {\n env: this.envKey,\n transport\n });\n return list;\n } catch {\n this.emitMetric('ff_revalidate_latency_ms', monotonicNow() - started, {\n env: this.envKey,\n transport,\n result: 'error'\n });\n return null;\n }\n }\n\n private revalidate(normalizedUser: FeatureFlareUser, defaultValue: boolean): Promise<Array<{ key: string; value: boolean }> | null> {\n const existing = this.inFlightRevalidate.get(this.envKey);\n if (existing) return existing;\n\n const promise = this.fetchFlagsFromNetwork(normalizedUser, defaultValue, 'network').finally(() => {\n this.inFlightRevalidate.delete(this.envKey);\n });\n\n this.inFlightRevalidate.set(this.envKey, promise);\n return promise;\n }\n\n async evaluate(\n flagKey: string,\n user: FeatureFlareUserPayload,\n defaultValue = false\n ): Promise<FeatureFlareEvaluationResult> {\n const started = monotonicNow();\n await this.ensurePersistentLoaded();\n\n const normalizedUser = this.normalizeUser(user);\n this.lastUser = normalizedUser;\n this.lastDefaultValue = defaultValue;\n\n if (this.killSwitches.has(flagKey)) {\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'kill_switch',\n isStale: false,\n latencyMs: monotonicNow() - started,\n source: 'kill_switch'\n };\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'disabled'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: false, metadata };\n }\n\n const cacheItem = this.cache.get(this.getCacheKey(flagKey));\n const cacheState = this.getCacheState(cacheItem);\n\n if (cacheItem && cacheState === 'fresh') {\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: cacheItem.source === 'bootstrap' || cacheItem.source === 'persistent' ? 'bootstrap' : 'fresh_cache',\n isStale: false,\n latencyMs: monotonicNow() - started,\n source: cacheItem.source,\n updatedAt: cacheItem.updatedAt,\n staleAt: cacheItem.staleAt,\n expiresAt: cacheItem.expiresAt\n };\n this.emitMetric('ff_cache_hit_ratio', 1, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'cache_hit'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: cacheItem.value, metadata };\n }\n\n if (cacheItem && cacheState === 'stale') {\n void this.revalidate(normalizedUser, defaultValue);\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'stale_cache',\n isStale: true,\n latencyMs: monotonicNow() - started,\n source: cacheItem.source,\n updatedAt: cacheItem.updatedAt,\n staleAt: cacheItem.staleAt,\n expiresAt: cacheItem.expiresAt\n };\n this.emitMetric('ff_cache_hit_ratio', 1, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'stale'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: cacheItem.value, metadata };\n }\n\n if (cacheItem && (cacheItem.source === 'bootstrap' || cacheItem.source === 'persistent')) {\n void this.revalidate(normalizedUser, defaultValue);\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'bootstrap',\n isStale: true,\n latencyMs: monotonicNow() - started,\n source: cacheItem.source,\n updatedAt: cacheItem.updatedAt,\n staleAt: cacheItem.staleAt,\n expiresAt: cacheItem.expiresAt\n };\n this.emitMetric('ff_cache_hit_ratio', 1, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'bootstrap'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: cacheItem.value, metadata };\n }\n\n try {\n const networkValue = await this.fetchEvalFromNetwork(flagKey, normalizedUser, defaultValue);\n if (networkValue !== null) {\n const item = this.cache.get(this.getCacheKey(flagKey));\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'network',\n isStale: false,\n latencyMs: monotonicNow() - started,\n source: 'network',\n updatedAt: item?.updatedAt,\n staleAt: item?.staleAt,\n expiresAt: item?.expiresAt\n };\n this.emitMetric('ff_cache_hit_ratio', 0, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'network'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: networkValue, metadata };\n }\n } catch {\n // Fall through to deterministic default for outage semantics.\n }\n\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'default',\n isStale: false,\n latencyMs: monotonicNow() - started,\n source: 'default'\n };\n this.emitMetric('ff_cache_hit_ratio', 0, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'default'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: defaultValue, metadata };\n }\n\n async bool(flagKey: string, user: FeatureFlareUserPayload, defaultValue = false): Promise<boolean> {\n const result = await this.evaluate(flagKey, user, defaultValue);\n return result.value;\n }\n\n async flags(user: FeatureFlareUserPayload, defaultValue = false): Promise<Array<{ key: string; value: boolean }>> {\n await this.ensurePersistentLoaded();\n const normalizedUser = this.normalizeUser(user);\n this.lastUser = normalizedUser;\n this.lastDefaultValue = defaultValue;\n\n const list = await this.revalidate(normalizedUser, defaultValue);\n if (list && list.length > 0) {\n return list.map((entry) => ({\n key: entry.key,\n value: this.killSwitches.has(entry.key) ? false : entry.value\n }));\n }\n\n const cached = this.collectCachedFlags();\n if (cached.length > 0) return cached;\n return [];\n }\n\n private applyRealtimeMessage(message: RealtimeEventPayload): void {\n if (typeof message.revision === 'number' && message.revision < this.revision) {\n return;\n }\n\n if (typeof message.revision === 'number') {\n this.revision = message.revision;\n }\n\n const changed = new Set<string>();\n const now = Date.now();\n\n if (message.type === 'flag.updated') {\n const flagKey = typeof message.data?.flagKey === 'string' ? message.data.flagKey : null;\n const value = typeof message.data?.value === 'boolean' ? message.data.value : null;\n if (flagKey !== null && value !== null) {\n this.setCacheItem(flagKey, value, 'realtime', message.revision ?? this.revision, now);\n changed.add(flagKey);\n }\n }\n\n if (message.type === 'flag.deleted') {\n const flagKey = typeof message.data?.flagKey === 'string' ? message.data.flagKey : null;\n if (flagKey !== null) {\n this.cache.delete(this.getCacheKey(flagKey));\n changed.add(flagKey);\n }\n }\n\n if (message.type === 'env.kill_switch.updated') {\n const started = monotonicNow();\n const flagKey = typeof message.data?.flagKey === 'string' ? message.data.flagKey : null;\n const enabled = typeof message.data?.enabled === 'boolean' ? message.data.enabled : true;\n if (flagKey !== null) {\n if (enabled) {\n this.killSwitches.add(flagKey);\n } else {\n this.killSwitches.delete(flagKey);\n }\n changed.add(flagKey);\n this.emitMetric('ff_killswitch_apply_latency_ms', monotonicNow() - started, {\n env: this.envKey,\n transport: this.eventSource ? 'sse' : 'polling',\n result: enabled ? 'enabled' : 'disabled'\n });\n }\n }\n\n if (message.type === 'snapshot.invalidate' && this.lastUser) {\n void this.revalidate(this.lastUser, this.lastDefaultValue);\n }\n\n const eventLagMs = Math.max(0, Date.now() - (message.timestamp ?? Date.now()));\n this.emitMetric('ff_realtime_lag_ms', eventLagMs, {\n env: this.envKey,\n transport: this.eventSource ? 'sse' : 'polling'\n });\n\n if (changed.size > 0) {\n this.emit('update', { changedKeys: [...changed], source: 'realtime' });\n void this.persistCache();\n }\n }\n\n private startPolling(): void {\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n\n const tick = async () => {\n if (!this.lastUser) {\n this.pollTimer = setTimeout(tick, this.realtimePollingMs);\n return;\n }\n await this.fetchFlagsFromNetwork(this.lastUser, this.lastDefaultValue, 'polling');\n this.pollTimer = setTimeout(tick, this.realtimePollingMs);\n };\n\n this.pollTimer = setTimeout(tick, this.realtimePollingMs);\n }\n\n private connectSse(attempt = 0): void {\n const EventSourceImpl = typeof EventSource !== 'undefined' ? EventSource : null;\n if (!EventSourceImpl || !this.sdkKey) {\n this.emit('connectionState', { state: 'degraded', transport: 'polling' });\n this.startPolling();\n return;\n }\n\n const url = new URL(this.realtimeSsePath, this.apiBaseUrl);\n url.searchParams.set('sdkKey', this.sdkKey);\n if (this.expectedEnvKey) {\n url.searchParams.set('expectedEnvKey', this.expectedEnvKey);\n }\n\n this.eventSource = new EventSourceImpl(url.toString());\n\n this.eventSource.onopen = () => {\n this.emit('connectionState', { state: 'connected', transport: 'sse' });\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n };\n\n this.eventSource.onmessage = (event: MessageEvent) => {\n try {\n const payload = JSON.parse(String(event.data)) as RealtimeEventPayload;\n this.applyRealtimeMessage(payload);\n } catch {\n // Ignore malformed realtime messages.\n }\n };\n\n this.eventSource.onerror = () => {\n this.emit('connectionState', { state: 'degraded', transport: 'polling' });\n this.eventSource?.close();\n this.eventSource = null;\n this.startPolling();\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n }\n const backoff = Math.min(this.backoffMs * (attempt + 1), 30000);\n this.reconnectTimer = setTimeout(() => {\n this.connectSse(attempt + 1);\n }, backoff);\n };\n }\n\n startRealtime(): void {\n this.realtimeEnabled = true;\n this.connectSse(0);\n }\n\n stopRealtime(): void {\n this.realtimeEnabled = false;\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.emit('connectionState', { state: 'offline', transport: 'none' });\n }\n\n /**\n * Report observed error metrics (error rate, latency) for a flag back to the FeatureFlare API.\n * The API evaluates the report against active rollback policies and may trigger an automated\n * rollback if configured thresholds are breached.\n *\n * Errors from this call are silently swallowed so that reporting never disrupts the host application.\n */\n async reportError(report: FeatureFlareErrorReport): Promise<void> {\n if (!this.sdkKey) return;\n try {\n await fetch(`${this.apiBaseUrl}/api/v1/sdk/report`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-featureflare-sdk-key': this.sdkKey\n },\n body: JSON.stringify({\n flagKey: report.flagKey,\n errorRate: report.errorRate,\n latencyMs: report.latencyMs,\n observedAt: report.observedAt ?? new Date().toISOString(),\n envKey: this.envKey,\n context: report.context\n })\n });\n } catch {\n // Reporting failures must never surface to the caller.\n }\n }\n\n dispose(): void {\n this.stopRealtime();\n this.listeners.update.clear();\n this.listeners.circuitOpen.clear();\n this.listeners.circuitClose.clear();\n this.listeners.connectionState.clear();\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":["metadata"],"mappings":"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","file":"index.js","sourcesContent":["export type FeatureFlareUserPayload = {\n /** Unique user identifier (preferred). */\n id?: string;\n /** Legacy alias for id. */\n key?: string;\n email?: string;\n name?: string;\n country?: string;\n /** Queryable attributes. */\n meta?: Record<string, string | number | boolean | null>;\n /** Legacy alias for meta. */\n custom?: Record<string, string | number | boolean | null>;\n};\n\ntype FeatureFlareUser = {\n key: string;\n email?: string;\n name?: string;\n country?: string;\n custom?: Record<string, string | number | boolean | null>;\n};\n\nconst DEFAULT_FEATUREFLARE_API_BASE_URL =\n 'https://shipit-api-392444455847.us-central1.run.app';\n\nfunction getApiBaseUrlFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_API_BASE_URL?.trim() ||\n process.env.SHIPIT_API_BASE_URL?.trim() ||\n null\n );\n }\n return null;\n}\n\nfunction getApiBaseUrl(explicit?: string): string {\n const fromOptions = explicit?.trim();\n if (fromOptions) return fromOptions;\n\n const fromEnv = getApiBaseUrlFromEnv();\n if (fromEnv) return fromEnv;\n\n return DEFAULT_FEATUREFLARE_API_BASE_URL;\n}\n\nexport type FeatureFlareCacheSource = 'bootstrap' | 'network' | 'realtime' | 'persistent';\nexport type FeatureFlareEvaluationReason = 'fresh_cache' | 'stale_cache' | 'bootstrap' | 'default' | 'network' | 'kill_switch';\n\nexport type FeatureFlareEvaluationMetadata = {\n reason: FeatureFlareEvaluationReason;\n isStale: boolean;\n latencyMs: number;\n source: FeatureFlareCacheSource | 'default' | 'kill_switch';\n updatedAt?: number;\n staleAt?: number;\n expiresAt?: number;\n};\n\nexport type FeatureFlareEvaluationResult = {\n value: boolean;\n metadata: FeatureFlareEvaluationMetadata;\n};\n\nexport type FeatureFlareMetricName =\n | 'ff_eval_latency_ms'\n | 'ff_cache_hit_ratio'\n | 'ff_revalidate_latency_ms'\n | 'ff_realtime_lag_ms'\n | 'ff_killswitch_apply_latency_ms';\n\nexport type FeatureFlareMetricTags = Record<string, string | number | boolean | undefined>;\n\nexport type FeatureFlareErrorReport = {\n /** The flag key being evaluated when the error was observed. */\n flagKey: string;\n /** Observed error rate as a fraction from 0 to 1 (e.g. 0.05 = 5%). */\n errorRate: number;\n /** Observed p99 latency in milliseconds. */\n latencyMs?: number;\n /** ISO-8601 timestamp of the observation window end. Defaults to now. */\n observedAt?: string;\n /** Optional free-form context about the error (e.g. HTTP status, exception name). */\n context?: Record<string, string | number | boolean>;\n};\n\nexport type FeatureFlarePersistentSnapshot = {\n revision?: number;\n killSwitches?: string[];\n flags: Record<\n string,\n {\n value: boolean;\n updatedAt: number;\n staleAt: number;\n expiresAt: number;\n source?: FeatureFlareCacheSource;\n revision?: number;\n }\n >;\n};\n\nexport type FeatureFlarePersistentCacheAdapter = {\n load: (envKey: string) => Promise<FeatureFlarePersistentSnapshot | null> | FeatureFlarePersistentSnapshot | null;\n save: (envKey: string, snapshot: FeatureFlarePersistentSnapshot) => Promise<void> | void;\n};\n\nexport type FeatureFlareBootstrapPayload = {\n revision?: number;\n killSwitches?: string[];\n flags?:\n | Record<string, boolean>\n | Array<{ key: string; value: boolean; revision?: number; updatedAt?: number }>;\n};\n\nexport type FeatureFlareClientOptions = {\n apiBaseUrl?: string;\n sdkKey?: string;\n projectKey?: string;\n envKey?: string;\n timeoutMs?: number;\n maxRetries?: number;\n backoffMs?: number;\n jitter?: number;\n cacheTtlMs?: number;\n staleTtlMs?: number;\n bootstrap?: FeatureFlareBootstrapPayload;\n persistentCache?: FeatureFlarePersistentCacheAdapter;\n onMetric?: (metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags) => void;\n realtime?: {\n enabled?: boolean;\n pollingIntervalMs?: number;\n ssePath?: string;\n };\n};\n\ntype CacheItem = {\n envKey: string;\n flagKey: string;\n value: boolean;\n updatedAt: number;\n staleAt: number;\n expiresAt: number;\n source: FeatureFlareCacheSource;\n revision: number;\n};\n\ntype RealtimeEventPayload = {\n type: 'flag.updated' | 'flag.deleted' | 'env.kill_switch.updated' | 'snapshot.invalidate';\n timestamp?: number;\n revision?: number;\n data?: Record<string, unknown>;\n};\n\ntype FeatureFlareClientEvents = {\n update: { changedKeys: string[]; source: FeatureFlareCacheSource | 'network' };\n circuitOpen: { envKey: string; reason: string };\n circuitClose: { envKey: string };\n connectionState: { state: 'connected' | 'degraded' | 'offline'; transport: 'sse' | 'polling' | 'none' };\n};\n\nfunction getEnvKeyFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_ENV_KEY?.trim() ||\n process.env.SHIPIT_ENV_KEY?.trim() ||\n null\n );\n }\n return null;\n}\n\nfunction getSdkKeyFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_CLIENT_KEY?.trim() ||\n process.env.FEATUREFLARE_SERVER_KEY?.trim() ||\n process.env.SHIPIT_CLIENT_KEY?.trim() ||\n process.env.SHIPIT_SERVER_KEY?.trim() ||\n null\n );\n }\n return null;\n}\n\nfunction monotonicNow(): number {\n if (typeof performance !== 'undefined' && typeof performance.now === 'function') {\n return performance.now();\n }\n return Date.now();\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nfunction isRetriableStatus(status: number): boolean {\n return status === 408 || status === 425 || status === 429 || status >= 500;\n}\n\nfunction normalizeBoolMap(\n input: { flags?: Array<{ key: string; value: boolean }>; values?: Record<string, boolean> }\n): Array<{ key: string; value: boolean }> {\n if (Array.isArray(input.flags)) {\n return input.flags\n .filter((entry): entry is { key: string; value: boolean } =>\n Boolean(entry) && typeof entry.key === 'string' && typeof entry.value === 'boolean'\n )\n .map((entry) => ({ key: entry.key, value: entry.value }));\n }\n\n const values = input.values ?? {};\n return Object.entries(values).map(([key, value]) => ({ key, value: Boolean(value) }));\n}\n\nexport class InMemoryMetricsCollector {\n private readonly buckets = new Map<string, number[]>();\n\n record = (metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags) => {\n const key = `${metricName}:${JSON.stringify(tags ?? {})}`;\n const list = this.buckets.get(key) ?? [];\n list.push(value);\n this.buckets.set(key, list);\n };\n\n get(metricName: FeatureFlareMetricName): Array<{ tags: FeatureFlareMetricTags; values: number[] }> {\n const rows: Array<{ tags: FeatureFlareMetricTags; values: number[] }> = [];\n for (const [key, values] of this.buckets.entries()) {\n if (!key.startsWith(`${metricName}:`)) continue;\n rows.push({\n tags: JSON.parse(key.slice(metricName.length + 1)) as FeatureFlareMetricTags,\n values: [...values]\n });\n }\n return rows;\n }\n}\n\nexport class FeatureFlareClient {\n private readonly apiBaseUrl: string;\n private readonly sdkKey: string | null;\n private readonly projectKey: string | null;\n private readonly envKey: string;\n private readonly expectedEnvKey: string | null;\n private readonly timeoutMs: number;\n private readonly maxRetries: number;\n private readonly backoffMs: number;\n private readonly jitter: number;\n private readonly cacheTtlMs: number;\n private readonly staleTtlMs: number;\n private readonly persistentCache: FeatureFlarePersistentCacheAdapter | undefined;\n private readonly onMetric?: (metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags) => void;\n private readonly listeners: {\n [K in keyof FeatureFlareClientEvents]: Set<(payload: FeatureFlareClientEvents[K]) => void>;\n } = {\n update: new Set(),\n circuitOpen: new Set(),\n circuitClose: new Set(),\n connectionState: new Set()\n };\n\n private readonly cache = new Map<string, CacheItem>();\n private readonly diagnostics = new Map<string, FeatureFlareEvaluationMetadata>();\n private readonly killSwitches = new Set<string>();\n\n private revision = 0;\n private circuitOpen = false;\n private persistentLoadPromise: Promise<void> | null = null;\n private readonly inFlightRevalidate = new Map<string, Promise<Array<{ key: string; value: boolean }> | null>>();\n private lastUser: FeatureFlareUser | null = null;\n private lastDefaultValue = false;\n\n private realtimeEnabled = true;\n private realtimePollingMs = 15000;\n private realtimeSsePath = '/api/v1/sdk/stream';\n private pollTimer: ReturnType<typeof setTimeout> | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private eventSource: EventSource | null = null;\n private visibilityListenersAttached = false;\n private realtimePausedByVisibility = false;\n\n private readonly handleRealtimeVisibilityChange = () => {\n if (!this.realtimeEnabled) return;\n\n const shouldPause = !this.isRealtimeWindowActive();\n if (shouldPause === this.realtimePausedByVisibility) return;\n\n this.realtimePausedByVisibility = shouldPause;\n if (shouldPause) {\n this.clearRealtimeTransport();\n this.emit('connectionState', { state: 'offline', transport: 'none' });\n return;\n }\n\n this.connectSse(0);\n };\n\n constructor(options: FeatureFlareClientOptions = {}) {\n this.apiBaseUrl = getApiBaseUrl(options.apiBaseUrl).replace(/\\/$/, '');\n this.sdkKey = options.sdkKey?.trim() || getSdkKeyFromEnv();\n this.projectKey = options.projectKey?.trim() ? options.projectKey.trim() : null;\n const explicitOrEnvKey = options.envKey?.trim() || getEnvKeyFromEnv() || null;\n this.envKey = explicitOrEnvKey ?? 'production';\n this.expectedEnvKey = explicitOrEnvKey;\n\n if (!this.sdkKey && !this.projectKey) {\n throw new Error(\n 'FeatureFlareClient requires either sdkKey (recommended) or projectKey (legacy). Set FEATUREFLARE_CLIENT_KEY or FEATUREFLARE_SERVER_KEY env var, or pass sdkKey in options.'\n );\n }\n\n this.timeoutMs = Number.isFinite(options.timeoutMs) && (options.timeoutMs ?? 0) > 0 ? Number(options.timeoutMs) : 3000;\n this.maxRetries = Number.isFinite(options.maxRetries) && (options.maxRetries ?? 0) >= 0 ? Number(options.maxRetries) : 2;\n this.backoffMs = Number.isFinite(options.backoffMs) && (options.backoffMs ?? 0) > 0 ? Number(options.backoffMs) : 200;\n this.jitter = Number.isFinite(options.jitter) && (options.jitter ?? 0) >= 0 ? Number(options.jitter) : 0.25;\n\n this.cacheTtlMs = Number.isFinite(options.cacheTtlMs) && (options.cacheTtlMs ?? 0) > 0 ? Number(options.cacheTtlMs) : 60000;\n const configuredStaleTtlMs =\n Number.isFinite(options.staleTtlMs) && (options.staleTtlMs ?? 0) > 0 ? Number(options.staleTtlMs) : 10000;\n this.staleTtlMs = Math.min(configuredStaleTtlMs, this.cacheTtlMs);\n\n this.persistentCache = options.persistentCache;\n this.onMetric = options.onMetric;\n\n this.realtimeEnabled = options.realtime?.enabled ?? true;\n this.realtimePollingMs =\n Number.isFinite(options.realtime?.pollingIntervalMs) && (options.realtime?.pollingIntervalMs ?? 0) > 0\n ? Number(options.realtime?.pollingIntervalMs)\n : 15000;\n this.realtimeSsePath = options.realtime?.ssePath ?? '/api/v1/sdk/stream';\n\n this.applyBootstrap(options.bootstrap);\n this.persistentLoadPromise = this.loadPersistentCache();\n\n if (this.realtimeEnabled && this.sdkKey) {\n this.startRealtime();\n }\n }\n\n private getCacheKey(flagKey: string): string {\n return `${this.envKey}:${flagKey}`;\n }\n\n private normalizeUser(input: FeatureFlareUserPayload): FeatureFlareUser {\n const key = (input.id ?? input.key ?? '').trim();\n if (!key) throw new Error('FeatureFlareClient requires user.id (or legacy user.key).');\n return {\n key,\n email: input.email,\n name: input.name,\n country: input.country,\n custom: input.meta ?? input.custom\n };\n }\n\n private emit<K extends keyof FeatureFlareClientEvents>(event: K, payload: FeatureFlareClientEvents[K]): void {\n for (const listener of this.listeners[event]) {\n listener(payload);\n }\n }\n\n on<K extends keyof FeatureFlareClientEvents>(\n event: K,\n listener: (payload: FeatureFlareClientEvents[K]) => void\n ): () => void {\n this.listeners[event].add(listener);\n return () => {\n this.listeners[event].delete(listener);\n };\n }\n\n private emitMetric(metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags): void {\n this.onMetric?.(metricName, value, tags);\n }\n\n private async ensurePersistentLoaded(): Promise<void> {\n if (!this.persistentLoadPromise) return;\n await this.persistentLoadPromise;\n }\n\n private async loadPersistentCache(): Promise<void> {\n if (!this.persistentCache) return;\n try {\n const snapshot = await this.persistentCache.load(this.envKey);\n if (!snapshot) return;\n this.revision = Math.max(this.revision, snapshot.revision ?? 0);\n for (const killSwitchKey of snapshot.killSwitches ?? []) {\n this.killSwitches.add(killSwitchKey);\n }\n\n for (const [flagKey, item] of Object.entries(snapshot.flags ?? {})) {\n const existing = this.cache.get(this.getCacheKey(flagKey));\n if (existing && existing.source === 'bootstrap') continue;\n this.cache.set(this.getCacheKey(flagKey), {\n envKey: this.envKey,\n flagKey,\n value: Boolean(item.value),\n updatedAt: Number(item.updatedAt) || Date.now(),\n staleAt: Number(item.staleAt) || Date.now(),\n expiresAt: Number(item.expiresAt) || Date.now(),\n source: item.source ?? 'persistent',\n revision: item.revision ?? 0\n });\n }\n } catch {\n // Ignore persistent cache failures; runtime must stay non-throwing for outage semantics.\n }\n }\n\n private async persistCache(): Promise<void> {\n if (!this.persistentCache) return;\n const snapshot: FeatureFlarePersistentSnapshot = {\n revision: this.revision,\n killSwitches: [...this.killSwitches],\n flags: {}\n };\n\n for (const [key, item] of this.cache.entries()) {\n if (!key.startsWith(`${this.envKey}:`)) continue;\n snapshot.flags[item.flagKey] = {\n value: item.value,\n updatedAt: item.updatedAt,\n staleAt: item.staleAt,\n expiresAt: item.expiresAt,\n source: item.source,\n revision: item.revision\n };\n }\n\n try {\n await this.persistentCache.save(this.envKey, snapshot);\n } catch {\n // Persistent errors must not break evaluation.\n }\n }\n\n private makeCacheWindow(at = Date.now()): Pick<CacheItem, 'updatedAt' | 'staleAt' | 'expiresAt'> {\n return {\n updatedAt: at,\n staleAt: at + this.staleTtlMs,\n expiresAt: at + this.cacheTtlMs\n };\n }\n\n private setCacheItem(\n flagKey: string,\n value: boolean,\n source: FeatureFlareCacheSource,\n revision = this.revision,\n at = Date.now()\n ): void {\n this.cache.set(this.getCacheKey(flagKey), {\n envKey: this.envKey,\n flagKey,\n value,\n source,\n revision,\n ...this.makeCacheWindow(at)\n });\n }\n\n private applyBootstrap(bootstrap?: FeatureFlareBootstrapPayload): void {\n if (!bootstrap) return;\n this.revision = Math.max(this.revision, bootstrap.revision ?? 0);\n for (const killSwitchKey of bootstrap.killSwitches ?? []) {\n this.killSwitches.add(killSwitchKey);\n }\n\n const apply = (flagKey: string, value: boolean, revision?: number, updatedAt?: number) => {\n this.setCacheItem(flagKey, value, 'bootstrap', revision ?? this.revision, updatedAt ?? Date.now());\n };\n\n if (Array.isArray(bootstrap.flags)) {\n for (const item of bootstrap.flags) {\n if (!item || typeof item.key !== 'string') continue;\n apply(item.key, Boolean(item.value), item.revision, item.updatedAt);\n }\n return;\n }\n\n for (const [flagKey, value] of Object.entries(bootstrap.flags ?? {})) {\n apply(flagKey, Boolean(value));\n }\n }\n\n private getCacheState(item: CacheItem | undefined, now = Date.now()): 'fresh' | 'stale' | 'expired' | 'missing' {\n if (!item) return 'missing';\n if (now <= item.staleAt) return 'fresh';\n if (now <= item.expiresAt) return 'stale';\n return 'expired';\n }\n\n private setCircuitState(isOpen: boolean, reason = ''): void {\n if (this.circuitOpen === isOpen) return;\n this.circuitOpen = isOpen;\n if (isOpen) {\n this.emit('circuitOpen', { envKey: this.envKey, reason });\n return;\n }\n this.emit('circuitClose', { envKey: this.envKey });\n }\n\n private async fetchWithRetry(url: string, init: RequestInit, transport: 'network' | 'polling') {\n let lastError: unknown = null;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n const ac = typeof AbortController !== 'undefined' ? new AbortController() : null;\n const timeout =\n ac !== null\n ? setTimeout(() => {\n ac.abort();\n }, this.timeoutMs)\n : null;\n\n try {\n const response = await fetch(url, {\n ...init,\n signal: ac?.signal\n });\n\n if (timeout) clearTimeout(timeout);\n\n if (!response.ok && isRetriableStatus(response.status) && attempt < this.maxRetries) {\n lastError = new Error(`HTTP ${response.status}`);\n const jitterOffset = this.backoffMs * this.jitter * Math.random();\n await sleep(this.backoffMs * (attempt + 1) + jitterOffset);\n continue;\n }\n\n return response;\n } catch (error) {\n if (timeout) clearTimeout(timeout);\n lastError = error;\n if (attempt >= this.maxRetries) break;\n const jitterOffset = this.backoffMs * this.jitter * Math.random();\n await sleep(this.backoffMs * (attempt + 1) + jitterOffset);\n }\n }\n\n this.setCircuitState(true, transport);\n throw lastError;\n }\n\n private collectCachedFlags(): Array<{ key: string; value: boolean }> {\n const now = Date.now();\n const flags: Array<{ key: string; value: boolean }> = [];\n\n for (const [cacheKey, item] of this.cache.entries()) {\n if (!cacheKey.startsWith(`${this.envKey}:`)) continue;\n if (this.killSwitches.has(item.flagKey)) {\n flags.push({ key: item.flagKey, value: false });\n continue;\n }\n\n const state = this.getCacheState(item, now);\n if (state === 'missing' || state === 'expired') continue;\n flags.push({ key: item.flagKey, value: item.value });\n }\n\n return flags.sort((a, b) => a.key.localeCompare(b.key));\n }\n\n getCachedFlags(): {\n flags: Array<{ key: string; value: boolean }>;\n hasData: boolean;\n } {\n const flags = this.collectCachedFlags();\n return { flags, hasData: flags.length > 0 };\n }\n\n getFlagDiagnostics(flagKey: string): FeatureFlareEvaluationMetadata | null {\n return this.diagnostics.get(this.getCacheKey(flagKey)) ?? null;\n }\n\n setKillSwitch(flagKey: string, enabled: boolean): void {\n const started = monotonicNow();\n if (enabled) {\n this.killSwitches.add(flagKey);\n } else {\n this.killSwitches.delete(flagKey);\n }\n const elapsed = monotonicNow() - started;\n this.emitMetric('ff_killswitch_apply_latency_ms', elapsed, {\n env: this.envKey,\n result: enabled ? 'enabled' : 'disabled'\n });\n this.emit('update', { changedKeys: [flagKey], source: 'realtime' });\n void this.persistCache();\n }\n\n private async fetchEvalFromNetwork(\n flagKey: string,\n normalizedUser: FeatureFlareUser,\n defaultValue: boolean\n ): Promise<boolean | null> {\n const response = this.sdkKey\n ? await this.fetchWithRetry(\n `${this.apiBaseUrl}/api/v1/sdk/eval`,\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-featureflare-sdk-key': this.sdkKey\n },\n body: JSON.stringify({\n flagKey,\n user: normalizedUser,\n defaultValue,\n expectedEnvKey: this.expectedEnvKey ?? undefined\n })\n },\n 'network'\n )\n : await this.fetchWithRetry(\n `${this.apiBaseUrl}/api/v1/eval`,\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n projectKey: this.projectKey,\n envKey: this.envKey,\n flagKey,\n user: normalizedUser,\n defaultValue\n })\n },\n 'network'\n );\n\n if (!response.ok) {\n if (!isRetriableStatus(response.status)) {\n this.setCircuitState(true, `http_${response.status}`);\n }\n return null;\n }\n\n const json = (await response.json()) as { value?: boolean; revision?: number; killSwitch?: boolean };\n const value = typeof json.value === 'boolean' ? json.value : defaultValue;\n\n if (json.killSwitch === true) {\n this.killSwitches.add(flagKey);\n }\n\n const revision = json.revision ?? this.revision;\n this.revision = Math.max(this.revision, revision);\n this.setCacheItem(flagKey, value, 'network', revision);\n this.setCircuitState(false);\n void this.persistCache();\n this.emit('update', { changedKeys: [flagKey], source: 'network' });\n return value;\n }\n\n private async fetchFlagsFromNetwork(\n normalizedUser: FeatureFlareUser,\n defaultValue: boolean,\n transport: 'network' | 'polling'\n ): Promise<Array<{ key: string; value: boolean }> | null> {\n if (!this.sdkKey) {\n return null;\n }\n\n const started = monotonicNow();\n\n try {\n const response = await this.fetchWithRetry(\n `${this.apiBaseUrl}/api/v1/sdk/flags`,\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-featureflare-sdk-key': this.sdkKey\n },\n body: JSON.stringify({\n user: normalizedUser,\n defaultValue,\n expectedEnvKey: this.expectedEnvKey ?? undefined\n })\n },\n transport\n );\n\n if (!response.ok) {\n if (!isRetriableStatus(response.status)) {\n this.setCircuitState(true, `http_${response.status}`);\n }\n return null;\n }\n\n const json = (await response.json()) as {\n flags?: Array<{ key: string; value: boolean }>;\n values?: Record<string, boolean>;\n revision?: number;\n killSwitches?: string[];\n };\n\n const list = normalizeBoolMap(json);\n const revision = json.revision ?? this.revision;\n this.revision = Math.max(this.revision, revision);\n\n if (Array.isArray(json.killSwitches)) {\n for (const key of json.killSwitches) {\n this.killSwitches.add(key);\n }\n }\n\n const changed = new Set<string>();\n for (const entry of list) {\n const existing = this.cache.get(this.getCacheKey(entry.key));\n if (!existing || existing.value !== entry.value || existing.revision !== revision) {\n changed.add(entry.key);\n }\n this.setCacheItem(entry.key, entry.value, 'network', revision);\n }\n\n if (changed.size > 0) {\n this.emit('update', { changedKeys: [...changed], source: 'network' });\n }\n\n this.setCircuitState(false);\n void this.persistCache();\n this.emitMetric('ff_revalidate_latency_ms', monotonicNow() - started, {\n env: this.envKey,\n transport\n });\n return list;\n } catch {\n this.emitMetric('ff_revalidate_latency_ms', monotonicNow() - started, {\n env: this.envKey,\n transport,\n result: 'error'\n });\n return null;\n }\n }\n\n private revalidate(normalizedUser: FeatureFlareUser, defaultValue: boolean): Promise<Array<{ key: string; value: boolean }> | null> {\n const existing = this.inFlightRevalidate.get(this.envKey);\n if (existing) return existing;\n\n const promise = this.fetchFlagsFromNetwork(normalizedUser, defaultValue, 'network').finally(() => {\n this.inFlightRevalidate.delete(this.envKey);\n });\n\n this.inFlightRevalidate.set(this.envKey, promise);\n return promise;\n }\n\n async evaluate(\n flagKey: string,\n user: FeatureFlareUserPayload,\n defaultValue = false\n ): Promise<FeatureFlareEvaluationResult> {\n const started = monotonicNow();\n await this.ensurePersistentLoaded();\n\n const normalizedUser = this.normalizeUser(user);\n this.lastUser = normalizedUser;\n this.lastDefaultValue = defaultValue;\n\n if (this.killSwitches.has(flagKey)) {\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'kill_switch',\n isStale: false,\n latencyMs: monotonicNow() - started,\n source: 'kill_switch'\n };\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'disabled'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: false, metadata };\n }\n\n const cacheItem = this.cache.get(this.getCacheKey(flagKey));\n const cacheState = this.getCacheState(cacheItem);\n\n if (cacheItem && cacheState === 'fresh') {\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: cacheItem.source === 'bootstrap' || cacheItem.source === 'persistent' ? 'bootstrap' : 'fresh_cache',\n isStale: false,\n latencyMs: monotonicNow() - started,\n source: cacheItem.source,\n updatedAt: cacheItem.updatedAt,\n staleAt: cacheItem.staleAt,\n expiresAt: cacheItem.expiresAt\n };\n this.emitMetric('ff_cache_hit_ratio', 1, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'cache_hit'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: cacheItem.value, metadata };\n }\n\n if (cacheItem && cacheState === 'stale') {\n void this.revalidate(normalizedUser, defaultValue);\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'stale_cache',\n isStale: true,\n latencyMs: monotonicNow() - started,\n source: cacheItem.source,\n updatedAt: cacheItem.updatedAt,\n staleAt: cacheItem.staleAt,\n expiresAt: cacheItem.expiresAt\n };\n this.emitMetric('ff_cache_hit_ratio', 1, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'stale'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: cacheItem.value, metadata };\n }\n\n if (cacheItem && (cacheItem.source === 'bootstrap' || cacheItem.source === 'persistent')) {\n void this.revalidate(normalizedUser, defaultValue);\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'bootstrap',\n isStale: true,\n latencyMs: monotonicNow() - started,\n source: cacheItem.source,\n updatedAt: cacheItem.updatedAt,\n staleAt: cacheItem.staleAt,\n expiresAt: cacheItem.expiresAt\n };\n this.emitMetric('ff_cache_hit_ratio', 1, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'bootstrap'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: cacheItem.value, metadata };\n }\n\n try {\n const networkValue = await this.fetchEvalFromNetwork(flagKey, normalizedUser, defaultValue);\n if (networkValue !== null) {\n const item = this.cache.get(this.getCacheKey(flagKey));\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'network',\n isStale: false,\n latencyMs: monotonicNow() - started,\n source: 'network',\n updatedAt: item?.updatedAt,\n staleAt: item?.staleAt,\n expiresAt: item?.expiresAt\n };\n this.emitMetric('ff_cache_hit_ratio', 0, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'network'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: networkValue, metadata };\n }\n } catch {\n // Fall through to deterministic default for outage semantics.\n }\n\n const metadata: FeatureFlareEvaluationMetadata = {\n reason: 'default',\n isStale: false,\n latencyMs: monotonicNow() - started,\n source: 'default'\n };\n this.emitMetric('ff_cache_hit_ratio', 0, { env: this.envKey, source: metadata.reason });\n this.emitMetric('ff_eval_latency_ms', metadata.latencyMs, {\n env: this.envKey,\n source: metadata.source,\n result: 'default'\n });\n this.diagnostics.set(this.getCacheKey(flagKey), metadata);\n return { value: defaultValue, metadata };\n }\n\n async bool(flagKey: string, user: FeatureFlareUserPayload, defaultValue = false): Promise<boolean> {\n const result = await this.evaluate(flagKey, user, defaultValue);\n return result.value;\n }\n\n async flags(user: FeatureFlareUserPayload, defaultValue = false): Promise<Array<{ key: string; value: boolean }>> {\n await this.ensurePersistentLoaded();\n const normalizedUser = this.normalizeUser(user);\n this.lastUser = normalizedUser;\n this.lastDefaultValue = defaultValue;\n\n const list = await this.revalidate(normalizedUser, defaultValue);\n if (list && list.length > 0) {\n return list.map((entry) => ({\n key: entry.key,\n value: this.killSwitches.has(entry.key) ? false : entry.value\n }));\n }\n\n const cached = this.collectCachedFlags();\n if (cached.length > 0) return cached;\n return [];\n }\n\n private applyRealtimeMessage(message: RealtimeEventPayload): void {\n if (typeof message.revision === 'number' && message.revision < this.revision) {\n return;\n }\n\n if (typeof message.revision === 'number') {\n this.revision = message.revision;\n }\n\n const changed = new Set<string>();\n const now = Date.now();\n\n if (message.type === 'flag.updated') {\n const flagKey = typeof message.data?.flagKey === 'string' ? message.data.flagKey : null;\n const value = typeof message.data?.value === 'boolean' ? message.data.value : null;\n if (flagKey !== null && value !== null) {\n this.setCacheItem(flagKey, value, 'realtime', message.revision ?? this.revision, now);\n changed.add(flagKey);\n }\n }\n\n if (message.type === 'flag.deleted') {\n const flagKey = typeof message.data?.flagKey === 'string' ? message.data.flagKey : null;\n if (flagKey !== null) {\n this.cache.delete(this.getCacheKey(flagKey));\n changed.add(flagKey);\n }\n }\n\n if (message.type === 'env.kill_switch.updated') {\n const started = monotonicNow();\n const flagKey = typeof message.data?.flagKey === 'string' ? message.data.flagKey : null;\n const enabled = typeof message.data?.enabled === 'boolean' ? message.data.enabled : true;\n if (flagKey !== null) {\n if (enabled) {\n this.killSwitches.add(flagKey);\n } else {\n this.killSwitches.delete(flagKey);\n }\n changed.add(flagKey);\n this.emitMetric('ff_killswitch_apply_latency_ms', monotonicNow() - started, {\n env: this.envKey,\n transport: this.eventSource ? 'sse' : 'polling',\n result: enabled ? 'enabled' : 'disabled'\n });\n }\n }\n\n if (message.type === 'snapshot.invalidate' && this.lastUser) {\n void this.fetchFlagsFromNetwork(this.lastUser, this.lastDefaultValue, 'network');\n }\n\n const eventLagMs = Math.max(0, Date.now() - (message.timestamp ?? Date.now()));\n this.emitMetric('ff_realtime_lag_ms', eventLagMs, {\n env: this.envKey,\n transport: this.eventSource ? 'sse' : 'polling'\n });\n\n if (changed.size > 0) {\n this.emit('update', { changedKeys: [...changed], source: 'realtime' });\n void this.persistCache();\n }\n }\n\n private isRealtimeWindowActive(): boolean {\n if (typeof document !== 'undefined' && document.hidden) {\n return false;\n }\n\n if (typeof document !== 'undefined' && typeof document.hasFocus === 'function') {\n return document.hasFocus();\n }\n\n return true;\n }\n\n private attachRealtimeVisibilityListeners(): void {\n if (this.visibilityListenersAttached) return;\n\n if (typeof document !== 'undefined' && typeof document.addEventListener === 'function') {\n document.addEventListener('visibilitychange', this.handleRealtimeVisibilityChange);\n this.visibilityListenersAttached = true;\n }\n\n if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {\n window.addEventListener('focus', this.handleRealtimeVisibilityChange);\n window.addEventListener('blur', this.handleRealtimeVisibilityChange);\n this.visibilityListenersAttached = true;\n }\n\n if (this.visibilityListenersAttached) {\n this.handleRealtimeVisibilityChange();\n }\n }\n\n private detachRealtimeVisibilityListeners(): void {\n if (!this.visibilityListenersAttached) return;\n\n if (typeof document !== 'undefined' && typeof document.removeEventListener === 'function') {\n document.removeEventListener('visibilitychange', this.handleRealtimeVisibilityChange);\n }\n\n if (typeof window !== 'undefined' && typeof window.removeEventListener === 'function') {\n window.removeEventListener('focus', this.handleRealtimeVisibilityChange);\n window.removeEventListener('blur', this.handleRealtimeVisibilityChange);\n }\n\n this.visibilityListenersAttached = false;\n this.realtimePausedByVisibility = false;\n }\n\n private clearRealtimeTransport(): void {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n }\n\n private startPolling(): void {\n if (this.realtimePausedByVisibility) return;\n\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n\n const tick = async () => {\n if (this.realtimePausedByVisibility || !this.realtimeEnabled) {\n this.pollTimer = null;\n return;\n }\n if (!this.lastUser) {\n this.pollTimer = setTimeout(tick, this.realtimePollingMs);\n return;\n }\n await this.fetchFlagsFromNetwork(this.lastUser, this.lastDefaultValue, 'polling');\n this.pollTimer = setTimeout(tick, this.realtimePollingMs);\n };\n\n this.pollTimer = setTimeout(tick, this.realtimePollingMs);\n }\n\n private connectSse(attempt = 0): void {\n if (this.realtimePausedByVisibility || !this.realtimeEnabled) {\n return;\n }\n\n const EventSourceImpl = typeof EventSource !== 'undefined' ? EventSource : null;\n if (!EventSourceImpl || !this.sdkKey) {\n this.emit('connectionState', { state: 'degraded', transport: 'polling' });\n this.startPolling();\n return;\n }\n\n const url = new URL(this.realtimeSsePath, this.apiBaseUrl);\n url.searchParams.set('sdkKey', this.sdkKey);\n if (this.expectedEnvKey) {\n url.searchParams.set('expectedEnvKey', this.expectedEnvKey);\n }\n\n this.eventSource = new EventSourceImpl(url.toString());\n\n this.eventSource.onopen = () => {\n this.emit('connectionState', { state: 'connected', transport: 'sse' });\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n };\n\n this.eventSource.onmessage = (event: MessageEvent) => {\n try {\n const payload = JSON.parse(String(event.data)) as RealtimeEventPayload;\n this.applyRealtimeMessage(payload);\n } catch {\n // Ignore malformed realtime messages.\n }\n };\n\n this.eventSource.onerror = () => {\n if (this.realtimePausedByVisibility || !this.realtimeEnabled) {\n this.clearRealtimeTransport();\n this.emit('connectionState', { state: 'offline', transport: 'none' });\n return;\n }\n\n this.emit('connectionState', { state: 'degraded', transport: 'polling' });\n this.eventSource?.close();\n this.eventSource = null;\n this.startPolling();\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n }\n const backoff = Math.min(this.backoffMs * (attempt + 1), 30000);\n this.reconnectTimer = setTimeout(() => {\n this.connectSse(attempt + 1);\n }, backoff);\n };\n }\n\n startRealtime(): void {\n this.realtimeEnabled = true;\n this.attachRealtimeVisibilityListeners();\n if (this.realtimePausedByVisibility) {\n this.emit('connectionState', { state: 'offline', transport: 'none' });\n return;\n }\n this.connectSse(0);\n }\n\n stopRealtime(): void {\n this.realtimeEnabled = false;\n this.detachRealtimeVisibilityListeners();\n this.clearRealtimeTransport();\n this.emit('connectionState', { state: 'offline', transport: 'none' });\n }\n\n /**\n * Report observed error metrics (error rate, latency) for a flag back to the FeatureFlare API.\n * The API evaluates the report against active rollback policies and may trigger an automated\n * rollback if configured thresholds are breached.\n *\n * Errors from this call are silently swallowed so that reporting never disrupts the host application.\n */\n async reportError(report: FeatureFlareErrorReport): Promise<void> {\n if (!this.sdkKey) return;\n try {\n await fetch(`${this.apiBaseUrl}/api/v1/sdk/report`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-featureflare-sdk-key': this.sdkKey\n },\n body: JSON.stringify({\n flagKey: report.flagKey,\n errorRate: report.errorRate,\n latencyMs: report.latencyMs,\n observedAt: report.observedAt ?? new Date().toISOString(),\n envKey: this.envKey,\n context: report.context\n })\n });\n } catch {\n // Reporting failures must never surface to the caller.\n }\n }\n\n dispose(): void {\n this.stopRealtime();\n this.listeners.update.clear();\n this.listeners.circuitOpen.clear();\n this.listeners.circuitClose.clear();\n this.listeners.connectionState.clear();\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@featureflare/sdk-js",
3
- "version": "0.0.34",
3
+ "version": "0.0.36",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"