@togglely/sdk 1.2.3 → 1.2.4
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 +17 -6
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +1 -1
- package/dist/index.umd.min.js.map +1 -1
- package/package.json +1 -1
package/dist/index.umd.js
CHANGED
|
@@ -31,7 +31,10 @@
|
|
|
31
31
|
this.pendingKeys = new Set();
|
|
32
32
|
this.pendingPromises = new Map();
|
|
33
33
|
this.batchTimeout = null;
|
|
34
|
+
this.refreshTimeout = null;
|
|
35
|
+
this.lastRefreshTime = 0;
|
|
34
36
|
this.BATCH_DELAY = 10; // ms to wait for batching requests
|
|
37
|
+
this.MIN_REFRESH_INTERVAL = 5000; // Minimum 5s between background refreshes
|
|
35
38
|
this.config = {
|
|
36
39
|
timeout: 5000,
|
|
37
40
|
offlineFallback: true,
|
|
@@ -181,8 +184,11 @@
|
|
|
181
184
|
// Check if we have a cached value first (stale-while-revalidate pattern)
|
|
182
185
|
const cachedValue = this.toggles.get(key);
|
|
183
186
|
if (cachedValue !== undefined) {
|
|
184
|
-
//
|
|
185
|
-
|
|
187
|
+
// Only trigger background refresh if enough time has passed
|
|
188
|
+
const now = Date.now();
|
|
189
|
+
if (now - this.lastRefreshTime > this.MIN_REFRESH_INTERVAL) {
|
|
190
|
+
this.scheduleBackgroundRefresh();
|
|
191
|
+
}
|
|
186
192
|
return cachedValue;
|
|
187
193
|
}
|
|
188
194
|
// Check if there's already a pending promise for this key (deduplication)
|
|
@@ -205,13 +211,15 @@
|
|
|
205
211
|
}
|
|
206
212
|
/**
|
|
207
213
|
* Schedule a background refresh of all toggles (for stale-while-revalidate)
|
|
214
|
+
* Throttled to prevent too frequent updates
|
|
208
215
|
*/
|
|
209
|
-
|
|
210
|
-
if (this.
|
|
216
|
+
scheduleBackgroundRefresh() {
|
|
217
|
+
if (this.refreshTimeout) {
|
|
211
218
|
return; // Already scheduled
|
|
212
219
|
}
|
|
213
|
-
this.
|
|
214
|
-
this.
|
|
220
|
+
this.refreshTimeout = setTimeout(() => {
|
|
221
|
+
this.refreshTimeout = null;
|
|
222
|
+
this.lastRefreshTime = Date.now();
|
|
215
223
|
// Refresh all toggles in background
|
|
216
224
|
this.refresh().catch(() => { });
|
|
217
225
|
}, this.BATCH_DELAY);
|
|
@@ -243,6 +251,8 @@
|
|
|
243
251
|
try {
|
|
244
252
|
// Fetch all toggles at once (more efficient than individual requests)
|
|
245
253
|
await this.refresh();
|
|
254
|
+
// Update last refresh time to prevent immediate background refresh
|
|
255
|
+
this.lastRefreshTime = Date.now();
|
|
246
256
|
// Resolve all pending promises with the fetched values
|
|
247
257
|
for (const key of keys) {
|
|
248
258
|
const keyPromises = promises.get(key) || [];
|
|
@@ -427,6 +437,7 @@
|
|
|
427
437
|
}
|
|
428
438
|
this.state.lastFetch = new Date();
|
|
429
439
|
this.state.lastError = null;
|
|
440
|
+
this.lastRefreshTime = Date.now();
|
|
430
441
|
if (!this.state.isReady) {
|
|
431
442
|
this.state.isReady = true;
|
|
432
443
|
this.emit('ready');
|
package/dist/index.umd.js.map
CHANGED
|
@@ -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 // 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
|
+
{"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.refreshTimeout = null;\n this.lastRefreshTime = 0;\n this.BATCH_DELAY = 10; // ms to wait for batching requests\n this.MIN_REFRESH_INTERVAL = 5000; // Minimum 5s between background refreshes\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 // Only trigger background refresh if enough time has passed\n const now = Date.now();\n if (now - this.lastRefreshTime > this.MIN_REFRESH_INTERVAL) {\n this.scheduleBackgroundRefresh();\n }\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 * Throttled to prevent too frequent updates\n */\n scheduleBackgroundRefresh() {\n if (this.refreshTimeout) {\n return; // Already scheduled\n }\n this.refreshTimeout = setTimeout(() => {\n this.refreshTimeout = null;\n this.lastRefreshTime = Date.now();\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 // Update last refresh time to prevent immediate background refresh\n this.lastRefreshTime = Date.now();\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 this.lastRefreshTime = Date.now();\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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"}
|
package/dist/index.umd.min.js
CHANGED
|
@@ -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.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.
|
|
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.refreshTimeout=null,this.lastRefreshTime=0,this.BATCH_DELAY=10,this.MIN_REFRESH_INTERVAL=5e3,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 Date.now()-this.lastRefreshTime>this.MIN_REFRESH_INTERVAL&&this.scheduleBackgroundRefresh(),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()}))}scheduleBackgroundRefresh(){this.refreshTimeout||(this.refreshTimeout=setTimeout(()=>{this.refreshTimeout=null,this.lastRefreshTime=Date.now(),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(),this.lastRefreshTime=Date.now();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.lastRefreshTime=Date.now(),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 // 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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"}
|
|
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.refreshTimeout = null;\n this.lastRefreshTime = 0;\n this.BATCH_DELAY = 10; // ms to wait for batching requests\n this.MIN_REFRESH_INTERVAL = 5000; // Minimum 5s between background refreshes\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 // Only trigger background refresh if enough time has passed\n const now = Date.now();\n if (now - this.lastRefreshTime > this.MIN_REFRESH_INTERVAL) {\n this.scheduleBackgroundRefresh();\n }\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 * Throttled to prevent too frequent updates\n */\n scheduleBackgroundRefresh() {\n if (this.refreshTimeout) {\n return; // Already scheduled\n }\n this.refreshTimeout = setTimeout(() => {\n this.refreshTimeout = null;\n this.lastRefreshTime = Date.now();\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 // Update last refresh time to prevent immediate background refresh\n this.lastRefreshTime = Date.now();\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 this.lastRefreshTime = Date.now();\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","refreshTimeout","lastRefreshTime","BATCH_DELAY","MIN_REFRESH_INTERVAL","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","Date","now","scheduleBackgroundRefresh","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","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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"}
|