@togglely/sdk 1.2.2 → 1.2.3

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.umd.js CHANGED
@@ -27,6 +27,11 @@
27
27
  };
28
28
  this.eventHandlers = new Map();
29
29
  this.offlineTogglesLoaded = false;
30
+ // Request batching
31
+ this.pendingKeys = new Set();
32
+ this.pendingPromises = new Map();
33
+ this.batchTimeout = null;
34
+ this.BATCH_DELAY = 10; // ms to wait for batching requests
30
35
  this.config = {
31
36
  timeout: 5000,
32
37
  offlineFallback: true,
@@ -167,82 +172,95 @@
167
172
  /**
168
173
  * Get raw toggle value
169
174
  * Uses stale-while-revalidate pattern: returns cached value immediately if available,
170
- * then refreshes from server in background
175
+ * then refreshes from server in background.
176
+ * Uses request batching: multiple getValue() calls within a short timeframe are batched into a single request.
171
177
  * @param key - The flag key
172
178
  * @returns Promise<ToggleValue | null>
173
179
  */
174
180
  async getValue(key) {
175
- // Check if we have a cached/offline value first (stale-while-revalidate pattern)
181
+ // Check if we have a cached value first (stale-while-revalidate pattern)
176
182
  const cachedValue = this.toggles.get(key);
177
- // Fetch from server in background (don't await if we have cached data)
178
- const fetchFromServer = async () => {
179
- try {
180
- const data = await this.fetchValueFromServer(key);
181
- if (data !== null) {
182
- this.toggles.set(key, data);
183
- }
184
- return data;
185
- }
186
- catch {
187
- // Silently fail - we already returned the cached value or will handle below
188
- return null;
189
- }
190
- };
191
- // If we have a cached value, return it immediately and update in background
192
183
  if (cachedValue !== undefined) {
193
- // Trigger the fetch in background without awaiting
194
- fetchFromServer().catch(() => { });
184
+ // Trigger a background refresh without awaiting
185
+ this.scheduleBatchRefresh();
195
186
  return cachedValue;
196
187
  }
197
- // No cached value - we need to wait for the server response
198
- const result = await fetchFromServer();
199
- if (result !== null) {
200
- return result;
188
+ // Check if there's already a pending promise for this key (deduplication)
189
+ const existingPromise = this.pendingPromises.get(key);
190
+ if (existingPromise) {
191
+ return new Promise((resolve, reject) => {
192
+ existingPromise.push({ resolve, reject });
193
+ });
201
194
  }
202
- // Try offline fallback
203
- if (this.config.offlineFallback) {
204
- const offlineValue = this.getOfflineToggle(key);
205
- if (offlineValue !== null) {
206
- return offlineValue;
207
- }
195
+ // Add key to batch and create a promise
196
+ this.pendingKeys.add(key);
197
+ return new Promise((resolve, reject) => {
198
+ // Store the promise callbacks
199
+ const promises = this.pendingPromises.get(key) || [];
200
+ promises.push({ resolve, reject });
201
+ this.pendingPromises.set(key, promises);
202
+ // Schedule the batch execution
203
+ this.scheduleBatchExecution();
204
+ });
205
+ }
206
+ /**
207
+ * Schedule a background refresh of all toggles (for stale-while-revalidate)
208
+ */
209
+ scheduleBatchRefresh() {
210
+ if (this.batchTimeout) {
211
+ return; // Already scheduled
208
212
  }
209
- // Return safe default
210
- return { value: false, enabled: false };
213
+ this.batchTimeout = setTimeout(() => {
214
+ this.batchTimeout = null;
215
+ // Refresh all toggles in background
216
+ this.refresh().catch(() => { });
217
+ }, this.BATCH_DELAY);
211
218
  }
212
219
  /**
213
- * Internal method to fetch a single toggle value from the server
220
+ * Schedule the batch execution for pending keys
214
221
  */
215
- async fetchValueFromServer(key) {
216
- const params = new URLSearchParams();
217
- // Support both brandKey and tenantId for maximum compatibility
218
- if (this.context.brandKey)
219
- params.set('brandKey', String(this.context.brandKey));
220
- if (this.context.tenantId)
221
- params.set('tenantId', String(this.context.tenantId));
222
- if (Object.keys(this.context).length > 0) {
223
- params.set('context', JSON.stringify(this.context));
222
+ scheduleBatchExecution() {
223
+ if (this.batchTimeout) {
224
+ return; // Already scheduled
224
225
  }
225
- const query = params.toString() ? `?${params.toString()}` : '';
226
- const url = `${this.config.baseUrl}/sdk/flags/${encodeURIComponent(this.config.project)}/${encodeURIComponent(this.config.environment)}/${encodeURIComponent(key)}${query}`;
227
- const headers = {
228
- 'Content-Type': 'application/json'
229
- };
230
- if (this.config.apiKey) {
231
- headers['Authorization'] = `Bearer ${this.config.apiKey}`;
226
+ this.batchTimeout = setTimeout(() => {
227
+ this.executeBatch();
228
+ }, this.BATCH_DELAY);
229
+ }
230
+ /**
231
+ * Execute the batch: fetch all pending keys in a single request
232
+ */
233
+ async executeBatch() {
234
+ this.batchTimeout = null;
235
+ const keys = Array.from(this.pendingKeys);
236
+ const promises = new Map(this.pendingPromises);
237
+ // Clear pending collections
238
+ this.pendingKeys.clear();
239
+ this.pendingPromises.clear();
240
+ if (keys.length === 0) {
241
+ return;
232
242
  }
233
- const response = await this.fetchWithTimeout(url, { headers });
234
- if (!response.ok) {
235
- if (response.status === 404) {
236
- return null;
243
+ try {
244
+ // Fetch all toggles at once (more efficient than individual requests)
245
+ await this.refresh();
246
+ // Resolve all pending promises with the fetched values
247
+ for (const key of keys) {
248
+ const keyPromises = promises.get(key) || [];
249
+ const value = this.toggles.get(key) || null;
250
+ for (const { resolve } of keyPromises) {
251
+ resolve(value);
252
+ }
237
253
  }
238
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
239
254
  }
240
- const data = await response.json();
241
- if (this.state.isOffline) {
242
- this.state.isOffline = false;
243
- this.emit('online');
255
+ catch (error) {
256
+ // Reject all pending promises
257
+ for (const key of keys) {
258
+ const keyPromises = promises.get(key) || [];
259
+ for (const { reject } of keyPromises) {
260
+ reject(error);
261
+ }
262
+ }
244
263
  }
245
- return data;
246
264
  }
247
265
  /**
248
266
  * Get all toggles
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../../core/dist/index.esm.js","../src/index.ts"],"sourcesContent":["/**\n * Togglely Core SDK - Framework agnostic feature flag management\n *\n * Features:\n * - Real-time feature flag evaluation\n * - Offline fallback via JSON file, environment variables, or window object\n * - Multi-brand/tenant support\n * - Type-safe flag access\n * - Build-time JSON generation for offline-first deployment\n */\n// ==================== Togglely Client ====================\nclass TogglelyClient {\n constructor(config) {\n this.toggles = new Map();\n this.context = {};\n this.state = {\n isReady: false,\n isOffline: false,\n lastError: null,\n lastFetch: null\n };\n this.eventHandlers = new Map();\n this.offlineTogglesLoaded = false;\n this.config = {\n timeout: 5000,\n offlineFallback: true,\n envPrefix: 'TOGGLELY_',\n autoFetch: true,\n offlineJsonPath: undefined,\n ...config\n };\n // Initialize event handlers\n this.eventHandlers.set('ready', new Set());\n this.eventHandlers.set('update', new Set());\n this.eventHandlers.set('error', new Set());\n this.eventHandlers.set('offline', new Set());\n this.eventHandlers.set('online', new Set());\n // Set initial context if provided (including brandKey/tenantId)\n const initialContext = { ...config.context };\n if (config.brandKey)\n initialContext.brandKey = config.brandKey;\n if (config.tenantId)\n initialContext.tenantId = config.tenantId;\n this.context = initialContext;\n // Load offline toggles first (if enabled)\n if (this.config.offlineFallback) {\n this.loadOfflineToggles();\n }\n // Initial fetch (if enabled)\n if (this.config.autoFetch) {\n this.refresh();\n }\n }\n // ==================== Event Handling ====================\n on(event, handler) {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.add(handler);\n }\n return () => this.off(event, handler);\n }\n off(event, handler) {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler);\n }\n }\n emit(event) {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.forEach(handler => handler({ ...this.state }));\n }\n }\n // ==================== Context ====================\n setContext(context) {\n this.context = { ...this.context, ...context };\n }\n getContext() {\n return { ...this.context };\n }\n clearContext() {\n this.context = {};\n }\n // ==================== State ====================\n getState() {\n return { ...this.state };\n }\n isReady() {\n return this.state.isReady;\n }\n isOffline() {\n return this.state.isOffline;\n }\n // ==================== Toggle Accessors ====================\n /**\n * Check if a boolean feature flag is enabled\n * @param key - The flag key\n * @param defaultValue - Default value if flag not found\n * @returns Promise<boolean>\n */\n async isEnabled(key, defaultValue = false) {\n const value = await this.getValue(key);\n if (value === null) {\n return defaultValue;\n }\n // enabled is the primary on/off switch for a flag.\n // value.value holds the flag's configured value (used for non-boolean use-cases).\n // For boolean flags: \n // - If NOT enabled (toggle is OFF globally for environment), return false\n // - If ENABLED (toggle is ON), return the boolean value itself (true/false)\n if (typeof value.value === 'boolean') {\n return value.enabled && value.value;\n }\n // Fallback for non-boolean flags or if value is missing\n return value.enabled;\n }\n /**\n * Get a string feature flag value\n * @param key - The flag key\n * @param defaultValue - Default value if flag not found or disabled\n * @returns Promise<string>\n */\n async getString(key, defaultValue = '') {\n const value = await this.getValue(key);\n if (value === null || !value.enabled)\n return defaultValue;\n return String(value.value);\n }\n /**\n * Get a number feature flag value\n * @param key - The flag key\n * @param defaultValue - Default value if flag not found or disabled\n * @returns Promise<number>\n */\n async getNumber(key, defaultValue = 0) {\n const value = await this.getValue(key);\n if (value === null || !value.enabled)\n return defaultValue;\n return Number(value.value);\n }\n /**\n * Get a JSON feature flag value\n * @param key - The flag key\n * @param defaultValue - Default value if flag not found or disabled\n * @returns Promise<T>\n */\n async getJSON(key, defaultValue = {}) {\n const value = await this.getValue(key);\n if (value === null || !value.enabled)\n return defaultValue;\n if (typeof value.value === 'string') {\n try {\n return JSON.parse(value.value);\n }\n catch {\n return defaultValue;\n }\n }\n return value.value;\n }\n /**\n * Get raw toggle value\n * Uses stale-while-revalidate pattern: returns cached value immediately if available,\n * then refreshes from server in background\n * @param key - The flag key\n * @returns Promise<ToggleValue | null>\n */\n async getValue(key) {\n // Check if we have a cached/offline value first (stale-while-revalidate pattern)\n const cachedValue = this.toggles.get(key);\n // Fetch from server in background (don't await if we have cached data)\n const fetchFromServer = async () => {\n try {\n const data = await this.fetchValueFromServer(key);\n if (data !== null) {\n this.toggles.set(key, data);\n }\n return data;\n }\n catch {\n // Silently fail - we already returned the cached value or will handle below\n return null;\n }\n };\n // If we have a cached value, return it immediately and update in background\n if (cachedValue !== undefined) {\n // Trigger the fetch in background without awaiting\n fetchFromServer().catch(() => { });\n return cachedValue;\n }\n // No cached value - we need to wait for the server response\n const result = await fetchFromServer();\n if (result !== null) {\n return result;\n }\n // Try offline fallback\n if (this.config.offlineFallback) {\n const offlineValue = this.getOfflineToggle(key);\n if (offlineValue !== null) {\n return offlineValue;\n }\n }\n // Return safe default\n return { value: false, enabled: false };\n }\n /**\n * Internal method to fetch a single toggle value from the server\n */\n async fetchValueFromServer(key) {\n const params = new URLSearchParams();\n // Support both brandKey and tenantId for maximum compatibility\n if (this.context.brandKey)\n params.set('brandKey', String(this.context.brandKey));\n if (this.context.tenantId)\n params.set('tenantId', String(this.context.tenantId));\n if (Object.keys(this.context).length > 0) {\n params.set('context', JSON.stringify(this.context));\n }\n const query = params.toString() ? `?${params.toString()}` : '';\n const url = `${this.config.baseUrl}/sdk/flags/${encodeURIComponent(this.config.project)}/${encodeURIComponent(this.config.environment)}/${encodeURIComponent(key)}${query}`;\n const headers = {\n 'Content-Type': 'application/json'\n };\n if (this.config.apiKey) {\n headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n }\n const response = await this.fetchWithTimeout(url, { headers });\n if (!response.ok) {\n if (response.status === 404) {\n return null;\n }\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n const data = await response.json();\n if (this.state.isOffline) {\n this.state.isOffline = false;\n this.emit('online');\n }\n return data;\n }\n /**\n * Get all toggles\n * @returns Record<string, ToggleValue>\n */\n getAllToggles() {\n const result = {};\n this.toggles.forEach((value, key) => {\n result[key] = value;\n });\n return result;\n }\n // ==================== Offline Fallback ====================\n /**\n * Load offline toggles from multiple sources (in priority order):\n * 1. Inline offlineToggles from config\n * 2. JSON file (if offlineJsonPath is set)\n * 3. window.__TOGGLELY_TOGGLES (browser)\n * 4. Environment variables (Node.js)\n */\n loadOfflineToggles() {\n try {\n // Priority 1: Inline offline toggles from config\n if (this.config.offlineToggles && Object.keys(this.config.offlineToggles).length > 0) {\n for (const [key, value] of Object.entries(this.config.offlineToggles)) {\n this.toggles.set(key, value);\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from config');\n return;\n }\n // Priority 2: JSON file (browser only - fetch synchronously not possible, will try async)\n if (this.config.offlineJsonPath && typeof window !== 'undefined') {\n this.loadOfflineJsonFile(this.config.offlineJsonPath);\n }\n // Priority 3: Browser environment - check window.__TOGGLELY_TOGGLES\n if (typeof window !== 'undefined' && window.__TOGGLELY_TOGGLES) {\n const offlineToggles = window.__TOGGLELY_TOGGLES;\n for (const [key, value] of Object.entries(offlineToggles)) {\n this.toggles.set(key, this.parseOfflineValue(value));\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from window.__TOGGLELY_TOGGLES');\n return;\n }\n // Priority 4: Node.js / Bun / Deno environment - check process.env\n if (typeof process !== 'undefined' && process.env) {\n const prefix = this.config.envPrefix;\n for (const [envKey, envValue] of Object.entries(process.env)) {\n if (envKey?.startsWith(prefix) && envValue !== undefined) {\n const toggleKey = envKey\n .slice(prefix.length)\n .toLowerCase()\n .replace(/_/g, '-');\n this.toggles.set(toggleKey, this.parseOfflineValue(envValue));\n }\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from environment variables');\n }\n }\n catch (error) {\n console.warn('[Togglely] Failed to load offline toggles:', error);\n }\n }\n /**\n * Load offline toggles from JSON file (async)\n */\n async loadOfflineJsonFile(path) {\n try {\n if (typeof window !== 'undefined') {\n // Browser - fetch the JSON file\n const response = await fetch(path);\n if (response.ok) {\n const data = await response.json();\n for (const [key, value] of Object.entries(data)) {\n this.toggles.set(key, this.parseOfflineValue(value));\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from JSON file:', path);\n }\n }\n else if (typeof require !== 'undefined') {\n // Node.js - require the JSON file\n const fs = require('fs');\n const pathModule = require('path');\n const fullPath = pathModule.resolve(path);\n if (fs.existsSync(fullPath)) {\n const data = JSON.parse(fs.readFileSync(fullPath, 'utf-8'));\n for (const [key, value] of Object.entries(data)) {\n this.toggles.set(key, this.parseOfflineValue(value));\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from JSON file:', fullPath);\n }\n }\n }\n catch (error) {\n console.warn('[Togglely] Failed to load offline JSON file:', error);\n }\n }\n getOfflineToggle(key) {\n if (!this.config.offlineFallback)\n return null;\n const cached = this.toggles.get(key);\n if (cached) {\n if (!this.state.isOffline) {\n this.state.isOffline = true;\n this.emit('offline');\n }\n return cached;\n }\n return null;\n }\n parseOfflineValue(value) {\n if (typeof value === 'string') {\n const lower = value.toLowerCase();\n if (lower === 'true')\n return { value: true, enabled: true };\n if (lower === 'false')\n return { value: false, enabled: true };\n if (!isNaN(Number(value))) {\n return { value: Number(value), enabled: true };\n }\n try {\n const parsed = JSON.parse(value);\n return { value: parsed, enabled: true };\n }\n catch {\n return { value, enabled: true };\n }\n }\n return { value, enabled: true };\n }\n // ==================== Refresh / Polling ====================\n /**\n * Refresh all toggles from the server\n */\n async refresh() {\n try {\n const params = new URLSearchParams();\n // Support both brandKey and tenantId for maximum compatibility\n if (this.context.brandKey)\n params.set('brandKey', String(this.context.brandKey));\n if (this.context.tenantId)\n params.set('tenantId', String(this.context.tenantId));\n if (Object.keys(this.context).length > 0) {\n params.set('context', JSON.stringify(this.context));\n }\n const headers = {\n 'Content-Type': 'application/json'\n };\n if (this.config.apiKey) {\n headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n }\n const response = await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${encodeURIComponent(this.config.project)}/${encodeURIComponent(this.config.environment)}?${params.toString()}`, { headers });\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n const data = await response.json();\n this.toggles.clear();\n for (const [key, value] of Object.entries(data)) {\n this.toggles.set(key, value);\n }\n this.state.lastFetch = new Date();\n this.state.lastError = null;\n if (!this.state.isReady) {\n this.state.isReady = true;\n this.emit('ready');\n }\n if (this.state.isOffline) {\n this.state.isOffline = false;\n this.emit('online');\n }\n this.emit('update');\n }\n catch (error) {\n this.state.lastError = error;\n if (this.config.offlineFallback && this.offlineTogglesLoaded) {\n if (!this.state.isOffline) {\n this.state.isOffline = true;\n this.emit('offline');\n }\n }\n this.emit('error');\n console.error('[Togglely] Failed to refresh toggles:', error);\n }\n }\n forceOfflineMode() {\n this.state.isOffline = true;\n this.emit('offline');\n }\n forceOnlineMode() {\n this.state.isOffline = false;\n this.refresh();\n this.emit('online');\n }\n // ==================== Cleanup ====================\n destroy() {\n this.toggles.clear();\n this.eventHandlers.forEach(handlers => handlers.clear());\n }\n // ==================== Private Helpers ====================\n fetchWithTimeout(url, options) {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n reject(new Error('Request timeout'));\n }, this.config.timeout);\n fetch(url, options)\n .then(response => {\n clearTimeout(timeoutId);\n resolve(response);\n })\n .catch(error => {\n clearTimeout(timeoutId);\n reject(error);\n });\n });\n }\n}\n// ==================== Utility Functions ====================\n/**\n * Create a client-side toggle loader script\n * Use this to inject offline toggles into your HTML\n */\nfunction createOfflineTogglesScript(toggles) {\n return `<script>window.__TOGGLELY_TOGGLES = ${JSON.stringify(toggles)};</script>`;\n}\n/**\n * Helper to convert toggles to environment variables\n */\nfunction togglesToEnvVars(toggles, prefix = 'TOGGLELY_') {\n const envVars = {};\n for (const [key, value] of Object.entries(toggles)) {\n const envKey = prefix + key.toUpperCase().replace(/-/g, '_');\n envVars[envKey] = typeof value === 'object' ? JSON.stringify(value) : String(value);\n }\n return envVars;\n}\n\nexport { TogglelyClient, createOfflineTogglesScript, TogglelyClient as default, togglesToEnvVars };\n//# sourceMappingURL=index.esm.js.map\n",null],"names":[],"mappings":";;;;;;IAAA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,MAAM,cAAc,CAAC;IACrB,IAAI,WAAW,CAAC,MAAM,EAAE;IACxB,QAAQ,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE;IAChC,QAAQ,IAAI,CAAC,OAAO,GAAG,EAAE;IACzB,QAAQ,IAAI,CAAC,KAAK,GAAG;IACrB,YAAY,OAAO,EAAE,KAAK;IAC1B,YAAY,SAAS,EAAE,KAAK;IAC5B,YAAY,SAAS,EAAE,IAAI;IAC3B,YAAY,SAAS,EAAE;IACvB,SAAS;IACT,QAAQ,IAAI,CAAC,aAAa,GAAG,IAAI,GAAG,EAAE;IACtC,QAAQ,IAAI,CAAC,oBAAoB,GAAG,KAAK;IACzC,QAAQ,IAAI,CAAC,MAAM,GAAG;IACtB,YAAY,OAAO,EAAE,IAAI;IACzB,YAAY,eAAe,EAAE,IAAI;IACjC,YAAY,SAAS,EAAE,WAAW;IAClC,YAAY,SAAS,EAAE,IAAI;IAC3B,YAAY,eAAe,EAAE,SAAS;IACtC,YAAY,GAAG;IACf,SAAS;IACT;IACA,QAAQ,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;IAClD,QAAQ,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,GAAG,EAAE,CAAC;IACnD,QAAQ,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;IAClD,QAAQ,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,GAAG,EAAE,CAAC;IACpD,QAAQ,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,GAAG,EAAE,CAAC;IACnD;IACA,QAAQ,MAAM,cAAc,GAAG,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE;IACpD,QAAQ,IAAI,MAAM,CAAC,QAAQ;IAC3B,YAAY,cAAc,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ;IACrD,QAAQ,IAAI,MAAM,CAAC,QAAQ;IAC3B,YAAY,cAAc,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ;IACrD,QAAQ,IAAI,CAAC,OAAO,GAAG,cAAc;IACrC;IACA,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE;IACzC,YAAY,IAAI,CAAC,kBAAkB,EAAE;IACrC,QAAQ;IACR;IACA,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE;IACnC,YAAY,IAAI,CAAC,OAAO,EAAE;IAC1B,QAAQ;IACR,IAAI;IACJ;IACA,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE;IACvB,QAAQ,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;IACtD,QAAQ,IAAI,QAAQ,EAAE;IACtB,YAAY,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;IACjC,QAAQ;IACR,QAAQ,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC;IAC7C,IAAI;IACJ,IAAI,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE;IACxB,QAAQ,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;IACtD,QAAQ,IAAI,QAAQ,EAAE;IACtB,YAAY,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC;IACpC,QAAQ;IACR,IAAI;IACJ,IAAI,IAAI,CAAC,KAAK,EAAE;IAChB,QAAQ,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;IACtD,QAAQ,IAAI,QAAQ,EAAE;IACtB,YAAY,QAAQ,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IACnE,QAAQ;IACR,IAAI;IACJ;IACA,IAAI,UAAU,CAAC,OAAO,EAAE;IACxB,QAAQ,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,OAAO,EAAE;IACtD,IAAI;IACJ,IAAI,UAAU,GAAG;IACjB,QAAQ,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE;IAClC,IAAI;IACJ,IAAI,YAAY,GAAG;IACnB,QAAQ,IAAI,CAAC,OAAO,GAAG,EAAE;IACzB,IAAI;IACJ;IACA,IAAI,QAAQ,GAAG;IACf,QAAQ,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE;IAChC,IAAI;IACJ,IAAI,OAAO,GAAG;IACd,QAAQ,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO;IACjC,IAAI;IACJ,IAAI,SAAS,GAAG;IAChB,QAAQ,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS;IACnC,IAAI;IACJ;IACA;IACA;IACA;IACA;IACA;IACA;IACA,IAAI,MAAM,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,KAAK,EAAE;IAC/C,QAAQ,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;IAC9C,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE;IAC5B,YAAY,OAAO,YAAY;IAC/B,QAAQ;IACR;IACA;IACA;IACA;IACA;IACA,QAAQ,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE;IAC9C,YAAY,OAAO,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK;IAC/C,QAAQ;IACR;IACA,QAAQ,OAAO,KAAK,CAAC,OAAO;IAC5B,IAAI;IACJ;IACA;IACA;IACA;IACA;IACA;IACA,IAAI,MAAM,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,EAAE,EAAE;IAC5C,QAAQ,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;IAC9C,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO;IAC5C,YAAY,OAAO,YAAY;IAC/B,QAAQ,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;IAClC,IAAI;IACJ;IACA;IACA;IACA;IACA;IACA;IACA,IAAI,MAAM,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,CAAC,EAAE;IAC3C,QAAQ,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;IAC9C,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO;IAC5C,YAAY,OAAO,YAAY;IAC/B,QAAQ,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;IAClC,IAAI;IACJ;IACA;IACA;IACA;IACA;IACA;IACA,IAAI,MAAM,OAAO,CAAC,GAAG,EAAE,YAAY,GAAG,EAAE,EAAE;IAC1C,QAAQ,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;IAC9C,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO;IAC5C,YAAY,OAAO,YAAY;IAC/B,QAAQ,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE;IAC7C,YAAY,IAAI;IAChB,gBAAgB,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;IAC9C,YAAY;IACZ,YAAY,MAAM;IAClB,gBAAgB,OAAO,YAAY;IACnC,YAAY;IACZ,QAAQ;IACR,QAAQ,OAAO,KAAK,CAAC,KAAK;IAC1B,IAAI;IACJ;IACA;IACA;IACA;IACA;IACA;IACA;IACA,IAAI,MAAM,QAAQ,CAAC,GAAG,EAAE;IACxB;IACA,QAAQ,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;IACjD;IACA,QAAQ,MAAM,eAAe,GAAG,YAAY;IAC5C,YAAY,IAAI;IAChB,gBAAgB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC;IACjE,gBAAgB,IAAI,IAAI,KAAK,IAAI,EAAE;IACnC,oBAAoB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC;IAC/C,gBAAgB;IAChB,gBAAgB,OAAO,IAAI;IAC3B,YAAY;IACZ,YAAY,MAAM;IAClB;IACA,gBAAgB,OAAO,IAAI;IAC3B,YAAY;IACZ,QAAQ,CAAC;IACT;IACA,QAAQ,IAAI,WAAW,KAAK,SAAS,EAAE;IACvC;IACA,YAAY,eAAe,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9C,YAAY,OAAO,WAAW;IAC9B,QAAQ;IACR;IACA,QAAQ,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE;IAC9C,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE;IAC7B,YAAY,OAAO,MAAM;IACzB,QAAQ;IACR;IACA,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE;IACzC,YAAY,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC;IAC3D,YAAY,IAAI,YAAY,KAAK,IAAI,EAAE;IACvC,gBAAgB,OAAO,YAAY;IACnC,YAAY;IACZ,QAAQ;IACR;IACA,QAAQ,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE;IAC/C,IAAI;IACJ;IACA;IACA;IACA,IAAI,MAAM,oBAAoB,CAAC,GAAG,EAAE;IACpC,QAAQ,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE;IAC5C;IACA,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ;IACjC,YAAY,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjE,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ;IACjC,YAAY,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjE,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;IAClD,YAAY,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/D,QAAQ;IACR,QAAQ,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE;IACtE,QAAQ,MAAM,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACnL,QAAQ,MAAM,OAAO,GAAG;IACxB,YAAY,cAAc,EAAE;IAC5B,SAAS;IACT,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;IAChC,YAAY,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrE,QAAQ;IACR,QAAQ,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC;IACtE,QAAQ,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;IAC1B,YAAY,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;IACzC,gBAAgB,OAAO,IAAI;IAC3B,YAAY;IACZ,YAAY,MAAM,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IAC9E,QAAQ;IACR,QAAQ,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE;IAC1C,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE;IAClC,YAAY,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,KAAK;IACxC,YAAY,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC/B,QAAQ;IACR,QAAQ,OAAO,IAAI;IACnB,IAAI;IACJ;IACA;IACA;IACA;IACA,IAAI,aAAa,GAAG;IACpB,QAAQ,MAAM,MAAM,GAAG,EAAE;IACzB,QAAQ,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,KAAK;IAC7C,YAAY,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK;IAC/B,QAAQ,CAAC,CAAC;IACV,QAAQ,OAAO,MAAM;IACrB,IAAI;IACJ;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,IAAI,kBAAkB,GAAG;IACzB,QAAQ,IAAI;IACZ;IACA,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;IAClG,gBAAgB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE;IACvF,oBAAoB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC;IAChD,gBAAgB;IAChB,gBAAgB,IAAI,CAAC,oBAAoB,GAAG,IAAI;IAChD,gBAAgB,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC;IAC5E,gBAAgB;IAChB,YAAY;IACZ;IACA,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;IAC9E,gBAAgB,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;IACrE,YAAY;IACZ;IACA,YAAY,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,kBAAkB,EAAE;IAC5E,gBAAgB,MAAM,cAAc,GAAG,MAAM,CAAC,kBAAkB;IAChE,gBAAgB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE;IAC3E,oBAAoB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACxE,gBAAgB;IAChB,gBAAgB,IAAI,CAAC,oBAAoB,GAAG,IAAI;IAChD,gBAAgB,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC;IAC/F,gBAAgB;IAChB,YAAY;IACZ;IACA,YAAY,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE;IAC/D,gBAAgB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS;IACpD,gBAAgB,KAAK,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;IAC9E,oBAAoB,IAAI,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,QAAQ,KAAK,SAAS,EAAE;IAC9E,wBAAwB,MAAM,SAAS,GAAG;IAC1C,6BAA6B,KAAK,CAAC,MAAM,CAAC,MAAM;IAChD,6BAA6B,WAAW;IACxC,6BAA6B,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;IAC/C,wBAAwB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACrF,oBAAoB;IACpB,gBAAgB;IAChB,gBAAgB,IAAI,CAAC,oBAAoB,GAAG,IAAI;IAChD,gBAAgB,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC;IAC3F,YAAY;IACZ,QAAQ;IACR,QAAQ,OAAO,KAAK,EAAE;IACtB,YAAY,OAAO,CAAC,IAAI,CAAC,4CAA4C,EAAE,KAAK,CAAC;IAC7E,QAAQ;IACR,IAAI;IACJ;IACA;IACA;IACA,IAAI,MAAM,mBAAmB,CAAC,IAAI,EAAE;IACpC,QAAQ,IAAI;IACZ,YAAY,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;IAC/C;IACA,gBAAgB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC;IAClD,gBAAgB,IAAI,QAAQ,CAAC,EAAE,EAAE;IACjC,oBAAoB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE;IACtD,oBAAoB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;IACrE,wBAAwB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAC5E,oBAAoB;IACpB,oBAAoB,IAAI,CAAC,oBAAoB,GAAG,IAAI;IACpD,oBAAoB,OAAO,CAAC,GAAG,CAAC,mDAAmD,EAAE,IAAI,CAAC;IAC1F,gBAAgB;IAChB,YAAY;IACZ,iBAAiB,IAAI,OAAO,OAAO,KAAK,WAAW,EAAE;IACrD;IACA,gBAAgB,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IACxC,gBAAgB,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAClD,gBAAgB,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC;IACzD,gBAAgB,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;IAC7C,oBAAoB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC/E,oBAAoB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;IACrE,wBAAwB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAC5E,oBAAoB;IACpB,oBAAoB,IAAI,CAAC,oBAAoB,GAAG,IAAI;IACpD,oBAAoB,OAAO,CAAC,GAAG,CAAC,mDAAmD,EAAE,QAAQ,CAAC;IAC9F,gBAAgB;IAChB,YAAY;IACZ,QAAQ;IACR,QAAQ,OAAO,KAAK,EAAE;IACtB,YAAY,OAAO,CAAC,IAAI,CAAC,8CAA8C,EAAE,KAAK,CAAC;IAC/E,QAAQ;IACR,IAAI;IACJ,IAAI,gBAAgB,CAAC,GAAG,EAAE;IAC1B,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe;IACxC,YAAY,OAAO,IAAI;IACvB,QAAQ,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;IAC5C,QAAQ,IAAI,MAAM,EAAE;IACpB,YAAY,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE;IACvC,gBAAgB,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI;IAC3C,gBAAgB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;IACpC,YAAY;IACZ,YAAY,OAAO,MAAM;IACzB,QAAQ;IACR,QAAQ,OAAO,IAAI;IACnB,IAAI;IACJ,IAAI,iBAAiB,CAAC,KAAK,EAAE;IAC7B,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;IACvC,YAAY,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE;IAC7C,YAAY,IAAI,KAAK,KAAK,MAAM;IAChC,gBAAgB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE;IACrD,YAAY,IAAI,KAAK,KAAK,OAAO;IACjC,gBAAgB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE;IACtD,YAAY,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;IACvC,gBAAgB,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE;IAC9D,YAAY;IACZ,YAAY,IAAI;IAChB,gBAAgB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;IAChD,gBAAgB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;IACvD,YAAY;IACZ,YAAY,MAAM;IAClB,gBAAgB,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE;IAC/C,YAAY;IACZ,QAAQ;IACR,QAAQ,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE;IACvC,IAAI;IACJ;IACA;IACA;IACA;IACA,IAAI,MAAM,OAAO,GAAG;IACpB,QAAQ,IAAI;IACZ,YAAY,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE;IAChD;IACA,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ;IACrC,gBAAgB,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrE,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ;IACrC,gBAAgB,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrE,YAAY,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;IACtD,gBAAgB,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnE,YAAY;IACZ,YAAY,MAAM,OAAO,GAAG;IAC5B,gBAAgB,cAAc,EAAE;IAChC,aAAa;IACb,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;IACpC,gBAAgB,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACzE,YAAY;IACZ,YAAY,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC;IACxN,YAAY,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;IAC9B,gBAAgB,MAAM,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1D,YAAY;IACZ,YAAY,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE;IAC9C,YAAY,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;IAChC,YAAY,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;IAC7D,gBAAgB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC;IAC5C,YAAY;IACZ,YAAY,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE;IAC7C,YAAY,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI;IACvC,YAAY,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;IACrC,gBAAgB,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI;IACzC,gBAAgB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;IAClC,YAAY;IACZ,YAAY,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE;IACtC,gBAAgB,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,KAAK;IAC5C,gBAAgB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;IACnC,YAAY;IACZ,YAAY,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC/B,QAAQ;IACR,QAAQ,OAAO,KAAK,EAAE;IACtB,YAAY,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,KAAK;IACxC,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,IAAI,CAAC,oBAAoB,EAAE;IAC1E,gBAAgB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE;IAC3C,oBAAoB,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI;IAC/C,oBAAoB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;IACxC,gBAAgB;IAChB,YAAY;IACZ,YAAY,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;IAC9B,YAAY,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC;IACzE,QAAQ;IACR,IAAI;IACJ,IAAI,gBAAgB,GAAG;IACvB,QAAQ,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI;IACnC,QAAQ,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;IAC5B,IAAI;IACJ,IAAI,eAAe,GAAG;IACtB,QAAQ,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,KAAK;IACpC,QAAQ,IAAI,CAAC,OAAO,EAAE;IACtB,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC3B,IAAI;IACJ;IACA,IAAI,OAAO,GAAG;IACd,QAAQ,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;IAC5B,QAAQ,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;IAChE,IAAI;IACJ;IACA,IAAI,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE;IACnC,QAAQ,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;IAChD,YAAY,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM;IAC/C,gBAAgB,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACpD,YAAY,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;IACnC,YAAY,KAAK,CAAC,GAAG,EAAE,OAAO;IAC9B,iBAAiB,IAAI,CAAC,QAAQ,IAAI;IAClC,gBAAgB,YAAY,CAAC,SAAS,CAAC;IACvC,gBAAgB,OAAO,CAAC,QAAQ,CAAC;IACjC,YAAY,CAAC;IACb,iBAAiB,KAAK,CAAC,KAAK,IAAI;IAChC,gBAAgB,YAAY,CAAC,SAAS,CAAC;IACvC,gBAAgB,MAAM,CAAC,KAAK,CAAC;IAC7B,YAAY,CAAC,CAAC;IACd,QAAQ,CAAC,CAAC;IACV,IAAI;IACJ;IACA;IACA;IACA;IACA;IACA;IACA,SAAS,0BAA0B,CAAC,OAAO,EAAE;IAC7C,IAAI,OAAO,CAAC,oCAAoC,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC;IACrF;IACA;IACA;IACA;IACA,SAAS,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE;IACzD,IAAI,MAAM,OAAO,GAAG,EAAE;IACtB,IAAI,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;IACxD,QAAQ,MAAM,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;IACpE,QAAQ,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,KAAK,KAAK,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3F,IAAI;IACJ,IAAI,OAAO,OAAO;IAClB;;IC7dA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA6DG;IAEH;IAgBA;IAEA;;;IAGG;IACG,SAAU,YAAY,CAAC,MAAsB,EAAA;IACjD,IAAA,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC;;IAGzC,IAAA,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;IAChC,QAAA,MAAc,CAAC,QAAQ,GAAG,MAAM;QACnC;IAEA,IAAA,OAAO,MAAM;IACf;IAEA;;IAEG;aACa,iBAAiB,GAAA;IAC/B,IAAA,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;IACjC,QAAA,OAAQ,MAAc,CAAC,QAAQ,IAAI,IAAI;QACzC;IACA,IAAA,OAAO,IAAI;IACb;IAEA;;IAEG;IACI,eAAe,SAAS,CAAC,GAAW,EAAE,eAAwB,KAAK,EAAA;IACxE,IAAA,MAAM,MAAM,GAAG,iBAAiB,EAAE;QAClC,IAAI,CAAC,MAAM,EAAE;IACX,QAAA,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC;IAChF,QAAA,OAAO,YAAY;QACrB;QACA,OAAO,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,YAAY,CAAC;IAC5C;IAEA;;IAEG;IACI,eAAe,SAAS,CAAC,GAAW,EAAE,eAAuB,EAAE,EAAA;IACpE,IAAA,MAAM,MAAM,GAAG,iBAAiB,EAAE;QAClC,IAAI,CAAC,MAAM,EAAE;IACX,QAAA,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC;IAChF,QAAA,OAAO,YAAY;QACrB;QACA,OAAO,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,YAAY,CAAC;IAC5C;IAEA;;IAEG;IACI,eAAe,SAAS,CAAC,GAAW,EAAE,eAAuB,CAAC,EAAA;IACnE,IAAA,MAAM,MAAM,GAAG,iBAAiB,EAAE;QAClC,IAAI,CAAC,MAAM,EAAE;IACX,QAAA,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC;IAChF,QAAA,OAAO,YAAY;QACrB;QACA,OAAO,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,YAAY,CAAC;IAC5C;IAEA;;IAEG;IACI,eAAe,OAAO,CAAU,GAAW,EAAE,eAAkB,EAAO,EAAA;IAC3E,IAAA,MAAM,MAAM,GAAG,iBAAiB,EAAE;QAClC,IAAI,CAAC,MAAM,EAAE;IACX,QAAA,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC;IAChF,QAAA,OAAO,YAAY;QACrB;QACA,OAAO,MAAM,CAAC,OAAO,CAAI,GAAG,EAAE,YAAY,CAAC;IAC7C;IAEA;IAEA;;;;;;;;;;;IAWG;IACI,eAAe,cAAc,CAClC,QAAgB,EAChB,SAAiB,EACjB,OAAA,GAKI,EAAE,EAAA;IAEN,IAAA,MAAM,EACJ,YAAY,GAAG,KAAK,EACpB,MAAM,GAAG,KAAK,EACd,SAAS,GAAG,iBAAiB,EAC7B,SAAS,GAAG,kBAAkB,EAC/B,GAAG,OAAO;IAEX,IAAA,MAAM,MAAM,GAAG,iBAAiB,EAAE;QAClC,IAAI,CAAC,MAAM,EAAE;IACX,QAAA,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC;YAChF;QACF;QAEA,MAAM,eAAe,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,YAAY,CAAC;IACvE,IAAA,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,eAAe,GAAG,eAAe;QAE9D,MAAM,QAAQ,GAAG,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC;IACpD,IAAA,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAG;YACpB,IAAI,UAAU,EAAE;IACd,YAAA,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC;IAC9B,YAAA,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC;IAC1B,YAAA,EAAkB,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE;YACxC;iBAAO;IACL,YAAA,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC;IAC9B,YAAA,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC;IAC1B,YAAA,EAAkB,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM;YAC5C;IACF,IAAA,CAAC,CAAC;IACJ;IAEA;;;;;;;;;;;;IAYG;IACG,SAAU,YAAY,CAC1B,MAA0G,EAAA;IAE1G,IAAA,MAAM,MAAM,GAAG,iBAAiB,EAAE;QAClC,IAAI,CAAC,MAAM,EAAE;IACX,QAAA,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC;IAChF,QAAA,OAAO,MAAK,EAAE,CAAC;QACjB;IAEA,IAAA,MAAM,SAAS,GAAG,YAAW;IAC3B,QAAA,KAAK,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;IACvD,YAAA,IAAI,SAAmB;gBACvB,IAAI,YAAY,GAAG,KAAK;gBACxB,IAAI,MAAM,GAAG,KAAK;IAElB,YAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;IAC7B,gBAAA,SAAS,GAAG,CAAC,KAAK,CAAC;gBACrB;IAAO,iBAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;oBAC/B,SAAS,GAAG,KAAK;gBACnB;qBAAO;IACL,gBAAA,SAAS,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC5B,gBAAA,YAAY,GAAG,KAAK,CAAC,YAAY,IAAI,KAAK;IAC1C,gBAAA,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK;gBAChC;gBAEA,MAAM,eAAe,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,YAAY,CAAC;IACvE,YAAA,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,eAAe,GAAG,eAAe;IAE9D,YAAA,SAAS,CAAC,OAAO,CAAC,QAAQ,IAAG;oBAC3B,MAAM,QAAQ,GAAG,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC;IACpD,gBAAA,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAG;IACnB,oBAAA,EAAkB,CAAC,KAAK,CAAC,OAAO,GAAG,UAAU,GAAG,EAAE,GAAG,MAAM;IAC9D,gBAAA,CAAC,CAAC;IACJ,YAAA,CAAC,CAAC;YACJ;IACF,IAAA,CAAC;;IAGD,IAAA,SAAS,EAAE;;QAGX,MAAM,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;IAElD,IAAA,OAAO,WAAW;IACpB;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.umd.js","sources":["../../core/dist/index.esm.js","../src/index.ts"],"sourcesContent":["/**\n * Togglely Core SDK - Framework agnostic feature flag management\n *\n * Features:\n * - Real-time feature flag evaluation\n * - Offline fallback via JSON file, environment variables, or window object\n * - Multi-brand/tenant support\n * - Type-safe flag access\n * - Build-time JSON generation for offline-first deployment\n */\n// ==================== Togglely Client ====================\nclass TogglelyClient {\n constructor(config) {\n this.toggles = new Map();\n this.context = {};\n this.state = {\n isReady: false,\n isOffline: false,\n lastError: null,\n lastFetch: null\n };\n this.eventHandlers = new Map();\n this.offlineTogglesLoaded = false;\n // Request batching\n this.pendingKeys = new Set();\n this.pendingPromises = new Map();\n this.batchTimeout = null;\n this.BATCH_DELAY = 10; // ms to wait for batching requests\n this.config = {\n timeout: 5000,\n offlineFallback: true,\n envPrefix: 'TOGGLELY_',\n autoFetch: true,\n offlineJsonPath: undefined,\n ...config\n };\n // Initialize event handlers\n this.eventHandlers.set('ready', new Set());\n this.eventHandlers.set('update', new Set());\n this.eventHandlers.set('error', new Set());\n this.eventHandlers.set('offline', new Set());\n this.eventHandlers.set('online', new Set());\n // Set initial context if provided (including brandKey/tenantId)\n const initialContext = { ...config.context };\n if (config.brandKey)\n initialContext.brandKey = config.brandKey;\n if (config.tenantId)\n initialContext.tenantId = config.tenantId;\n this.context = initialContext;\n // Load offline toggles first (if enabled)\n if (this.config.offlineFallback) {\n this.loadOfflineToggles();\n }\n // Initial fetch (if enabled)\n if (this.config.autoFetch) {\n this.refresh();\n }\n }\n // ==================== Event Handling ====================\n on(event, handler) {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.add(handler);\n }\n return () => this.off(event, handler);\n }\n off(event, handler) {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler);\n }\n }\n emit(event) {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.forEach(handler => handler({ ...this.state }));\n }\n }\n // ==================== Context ====================\n setContext(context) {\n this.context = { ...this.context, ...context };\n }\n getContext() {\n return { ...this.context };\n }\n clearContext() {\n this.context = {};\n }\n // ==================== State ====================\n getState() {\n return { ...this.state };\n }\n isReady() {\n return this.state.isReady;\n }\n isOffline() {\n return this.state.isOffline;\n }\n // ==================== Toggle Accessors ====================\n /**\n * Check if a boolean feature flag is enabled\n * @param key - The flag key\n * @param defaultValue - Default value if flag not found\n * @returns Promise<boolean>\n */\n async isEnabled(key, defaultValue = false) {\n const value = await this.getValue(key);\n if (value === null) {\n return defaultValue;\n }\n // enabled is the primary on/off switch for a flag.\n // value.value holds the flag's configured value (used for non-boolean use-cases).\n // For boolean flags: \n // - If NOT enabled (toggle is OFF globally for environment), return false\n // - If ENABLED (toggle is ON), return the boolean value itself (true/false)\n if (typeof value.value === 'boolean') {\n return value.enabled && value.value;\n }\n // Fallback for non-boolean flags or if value is missing\n return value.enabled;\n }\n /**\n * Get a string feature flag value\n * @param key - The flag key\n * @param defaultValue - Default value if flag not found or disabled\n * @returns Promise<string>\n */\n async getString(key, defaultValue = '') {\n const value = await this.getValue(key);\n if (value === null || !value.enabled)\n return defaultValue;\n return String(value.value);\n }\n /**\n * Get a number feature flag value\n * @param key - The flag key\n * @param defaultValue - Default value if flag not found or disabled\n * @returns Promise<number>\n */\n async getNumber(key, defaultValue = 0) {\n const value = await this.getValue(key);\n if (value === null || !value.enabled)\n return defaultValue;\n return Number(value.value);\n }\n /**\n * Get a JSON feature flag value\n * @param key - The flag key\n * @param defaultValue - Default value if flag not found or disabled\n * @returns Promise<T>\n */\n async getJSON(key, defaultValue = {}) {\n const value = await this.getValue(key);\n if (value === null || !value.enabled)\n return defaultValue;\n if (typeof value.value === 'string') {\n try {\n return JSON.parse(value.value);\n }\n catch {\n return defaultValue;\n }\n }\n return value.value;\n }\n /**\n * Get raw toggle value\n * Uses stale-while-revalidate pattern: returns cached value immediately if available,\n * then refreshes from server in background.\n * Uses request batching: multiple getValue() calls within a short timeframe are batched into a single request.\n * @param key - The flag key\n * @returns Promise<ToggleValue | null>\n */\n async getValue(key) {\n // Check if we have a cached value first (stale-while-revalidate pattern)\n const cachedValue = this.toggles.get(key);\n if (cachedValue !== undefined) {\n // Trigger a background refresh without awaiting\n this.scheduleBatchRefresh();\n return cachedValue;\n }\n // Check if there's already a pending promise for this key (deduplication)\n const existingPromise = this.pendingPromises.get(key);\n if (existingPromise) {\n return new Promise((resolve, reject) => {\n existingPromise.push({ resolve, reject });\n });\n }\n // Add key to batch and create a promise\n this.pendingKeys.add(key);\n return new Promise((resolve, reject) => {\n // Store the promise callbacks\n const promises = this.pendingPromises.get(key) || [];\n promises.push({ resolve, reject });\n this.pendingPromises.set(key, promises);\n // Schedule the batch execution\n this.scheduleBatchExecution();\n });\n }\n /**\n * Schedule a background refresh of all toggles (for stale-while-revalidate)\n */\n scheduleBatchRefresh() {\n if (this.batchTimeout) {\n return; // Already scheduled\n }\n this.batchTimeout = setTimeout(() => {\n this.batchTimeout = null;\n // Refresh all toggles in background\n this.refresh().catch(() => { });\n }, this.BATCH_DELAY);\n }\n /**\n * Schedule the batch execution for pending keys\n */\n scheduleBatchExecution() {\n if (this.batchTimeout) {\n return; // Already scheduled\n }\n this.batchTimeout = setTimeout(() => {\n this.executeBatch();\n }, this.BATCH_DELAY);\n }\n /**\n * Execute the batch: fetch all pending keys in a single request\n */\n async executeBatch() {\n this.batchTimeout = null;\n const keys = Array.from(this.pendingKeys);\n const promises = new Map(this.pendingPromises);\n // Clear pending collections\n this.pendingKeys.clear();\n this.pendingPromises.clear();\n if (keys.length === 0) {\n return;\n }\n try {\n // Fetch all toggles at once (more efficient than individual requests)\n await this.refresh();\n // Resolve all pending promises with the fetched values\n for (const key of keys) {\n const keyPromises = promises.get(key) || [];\n const value = this.toggles.get(key) || null;\n for (const { resolve } of keyPromises) {\n resolve(value);\n }\n }\n }\n catch (error) {\n // Reject all pending promises\n for (const key of keys) {\n const keyPromises = promises.get(key) || [];\n for (const { reject } of keyPromises) {\n reject(error);\n }\n }\n }\n }\n /**\n * Get all toggles\n * @returns Record<string, ToggleValue>\n */\n getAllToggles() {\n const result = {};\n this.toggles.forEach((value, key) => {\n result[key] = value;\n });\n return result;\n }\n // ==================== Offline Fallback ====================\n /**\n * Load offline toggles from multiple sources (in priority order):\n * 1. Inline offlineToggles from config\n * 2. JSON file (if offlineJsonPath is set)\n * 3. window.__TOGGLELY_TOGGLES (browser)\n * 4. Environment variables (Node.js)\n */\n loadOfflineToggles() {\n try {\n // Priority 1: Inline offline toggles from config\n if (this.config.offlineToggles && Object.keys(this.config.offlineToggles).length > 0) {\n for (const [key, value] of Object.entries(this.config.offlineToggles)) {\n this.toggles.set(key, value);\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from config');\n return;\n }\n // Priority 2: JSON file (browser only - fetch synchronously not possible, will try async)\n if (this.config.offlineJsonPath && typeof window !== 'undefined') {\n this.loadOfflineJsonFile(this.config.offlineJsonPath);\n }\n // Priority 3: Browser environment - check window.__TOGGLELY_TOGGLES\n if (typeof window !== 'undefined' && window.__TOGGLELY_TOGGLES) {\n const offlineToggles = window.__TOGGLELY_TOGGLES;\n for (const [key, value] of Object.entries(offlineToggles)) {\n this.toggles.set(key, this.parseOfflineValue(value));\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from window.__TOGGLELY_TOGGLES');\n return;\n }\n // Priority 4: Node.js / Bun / Deno environment - check process.env\n if (typeof process !== 'undefined' && process.env) {\n const prefix = this.config.envPrefix;\n for (const [envKey, envValue] of Object.entries(process.env)) {\n if (envKey?.startsWith(prefix) && envValue !== undefined) {\n const toggleKey = envKey\n .slice(prefix.length)\n .toLowerCase()\n .replace(/_/g, '-');\n this.toggles.set(toggleKey, this.parseOfflineValue(envValue));\n }\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from environment variables');\n }\n }\n catch (error) {\n console.warn('[Togglely] Failed to load offline toggles:', error);\n }\n }\n /**\n * Load offline toggles from JSON file (async)\n */\n async loadOfflineJsonFile(path) {\n try {\n if (typeof window !== 'undefined') {\n // Browser - fetch the JSON file\n const response = await fetch(path);\n if (response.ok) {\n const data = await response.json();\n for (const [key, value] of Object.entries(data)) {\n this.toggles.set(key, this.parseOfflineValue(value));\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from JSON file:', path);\n }\n }\n else if (typeof require !== 'undefined') {\n // Node.js - require the JSON file\n const fs = require('fs');\n const pathModule = require('path');\n const fullPath = pathModule.resolve(path);\n if (fs.existsSync(fullPath)) {\n const data = JSON.parse(fs.readFileSync(fullPath, 'utf-8'));\n for (const [key, value] of Object.entries(data)) {\n this.toggles.set(key, this.parseOfflineValue(value));\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from JSON file:', fullPath);\n }\n }\n }\n catch (error) {\n console.warn('[Togglely] Failed to load offline JSON file:', error);\n }\n }\n getOfflineToggle(key) {\n if (!this.config.offlineFallback)\n return null;\n const cached = this.toggles.get(key);\n if (cached) {\n if (!this.state.isOffline) {\n this.state.isOffline = true;\n this.emit('offline');\n }\n return cached;\n }\n return null;\n }\n parseOfflineValue(value) {\n if (typeof value === 'string') {\n const lower = value.toLowerCase();\n if (lower === 'true')\n return { value: true, enabled: true };\n if (lower === 'false')\n return { value: false, enabled: true };\n if (!isNaN(Number(value))) {\n return { value: Number(value), enabled: true };\n }\n try {\n const parsed = JSON.parse(value);\n return { value: parsed, enabled: true };\n }\n catch {\n return { value, enabled: true };\n }\n }\n return { value, enabled: true };\n }\n // ==================== Refresh / Polling ====================\n /**\n * Refresh all toggles from the server\n */\n async refresh() {\n try {\n const params = new URLSearchParams();\n // Support both brandKey and tenantId for maximum compatibility\n if (this.context.brandKey)\n params.set('brandKey', String(this.context.brandKey));\n if (this.context.tenantId)\n params.set('tenantId', String(this.context.tenantId));\n if (Object.keys(this.context).length > 0) {\n params.set('context', JSON.stringify(this.context));\n }\n const headers = {\n 'Content-Type': 'application/json'\n };\n if (this.config.apiKey) {\n headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n }\n const response = await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${encodeURIComponent(this.config.project)}/${encodeURIComponent(this.config.environment)}?${params.toString()}`, { headers });\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n const data = await response.json();\n this.toggles.clear();\n for (const [key, value] of Object.entries(data)) {\n this.toggles.set(key, value);\n }\n this.state.lastFetch = new Date();\n this.state.lastError = null;\n if (!this.state.isReady) {\n this.state.isReady = true;\n this.emit('ready');\n }\n if (this.state.isOffline) {\n this.state.isOffline = false;\n this.emit('online');\n }\n this.emit('update');\n }\n catch (error) {\n this.state.lastError = error;\n if (this.config.offlineFallback && this.offlineTogglesLoaded) {\n if (!this.state.isOffline) {\n this.state.isOffline = true;\n this.emit('offline');\n }\n }\n this.emit('error');\n console.error('[Togglely] Failed to refresh toggles:', error);\n }\n }\n forceOfflineMode() {\n this.state.isOffline = true;\n this.emit('offline');\n }\n forceOnlineMode() {\n this.state.isOffline = false;\n this.refresh();\n this.emit('online');\n }\n // ==================== Cleanup ====================\n destroy() {\n this.toggles.clear();\n this.eventHandlers.forEach(handlers => handlers.clear());\n }\n // ==================== Private Helpers ====================\n fetchWithTimeout(url, options) {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n reject(new Error('Request timeout'));\n }, this.config.timeout);\n fetch(url, options)\n .then(response => {\n clearTimeout(timeoutId);\n resolve(response);\n })\n .catch(error => {\n clearTimeout(timeoutId);\n reject(error);\n });\n });\n }\n}\n// ==================== Utility Functions ====================\n/**\n * Create a client-side toggle loader script\n * Use this to inject offline toggles into your HTML\n */\nfunction createOfflineTogglesScript(toggles) {\n return `<script>window.__TOGGLELY_TOGGLES = ${JSON.stringify(toggles)};</script>`;\n}\n/**\n * Helper to convert toggles to environment variables\n */\nfunction togglesToEnvVars(toggles, prefix = 'TOGGLELY_') {\n const envVars = {};\n for (const [key, value] of Object.entries(toggles)) {\n const envKey = prefix + key.toUpperCase().replace(/-/g, '_');\n envVars[envKey] = typeof value === 'object' ? JSON.stringify(value) : String(value);\n }\n return envVars;\n}\n\nexport { TogglelyClient, createOfflineTogglesScript, TogglelyClient as default, togglesToEnvVars };\n//# sourceMappingURL=index.esm.js.map\n",null],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Flagify={})}(this,function(e){"use strict";class t{constructor(e){this.toggles=new Map,this.context={},this.state={isReady:!1,isOffline:!1,lastError:null,lastFetch:null},this.eventHandlers=new Map,this.offlineTogglesLoaded=!1,this.config={timeout:5e3,offlineFallback:!0,envPrefix:"TOGGLELY_",autoFetch:!0,offlineJsonPath:void 0,...e},this.eventHandlers.set("ready",new Set),this.eventHandlers.set("update",new Set),this.eventHandlers.set("error",new Set),this.eventHandlers.set("offline",new Set),this.eventHandlers.set("online",new Set);const t={...e.context};e.brandKey&&(t.brandKey=e.brandKey),e.tenantId&&(t.tenantId=e.tenantId),this.context=t,this.config.offlineFallback&&this.loadOfflineToggles(),this.config.autoFetch&&this.refresh()}on(e,t){const n=this.eventHandlers.get(e);return n&&n.add(t),()=>this.off(e,t)}off(e,t){const n=this.eventHandlers.get(e);n&&n.delete(t)}emit(e){const t=this.eventHandlers.get(e);t&&t.forEach(e=>e({...this.state}))}setContext(e){this.context={...this.context,...e}}getContext(){return{...this.context}}clearContext(){this.context={}}getState(){return{...this.state}}isReady(){return this.state.isReady}isOffline(){return this.state.isOffline}async isEnabled(e,t=!1){const n=await this.getValue(e);return null===n?t:"boolean"==typeof n.value?n.enabled&&n.value:n.enabled}async getString(e,t=""){const n=await this.getValue(e);return null!==n&&n.enabled?String(n.value):t}async getNumber(e,t=0){const n=await this.getValue(e);return null!==n&&n.enabled?Number(n.value):t}async getJSON(e,t={}){const n=await this.getValue(e);if(null===n||!n.enabled)return t;if("string"==typeof n.value)try{return JSON.parse(n.value)}catch{return t}return n.value}async getValue(e){const t=this.toggles.get(e),n=async()=>{try{const t=await this.fetchValueFromServer(e);return null!==t&&this.toggles.set(e,t),t}catch{return null}};if(void 0!==t)return n().catch(()=>{}),t;const o=await n();if(null!==o)return o;if(this.config.offlineFallback){const t=this.getOfflineToggle(e);if(null!==t)return t}return{value:!1,enabled:!1}}async fetchValueFromServer(e){const t=new URLSearchParams;this.context.brandKey&&t.set("brandKey",String(this.context.brandKey)),this.context.tenantId&&t.set("tenantId",String(this.context.tenantId)),Object.keys(this.context).length>0&&t.set("context",JSON.stringify(this.context));const n=t.toString()?`?${t.toString()}`:"",o=`${this.config.baseUrl}/sdk/flags/${encodeURIComponent(this.config.project)}/${encodeURIComponent(this.config.environment)}/${encodeURIComponent(e)}${n}`,s={"Content-Type":"application/json"};this.config.apiKey&&(s.Authorization=`Bearer ${this.config.apiKey}`);const i=await this.fetchWithTimeout(o,{headers:s});if(!i.ok){if(404===i.status)return null;throw new Error(`HTTP ${i.status}: ${i.statusText}`)}const l=await i.json();return this.state.isOffline&&(this.state.isOffline=!1,this.emit("online")),l}getAllToggles(){const e={};return this.toggles.forEach((t,n)=>{e[n]=t}),e}loadOfflineToggles(){try{if(this.config.offlineToggles&&Object.keys(this.config.offlineToggles).length>0){for(const[e,t]of Object.entries(this.config.offlineToggles))this.toggles.set(e,t);return this.offlineTogglesLoaded=!0,void console.log("[Togglely] Loaded offline toggles from config")}if(this.config.offlineJsonPath&&"undefined"!=typeof window&&this.loadOfflineJsonFile(this.config.offlineJsonPath),"undefined"!=typeof window&&window.__TOGGLELY_TOGGLES){const e=window.__TOGGLELY_TOGGLES;for(const[t,n]of Object.entries(e))this.toggles.set(t,this.parseOfflineValue(n));return this.offlineTogglesLoaded=!0,void console.log("[Togglely] Loaded offline toggles from window.__TOGGLELY_TOGGLES")}if("undefined"!=typeof process&&process.env){const e=this.config.envPrefix;for(const[t,n]of Object.entries(process.env))if(t?.startsWith(e)&&void 0!==n){const o=t.slice(e.length).toLowerCase().replace(/_/g,"-");this.toggles.set(o,this.parseOfflineValue(n))}this.offlineTogglesLoaded=!0,console.log("[Togglely] Loaded offline toggles from environment variables")}}catch(e){console.warn("[Togglely] Failed to load offline toggles:",e)}}async loadOfflineJsonFile(e){try{if("undefined"!=typeof window){const t=await fetch(e);if(t.ok){const n=await t.json();for(const[e,t]of Object.entries(n))this.toggles.set(e,this.parseOfflineValue(t));this.offlineTogglesLoaded=!0,console.log("[Togglely] Loaded offline toggles from JSON file:",e)}}else if("undefined"!=typeof require){const t=require("fs"),n=require("path").resolve(e);if(t.existsSync(n)){const e=JSON.parse(t.readFileSync(n,"utf-8"));for(const[t,n]of Object.entries(e))this.toggles.set(t,this.parseOfflineValue(n));this.offlineTogglesLoaded=!0,console.log("[Togglely] Loaded offline toggles from JSON file:",n)}}}catch(e){console.warn("[Togglely] Failed to load offline JSON file:",e)}}getOfflineToggle(e){if(!this.config.offlineFallback)return null;const t=this.toggles.get(e);return t?(this.state.isOffline||(this.state.isOffline=!0,this.emit("offline")),t):null}parseOfflineValue(e){if("string"==typeof e){const t=e.toLowerCase();if("true"===t)return{value:!0,enabled:!0};if("false"===t)return{value:!1,enabled:!0};if(!isNaN(Number(e)))return{value:Number(e),enabled:!0};try{return{value:JSON.parse(e),enabled:!0}}catch{return{value:e,enabled:!0}}}return{value:e,enabled:!0}}async refresh(){try{const e=new URLSearchParams;this.context.brandKey&&e.set("brandKey",String(this.context.brandKey)),this.context.tenantId&&e.set("tenantId",String(this.context.tenantId)),Object.keys(this.context).length>0&&e.set("context",JSON.stringify(this.context));const t={"Content-Type":"application/json"};this.config.apiKey&&(t.Authorization=`Bearer ${this.config.apiKey}`);const n=await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${encodeURIComponent(this.config.project)}/${encodeURIComponent(this.config.environment)}?${e.toString()}`,{headers:t});if(!n.ok)throw new Error(`HTTP ${n.status}`);const o=await n.json();this.toggles.clear();for(const[e,t]of Object.entries(o))this.toggles.set(e,t);this.state.lastFetch=new Date,this.state.lastError=null,this.state.isReady||(this.state.isReady=!0,this.emit("ready")),this.state.isOffline&&(this.state.isOffline=!1,this.emit("online")),this.emit("update")}catch(e){this.state.lastError=e,this.config.offlineFallback&&this.offlineTogglesLoaded&&(this.state.isOffline||(this.state.isOffline=!0,this.emit("offline"))),this.emit("error"),console.error("[Togglely] Failed to refresh toggles:",e)}}forceOfflineMode(){this.state.isOffline=!0,this.emit("offline")}forceOnlineMode(){this.state.isOffline=!1,this.refresh(),this.emit("online")}destroy(){this.toggles.clear(),this.eventHandlers.forEach(e=>e.clear())}fetchWithTimeout(e,t){return new Promise((n,o)=>{const s=setTimeout(()=>{o(new Error("Request timeout"))},this.config.timeout);fetch(e,t).then(e=>{clearTimeout(s),n(e)}).catch(e=>{clearTimeout(s),o(e)})})}}function n(){return"undefined"!=typeof window&&window.togglely||null}e.TogglelyClient=t,e.createOfflineTogglesScript=function(e){return`<script>window.__TOGGLELY_TOGGLES = ${JSON.stringify(e)};<\/script>`},e.default=t,e.getGlobalTogglely=n,e.getJSON=async function(e,t={}){const o=n();return o?o.getJSON(e,t):(console.error("[Togglely] No global instance found. Call initTogglely() first."),t)},e.getNumber=async function(e,t=0){const o=n();return o?o.getNumber(e,t):(console.error("[Togglely] No global instance found. Call initTogglely() first."),t)},e.getString=async function(e,t=""){const o=n();return o?o.getString(e,t):(console.error("[Togglely] No global instance found. Call initTogglely() first."),t)},e.initTogglely=function(e){const n=new t(e);return"undefined"!=typeof window&&(window.togglely=n),n},e.isEnabled=async function(e,t=!1){const o=n();return o?o.isEnabled(e,t):(console.error("[Togglely] No global instance found. Call initTogglely() first."),t)},e.togglelyInit=function(e){const t=n();if(!t)return console.error("[Togglely] No global instance found. Call initTogglely() first."),()=>{};const o=async()=>{for(const[n,o]of Object.entries(e)){let e,s=!1,i=!1;"string"==typeof o?e=[o]:Array.isArray(o)?e=o:(e=[o.selector],s=o.defaultValue??!1,i=o.invert??!1);const l=await t.isEnabled(n,s),r=i?!l:l;e.forEach(e=>{document.querySelectorAll(e).forEach(e=>{e.style.display=r?"":"none"})})}};return o(),t.on("update",o)},e.togglelyToggle=async function(e,t,o={}){const{defaultValue:s=!1,invert:i=!1,hideClass:l="togglely-hidden",showClass:r="togglely-visible"}=o,a=n();if(!a)return void console.error("[Togglely] No global instance found. Call initTogglely() first.");const f=await a.isEnabled(t,s),c=i?!f:f;document.querySelectorAll(e).forEach(e=>{c?(e.classList.remove(l),e.classList.add(r),e.style.display=""):(e.classList.remove(r),e.classList.add(l),e.style.display="none")})},e.togglesToEnvVars=function(e,t="TOGGLELY_"){const n={};for(const[o,s]of Object.entries(e)){n[t+o.toUpperCase().replace(/-/g,"_")]="object"==typeof s?JSON.stringify(s):String(s)}return n},Object.defineProperty(e,"__esModule",{value:!0})});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Flagify={})}(this,function(e){"use strict";class t{constructor(e){this.toggles=new Map,this.context={},this.state={isReady:!1,isOffline:!1,lastError:null,lastFetch:null},this.eventHandlers=new Map,this.offlineTogglesLoaded=!1,this.pendingKeys=new Set,this.pendingPromises=new Map,this.batchTimeout=null,this.BATCH_DELAY=10,this.config={timeout:5e3,offlineFallback:!0,envPrefix:"TOGGLELY_",autoFetch:!0,offlineJsonPath:void 0,...e},this.eventHandlers.set("ready",new Set),this.eventHandlers.set("update",new Set),this.eventHandlers.set("error",new Set),this.eventHandlers.set("offline",new Set),this.eventHandlers.set("online",new Set);const t={...e.context};e.brandKey&&(t.brandKey=e.brandKey),e.tenantId&&(t.tenantId=e.tenantId),this.context=t,this.config.offlineFallback&&this.loadOfflineToggles(),this.config.autoFetch&&this.refresh()}on(e,t){const n=this.eventHandlers.get(e);return n&&n.add(t),()=>this.off(e,t)}off(e,t){const n=this.eventHandlers.get(e);n&&n.delete(t)}emit(e){const t=this.eventHandlers.get(e);t&&t.forEach(e=>e({...this.state}))}setContext(e){this.context={...this.context,...e}}getContext(){return{...this.context}}clearContext(){this.context={}}getState(){return{...this.state}}isReady(){return this.state.isReady}isOffline(){return this.state.isOffline}async isEnabled(e,t=!1){const n=await this.getValue(e);return null===n?t:"boolean"==typeof n.value?n.enabled&&n.value:n.enabled}async getString(e,t=""){const n=await this.getValue(e);return null!==n&&n.enabled?String(n.value):t}async getNumber(e,t=0){const n=await this.getValue(e);return null!==n&&n.enabled?Number(n.value):t}async getJSON(e,t={}){const n=await this.getValue(e);if(null===n||!n.enabled)return t;if("string"==typeof n.value)try{return JSON.parse(n.value)}catch{return t}return n.value}async getValue(e){const t=this.toggles.get(e);if(void 0!==t)return this.scheduleBatchRefresh(),t;const n=this.pendingPromises.get(e);return n?new Promise((e,t)=>{n.push({resolve:e,reject:t})}):(this.pendingKeys.add(e),new Promise((t,n)=>{const s=this.pendingPromises.get(e)||[];s.push({resolve:t,reject:n}),this.pendingPromises.set(e,s),this.scheduleBatchExecution()}))}scheduleBatchRefresh(){this.batchTimeout||(this.batchTimeout=setTimeout(()=>{this.batchTimeout=null,this.refresh().catch(()=>{})},this.BATCH_DELAY))}scheduleBatchExecution(){this.batchTimeout||(this.batchTimeout=setTimeout(()=>{this.executeBatch()},this.BATCH_DELAY))}async executeBatch(){this.batchTimeout=null;const e=Array.from(this.pendingKeys),t=new Map(this.pendingPromises);if(this.pendingKeys.clear(),this.pendingPromises.clear(),0!==e.length)try{await this.refresh();for(const n of e){const e=t.get(n)||[],s=this.toggles.get(n)||null;for(const{resolve:t}of e)t(s)}}catch(n){for(const s of e){const e=t.get(s)||[];for(const{reject:t}of e)t(n)}}}getAllToggles(){const e={};return this.toggles.forEach((t,n)=>{e[n]=t}),e}loadOfflineToggles(){try{if(this.config.offlineToggles&&Object.keys(this.config.offlineToggles).length>0){for(const[e,t]of Object.entries(this.config.offlineToggles))this.toggles.set(e,t);return this.offlineTogglesLoaded=!0,void console.log("[Togglely] Loaded offline toggles from config")}if(this.config.offlineJsonPath&&"undefined"!=typeof window&&this.loadOfflineJsonFile(this.config.offlineJsonPath),"undefined"!=typeof window&&window.__TOGGLELY_TOGGLES){const e=window.__TOGGLELY_TOGGLES;for(const[t,n]of Object.entries(e))this.toggles.set(t,this.parseOfflineValue(n));return this.offlineTogglesLoaded=!0,void console.log("[Togglely] Loaded offline toggles from window.__TOGGLELY_TOGGLES")}if("undefined"!=typeof process&&process.env){const e=this.config.envPrefix;for(const[t,n]of Object.entries(process.env))if(t?.startsWith(e)&&void 0!==n){const s=t.slice(e.length).toLowerCase().replace(/_/g,"-");this.toggles.set(s,this.parseOfflineValue(n))}this.offlineTogglesLoaded=!0,console.log("[Togglely] Loaded offline toggles from environment variables")}}catch(e){console.warn("[Togglely] Failed to load offline toggles:",e)}}async loadOfflineJsonFile(e){try{if("undefined"!=typeof window){const t=await fetch(e);if(t.ok){const n=await t.json();for(const[e,t]of Object.entries(n))this.toggles.set(e,this.parseOfflineValue(t));this.offlineTogglesLoaded=!0,console.log("[Togglely] Loaded offline toggles from JSON file:",e)}}else if("undefined"!=typeof require){const t=require("fs"),n=require("path").resolve(e);if(t.existsSync(n)){const e=JSON.parse(t.readFileSync(n,"utf-8"));for(const[t,n]of Object.entries(e))this.toggles.set(t,this.parseOfflineValue(n));this.offlineTogglesLoaded=!0,console.log("[Togglely] Loaded offline toggles from JSON file:",n)}}}catch(e){console.warn("[Togglely] Failed to load offline JSON file:",e)}}getOfflineToggle(e){if(!this.config.offlineFallback)return null;const t=this.toggles.get(e);return t?(this.state.isOffline||(this.state.isOffline=!0,this.emit("offline")),t):null}parseOfflineValue(e){if("string"==typeof e){const t=e.toLowerCase();if("true"===t)return{value:!0,enabled:!0};if("false"===t)return{value:!1,enabled:!0};if(!isNaN(Number(e)))return{value:Number(e),enabled:!0};try{return{value:JSON.parse(e),enabled:!0}}catch{return{value:e,enabled:!0}}}return{value:e,enabled:!0}}async refresh(){try{const e=new URLSearchParams;this.context.brandKey&&e.set("brandKey",String(this.context.brandKey)),this.context.tenantId&&e.set("tenantId",String(this.context.tenantId)),Object.keys(this.context).length>0&&e.set("context",JSON.stringify(this.context));const t={"Content-Type":"application/json"};this.config.apiKey&&(t.Authorization=`Bearer ${this.config.apiKey}`);const n=await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${encodeURIComponent(this.config.project)}/${encodeURIComponent(this.config.environment)}?${e.toString()}`,{headers:t});if(!n.ok)throw new Error(`HTTP ${n.status}`);const s=await n.json();this.toggles.clear();for(const[e,t]of Object.entries(s))this.toggles.set(e,t);this.state.lastFetch=new Date,this.state.lastError=null,this.state.isReady||(this.state.isReady=!0,this.emit("ready")),this.state.isOffline&&(this.state.isOffline=!1,this.emit("online")),this.emit("update")}catch(e){this.state.lastError=e,this.config.offlineFallback&&this.offlineTogglesLoaded&&(this.state.isOffline||(this.state.isOffline=!0,this.emit("offline"))),this.emit("error"),console.error("[Togglely] Failed to refresh toggles:",e)}}forceOfflineMode(){this.state.isOffline=!0,this.emit("offline")}forceOnlineMode(){this.state.isOffline=!1,this.refresh(),this.emit("online")}destroy(){this.toggles.clear(),this.eventHandlers.forEach(e=>e.clear())}fetchWithTimeout(e,t){return new Promise((n,s)=>{const o=setTimeout(()=>{s(new Error("Request timeout"))},this.config.timeout);fetch(e,t).then(e=>{clearTimeout(o),n(e)}).catch(e=>{clearTimeout(o),s(e)})})}}function n(){return"undefined"!=typeof window&&window.togglely||null}e.TogglelyClient=t,e.createOfflineTogglesScript=function(e){return`<script>window.__TOGGLELY_TOGGLES = ${JSON.stringify(e)};<\/script>`},e.default=t,e.getGlobalTogglely=n,e.getJSON=async function(e,t={}){const s=n();return s?s.getJSON(e,t):(console.error("[Togglely] No global instance found. Call initTogglely() first."),t)},e.getNumber=async function(e,t=0){const s=n();return s?s.getNumber(e,t):(console.error("[Togglely] No global instance found. Call initTogglely() first."),t)},e.getString=async function(e,t=""){const s=n();return s?s.getString(e,t):(console.error("[Togglely] No global instance found. Call initTogglely() first."),t)},e.initTogglely=function(e){const n=new t(e);return"undefined"!=typeof window&&(window.togglely=n),n},e.isEnabled=async function(e,t=!1){const s=n();return s?s.isEnabled(e,t):(console.error("[Togglely] No global instance found. Call initTogglely() first."),t)},e.togglelyInit=function(e){const t=n();if(!t)return console.error("[Togglely] No global instance found. Call initTogglely() first."),()=>{};const s=async()=>{for(const[n,s]of Object.entries(e)){let e,o=!1,i=!1;"string"==typeof s?e=[s]:Array.isArray(s)?e=s:(e=[s.selector],o=s.defaultValue??!1,i=s.invert??!1);const l=await t.isEnabled(n,o),r=i?!l:l;e.forEach(e=>{document.querySelectorAll(e).forEach(e=>{e.style.display=r?"":"none"})})}};return s(),t.on("update",s)},e.togglelyToggle=async function(e,t,s={}){const{defaultValue:o=!1,invert:i=!1,hideClass:l="togglely-hidden",showClass:r="togglely-visible"}=s,a=n();if(!a)return void console.error("[Togglely] No global instance found. Call initTogglely() first.");const f=await a.isEnabled(t,o),c=i?!f:f;document.querySelectorAll(e).forEach(e=>{c?(e.classList.remove(l),e.classList.add(r),e.style.display=""):(e.classList.remove(r),e.classList.add(l),e.style.display="none")})},e.togglesToEnvVars=function(e,t="TOGGLELY_"){const n={};for(const[s,o]of Object.entries(e)){n[t+s.toUpperCase().replace(/-/g,"_")]="object"==typeof o?JSON.stringify(o):String(o)}return n},Object.defineProperty(e,"__esModule",{value:!0})});
2
2
  //# sourceMappingURL=index.umd.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.min.js","sources":["../../core/dist/index.esm.js","../src/index.ts"],"sourcesContent":["/**\n * Togglely Core SDK - Framework agnostic feature flag management\n *\n * Features:\n * - Real-time feature flag evaluation\n * - Offline fallback via JSON file, environment variables, or window object\n * - Multi-brand/tenant support\n * - Type-safe flag access\n * - Build-time JSON generation for offline-first deployment\n */\n// ==================== Togglely Client ====================\nclass TogglelyClient {\n constructor(config) {\n this.toggles = new Map();\n this.context = {};\n this.state = {\n isReady: false,\n isOffline: false,\n lastError: null,\n lastFetch: null\n };\n this.eventHandlers = new Map();\n this.offlineTogglesLoaded = false;\n this.config = {\n timeout: 5000,\n offlineFallback: true,\n envPrefix: 'TOGGLELY_',\n autoFetch: true,\n offlineJsonPath: undefined,\n ...config\n };\n // Initialize event handlers\n this.eventHandlers.set('ready', new Set());\n this.eventHandlers.set('update', new Set());\n this.eventHandlers.set('error', new Set());\n this.eventHandlers.set('offline', new Set());\n this.eventHandlers.set('online', new Set());\n // Set initial context if provided (including brandKey/tenantId)\n const initialContext = { ...config.context };\n if (config.brandKey)\n initialContext.brandKey = config.brandKey;\n if (config.tenantId)\n initialContext.tenantId = config.tenantId;\n this.context = initialContext;\n // Load offline toggles first (if enabled)\n if (this.config.offlineFallback) {\n this.loadOfflineToggles();\n }\n // Initial fetch (if enabled)\n if (this.config.autoFetch) {\n this.refresh();\n }\n }\n // ==================== Event Handling ====================\n on(event, handler) {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.add(handler);\n }\n return () => this.off(event, handler);\n }\n off(event, handler) {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler);\n }\n }\n emit(event) {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.forEach(handler => handler({ ...this.state }));\n }\n }\n // ==================== Context ====================\n setContext(context) {\n this.context = { ...this.context, ...context };\n }\n getContext() {\n return { ...this.context };\n }\n clearContext() {\n this.context = {};\n }\n // ==================== State ====================\n getState() {\n return { ...this.state };\n }\n isReady() {\n return this.state.isReady;\n }\n isOffline() {\n return this.state.isOffline;\n }\n // ==================== Toggle Accessors ====================\n /**\n * Check if a boolean feature flag is enabled\n * @param key - The flag key\n * @param defaultValue - Default value if flag not found\n * @returns Promise<boolean>\n */\n async isEnabled(key, defaultValue = false) {\n const value = await this.getValue(key);\n if (value === null) {\n return defaultValue;\n }\n // enabled is the primary on/off switch for a flag.\n // value.value holds the flag's configured value (used for non-boolean use-cases).\n // For boolean flags: \n // - If NOT enabled (toggle is OFF globally for environment), return false\n // - If ENABLED (toggle is ON), return the boolean value itself (true/false)\n if (typeof value.value === 'boolean') {\n return value.enabled && value.value;\n }\n // Fallback for non-boolean flags or if value is missing\n return value.enabled;\n }\n /**\n * Get a string feature flag value\n * @param key - The flag key\n * @param defaultValue - Default value if flag not found or disabled\n * @returns Promise<string>\n */\n async getString(key, defaultValue = '') {\n const value = await this.getValue(key);\n if (value === null || !value.enabled)\n return defaultValue;\n return String(value.value);\n }\n /**\n * Get a number feature flag value\n * @param key - The flag key\n * @param defaultValue - Default value if flag not found or disabled\n * @returns Promise<number>\n */\n async getNumber(key, defaultValue = 0) {\n const value = await this.getValue(key);\n if (value === null || !value.enabled)\n return defaultValue;\n return Number(value.value);\n }\n /**\n * Get a JSON feature flag value\n * @param key - The flag key\n * @param defaultValue - Default value if flag not found or disabled\n * @returns Promise<T>\n */\n async getJSON(key, defaultValue = {}) {\n const value = await this.getValue(key);\n if (value === null || !value.enabled)\n return defaultValue;\n if (typeof value.value === 'string') {\n try {\n return JSON.parse(value.value);\n }\n catch {\n return defaultValue;\n }\n }\n return value.value;\n }\n /**\n * Get raw toggle value\n * Uses stale-while-revalidate pattern: returns cached value immediately if available,\n * then refreshes from server in background\n * @param key - The flag key\n * @returns Promise<ToggleValue | null>\n */\n async getValue(key) {\n // Check if we have a cached/offline value first (stale-while-revalidate pattern)\n const cachedValue = this.toggles.get(key);\n // Fetch from server in background (don't await if we have cached data)\n const fetchFromServer = async () => {\n try {\n const data = await this.fetchValueFromServer(key);\n if (data !== null) {\n this.toggles.set(key, data);\n }\n return data;\n }\n catch {\n // Silently fail - we already returned the cached value or will handle below\n return null;\n }\n };\n // If we have a cached value, return it immediately and update in background\n if (cachedValue !== undefined) {\n // Trigger the fetch in background without awaiting\n fetchFromServer().catch(() => { });\n return cachedValue;\n }\n // No cached value - we need to wait for the server response\n const result = await fetchFromServer();\n if (result !== null) {\n return result;\n }\n // Try offline fallback\n if (this.config.offlineFallback) {\n const offlineValue = this.getOfflineToggle(key);\n if (offlineValue !== null) {\n return offlineValue;\n }\n }\n // Return safe default\n return { value: false, enabled: false };\n }\n /**\n * Internal method to fetch a single toggle value from the server\n */\n async fetchValueFromServer(key) {\n const params = new URLSearchParams();\n // Support both brandKey and tenantId for maximum compatibility\n if (this.context.brandKey)\n params.set('brandKey', String(this.context.brandKey));\n if (this.context.tenantId)\n params.set('tenantId', String(this.context.tenantId));\n if (Object.keys(this.context).length > 0) {\n params.set('context', JSON.stringify(this.context));\n }\n const query = params.toString() ? `?${params.toString()}` : '';\n const url = `${this.config.baseUrl}/sdk/flags/${encodeURIComponent(this.config.project)}/${encodeURIComponent(this.config.environment)}/${encodeURIComponent(key)}${query}`;\n const headers = {\n 'Content-Type': 'application/json'\n };\n if (this.config.apiKey) {\n headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n }\n const response = await this.fetchWithTimeout(url, { headers });\n if (!response.ok) {\n if (response.status === 404) {\n return null;\n }\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n const data = await response.json();\n if (this.state.isOffline) {\n this.state.isOffline = false;\n this.emit('online');\n }\n return data;\n }\n /**\n * Get all toggles\n * @returns Record<string, ToggleValue>\n */\n getAllToggles() {\n const result = {};\n this.toggles.forEach((value, key) => {\n result[key] = value;\n });\n return result;\n }\n // ==================== Offline Fallback ====================\n /**\n * Load offline toggles from multiple sources (in priority order):\n * 1. Inline offlineToggles from config\n * 2. JSON file (if offlineJsonPath is set)\n * 3. window.__TOGGLELY_TOGGLES (browser)\n * 4. Environment variables (Node.js)\n */\n loadOfflineToggles() {\n try {\n // Priority 1: Inline offline toggles from config\n if (this.config.offlineToggles && Object.keys(this.config.offlineToggles).length > 0) {\n for (const [key, value] of Object.entries(this.config.offlineToggles)) {\n this.toggles.set(key, value);\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from config');\n return;\n }\n // Priority 2: JSON file (browser only - fetch synchronously not possible, will try async)\n if (this.config.offlineJsonPath && typeof window !== 'undefined') {\n this.loadOfflineJsonFile(this.config.offlineJsonPath);\n }\n // Priority 3: Browser environment - check window.__TOGGLELY_TOGGLES\n if (typeof window !== 'undefined' && window.__TOGGLELY_TOGGLES) {\n const offlineToggles = window.__TOGGLELY_TOGGLES;\n for (const [key, value] of Object.entries(offlineToggles)) {\n this.toggles.set(key, this.parseOfflineValue(value));\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from window.__TOGGLELY_TOGGLES');\n return;\n }\n // Priority 4: Node.js / Bun / Deno environment - check process.env\n if (typeof process !== 'undefined' && process.env) {\n const prefix = this.config.envPrefix;\n for (const [envKey, envValue] of Object.entries(process.env)) {\n if (envKey?.startsWith(prefix) && envValue !== undefined) {\n const toggleKey = envKey\n .slice(prefix.length)\n .toLowerCase()\n .replace(/_/g, '-');\n this.toggles.set(toggleKey, this.parseOfflineValue(envValue));\n }\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from environment variables');\n }\n }\n catch (error) {\n console.warn('[Togglely] Failed to load offline toggles:', error);\n }\n }\n /**\n * Load offline toggles from JSON file (async)\n */\n async loadOfflineJsonFile(path) {\n try {\n if (typeof window !== 'undefined') {\n // Browser - fetch the JSON file\n const response = await fetch(path);\n if (response.ok) {\n const data = await response.json();\n for (const [key, value] of Object.entries(data)) {\n this.toggles.set(key, this.parseOfflineValue(value));\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from JSON file:', path);\n }\n }\n else if (typeof require !== 'undefined') {\n // Node.js - require the JSON file\n const fs = require('fs');\n const pathModule = require('path');\n const fullPath = pathModule.resolve(path);\n if (fs.existsSync(fullPath)) {\n const data = JSON.parse(fs.readFileSync(fullPath, 'utf-8'));\n for (const [key, value] of Object.entries(data)) {\n this.toggles.set(key, this.parseOfflineValue(value));\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from JSON file:', fullPath);\n }\n }\n }\n catch (error) {\n console.warn('[Togglely] Failed to load offline JSON file:', error);\n }\n }\n getOfflineToggle(key) {\n if (!this.config.offlineFallback)\n return null;\n const cached = this.toggles.get(key);\n if (cached) {\n if (!this.state.isOffline) {\n this.state.isOffline = true;\n this.emit('offline');\n }\n return cached;\n }\n return null;\n }\n parseOfflineValue(value) {\n if (typeof value === 'string') {\n const lower = value.toLowerCase();\n if (lower === 'true')\n return { value: true, enabled: true };\n if (lower === 'false')\n return { value: false, enabled: true };\n if (!isNaN(Number(value))) {\n return { value: Number(value), enabled: true };\n }\n try {\n const parsed = JSON.parse(value);\n return { value: parsed, enabled: true };\n }\n catch {\n return { value, enabled: true };\n }\n }\n return { value, enabled: true };\n }\n // ==================== Refresh / Polling ====================\n /**\n * Refresh all toggles from the server\n */\n async refresh() {\n try {\n const params = new URLSearchParams();\n // Support both brandKey and tenantId for maximum compatibility\n if (this.context.brandKey)\n params.set('brandKey', String(this.context.brandKey));\n if (this.context.tenantId)\n params.set('tenantId', String(this.context.tenantId));\n if (Object.keys(this.context).length > 0) {\n params.set('context', JSON.stringify(this.context));\n }\n const headers = {\n 'Content-Type': 'application/json'\n };\n if (this.config.apiKey) {\n headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n }\n const response = await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${encodeURIComponent(this.config.project)}/${encodeURIComponent(this.config.environment)}?${params.toString()}`, { headers });\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n const data = await response.json();\n this.toggles.clear();\n for (const [key, value] of Object.entries(data)) {\n this.toggles.set(key, value);\n }\n this.state.lastFetch = new Date();\n this.state.lastError = null;\n if (!this.state.isReady) {\n this.state.isReady = true;\n this.emit('ready');\n }\n if (this.state.isOffline) {\n this.state.isOffline = false;\n this.emit('online');\n }\n this.emit('update');\n }\n catch (error) {\n this.state.lastError = error;\n if (this.config.offlineFallback && this.offlineTogglesLoaded) {\n if (!this.state.isOffline) {\n this.state.isOffline = true;\n this.emit('offline');\n }\n }\n this.emit('error');\n console.error('[Togglely] Failed to refresh toggles:', error);\n }\n }\n forceOfflineMode() {\n this.state.isOffline = true;\n this.emit('offline');\n }\n forceOnlineMode() {\n this.state.isOffline = false;\n this.refresh();\n this.emit('online');\n }\n // ==================== Cleanup ====================\n destroy() {\n this.toggles.clear();\n this.eventHandlers.forEach(handlers => handlers.clear());\n }\n // ==================== Private Helpers ====================\n fetchWithTimeout(url, options) {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n reject(new Error('Request timeout'));\n }, this.config.timeout);\n fetch(url, options)\n .then(response => {\n clearTimeout(timeoutId);\n resolve(response);\n })\n .catch(error => {\n clearTimeout(timeoutId);\n reject(error);\n });\n });\n }\n}\n// ==================== Utility Functions ====================\n/**\n * Create a client-side toggle loader script\n * Use this to inject offline toggles into your HTML\n */\nfunction createOfflineTogglesScript(toggles) {\n return `<script>window.__TOGGLELY_TOGGLES = ${JSON.stringify(toggles)};</script>`;\n}\n/**\n * Helper to convert toggles to environment variables\n */\nfunction togglesToEnvVars(toggles, prefix = 'TOGGLELY_') {\n const envVars = {};\n for (const [key, value] of Object.entries(toggles)) {\n const envKey = prefix + key.toUpperCase().replace(/-/g, '_');\n envVars[envKey] = typeof value === 'object' ? JSON.stringify(value) : String(value);\n }\n return envVars;\n}\n\nexport { TogglelyClient, createOfflineTogglesScript, TogglelyClient as default, togglesToEnvVars };\n//# sourceMappingURL=index.esm.js.map\n",null],"names":["TogglelyClient","constructor","config","this","toggles","Map","context","state","isReady","isOffline","lastError","lastFetch","eventHandlers","offlineTogglesLoaded","timeout","offlineFallback","envPrefix","autoFetch","offlineJsonPath","undefined","set","Set","initialContext","brandKey","tenantId","loadOfflineToggles","refresh","on","event","handler","handlers","get","add","off","delete","emit","forEach","setContext","getContext","clearContext","getState","isEnabled","key","defaultValue","value","getValue","enabled","getString","String","getNumber","Number","getJSON","JSON","parse","cachedValue","fetchFromServer","async","data","fetchValueFromServer","catch","result","offlineValue","getOfflineToggle","params","URLSearchParams","Object","keys","length","stringify","query","toString","url","baseUrl","encodeURIComponent","project","environment","headers","apiKey","response","fetchWithTimeout","ok","status","Error","statusText","json","getAllToggles","offlineToggles","entries","console","log","window","loadOfflineJsonFile","__TOGGLELY_TOGGLES","parseOfflineValue","process","env","prefix","envKey","envValue","startsWith","toggleKey","slice","toLowerCase","replace","error","warn","path","fetch","require","fs","fullPath","resolve","existsSync","readFileSync","cached","lower","isNaN","clear","Date","forceOfflineMode","forceOnlineMode","destroy","options","Promise","reject","timeoutId","setTimeout","then","clearTimeout","getGlobalTogglely","togglely","client","updateAll","selectors","invert","Array","isArray","selector","isToggleEnabled","shouldShow","document","querySelectorAll","el","style","display","hideClass","showClass","classList","remove","envVars","toUpperCase"],"mappings":"8OAWA,MAAMA,EACF,WAAAC,CAAYC,GACRC,KAAKC,QAAU,IAAIC,IACnBF,KAAKG,QAAU,CAAA,EACfH,KAAKI,MAAQ,CACTC,SAAS,EACTC,WAAW,EACXC,UAAW,KACXC,UAAW,MAEfR,KAAKS,cAAgB,IAAIP,IACzBF,KAAKU,sBAAuB,EAC5BV,KAAKD,OAAS,CACVY,QAAS,IACTC,iBAAiB,EACjBC,UAAW,YACXC,WAAW,EACXC,qBAAiBC,KACdjB,GAGPC,KAAKS,cAAcQ,IAAI,QAAS,IAAIC,KACpClB,KAAKS,cAAcQ,IAAI,SAAU,IAAIC,KACrClB,KAAKS,cAAcQ,IAAI,QAAS,IAAIC,KACpClB,KAAKS,cAAcQ,IAAI,UAAW,IAAIC,KACtClB,KAAKS,cAAcQ,IAAI,SAAU,IAAIC,KAErC,MAAMC,EAAiB,IAAKpB,EAAOI,SAC/BJ,EAAOqB,WACPD,EAAeC,SAAWrB,EAAOqB,UACjCrB,EAAOsB,WACPF,EAAeE,SAAWtB,EAAOsB,UACrCrB,KAAKG,QAAUgB,EAEXnB,KAAKD,OAAOa,iBACZZ,KAAKsB,qBAGLtB,KAAKD,OAAOe,WACZd,KAAKuB,SAEb,CAEA,EAAAC,CAAGC,EAAOC,GACN,MAAMC,EAAW3B,KAAKS,cAAcmB,IAAIH,GAIxC,OAHIE,GACAA,EAASE,IAAIH,GAEV,IAAM1B,KAAK8B,IAAIL,EAAOC,EACjC,CACA,GAAAI,CAAIL,EAAOC,GACP,MAAMC,EAAW3B,KAAKS,cAAcmB,IAAIH,GACpCE,GACAA,EAASI,OAAOL,EAExB,CACA,IAAAM,CAAKP,GACD,MAAME,EAAW3B,KAAKS,cAAcmB,IAAIH,GACpCE,GACAA,EAASM,QAAQP,GAAWA,EAAQ,IAAK1B,KAAKI,QAEtD,CAEA,UAAA8B,CAAW/B,GACPH,KAAKG,QAAU,IAAKH,KAAKG,WAAYA,EACzC,CACA,UAAAgC,GACI,MAAO,IAAKnC,KAAKG,QACrB,CACA,YAAAiC,GACIpC,KAAKG,QAAU,CAAA,CACnB,CAEA,QAAAkC,GACI,MAAO,IAAKrC,KAAKI,MACrB,CACA,OAAAC,GACI,OAAOL,KAAKI,MAAMC,OACtB,CACA,SAAAC,GACI,OAAON,KAAKI,MAAME,SACtB,CAQA,eAAMgC,CAAUC,EAAKC,GAAe,GAChC,MAAMC,QAAczC,KAAK0C,SAASH,GAClC,OAAc,OAAVE,EACOD,EAOgB,kBAAhBC,EAAMA,MACNA,EAAME,SAAWF,EAAMA,MAG3BA,EAAME,OACjB,CAOA,eAAMC,CAAUL,EAAKC,EAAe,IAChC,MAAMC,QAAczC,KAAK0C,SAASH,GAClC,OAAc,OAAVE,GAAmBA,EAAME,QAEtBE,OAAOJ,EAAMA,OADTD,CAEf,CAOA,eAAMM,CAAUP,EAAKC,EAAe,GAChC,MAAMC,QAAczC,KAAK0C,SAASH,GAClC,OAAc,OAAVE,GAAmBA,EAAME,QAEtBI,OAAON,EAAMA,OADTD,CAEf,CAOA,aAAMQ,CAAQT,EAAKC,EAAe,IAC9B,MAAMC,QAAczC,KAAK0C,SAASH,GAClC,GAAc,OAAVE,IAAmBA,EAAME,QACzB,OAAOH,EACX,GAA2B,iBAAhBC,EAAMA,MACb,IACI,OAAOQ,KAAKC,MAAMT,EAAMA,MAC5B,CACA,MACI,OAAOD,CACX,CAEJ,OAAOC,EAAMA,KACjB,CAQA,cAAMC,CAASH,GAEX,MAAMY,EAAcnD,KAAKC,QAAQ2B,IAAIW,GAE/Ba,EAAkBC,UACpB,IACI,MAAMC,QAAatD,KAAKuD,qBAAqBhB,GAI7C,OAHa,OAATe,GACAtD,KAAKC,QAAQgB,IAAIsB,EAAKe,GAEnBA,CACX,CACA,MAEI,OAAO,IACX,GAGJ,QAAoBtC,IAAhBmC,EAGA,OADAC,IAAkBI,MAAM,QACjBL,EAGX,MAAMM,QAAeL,IACrB,GAAe,OAAXK,EACA,OAAOA,EAGX,GAAIzD,KAAKD,OAAOa,gBAAiB,CAC7B,MAAM8C,EAAe1D,KAAK2D,iBAAiBpB,GAC3C,GAAqB,OAAjBmB,EACA,OAAOA,CAEf,CAEA,MAAO,CAAEjB,OAAO,EAAOE,SAAS,EACpC,CAIA,0BAAMY,CAAqBhB,GACvB,MAAMqB,EAAS,IAAIC,gBAEf7D,KAAKG,QAAQiB,UACbwC,EAAO3C,IAAI,WAAY4B,OAAO7C,KAAKG,QAAQiB,WAC3CpB,KAAKG,QAAQkB,UACbuC,EAAO3C,IAAI,WAAY4B,OAAO7C,KAAKG,QAAQkB,WAC3CyC,OAAOC,KAAK/D,KAAKG,SAAS6D,OAAS,GACnCJ,EAAO3C,IAAI,UAAWgC,KAAKgB,UAAUjE,KAAKG,UAE9C,MAAM+D,EAAQN,EAAOO,WAAa,IAAIP,EAAOO,aAAe,GACtDC,EAAM,GAAGpE,KAAKD,OAAOsE,qBAAqBC,mBAAmBtE,KAAKD,OAAOwE,YAAYD,mBAAmBtE,KAAKD,OAAOyE,gBAAgBF,mBAAmB/B,KAAO2B,IAC9JO,EAAU,CACZ,eAAgB,oBAEhBzE,KAAKD,OAAO2E,SACZD,EAAuB,cAAI,UAAUzE,KAAKD,OAAO2E,UAErD,MAAMC,QAAiB3E,KAAK4E,iBAAiBR,EAAK,CAAEK,YACpD,IAAKE,EAASE,GAAI,CACd,GAAwB,MAApBF,EAASG,OACT,OAAO,KAEX,MAAM,IAAIC,MAAM,QAAQJ,EAASG,WAAWH,EAASK,aACzD,CACA,MAAM1B,QAAaqB,EAASM,OAK5B,OAJIjF,KAAKI,MAAME,YACXN,KAAKI,MAAME,WAAY,EACvBN,KAAKgC,KAAK,WAEPsB,CACX,CAKA,aAAA4B,GACI,MAAMzB,EAAS,CAAA,EAIf,OAHAzD,KAAKC,QAAQgC,QAAQ,CAACQ,EAAOF,KACzBkB,EAAOlB,GAAOE,IAEXgB,CACX,CASA,kBAAAnC,GACI,IAEI,GAAItB,KAAKD,OAAOoF,gBAAkBrB,OAAOC,KAAK/D,KAAKD,OAAOoF,gBAAgBnB,OAAS,EAAG,CAClF,IAAK,MAAOzB,EAAKE,KAAUqB,OAAOsB,QAAQpF,KAAKD,OAAOoF,gBAClDnF,KAAKC,QAAQgB,IAAIsB,EAAKE,GAI1B,OAFAzC,KAAKU,sBAAuB,OAC5B2E,QAAQC,IAAI,gDAEhB,CAMA,GAJItF,KAAKD,OAAOgB,iBAAqC,oBAAXwE,QACtCvF,KAAKwF,oBAAoBxF,KAAKD,OAAOgB,iBAGnB,oBAAXwE,QAA0BA,OAAOE,mBAAoB,CAC5D,MAAMN,EAAiBI,OAAOE,mBAC9B,IAAK,MAAOlD,EAAKE,KAAUqB,OAAOsB,QAAQD,GACtCnF,KAAKC,QAAQgB,IAAIsB,EAAKvC,KAAK0F,kBAAkBjD,IAIjD,OAFAzC,KAAKU,sBAAuB,OAC5B2E,QAAQC,IAAI,mEAEhB,CAEA,GAAuB,oBAAZK,SAA2BA,QAAQC,IAAK,CAC/C,MAAMC,EAAS7F,KAAKD,OAAOc,UAC3B,IAAK,MAAOiF,EAAQC,KAAajC,OAAOsB,QAAQO,QAAQC,KACpD,GAAIE,GAAQE,WAAWH,SAAwB7E,IAAb+E,EAAwB,CACtD,MAAME,EAAYH,EACbI,MAAML,EAAO7B,QACbmC,cACAC,QAAQ,KAAM,KACnBpG,KAAKC,QAAQgB,IAAIgF,EAAWjG,KAAK0F,kBAAkBK,GACvD,CAEJ/F,KAAKU,sBAAuB,EAC5B2E,QAAQC,IAAI,+DAChB,CACJ,CACA,MAAOe,GACHhB,QAAQiB,KAAK,6CAA8CD,EAC/D,CACJ,CAIA,yBAAMb,CAAoBe,GACtB,IACI,GAAsB,oBAAXhB,OAAwB,CAE/B,MAAMZ,QAAiB6B,MAAMD,GAC7B,GAAI5B,EAASE,GAAI,CACb,MAAMvB,QAAaqB,EAASM,OAC5B,IAAK,MAAO1C,EAAKE,KAAUqB,OAAOsB,QAAQ9B,GACtCtD,KAAKC,QAAQgB,IAAIsB,EAAKvC,KAAK0F,kBAAkBjD,IAEjDzC,KAAKU,sBAAuB,EAC5B2E,QAAQC,IAAI,oDAAqDiB,EACrE,CACJ,MACK,GAAuB,oBAAZE,QAAyB,CAErC,MAAMC,EAAKD,QAAQ,MAEbE,EADaF,QAAQ,QACCG,QAAQL,GACpC,GAAIG,EAAGG,WAAWF,GAAW,CACzB,MAAMrD,EAAOL,KAAKC,MAAMwD,EAAGI,aAAaH,EAAU,UAClD,IAAK,MAAOpE,EAAKE,KAAUqB,OAAOsB,QAAQ9B,GACtCtD,KAAKC,QAAQgB,IAAIsB,EAAKvC,KAAK0F,kBAAkBjD,IAEjDzC,KAAKU,sBAAuB,EAC5B2E,QAAQC,IAAI,oDAAqDqB,EACrE,CACJ,CACJ,CACA,MAAON,GACHhB,QAAQiB,KAAK,+CAAgDD,EACjE,CACJ,CACA,gBAAA1C,CAAiBpB,GACb,IAAKvC,KAAKD,OAAOa,gBACb,OAAO,KACX,MAAMmG,EAAS/G,KAAKC,QAAQ2B,IAAIW,GAChC,OAAIwE,GACK/G,KAAKI,MAAME,YACZN,KAAKI,MAAME,WAAY,EACvBN,KAAKgC,KAAK,YAEP+E,GAEJ,IACX,CACA,iBAAArB,CAAkBjD,GACd,GAAqB,iBAAVA,EAAoB,CAC3B,MAAMuE,EAAQvE,EAAM0D,cACpB,GAAc,SAAVa,EACA,MAAO,CAAEvE,OAAO,EAAME,SAAS,GACnC,GAAc,UAAVqE,EACA,MAAO,CAAEvE,OAAO,EAAOE,SAAS,GACpC,IAAKsE,MAAMlE,OAAON,IACd,MAAO,CAAEA,MAAOM,OAAON,GAAQE,SAAS,GAE5C,IAEI,MAAO,CAAEF,MADMQ,KAAKC,MAAMT,GACFE,SAAS,EACrC,CACA,MACI,MAAO,CAAEF,QAAOE,SAAS,EAC7B,CACJ,CACA,MAAO,CAAEF,QAAOE,SAAS,EAC7B,CAKA,aAAMpB,GACF,IACI,MAAMqC,EAAS,IAAIC,gBAEf7D,KAAKG,QAAQiB,UACbwC,EAAO3C,IAAI,WAAY4B,OAAO7C,KAAKG,QAAQiB,WAC3CpB,KAAKG,QAAQkB,UACbuC,EAAO3C,IAAI,WAAY4B,OAAO7C,KAAKG,QAAQkB,WAC3CyC,OAAOC,KAAK/D,KAAKG,SAAS6D,OAAS,GACnCJ,EAAO3C,IAAI,UAAWgC,KAAKgB,UAAUjE,KAAKG,UAE9C,MAAMsE,EAAU,CACZ,eAAgB,oBAEhBzE,KAAKD,OAAO2E,SACZD,EAAuB,cAAI,UAAUzE,KAAKD,OAAO2E,UAErD,MAAMC,QAAiB3E,KAAK4E,iBAAiB,GAAG5E,KAAKD,OAAOsE,qBAAqBC,mBAAmBtE,KAAKD,OAAOwE,YAAYD,mBAAmBtE,KAAKD,OAAOyE,gBAAgBZ,EAAOO,aAAc,CAAEM,YAClM,IAAKE,EAASE,GACV,MAAM,IAAIE,MAAM,QAAQJ,EAASG,UAErC,MAAMxB,QAAaqB,EAASM,OAC5BjF,KAAKC,QAAQiH,QACb,IAAK,MAAO3E,EAAKE,KAAUqB,OAAOsB,QAAQ9B,GACtCtD,KAAKC,QAAQgB,IAAIsB,EAAKE,GAE1BzC,KAAKI,MAAMI,UAAY,IAAI2G,KAC3BnH,KAAKI,MAAMG,UAAY,KAClBP,KAAKI,MAAMC,UACZL,KAAKI,MAAMC,SAAU,EACrBL,KAAKgC,KAAK,UAEVhC,KAAKI,MAAME,YACXN,KAAKI,MAAME,WAAY,EACvBN,KAAKgC,KAAK,WAEdhC,KAAKgC,KAAK,SACd,CACA,MAAOqE,GACHrG,KAAKI,MAAMG,UAAY8F,EACnBrG,KAAKD,OAAOa,iBAAmBZ,KAAKU,uBAC/BV,KAAKI,MAAME,YACZN,KAAKI,MAAME,WAAY,EACvBN,KAAKgC,KAAK,aAGlBhC,KAAKgC,KAAK,SACVqD,QAAQgB,MAAM,wCAAyCA,EAC3D,CACJ,CACA,gBAAAe,GACIpH,KAAKI,MAAME,WAAY,EACvBN,KAAKgC,KAAK,UACd,CACA,eAAAqF,GACIrH,KAAKI,MAAME,WAAY,EACvBN,KAAKuB,UACLvB,KAAKgC,KAAK,SACd,CAEA,OAAAsF,GACItH,KAAKC,QAAQiH,QACblH,KAAKS,cAAcwB,QAAQN,GAAYA,EAASuF,QACpD,CAEA,gBAAAtC,CAAiBR,EAAKmD,GAClB,OAAO,IAAIC,QAAQ,CAACZ,EAASa,KACzB,MAAMC,EAAYC,WAAW,KACzBF,EAAO,IAAI1C,MAAM,qBAClB/E,KAAKD,OAAOY,SACf6F,MAAMpC,EAAKmD,GACNK,KAAKjD,IACNkD,aAAaH,GACbd,EAAQjC,KAEPnB,MAAM6C,IACPwB,aAAaH,GACbD,EAAOpB,MAGnB,WCtWYyB,IACd,MAAsB,oBAAXvC,QACDA,OAAewC,UAElB,IACT,iDDwWA,SAAoC9H,GAChC,MAAO,uCAAuCgD,KAAKgB,UAAUhE,eACjE,8CCjUOoD,eAAgCd,EAAaC,EAAkB,IACpE,MAAMwF,EAASF,IACf,OAAKE,EAIEA,EAAOhF,QAAWT,EAAKC,IAH5B6C,QAAQgB,MAAM,mEACP7D,EAGX,cAnBOa,eAAyBd,EAAaC,EAAuB,GAClE,MAAMwF,EAASF,IACf,OAAKE,EAIEA,EAAOlF,UAAUP,EAAKC,IAH3B6C,QAAQgB,MAAM,mEACP7D,EAGX,cAnBOa,eAAyBd,EAAaC,EAAuB,IAClE,MAAMwF,EAASF,IACf,OAAKE,EAIEA,EAAOpF,UAAUL,EAAKC,IAH3B6C,QAAQgB,MAAM,mEACP7D,EAGX,iBA3CM,SAAuBzC,GAC3B,MAAMiI,EAAS,IAAInI,EAAeE,GAOlC,MAJsB,oBAAXwF,SACRA,OAAewC,SAAWC,GAGtBA,CACT,cAeO3E,eAAyBd,EAAaC,GAAwB,GACnE,MAAMwF,EAASF,IACf,OAAKE,EAIEA,EAAO1F,UAAUC,EAAKC,IAH3B6C,QAAQgB,MAAM,mEACP7D,EAGX,iBAyGM,SACJzC,GAEA,MAAMiI,EAASF,IACf,IAAKE,EAEH,OADA3C,QAAQgB,MAAM,mEACP,OAGT,MAAM4B,EAAY5E,UAChB,IAAK,MAAO4C,EAAWxD,KAAUqB,OAAOsB,QAAQrF,GAAS,CACvD,IAAImI,EACA1F,GAAe,EACf2F,GAAS,EAEQ,iBAAV1F,EACTyF,EAAY,CAACzF,GACJ2F,MAAMC,QAAQ5F,GACvByF,EAAYzF,GAEZyF,EAAY,CAACzF,EAAM6F,UACnB9F,EAAeC,EAAMD,eAAgB,EACrC2F,EAAS1F,EAAM0F,SAAU,GAG3B,MAAMI,QAAwBP,EAAO1F,UAAU2D,EAAWzD,GACpDgG,EAAaL,GAAUI,EAAkBA,EAE/CL,EAAUjG,QAAQqG,IACCG,SAASC,iBAAiBJ,GAClCrG,QAAQ0G,IACdA,EAAmBC,MAAMC,QAAUL,EAAa,GAAK,UAG5D,GASF,OALAP,IAGoBD,EAAOxG,GAAG,SAAUyG,EAG1C,mBAjGO5E,eACLiF,EACArC,EACAsB,EAKI,CAAA,GAEJ,MAAM/E,aACJA,GAAe,EAAK2F,OACpBA,GAAS,EAAKW,UACdA,EAAY,kBAAiBC,UAC7BA,EAAY,oBACVxB,EAEES,EAASF,IACf,IAAKE,EAEH,YADA3C,QAAQgB,MAAM,mEAIhB,MAAMkC,QAAwBP,EAAO1F,UAAU2D,EAAWzD,GACpDgG,EAAaL,GAAUI,EAAkBA,EAE9BE,SAASC,iBAAiBJ,GAClCrG,QAAQ0G,IACXH,GACFG,EAAGK,UAAUC,OAAOH,GACpBH,EAAGK,UAAUnH,IAAIkH,GAChBJ,EAAmBC,MAAMC,QAAU,KAEpCF,EAAGK,UAAUC,OAAOF,GACpBJ,EAAGK,UAAUnH,IAAIiH,GAChBH,EAAmBC,MAAMC,QAAU,SAG1C,qBDwQA,SAA0B5I,EAAS4F,EAAS,aACxC,MAAMqD,EAAU,CAAA,EAChB,IAAK,MAAO3G,EAAKE,KAAUqB,OAAOsB,QAAQnF,GAAU,CAEhDiJ,EADerD,EAAStD,EAAI4G,cAAc/C,QAAQ,KAAM,MACrB,iBAAV3D,EAAqBQ,KAAKgB,UAAUxB,GAASI,OAAOJ,EACjF,CACA,OAAOyG,CACX"}
1
+ {"version":3,"file":"index.umd.min.js","sources":["../../core/dist/index.esm.js","../src/index.ts"],"sourcesContent":["/**\n * Togglely Core SDK - Framework agnostic feature flag management\n *\n * Features:\n * - Real-time feature flag evaluation\n * - Offline fallback via JSON file, environment variables, or window object\n * - Multi-brand/tenant support\n * - Type-safe flag access\n * - Build-time JSON generation for offline-first deployment\n */\n// ==================== Togglely Client ====================\nclass TogglelyClient {\n constructor(config) {\n this.toggles = new Map();\n this.context = {};\n this.state = {\n isReady: false,\n isOffline: false,\n lastError: null,\n lastFetch: null\n };\n this.eventHandlers = new Map();\n this.offlineTogglesLoaded = false;\n // Request batching\n this.pendingKeys = new Set();\n this.pendingPromises = new Map();\n this.batchTimeout = null;\n this.BATCH_DELAY = 10; // ms to wait for batching requests\n this.config = {\n timeout: 5000,\n offlineFallback: true,\n envPrefix: 'TOGGLELY_',\n autoFetch: true,\n offlineJsonPath: undefined,\n ...config\n };\n // Initialize event handlers\n this.eventHandlers.set('ready', new Set());\n this.eventHandlers.set('update', new Set());\n this.eventHandlers.set('error', new Set());\n this.eventHandlers.set('offline', new Set());\n this.eventHandlers.set('online', new Set());\n // Set initial context if provided (including brandKey/tenantId)\n const initialContext = { ...config.context };\n if (config.brandKey)\n initialContext.brandKey = config.brandKey;\n if (config.tenantId)\n initialContext.tenantId = config.tenantId;\n this.context = initialContext;\n // Load offline toggles first (if enabled)\n if (this.config.offlineFallback) {\n this.loadOfflineToggles();\n }\n // Initial fetch (if enabled)\n if (this.config.autoFetch) {\n this.refresh();\n }\n }\n // ==================== Event Handling ====================\n on(event, handler) {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.add(handler);\n }\n return () => this.off(event, handler);\n }\n off(event, handler) {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler);\n }\n }\n emit(event) {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.forEach(handler => handler({ ...this.state }));\n }\n }\n // ==================== Context ====================\n setContext(context) {\n this.context = { ...this.context, ...context };\n }\n getContext() {\n return { ...this.context };\n }\n clearContext() {\n this.context = {};\n }\n // ==================== State ====================\n getState() {\n return { ...this.state };\n }\n isReady() {\n return this.state.isReady;\n }\n isOffline() {\n return this.state.isOffline;\n }\n // ==================== Toggle Accessors ====================\n /**\n * Check if a boolean feature flag is enabled\n * @param key - The flag key\n * @param defaultValue - Default value if flag not found\n * @returns Promise<boolean>\n */\n async isEnabled(key, defaultValue = false) {\n const value = await this.getValue(key);\n if (value === null) {\n return defaultValue;\n }\n // enabled is the primary on/off switch for a flag.\n // value.value holds the flag's configured value (used for non-boolean use-cases).\n // For boolean flags: \n // - If NOT enabled (toggle is OFF globally for environment), return false\n // - If ENABLED (toggle is ON), return the boolean value itself (true/false)\n if (typeof value.value === 'boolean') {\n return value.enabled && value.value;\n }\n // Fallback for non-boolean flags or if value is missing\n return value.enabled;\n }\n /**\n * Get a string feature flag value\n * @param key - The flag key\n * @param defaultValue - Default value if flag not found or disabled\n * @returns Promise<string>\n */\n async getString(key, defaultValue = '') {\n const value = await this.getValue(key);\n if (value === null || !value.enabled)\n return defaultValue;\n return String(value.value);\n }\n /**\n * Get a number feature flag value\n * @param key - The flag key\n * @param defaultValue - Default value if flag not found or disabled\n * @returns Promise<number>\n */\n async getNumber(key, defaultValue = 0) {\n const value = await this.getValue(key);\n if (value === null || !value.enabled)\n return defaultValue;\n return Number(value.value);\n }\n /**\n * Get a JSON feature flag value\n * @param key - The flag key\n * @param defaultValue - Default value if flag not found or disabled\n * @returns Promise<T>\n */\n async getJSON(key, defaultValue = {}) {\n const value = await this.getValue(key);\n if (value === null || !value.enabled)\n return defaultValue;\n if (typeof value.value === 'string') {\n try {\n return JSON.parse(value.value);\n }\n catch {\n return defaultValue;\n }\n }\n return value.value;\n }\n /**\n * Get raw toggle value\n * Uses stale-while-revalidate pattern: returns cached value immediately if available,\n * then refreshes from server in background.\n * Uses request batching: multiple getValue() calls within a short timeframe are batched into a single request.\n * @param key - The flag key\n * @returns Promise<ToggleValue | null>\n */\n async getValue(key) {\n // Check if we have a cached value first (stale-while-revalidate pattern)\n const cachedValue = this.toggles.get(key);\n if (cachedValue !== undefined) {\n // Trigger a background refresh without awaiting\n this.scheduleBatchRefresh();\n return cachedValue;\n }\n // Check if there's already a pending promise for this key (deduplication)\n const existingPromise = this.pendingPromises.get(key);\n if (existingPromise) {\n return new Promise((resolve, reject) => {\n existingPromise.push({ resolve, reject });\n });\n }\n // Add key to batch and create a promise\n this.pendingKeys.add(key);\n return new Promise((resolve, reject) => {\n // Store the promise callbacks\n const promises = this.pendingPromises.get(key) || [];\n promises.push({ resolve, reject });\n this.pendingPromises.set(key, promises);\n // Schedule the batch execution\n this.scheduleBatchExecution();\n });\n }\n /**\n * Schedule a background refresh of all toggles (for stale-while-revalidate)\n */\n scheduleBatchRefresh() {\n if (this.batchTimeout) {\n return; // Already scheduled\n }\n this.batchTimeout = setTimeout(() => {\n this.batchTimeout = null;\n // Refresh all toggles in background\n this.refresh().catch(() => { });\n }, this.BATCH_DELAY);\n }\n /**\n * Schedule the batch execution for pending keys\n */\n scheduleBatchExecution() {\n if (this.batchTimeout) {\n return; // Already scheduled\n }\n this.batchTimeout = setTimeout(() => {\n this.executeBatch();\n }, this.BATCH_DELAY);\n }\n /**\n * Execute the batch: fetch all pending keys in a single request\n */\n async executeBatch() {\n this.batchTimeout = null;\n const keys = Array.from(this.pendingKeys);\n const promises = new Map(this.pendingPromises);\n // Clear pending collections\n this.pendingKeys.clear();\n this.pendingPromises.clear();\n if (keys.length === 0) {\n return;\n }\n try {\n // Fetch all toggles at once (more efficient than individual requests)\n await this.refresh();\n // Resolve all pending promises with the fetched values\n for (const key of keys) {\n const keyPromises = promises.get(key) || [];\n const value = this.toggles.get(key) || null;\n for (const { resolve } of keyPromises) {\n resolve(value);\n }\n }\n }\n catch (error) {\n // Reject all pending promises\n for (const key of keys) {\n const keyPromises = promises.get(key) || [];\n for (const { reject } of keyPromises) {\n reject(error);\n }\n }\n }\n }\n /**\n * Get all toggles\n * @returns Record<string, ToggleValue>\n */\n getAllToggles() {\n const result = {};\n this.toggles.forEach((value, key) => {\n result[key] = value;\n });\n return result;\n }\n // ==================== Offline Fallback ====================\n /**\n * Load offline toggles from multiple sources (in priority order):\n * 1. Inline offlineToggles from config\n * 2. JSON file (if offlineJsonPath is set)\n * 3. window.__TOGGLELY_TOGGLES (browser)\n * 4. Environment variables (Node.js)\n */\n loadOfflineToggles() {\n try {\n // Priority 1: Inline offline toggles from config\n if (this.config.offlineToggles && Object.keys(this.config.offlineToggles).length > 0) {\n for (const [key, value] of Object.entries(this.config.offlineToggles)) {\n this.toggles.set(key, value);\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from config');\n return;\n }\n // Priority 2: JSON file (browser only - fetch synchronously not possible, will try async)\n if (this.config.offlineJsonPath && typeof window !== 'undefined') {\n this.loadOfflineJsonFile(this.config.offlineJsonPath);\n }\n // Priority 3: Browser environment - check window.__TOGGLELY_TOGGLES\n if (typeof window !== 'undefined' && window.__TOGGLELY_TOGGLES) {\n const offlineToggles = window.__TOGGLELY_TOGGLES;\n for (const [key, value] of Object.entries(offlineToggles)) {\n this.toggles.set(key, this.parseOfflineValue(value));\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from window.__TOGGLELY_TOGGLES');\n return;\n }\n // Priority 4: Node.js / Bun / Deno environment - check process.env\n if (typeof process !== 'undefined' && process.env) {\n const prefix = this.config.envPrefix;\n for (const [envKey, envValue] of Object.entries(process.env)) {\n if (envKey?.startsWith(prefix) && envValue !== undefined) {\n const toggleKey = envKey\n .slice(prefix.length)\n .toLowerCase()\n .replace(/_/g, '-');\n this.toggles.set(toggleKey, this.parseOfflineValue(envValue));\n }\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from environment variables');\n }\n }\n catch (error) {\n console.warn('[Togglely] Failed to load offline toggles:', error);\n }\n }\n /**\n * Load offline toggles from JSON file (async)\n */\n async loadOfflineJsonFile(path) {\n try {\n if (typeof window !== 'undefined') {\n // Browser - fetch the JSON file\n const response = await fetch(path);\n if (response.ok) {\n const data = await response.json();\n for (const [key, value] of Object.entries(data)) {\n this.toggles.set(key, this.parseOfflineValue(value));\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from JSON file:', path);\n }\n }\n else if (typeof require !== 'undefined') {\n // Node.js - require the JSON file\n const fs = require('fs');\n const pathModule = require('path');\n const fullPath = pathModule.resolve(path);\n if (fs.existsSync(fullPath)) {\n const data = JSON.parse(fs.readFileSync(fullPath, 'utf-8'));\n for (const [key, value] of Object.entries(data)) {\n this.toggles.set(key, this.parseOfflineValue(value));\n }\n this.offlineTogglesLoaded = true;\n console.log('[Togglely] Loaded offline toggles from JSON file:', fullPath);\n }\n }\n }\n catch (error) {\n console.warn('[Togglely] Failed to load offline JSON file:', error);\n }\n }\n getOfflineToggle(key) {\n if (!this.config.offlineFallback)\n return null;\n const cached = this.toggles.get(key);\n if (cached) {\n if (!this.state.isOffline) {\n this.state.isOffline = true;\n this.emit('offline');\n }\n return cached;\n }\n return null;\n }\n parseOfflineValue(value) {\n if (typeof value === 'string') {\n const lower = value.toLowerCase();\n if (lower === 'true')\n return { value: true, enabled: true };\n if (lower === 'false')\n return { value: false, enabled: true };\n if (!isNaN(Number(value))) {\n return { value: Number(value), enabled: true };\n }\n try {\n const parsed = JSON.parse(value);\n return { value: parsed, enabled: true };\n }\n catch {\n return { value, enabled: true };\n }\n }\n return { value, enabled: true };\n }\n // ==================== Refresh / Polling ====================\n /**\n * Refresh all toggles from the server\n */\n async refresh() {\n try {\n const params = new URLSearchParams();\n // Support both brandKey and tenantId for maximum compatibility\n if (this.context.brandKey)\n params.set('brandKey', String(this.context.brandKey));\n if (this.context.tenantId)\n params.set('tenantId', String(this.context.tenantId));\n if (Object.keys(this.context).length > 0) {\n params.set('context', JSON.stringify(this.context));\n }\n const headers = {\n 'Content-Type': 'application/json'\n };\n if (this.config.apiKey) {\n headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n }\n const response = await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${encodeURIComponent(this.config.project)}/${encodeURIComponent(this.config.environment)}?${params.toString()}`, { headers });\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n const data = await response.json();\n this.toggles.clear();\n for (const [key, value] of Object.entries(data)) {\n this.toggles.set(key, value);\n }\n this.state.lastFetch = new Date();\n this.state.lastError = null;\n if (!this.state.isReady) {\n this.state.isReady = true;\n this.emit('ready');\n }\n if (this.state.isOffline) {\n this.state.isOffline = false;\n this.emit('online');\n }\n this.emit('update');\n }\n catch (error) {\n this.state.lastError = error;\n if (this.config.offlineFallback && this.offlineTogglesLoaded) {\n if (!this.state.isOffline) {\n this.state.isOffline = true;\n this.emit('offline');\n }\n }\n this.emit('error');\n console.error('[Togglely] Failed to refresh toggles:', error);\n }\n }\n forceOfflineMode() {\n this.state.isOffline = true;\n this.emit('offline');\n }\n forceOnlineMode() {\n this.state.isOffline = false;\n this.refresh();\n this.emit('online');\n }\n // ==================== Cleanup ====================\n destroy() {\n this.toggles.clear();\n this.eventHandlers.forEach(handlers => handlers.clear());\n }\n // ==================== Private Helpers ====================\n fetchWithTimeout(url, options) {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n reject(new Error('Request timeout'));\n }, this.config.timeout);\n fetch(url, options)\n .then(response => {\n clearTimeout(timeoutId);\n resolve(response);\n })\n .catch(error => {\n clearTimeout(timeoutId);\n reject(error);\n });\n });\n }\n}\n// ==================== Utility Functions ====================\n/**\n * Create a client-side toggle loader script\n * Use this to inject offline toggles into your HTML\n */\nfunction createOfflineTogglesScript(toggles) {\n return `<script>window.__TOGGLELY_TOGGLES = ${JSON.stringify(toggles)};</script>`;\n}\n/**\n * Helper to convert toggles to environment variables\n */\nfunction togglesToEnvVars(toggles, prefix = 'TOGGLELY_') {\n const envVars = {};\n for (const [key, value] of Object.entries(toggles)) {\n const envKey = prefix + key.toUpperCase().replace(/-/g, '_');\n envVars[envKey] = typeof value === 'object' ? JSON.stringify(value) : String(value);\n }\n return envVars;\n}\n\nexport { TogglelyClient, createOfflineTogglesScript, TogglelyClient as default, togglesToEnvVars };\n//# sourceMappingURL=index.esm.js.map\n",null],"names":["TogglelyClient","constructor","config","this","toggles","Map","context","state","isReady","isOffline","lastError","lastFetch","eventHandlers","offlineTogglesLoaded","pendingKeys","Set","pendingPromises","batchTimeout","BATCH_DELAY","timeout","offlineFallback","envPrefix","autoFetch","offlineJsonPath","undefined","set","initialContext","brandKey","tenantId","loadOfflineToggles","refresh","on","event","handler","handlers","get","add","off","delete","emit","forEach","setContext","getContext","clearContext","getState","isEnabled","key","defaultValue","value","getValue","enabled","getString","String","getNumber","Number","getJSON","JSON","parse","cachedValue","scheduleBatchRefresh","existingPromise","Promise","resolve","reject","push","promises","scheduleBatchExecution","setTimeout","catch","executeBatch","keys","Array","from","clear","length","keyPromises","error","getAllToggles","result","offlineToggles","Object","entries","console","log","window","loadOfflineJsonFile","__TOGGLELY_TOGGLES","parseOfflineValue","process","env","prefix","envKey","envValue","startsWith","toggleKey","slice","toLowerCase","replace","warn","path","response","fetch","ok","data","json","require","fs","fullPath","existsSync","readFileSync","getOfflineToggle","cached","lower","isNaN","params","URLSearchParams","stringify","headers","apiKey","fetchWithTimeout","baseUrl","encodeURIComponent","project","environment","toString","Error","status","Date","forceOfflineMode","forceOnlineMode","destroy","url","options","timeoutId","then","clearTimeout","getGlobalTogglely","togglely","async","client","updateAll","selectors","invert","isArray","selector","isToggleEnabled","shouldShow","document","querySelectorAll","el","style","display","hideClass","showClass","classList","remove","envVars","toUpperCase"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@togglely/sdk",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "Vanilla JavaScript SDK for Togglely - Feature toggles for any framework",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",