@togglely/sdk 1.1.2 → 1.2.0

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/README.md CHANGED
@@ -1,63 +1,64 @@
1
- # @togglely/sdk
1
+ # Togglely Vanilla JavaScript SDK
2
2
 
3
- Vanilla JavaScript SDK for Togglely - Works with any framework or vanilla JS.
3
+ Vanilla JavaScript SDK for [Togglely](https://togglely.io) feature flag management. Works in browsers and Node.js without any framework.
4
+
5
+ ## Features
6
+
7
+ - 🌍 **Universal** - Works in browser and Node.js
8
+ - 📦 **Zero dependencies** - Lightweight and fast
9
+ - 💾 **Offline support** - JSON file, environment variables, or window object
10
+ - 🎯 **Simple API** - Easy to use with global instance
11
+ - 🔒 **TypeScript** - Full type support
4
12
 
5
13
  ## Installation
6
14
 
15
+ ### NPM
16
+
7
17
  ```bash
8
18
  npm install @togglely/sdk
9
19
  ```
10
20
 
11
- Or via CDN:
21
+ ### CDN
12
22
 
13
23
  ```html
14
24
  <script src="https://unpkg.com/@togglely/sdk/dist/index.umd.min.js"></script>
15
25
  ```
16
26
 
17
- ## Usage
18
-
19
- ### ES Modules
20
-
21
- ```javascript
22
- import { TogglelyClient } from '@togglely/sdk';
23
-
24
- const client = new TogglelyClient({
25
- apiKey: 'your-api-key',
26
- environment: 'production',
27
- baseUrl: 'https://your-togglely-instance.com'
28
- });
29
-
30
- const isEnabled = await client.isEnabled('new-feature', false);
31
- ```
27
+ ## Quick Start
32
28
 
33
- ### Global Instance (Vanilla JS)
29
+ ### Browser (Module)
34
30
 
35
31
  ```javascript
36
32
  import { initTogglely, isEnabled } from '@togglely/sdk';
37
33
 
38
- // Initialize global instance
34
+ // Initialize
39
35
  initTogglely({
40
36
  apiKey: 'your-api-key',
37
+ project: 'my-project',
41
38
  environment: 'production',
42
- baseUrl: 'https://your-togglely-instance.com'
39
+ baseUrl: 'https://togglely.io',
43
40
  });
44
41
 
45
42
  // Use global helpers
46
- const enabled = await isEnabled('new-feature', false);
43
+ const newFeature = await isEnabled('new-feature', false);
44
+ if (newFeature) {
45
+ document.getElementById('new-feature').style.display = 'block';
46
+ }
47
47
  ```
48
48
 
49
- ### CDN Usage
49
+ ### Browser (CDN)
50
50
 
51
51
  ```html
52
52
  <script src="https://unpkg.com/@togglely/sdk/dist/index.umd.min.js"></script>
53
53
  <script>
54
- const client = new Togglely.TogglelyClient({
54
+ Togglely.initTogglely({
55
55
  apiKey: 'your-api-key',
56
+ project: 'my-project',
56
57
  environment: 'production',
57
- baseUrl: 'https://your-togglely-instance.com'
58
+ baseUrl: 'https://togglely.io',
58
59
  });
59
60
 
60
- client.isEnabled('new-feature').then(function(enabled) {
61
+ Togglely.isEnabled('new-feature').then(function(enabled) {
61
62
  if (enabled) {
62
63
  document.getElementById('new-feature').style.display = 'block';
63
64
  }
@@ -65,26 +66,199 @@ const enabled = await isEnabled('new-feature', false);
65
66
  </script>
66
67
  ```
67
68
 
68
- ### DOM Helpers
69
+ ### Node.js
69
70
 
70
71
  ```javascript
71
- import { togglelyToggle, togglelyInit } from '@togglely/sdk';
72
+ const { TogglelyClient } = require('@togglely/sdk');
73
+
74
+ const client = new TogglelyClient({
75
+ apiKey: 'your-api-key',
76
+ project: 'my-project',
77
+ environment: 'production',
78
+ baseUrl: 'https://togglely.io',
79
+ });
72
80
 
73
- // Toggle element visibility based on toggle
74
- togglelyToggle('#new-feature', 'new-feature');
81
+ const isEnabled = await client.isEnabled('new-feature', false);
82
+ console.log('New feature:', isEnabled);
83
+ ```
75
84
 
76
- // Initialize multiple elements
77
- togglelyInit({
85
+ ## Configuration
86
+
87
+ ```javascript
88
+ initTogglely({
89
+ apiKey: 'your-api-key',
90
+ project: 'my-project',
91
+ environment: 'production',
92
+ baseUrl: 'https://togglely.io',
93
+ tenantId: 'brand-a', // For multi-brand projects
94
+ offlineJsonPath: '/toggles.json', // Offline fallback
95
+ timeout: 5000, // Request timeout
96
+ });
97
+ ```
98
+
99
+ ## Global Helpers
100
+
101
+ After calling `initTogglely()`, you can use these global helpers:
102
+
103
+ ```javascript
104
+ import { isEnabled, getString, getNumber, getJSON } from '@togglely/sdk';
105
+
106
+ // Boolean toggle
107
+ const enabled = await isEnabled('new-feature', false);
108
+
109
+ // String toggle
110
+ const message = await getString('welcome-message', 'Hello!');
111
+
112
+ // Number toggle
113
+ const limit = await getNumber('max-items', 10);
114
+
115
+ // JSON toggle
116
+ const config = await getJSON('app-config', { theme: 'dark' });
117
+ ```
118
+
119
+ ## DOM Helpers
120
+
121
+ ### togglelyToggle
122
+
123
+ Show/hide elements based on a toggle:
124
+
125
+ ```javascript
126
+ import { togglelyToggle } from '@togglely/sdk';
127
+
128
+ // Show element when toggle is enabled
129
+ await togglelyToggle('#new-feature', 'new-feature');
130
+
131
+ // Hide element when toggle is disabled (invert)
132
+ await togglelyToggle('#old-feature', 'new-feature', { invert: true });
133
+
134
+ // With default value
135
+ await togglelyToggle('#beta', 'beta-feature', { defaultValue: true });
136
+ ```
137
+
138
+ ### togglelyInit
139
+
140
+ Initialize multiple elements:
141
+
142
+ ```javascript
143
+ import { togglelyInit } from '@togglely/sdk';
144
+
145
+ const unsubscribe = togglelyInit({
146
+ // Simple selectors
78
147
  'new-feature': ['.new-feature', '.new-banner'],
79
- 'dark-mode': ['body'],
148
+
149
+ // With options
80
150
  'premium': {
81
151
  selector: '.premium-content',
82
- defaultValue: false,
83
- invert: false
152
+ defaultValue: false
153
+ },
154
+
155
+ // Invert (hide when enabled)
156
+ 'new-ui': {
157
+ selector: '.old-ui',
158
+ invert: true
84
159
  }
85
160
  });
161
+
162
+ // Cleanup
163
+ unsubscribe();
164
+ ```
165
+
166
+ ## Offline Fallback
167
+
168
+ ### Environment Variables (Node.js)
169
+
170
+ ```bash
171
+ TOGGLELY_NEW_FEATURE=true
172
+ TOGGLELY_MAX_ITEMS=100
173
+ TOGGLELY_WELCOME_MESSAGE="Hello World"
174
+ ```
175
+
176
+ ```javascript
177
+ const client = new TogglelyClient({
178
+ apiKey: 'your-api-key',
179
+ project: 'my-project',
180
+ environment: 'production',
181
+ baseUrl: 'https://togglely.io',
182
+ envPrefix: 'TOGGLELY_', // Default
183
+ });
184
+ ```
185
+
186
+ ### Window Object (Browser)
187
+
188
+ ```html
189
+ <script>
190
+ window.__TOGGLELY_TOGGLES = {
191
+ 'new-feature': { value: true, enabled: true },
192
+ 'max-items': { value: 100, enabled: true },
193
+ 'welcome-message': { value: 'Hello World', enabled: true }
194
+ };
195
+ </script>
196
+ <script src="https://unpkg.com/@togglely/sdk/dist/index.umd.min.js"></script>
197
+ ```
198
+
199
+ ### JSON File
200
+
201
+ Generate offline JSON:
202
+
203
+ ```bash
204
+ togglely-pull --apiKey=xxx --project=my-project --environment=production --output=./toggles.json
205
+ ```
206
+
207
+ Use in your app:
208
+
209
+ ```javascript
210
+ initTogglely({
211
+ apiKey: 'your-api-key',
212
+ project: 'my-project',
213
+ environment: 'production',
214
+ baseUrl: 'https://togglely.io',
215
+ offlineJsonPath: '/toggles.json',
216
+ });
217
+ ```
218
+
219
+ ## Direct Client Usage
220
+
221
+ For more control, use the client directly:
222
+
223
+ ```javascript
224
+ import { TogglelyClient } from '@togglely/sdk';
225
+
226
+ const client = new TogglelyClient({
227
+ apiKey: 'your-api-key',
228
+ project: 'my-project',
229
+ environment: 'production',
230
+ baseUrl: 'https://togglely.io',
231
+ tenantId: 'brand-a',
232
+ });
233
+
234
+ // Set targeting context
235
+ client.setContext({ userId: '123', country: 'DE' });
236
+
237
+ // Check toggle
238
+ const enabled = await client.isEnabled('new-feature', false);
239
+
240
+ // Listen to events
241
+ client.on('ready', () => console.log('Ready!'));
242
+ client.on('offline', () => console.log('Offline mode'));
243
+ client.on('update', () => console.log('Toggles updated'));
244
+
245
+ // Get all toggles
246
+ const all = client.getAllToggles();
247
+
248
+ // Cleanup
249
+ client.destroy();
250
+ ```
251
+
252
+ ## Build-Time JSON Generation
253
+
254
+ ```json
255
+ {
256
+ "scripts": {
257
+ "build": "togglely-pull --apiKey=$TOGGLELY_APIKEY --project=my-project --environment=production --output=./toggles.json"
258
+ }
259
+ }
86
260
  ```
87
261
 
88
- ## API
262
+ ## License
89
263
 
90
- Same as `@togglely/sdk-core`.
264
+ MIT
package/dist/index.umd.js CHANGED
@@ -5,13 +5,16 @@
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
7
  /**
8
- * Togglely Core SDK - Framework agnostic
8
+ * Togglely Core SDK - Framework agnostic feature flag management
9
9
  *
10
- * Supports offline fallback via environment variables
11
- */
12
- /**
13
- * Core Togglely Client
10
+ * Features:
11
+ * - Real-time feature flag evaluation
12
+ * - Offline fallback via JSON file, environment variables, or window object
13
+ * - Multi-brand/tenant support
14
+ * - Type-safe flag access
15
+ * - Build-time JSON generation for offline-first deployment
14
16
  */
17
+ // ==================== Togglely Client ====================
15
18
  class TogglelyClient {
16
19
  constructor(config) {
17
20
  this.toggles = new Map();
@@ -25,10 +28,11 @@
25
28
  this.eventHandlers = new Map();
26
29
  this.offlineTogglesLoaded = false;
27
30
  this.config = {
28
- refreshInterval: 60000,
29
31
  timeout: 5000,
30
32
  offlineFallback: true,
31
33
  envPrefix: 'TOGGLELY_',
34
+ autoFetch: true,
35
+ offlineJsonPath: undefined,
32
36
  ...config
33
37
  };
34
38
  // Initialize event handlers
@@ -37,12 +41,21 @@
37
41
  this.eventHandlers.set('error', new Set());
38
42
  this.eventHandlers.set('offline', new Set());
39
43
  this.eventHandlers.set('online', new Set());
44
+ // Set initial context if provided (including brandKey/tenantId)
45
+ const initialContext = { ...config.context };
46
+ if (config.brandKey)
47
+ initialContext.brandKey = config.brandKey;
48
+ if (config.tenantId)
49
+ initialContext.tenantId = config.tenantId;
50
+ this.context = initialContext;
40
51
  // Load offline toggles first (if enabled)
41
52
  if (this.config.offlineFallback) {
42
53
  this.loadOfflineToggles();
43
54
  }
44
- // Start polling
45
- this.startPolling();
55
+ // Initial fetch (if enabled)
56
+ if (this.config.autoFetch) {
57
+ this.refresh();
58
+ }
46
59
  }
47
60
  // ==================== Event Handling ====================
48
61
  on(event, handler) {
@@ -85,24 +98,49 @@
85
98
  return this.state.isOffline;
86
99
  }
87
100
  // ==================== Toggle Accessors ====================
101
+ /**
102
+ * Check if a boolean feature flag is enabled
103
+ * @param key - The flag key
104
+ * @param defaultValue - Default value if flag not found
105
+ * @returns Promise<boolean>
106
+ */
88
107
  async isEnabled(key, defaultValue = false) {
89
108
  const value = await this.getValue(key);
90
- if (value === null)
109
+ if (value === null) {
91
110
  return defaultValue;
111
+ }
92
112
  return value.enabled && value.value === true;
93
113
  }
114
+ /**
115
+ * Get a string feature flag value
116
+ * @param key - The flag key
117
+ * @param defaultValue - Default value if flag not found or disabled
118
+ * @returns Promise<string>
119
+ */
94
120
  async getString(key, defaultValue = '') {
95
121
  const value = await this.getValue(key);
96
122
  if (value === null || !value.enabled)
97
123
  return defaultValue;
98
124
  return String(value.value);
99
125
  }
126
+ /**
127
+ * Get a number feature flag value
128
+ * @param key - The flag key
129
+ * @param defaultValue - Default value if flag not found or disabled
130
+ * @returns Promise<number>
131
+ */
100
132
  async getNumber(key, defaultValue = 0) {
101
133
  const value = await this.getValue(key);
102
134
  if (value === null || !value.enabled)
103
135
  return defaultValue;
104
136
  return Number(value.value);
105
137
  }
138
+ /**
139
+ * Get a JSON feature flag value
140
+ * @param key - The flag key
141
+ * @param defaultValue - Default value if flag not found or disabled
142
+ * @returns Promise<T>
143
+ */
106
144
  async getJSON(key, defaultValue = {}) {
107
145
  const value = await this.getValue(key);
108
146
  if (value === null || !value.enabled)
@@ -117,29 +155,41 @@
117
155
  }
118
156
  return value.value;
119
157
  }
158
+ /**
159
+ * Get raw toggle value
160
+ * @param key - The flag key
161
+ * @returns Promise<ToggleValue | null>
162
+ */
120
163
  async getValue(key) {
121
- // Try cache first
122
- const cached = this.toggles.get(key);
123
- if (cached) {
124
- return cached;
164
+ // Try cache first - but only if no context is set
165
+ if (Object.keys(this.context).length === 0) {
166
+ const cached = this.toggles.get(key);
167
+ if (cached) {
168
+ return cached;
169
+ }
125
170
  }
126
171
  // Fetch from server
127
172
  try {
128
- const response = await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${this.config.environment}/${key}`, {
129
- headers: {
130
- 'Authorization': `Bearer ${this.config.apiKey}`,
131
- 'Content-Type': 'application/json'
132
- }
133
- });
173
+ const params = new URLSearchParams();
174
+ if (this.config.apiKey)
175
+ params.set('apiKey', this.config.apiKey);
176
+ const brandKey = this.context.tenantId || this.context.brandKey;
177
+ if (brandKey)
178
+ params.set('tenantId', String(brandKey));
179
+ if (Object.keys(this.context).length > 0) {
180
+ params.set('context', JSON.stringify(this.context));
181
+ }
182
+ const query = params.toString() ? `?${params.toString()}` : '';
183
+ const url = `${this.config.baseUrl}/sdk/flags/${encodeURIComponent(this.config.project)}/${encodeURIComponent(this.config.environment)}/${encodeURIComponent(key)}${query}`;
184
+ const response = await this.fetchWithTimeout(url, { headers: { 'Content-Type': 'application/json' } });
134
185
  if (!response.ok) {
135
186
  if (response.status === 404) {
136
187
  return null;
137
188
  }
138
- throw new Error(`HTTP ${response.status}`);
189
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
139
190
  }
140
191
  const data = await response.json();
141
192
  this.toggles.set(key, data);
142
- // Update state if we were offline
143
193
  if (this.state.isOffline) {
144
194
  this.state.isOffline = false;
145
195
  this.emit('online');
@@ -148,14 +198,20 @@
148
198
  }
149
199
  catch (error) {
150
200
  // Try offline fallback
151
- const offlineValue = this.getOfflineToggle(key);
152
- if (offlineValue !== null) {
153
- return offlineValue;
201
+ if (this.config.offlineFallback) {
202
+ const offlineValue = this.getOfflineToggle(key);
203
+ if (offlineValue !== null) {
204
+ return offlineValue;
205
+ }
154
206
  }
155
- console.error(`[Togglely] Failed to fetch toggle "${key}":`, error);
156
- return null;
207
+ // Return safe default
208
+ return { value: false, enabled: false };
157
209
  }
158
210
  }
211
+ /**
212
+ * Get all toggles
213
+ * @returns Record<string, ToggleValue>
214
+ */
159
215
  getAllToggles() {
160
216
  const result = {};
161
217
  this.toggles.forEach((value, key) => {
@@ -165,12 +221,28 @@
165
221
  }
166
222
  // ==================== Offline Fallback ====================
167
223
  /**
168
- * Load toggles from environment variables
169
- * Format: TOGGLELY_<TOGGLE_KEY>=<value> or TOGGLELY_<TOGGLE_KEY>_ENABLED=true
224
+ * Load offline toggles from multiple sources (in priority order):
225
+ * 1. Inline offlineToggles from config
226
+ * 2. JSON file (if offlineJsonPath is set)
227
+ * 3. window.__TOGGLELY_TOGGLES (browser)
228
+ * 4. Environment variables (Node.js)
170
229
  */
171
230
  loadOfflineToggles() {
172
231
  try {
173
- // Browser environment - check window.__TOGGLELY_TOGGLES
232
+ // Priority 1: Inline offline toggles from config
233
+ if (this.config.offlineToggles && Object.keys(this.config.offlineToggles).length > 0) {
234
+ for (const [key, value] of Object.entries(this.config.offlineToggles)) {
235
+ this.toggles.set(key, value);
236
+ }
237
+ this.offlineTogglesLoaded = true;
238
+ console.log('[Togglely] Loaded offline toggles from config');
239
+ return;
240
+ }
241
+ // Priority 2: JSON file (browser only - fetch synchronously not possible, will try async)
242
+ if (this.config.offlineJsonPath && typeof window !== 'undefined') {
243
+ this.loadOfflineJsonFile(this.config.offlineJsonPath);
244
+ }
245
+ // Priority 3: Browser environment - check window.__TOGGLELY_TOGGLES
174
246
  if (typeof window !== 'undefined' && window.__TOGGLELY_TOGGLES) {
175
247
  const offlineToggles = window.__TOGGLELY_TOGGLES;
176
248
  for (const [key, value] of Object.entries(offlineToggles)) {
@@ -180,12 +252,11 @@
180
252
  console.log('[Togglely] Loaded offline toggles from window.__TOGGLELY_TOGGLES');
181
253
  return;
182
254
  }
183
- // Node.js / Bun / Deno environment - check process.env
255
+ // Priority 4: Node.js / Bun / Deno environment - check process.env
184
256
  if (typeof process !== 'undefined' && process.env) {
185
257
  const prefix = this.config.envPrefix;
186
258
  for (const [envKey, envValue] of Object.entries(process.env)) {
187
259
  if (envKey?.startsWith(prefix) && envValue !== undefined) {
188
- // Parse toggle key: TOGGLELY_MY_FEATURE -> my-feature
189
260
  const toggleKey = envKey
190
261
  .slice(prefix.length)
191
262
  .toLowerCase()
@@ -201,13 +272,47 @@
201
272
  console.warn('[Togglely] Failed to load offline toggles:', error);
202
273
  }
203
274
  }
275
+ /**
276
+ * Load offline toggles from JSON file (async)
277
+ */
278
+ async loadOfflineJsonFile(path) {
279
+ try {
280
+ if (typeof window !== 'undefined') {
281
+ // Browser - fetch the JSON file
282
+ const response = await fetch(path);
283
+ if (response.ok) {
284
+ const data = await response.json();
285
+ for (const [key, value] of Object.entries(data)) {
286
+ this.toggles.set(key, this.parseOfflineValue(value));
287
+ }
288
+ this.offlineTogglesLoaded = true;
289
+ console.log('[Togglely] Loaded offline toggles from JSON file:', path);
290
+ }
291
+ }
292
+ else if (typeof require !== 'undefined') {
293
+ // Node.js - require the JSON file
294
+ const fs = require('fs');
295
+ const pathModule = require('path');
296
+ const fullPath = pathModule.resolve(path);
297
+ if (fs.existsSync(fullPath)) {
298
+ const data = JSON.parse(fs.readFileSync(fullPath, 'utf-8'));
299
+ for (const [key, value] of Object.entries(data)) {
300
+ this.toggles.set(key, this.parseOfflineValue(value));
301
+ }
302
+ this.offlineTogglesLoaded = true;
303
+ console.log('[Togglely] Loaded offline toggles from JSON file:', fullPath);
304
+ }
305
+ }
306
+ }
307
+ catch (error) {
308
+ console.warn('[Togglely] Failed to load offline JSON file:', error);
309
+ }
310
+ }
204
311
  getOfflineToggle(key) {
205
312
  if (!this.config.offlineFallback)
206
313
  return null;
207
- // Try to get from already loaded offline toggles
208
314
  const cached = this.toggles.get(key);
209
315
  if (cached) {
210
- // If we haven't emitted offline event yet, do it now
211
316
  if (!this.state.isOffline) {
212
317
  this.state.isOffline = true;
213
318
  this.emit('offline');
@@ -217,38 +322,41 @@
217
322
  return null;
218
323
  }
219
324
  parseOfflineValue(value) {
220
- // Handle boolean strings
221
325
  if (typeof value === 'string') {
222
326
  const lower = value.toLowerCase();
223
327
  if (lower === 'true')
224
328
  return { value: true, enabled: true };
225
329
  if (lower === 'false')
226
330
  return { value: false, enabled: true };
227
- // Try to parse as number
228
331
  if (!isNaN(Number(value))) {
229
332
  return { value: Number(value), enabled: true };
230
333
  }
231
- // Try to parse as JSON
232
334
  try {
233
335
  const parsed = JSON.parse(value);
234
336
  return { value: parsed, enabled: true };
235
337
  }
236
338
  catch {
237
- // Return as string
238
339
  return { value, enabled: true };
239
340
  }
240
341
  }
241
342
  return { value, enabled: true };
242
343
  }
243
344
  // ==================== Refresh / Polling ====================
345
+ /**
346
+ * Refresh all toggles from the server
347
+ */
244
348
  async refresh() {
245
349
  try {
246
- const response = await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${this.config.environment}`, {
247
- headers: {
248
- 'Authorization': `Bearer ${this.config.apiKey}`,
249
- 'Content-Type': 'application/json'
250
- }
251
- });
350
+ const params = new URLSearchParams();
351
+ if (this.config.apiKey)
352
+ params.set('apiKey', this.config.apiKey);
353
+ const brandKey = this.context.tenantId || this.context.brandKey;
354
+ if (brandKey)
355
+ params.set('tenantId', String(brandKey));
356
+ if (Object.keys(this.context).length > 0) {
357
+ params.set('context', JSON.stringify(this.context));
358
+ }
359
+ const response = await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${encodeURIComponent(this.config.project)}/${encodeURIComponent(this.config.environment)}?${params.toString()}`, { headers: { 'Content-Type': 'application/json' } });
252
360
  if (!response.ok) {
253
361
  throw new Error(`HTTP ${response.status}`);
254
362
  }
@@ -263,7 +371,6 @@
263
371
  this.state.isReady = true;
264
372
  this.emit('ready');
265
373
  }
266
- // If we were offline, go online
267
374
  if (this.state.isOffline) {
268
375
  this.state.isOffline = false;
269
376
  this.emit('online');
@@ -272,7 +379,6 @@
272
379
  }
273
380
  catch (error) {
274
381
  this.state.lastError = error;
275
- // If we have offline toggles, switch to offline mode
276
382
  if (this.config.offlineFallback && this.offlineTogglesLoaded) {
277
383
  if (!this.state.isOffline) {
278
384
  this.state.isOffline = true;
@@ -294,23 +400,10 @@
294
400
  }
295
401
  // ==================== Cleanup ====================
296
402
  destroy() {
297
- if (this.refreshTimer) {
298
- clearInterval(this.refreshTimer);
299
- }
300
403
  this.toggles.clear();
301
404
  this.eventHandlers.forEach(handlers => handlers.clear());
302
405
  }
303
406
  // ==================== Private Helpers ====================
304
- startPolling() {
305
- // Initial fetch
306
- this.refresh();
307
- // Set up polling
308
- this.refreshTimer = setInterval(() => {
309
- if (!this.state.isOffline) {
310
- this.refresh();
311
- }
312
- }, this.config.refreshInterval);
313
- }
314
407
  fetchWithTimeout(url, options) {
315
408
  return new Promise((resolve, reject) => {
316
409
  const timeoutId = setTimeout(() => {
@@ -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\n *\n * Supports offline fallback via environment variables\n */\n/**\n * Core Togglely Client\n */\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 refreshInterval: 60000,\n timeout: 5000,\n offlineFallback: true,\n envPrefix: 'TOGGLELY_',\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 // Load offline toggles first (if enabled)\n if (this.config.offlineFallback) {\n this.loadOfflineToggles();\n }\n // Start polling\n this.startPolling();\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 async isEnabled(key, defaultValue = false) {\n const value = await this.getValue(key);\n if (value === null)\n return defaultValue;\n return value.enabled && value.value === true;\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 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 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 async getValue(key) {\n // Try cache first\n const cached = this.toggles.get(key);\n if (cached) {\n return cached;\n }\n // Fetch from server\n try {\n const response = await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${this.config.environment}/${key}`, {\n headers: {\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'Content-Type': 'application/json'\n }\n });\n if (!response.ok) {\n if (response.status === 404) {\n return null;\n }\n throw new Error(`HTTP ${response.status}`);\n }\n const data = await response.json();\n this.toggles.set(key, data);\n // Update state if we were offline\n if (this.state.isOffline) {\n this.state.isOffline = false;\n this.emit('online');\n }\n return data;\n }\n catch (error) {\n // Try offline fallback\n const offlineValue = this.getOfflineToggle(key);\n if (offlineValue !== null) {\n return offlineValue;\n }\n console.error(`[Togglely] Failed to fetch toggle \"${key}\":`, error);\n return null;\n }\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 toggles from environment variables\n * Format: TOGGLELY_<TOGGLE_KEY>=<value> or TOGGLELY_<TOGGLE_KEY>_ENABLED=true\n */\n loadOfflineToggles() {\n try {\n // 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 // 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 // Parse toggle key: TOGGLELY_MY_FEATURE -> my-feature\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 getOfflineToggle(key) {\n if (!this.config.offlineFallback)\n return null;\n // Try to get from already loaded offline toggles\n const cached = this.toggles.get(key);\n if (cached) {\n // If we haven't emitted offline event yet, do it now\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 // Handle boolean strings\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 // Try to parse as number\n if (!isNaN(Number(value))) {\n return { value: Number(value), enabled: true };\n }\n // Try to parse as JSON\n try {\n const parsed = JSON.parse(value);\n return { value: parsed, enabled: true };\n }\n catch {\n // Return as string\n return { value, enabled: true };\n }\n }\n return { value, enabled: true };\n }\n // ==================== Refresh / Polling ====================\n async refresh() {\n try {\n const response = await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${this.config.environment}`, {\n headers: {\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'Content-Type': 'application/json'\n }\n });\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 we were offline, go online\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 we have offline toggles, switch to offline mode\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 if (this.refreshTimer) {\n clearInterval(this.refreshTimer);\n }\n this.toggles.clear();\n this.eventHandlers.forEach(handlers => handlers.clear());\n }\n // ==================== Private Helpers ====================\n startPolling() {\n // Initial fetch\n this.refresh();\n // Set up polling\n this.refreshTimer = setInterval(() => {\n if (!this.state.isOffline) {\n this.refresh();\n }\n }, this.config.refreshInterval);\n }\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 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 return value.enabled && value.value === true;\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 * @param key - The flag key\n * @returns Promise<ToggleValue | null>\n */\n async getValue(key) {\n // Try cache first - but only if no context is set\n if (Object.keys(this.context).length === 0) {\n const cached = this.toggles.get(key);\n if (cached) {\n return cached;\n }\n }\n // Fetch from server\n try {\n const params = new URLSearchParams();\n if (this.config.apiKey)\n params.set('apiKey', this.config.apiKey);\n const brandKey = this.context.tenantId || this.context.brandKey;\n if (brandKey)\n params.set('tenantId', String(brandKey));\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 response = await this.fetchWithTimeout(url, { headers: { 'Content-Type': 'application/json' } });\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 this.toggles.set(key, data);\n if (this.state.isOffline) {\n this.state.isOffline = false;\n this.emit('online');\n }\n return data;\n }\n catch (error) {\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 /**\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 if (this.config.apiKey)\n params.set('apiKey', this.config.apiKey);\n const brandKey = this.context.tenantId || this.context.brandKey;\n if (brandKey)\n params.set('tenantId', String(brandKey));\n if (Object.keys(this.context).length > 0) {\n params.set('context', JSON.stringify(this.context));\n }\n const response = await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${encodeURIComponent(this.config.project)}/${encodeURIComponent(this.config.environment)}?${params.toString()}`, { headers: { 'Content-Type': 'application/json' } });\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={refreshInterval:6e4,timeout:5e3,offlineFallback:!0,envPrefix:"TOGGLELY_",...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),this.config.offlineFallback&&this.loadOfflineToggles(),this.startPolling()}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:n.enabled&&!0===n.value}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(t)return t;try{const t=await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${this.config.environment}/${e}`,{headers:{Authorization:`Bearer ${this.config.apiKey}`,"Content-Type":"application/json"}});if(!t.ok){if(404===t.status)return null;throw new Error(`HTTP ${t.status}`)}const n=await t.json();return this.toggles.set(e,n),this.state.isOffline&&(this.state.isOffline=!1,this.emit("online")),n}catch(t){const n=this.getOfflineToggle(e);return null!==n?n:(console.error(`[Togglely] Failed to fetch toggle "${e}":`,t),null)}}getAllToggles(){const e={};return this.toggles.forEach((t,n)=>{e[n]=t}),e}loadOfflineToggles(){try{if("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)}}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=await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${this.config.environment}`,{headers:{Authorization:`Bearer ${this.config.apiKey}`,"Content-Type":"application/json"}});if(!e.ok)throw new Error(`HTTP ${e.status}`);const t=await e.json();this.toggles.clear();for(const[e,n]of Object.entries(t))this.toggles.set(e,n);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.refreshTimer&&clearInterval(this.refreshTimer),this.toggles.clear(),this.eventHandlers.forEach(e=>e.clear())}startPolling(){this.refresh(),this.refreshTimer=setInterval(()=>{this.state.isOffline||this.refresh()},this.config.refreshInterval)}fetchWithTimeout(e,t){return new Promise((n,s)=>{const i=setTimeout(()=>{s(new Error("Request timeout"))},this.config.timeout);fetch(e,t).then(e=>{clearTimeout(i),n(e)}).catch(e=>{clearTimeout(i),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,i=!1,o=!1;"string"==typeof s?e=[s]:Array.isArray(s)?e=s:(e=[s.selector],i=s.defaultValue??!1,o=s.invert??!1);const l=await t.isEnabled(n,i),r=o?!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:i=!1,invert:o=!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,i),g=o?!f:f;document.querySelectorAll(e).forEach(e=>{g?(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,i]of Object.entries(e)){n[t+s.toUpperCase().replace(/-/g,"_")]="object"==typeof i?JSON.stringify(i):String(i)}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.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:n.enabled&&!0===n.value}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){if(0===Object.keys(this.context).length){const t=this.toggles.get(e);if(t)return t}try{const t=new URLSearchParams;this.config.apiKey&&t.set("apiKey",this.config.apiKey);const n=this.context.tenantId||this.context.brandKey;n&&t.set("tenantId",String(n)),Object.keys(this.context).length>0&&t.set("context",JSON.stringify(this.context));const o=t.toString()?`?${t.toString()}`:"",s=`${this.config.baseUrl}/sdk/flags/${encodeURIComponent(this.config.project)}/${encodeURIComponent(this.config.environment)}/${encodeURIComponent(e)}${o}`,i=await this.fetchWithTimeout(s,{headers:{"Content-Type":"application/json"}});if(!i.ok){if(404===i.status)return null;throw new Error(`HTTP ${i.status}: ${i.statusText}`)}const l=await i.json();return this.toggles.set(e,l),this.state.isOffline&&(this.state.isOffline=!1,this.emit("online")),l}catch(t){if(this.config.offlineFallback){const t=this.getOfflineToggle(e);if(null!==t)return t}return{value:!1,enabled:!1}}}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.config.apiKey&&e.set("apiKey",this.config.apiKey);const t=this.context.tenantId||this.context.brandKey;t&&e.set("tenantId",String(t)),Object.keys(this.context).length>0&&e.set("context",JSON.stringify(this.context));const n=await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${encodeURIComponent(this.config.project)}/${encodeURIComponent(this.config.environment)}?${e.toString()}`,{headers:{"Content-Type":"application/json"}});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})});
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\n *\n * Supports offline fallback via environment variables\n */\n/**\n * Core Togglely Client\n */\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 refreshInterval: 60000,\n timeout: 5000,\n offlineFallback: true,\n envPrefix: 'TOGGLELY_',\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 // Load offline toggles first (if enabled)\n if (this.config.offlineFallback) {\n this.loadOfflineToggles();\n }\n // Start polling\n this.startPolling();\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 async isEnabled(key, defaultValue = false) {\n const value = await this.getValue(key);\n if (value === null)\n return defaultValue;\n return value.enabled && value.value === true;\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 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 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 async getValue(key) {\n // Try cache first\n const cached = this.toggles.get(key);\n if (cached) {\n return cached;\n }\n // Fetch from server\n try {\n const response = await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${this.config.environment}/${key}`, {\n headers: {\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'Content-Type': 'application/json'\n }\n });\n if (!response.ok) {\n if (response.status === 404) {\n return null;\n }\n throw new Error(`HTTP ${response.status}`);\n }\n const data = await response.json();\n this.toggles.set(key, data);\n // Update state if we were offline\n if (this.state.isOffline) {\n this.state.isOffline = false;\n this.emit('online');\n }\n return data;\n }\n catch (error) {\n // Try offline fallback\n const offlineValue = this.getOfflineToggle(key);\n if (offlineValue !== null) {\n return offlineValue;\n }\n console.error(`[Togglely] Failed to fetch toggle \"${key}\":`, error);\n return null;\n }\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 toggles from environment variables\n * Format: TOGGLELY_<TOGGLE_KEY>=<value> or TOGGLELY_<TOGGLE_KEY>_ENABLED=true\n */\n loadOfflineToggles() {\n try {\n // 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 // 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 // Parse toggle key: TOGGLELY_MY_FEATURE -> my-feature\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 getOfflineToggle(key) {\n if (!this.config.offlineFallback)\n return null;\n // Try to get from already loaded offline toggles\n const cached = this.toggles.get(key);\n if (cached) {\n // If we haven't emitted offline event yet, do it now\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 // Handle boolean strings\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 // Try to parse as number\n if (!isNaN(Number(value))) {\n return { value: Number(value), enabled: true };\n }\n // Try to parse as JSON\n try {\n const parsed = JSON.parse(value);\n return { value: parsed, enabled: true };\n }\n catch {\n // Return as string\n return { value, enabled: true };\n }\n }\n return { value, enabled: true };\n }\n // ==================== Refresh / Polling ====================\n async refresh() {\n try {\n const response = await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${this.config.environment}`, {\n headers: {\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'Content-Type': 'application/json'\n }\n });\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 we were offline, go online\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 we have offline toggles, switch to offline mode\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 if (this.refreshTimer) {\n clearInterval(this.refreshTimer);\n }\n this.toggles.clear();\n this.eventHandlers.forEach(handlers => handlers.clear());\n }\n // ==================== Private Helpers ====================\n startPolling() {\n // Initial fetch\n this.refresh();\n // Set up polling\n this.refreshTimer = setInterval(() => {\n if (!this.state.isOffline) {\n this.refresh();\n }\n }, this.config.refreshInterval);\n }\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","refreshInterval","timeout","offlineFallback","envPrefix","set","Set","loadOfflineToggles","startPolling","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","cached","response","fetchWithTimeout","baseUrl","environment","headers","Authorization","apiKey","ok","status","Error","data","json","error","offlineValue","getOfflineToggle","console","getAllToggles","result","window","__TOGGLELY_TOGGLES","offlineToggles","Object","entries","parseOfflineValue","log","process","env","prefix","envKey","envValue","startsWith","undefined","toggleKey","slice","length","toLowerCase","replace","warn","lower","isNaN","refresh","clear","Date","forceOfflineMode","forceOnlineMode","destroy","refreshTimer","clearInterval","setInterval","url","options","Promise","resolve","reject","timeoutId","setTimeout","fetch","then","clearTimeout","catch","getGlobalTogglely","togglely","stringify","async","client","updateAll","selectors","invert","Array","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 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 return value.enabled && value.value === true;\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 * @param key - The flag key\n * @returns Promise<ToggleValue | null>\n */\n async getValue(key) {\n // Try cache first - but only if no context is set\n if (Object.keys(this.context).length === 0) {\n const cached = this.toggles.get(key);\n if (cached) {\n return cached;\n }\n }\n // Fetch from server\n try {\n const params = new URLSearchParams();\n if (this.config.apiKey)\n params.set('apiKey', this.config.apiKey);\n const brandKey = this.context.tenantId || this.context.brandKey;\n if (brandKey)\n params.set('tenantId', String(brandKey));\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 response = await this.fetchWithTimeout(url, { headers: { 'Content-Type': 'application/json' } });\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 this.toggles.set(key, data);\n if (this.state.isOffline) {\n this.state.isOffline = false;\n this.emit('online');\n }\n return data;\n }\n catch (error) {\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 /**\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 if (this.config.apiKey)\n params.set('apiKey', this.config.apiKey);\n const brandKey = this.context.tenantId || this.context.brandKey;\n if (brandKey)\n params.set('tenantId', String(brandKey));\n if (Object.keys(this.context).length > 0) {\n params.set('context', JSON.stringify(this.context));\n }\n const response = await this.fetchWithTimeout(`${this.config.baseUrl}/sdk/flags/${encodeURIComponent(this.config.project)}/${encodeURIComponent(this.config.environment)}?${params.toString()}`, { headers: { 'Content-Type': 'application/json' } });\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","Object","keys","length","cached","params","URLSearchParams","apiKey","stringify","query","toString","url","baseUrl","encodeURIComponent","project","environment","response","fetchWithTimeout","headers","ok","status","Error","statusText","data","json","error","offlineValue","getOfflineToggle","getAllToggles","result","offlineToggles","entries","console","log","window","loadOfflineJsonFile","__TOGGLELY_TOGGLES","parseOfflineValue","process","env","prefix","envKey","envValue","startsWith","toggleKey","slice","toLowerCase","replace","warn","path","fetch","require","fs","fullPath","resolve","existsSync","readFileSync","lower","isNaN","clear","Date","forceOfflineMode","forceOnlineMode","destroy","options","Promise","reject","timeoutId","setTimeout","then","clearTimeout","catch","getGlobalTogglely","togglely","async","client","updateAll","selectors","invert","Array","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,36 +1,36 @@
1
- {
2
- "name": "@togglely/sdk",
3
- "version": "1.1.2",
4
- "description": "Vanilla JavaScript SDK for Togglely - Feature toggles for any framework",
5
- "main": "dist/index.js",
6
- "module": "dist/index.esm.js",
7
- "types": "dist/index.d.ts",
8
- "unpkg": "dist/index.umd.js",
9
- "files": [
10
- "dist"
11
- ],
12
- "scripts": {
13
- "build": "tsc && rollup -c",
14
- "test": "jest"
15
- },
16
- "keywords": [
17
- "feature-flags",
18
- "feature-toggles",
19
- "togglely",
20
- "vanilla",
21
- "javascript"
22
- ],
23
- "author": "Togglely",
24
- "license": "MIT",
25
- "dependencies": {
26
- "@togglely/sdk-core": "^1.0.0"
27
- },
28
- "devDependencies": {
29
- "@rollup/plugin-node-resolve": "^15.2.3",
30
- "@rollup/plugin-terser": "^0.4.4",
31
- "@rollup/plugin-typescript": "^11.1.5",
32
- "rollup": "^4.9.1",
33
- "tslib": "^2.6.2",
34
- "typescript": "^5.3.3"
35
- }
1
+ {
2
+ "name": "@togglely/sdk",
3
+ "version": "1.2.0",
4
+ "description": "Vanilla JavaScript SDK for Togglely - Feature toggles for any framework",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.esm.js",
7
+ "types": "dist/index.d.ts",
8
+ "unpkg": "dist/index.umd.js",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc && rollup -c",
14
+ "test": "jest"
15
+ },
16
+ "keywords": [
17
+ "feature-flags",
18
+ "feature-toggles",
19
+ "togglely",
20
+ "vanilla",
21
+ "javascript"
22
+ ],
23
+ "author": "Togglely",
24
+ "license": "MIT",
25
+ "dependencies": {
26
+ "@togglely/sdk-core": "^1.0.0"
27
+ },
28
+ "devDependencies": {
29
+ "@rollup/plugin-node-resolve": "^15.2.3",
30
+ "@rollup/plugin-terser": "^0.4.4",
31
+ "@rollup/plugin-typescript": "^11.1.5",
32
+ "rollup": "^4.9.1",
33
+ "tslib": "^2.6.2",
34
+ "typescript": "^5.3.3"
35
+ }
36
36
  }