@ojolowoblue/lamba 1.0.5 → 1.0.7

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
@@ -167,7 +167,7 @@ const isNewHeader = useLambaEnv<boolean>('VITE_NEW_HEADER', false);
167
167
 
168
168
  ### `lamba.init(options?: LambaOptions): LambaManager`
169
169
 
170
- Initializes the lamba manager, hydrates saved overrides from `localStorage`, enables network interceptors, and mounts the floating Shadow DOM UI.
170
+ Initializes the lamba manager, hydrates saved overrides from the configured storage backend, enables network interceptors, and mounts the floating Shadow DOM UI.
171
171
 
172
172
  | Option | Type | Default | Description |
173
173
  | :--- | :--- | :--- | :--- |
@@ -178,6 +178,8 @@ Initializes the lamba manager, hydrates saved overrides from `localStorage`, ena
178
178
  | `autoFetchEnvFile` | `boolean` | `false` | Whether to attempt fetching root `/.env` file during local development. |
179
179
  | `interceptNetworkRequests` | `boolean` | `true` | Whether to implicitly intercept `fetch` & `XHR` calls matching original base URLs. |
180
180
  | `allowedPrefixes` | `string \| string[] \| RegExp \| null` | `null` | Optional prefix filter (e.g. `['VITE_', 'NEXT_PUBLIC_']`). Omitting allows ALL keys regardless of prefix. |
181
+ | `storageStrategy` | `'local' \| 'session' \| 'memory'` | `'local'` | Where overrides and presets are persisted. See [Storage Strategies](#-storage-strategies) below. |
182
+ | `storage` | `LambaStorageAdapter` | `undefined` | Provide a fully custom storage adapter. Takes precedence over `storageStrategy`. |
181
183
 
182
184
  ---
183
185
 
@@ -187,7 +189,7 @@ Initializes the lamba manager, hydrates saved overrides from `localStorage`, ena
187
189
  Returns the active value for the specified environment key (returns active override if present, otherwise default value or fallback). Preserves numbers, booleans, and objects.
188
190
 
189
191
  #### `lamba.set(key: string, value: any): void`
190
- Programmatically overrides an environment variable live at runtime with any data type. The change is persisted in `localStorage` and triggers UI and listener updates.
192
+ Programmatically overrides an environment variable live at runtime with any data type. The change is persisted in the configured storage backend and triggers UI and listener updates.
191
193
 
192
194
  #### `lamba.remove(key: string): void`
193
195
  Removes an override for a specific environment variable key, reverting it to its default value.
@@ -212,6 +214,57 @@ Programmatically controls the visibility of the lamba modal panel.
212
214
 
213
215
  ---
214
216
 
217
+ ## 🔐 Storage Strategies
218
+
219
+ Control where lamba persists overrides and presets via the `storageStrategy` option:
220
+
221
+ | Strategy | Visibility in DevTools | Survives Tab Close? | XSS Storage Scraping Risk |
222
+ | :--- | :--- | :--- | :--- |
223
+ | `'local'` *(default)* | ⚠️ Visible (plain-text) | ✅ Yes (Indefinitely) | ⚠️ Yes |
224
+ | `'session'` | ⚠️ Visible (plain-text) | ❌ No (Cleared on close) | ⚠️ Yes |
225
+ | `'memory'` | ✅ **Not visible (0 bytes stored)** | ❌ No (GC'd on close) | ✅ **No** |
226
+
227
+ ### In-Memory (Most Secure)
228
+
229
+ ```typescript
230
+ lamba.init({
231
+ storageStrategy: 'memory', // Nothing written to DevTools Storage
232
+ env: { VITE_API_URL: import.meta.env.VITE_API_URL },
233
+ });
234
+ ```
235
+
236
+ ### Session (Tab-Ephemeral)
237
+
238
+ ```typescript
239
+ lamba.init({
240
+ storageStrategy: 'session', // Cleared automatically when tab closes
241
+ env: { VITE_API_URL: import.meta.env.VITE_API_URL },
242
+ });
243
+ ```
244
+
245
+ ### Custom Adapter
246
+
247
+ Implement the `LambaStorageAdapter` interface to plug in any storage backend (encrypted storage, Electron keytar, IndexedDB, etc.):
248
+
249
+ ```typescript
250
+ import lamba, { type LambaStorageAdapter } from '@ojolowoblue/lamba';
251
+
252
+ // Example: an encrypted wrapper around sessionStorage
253
+ const encryptedAdapter: LambaStorageAdapter = {
254
+ getItem: (key) => decrypt(sessionStorage.getItem(key)),
255
+ setItem: (key, value) => sessionStorage.setItem(key, encrypt(value)),
256
+ removeItem: (key) => sessionStorage.removeItem(key),
257
+ clear: () => sessionStorage.clear(),
258
+ };
259
+
260
+ lamba.init({
261
+ storage: encryptedAdapter,
262
+ env: { VITE_API_URL: import.meta.env.VITE_API_URL },
263
+ });
264
+ ```
265
+
266
+ ---
267
+
215
268
  ## 🔒 Production Security Best Practice
216
269
 
217
270
  To prevent end-users from overriding environment variables in production, conditionally initialize `lamba` only in non-production environments:
@@ -221,6 +274,7 @@ import lamba from '@ojolowoblue/lamba';
221
274
 
222
275
  lamba.init({
223
276
  enabled: process.env.NODE_ENV !== 'production',
277
+ storageStrategy: 'memory', // Use memory storage so nothing lingers in DevTools
224
278
  env: {
225
279
  VITE_API_URL: import.meta.env.VITE_API_URL,
226
280
  },
@@ -233,12 +287,12 @@ lamba.init({
233
287
 
234
288
  <details>
235
289
  <summary><b>Does lamba modify my local <code>.env</code> files on disk?</b></summary>
236
- <p>No. <code>lamba</code> operates entirely in browser memory and persists overrides in <code>localStorage</code>. It does not write to disk, so your git status remains clean.</p>
290
+ <p>No. <code>lamba</code> operates entirely in browser memory and optionally persists overrides in storage. It does not write to disk, so your git status remains clean.</p>
237
291
  </details>
238
292
 
239
293
  <details>
240
294
  <summary><b>Do overrides persist when I refresh the page?</b></summary>
241
- <p>Yes. Overrides and active preset profiles are saved in <code>localStorage</code> and automatically restored upon page reloads.</p>
295
+ <p>It depends on the <code>storageStrategy</code>. With <code>'local'</code> (default), overrides persist indefinitely. With <code>'session'</code>, they survive reloads but clear when the tab is closed. With <code>'memory'</code>, overrides are lost on any page reload.</p>
242
296
  </details>
243
297
 
244
298
  <details>
package/dist/index.d.mts CHANGED
@@ -1,3 +1,50 @@
1
+ /**
2
+ * Abstract interface for pluggable storage backends used by lamba to persist
3
+ * overrides and presets. All methods are synchronous for simplicity (async
4
+ * adapters can wrap with Promises if needed in custom implementations).
5
+ */
6
+ interface LambaStorageAdapter {
7
+ getItem(key: string): string | null;
8
+ setItem(key: string, value: string): void;
9
+ removeItem(key: string): void;
10
+ clear(): void;
11
+ }
12
+ /**
13
+ * LocalStorage-backed adapter (default).
14
+ * Overrides persist indefinitely across tabs and page reloads.
15
+ * Visible in DevTools → Application → Local Storage.
16
+ */
17
+ declare class LocalStorageAdapter implements LambaStorageAdapter {
18
+ getItem(key: string): string | null;
19
+ setItem(key: string, value: string): void;
20
+ removeItem(key: string): void;
21
+ clear(): void;
22
+ }
23
+ /**
24
+ * SessionStorage-backed adapter.
25
+ * Overrides survive page reloads within the same tab, but are automatically
26
+ * destroyed when the tab is closed. Still visible in DevTools Storage panel.
27
+ */
28
+ declare class SessionStorageAdapter implements LambaStorageAdapter {
29
+ getItem(key: string): string | null;
30
+ setItem(key: string, value: string): void;
31
+ removeItem(key: string): void;
32
+ clear(): void;
33
+ }
34
+ /**
35
+ * In-memory adapter.
36
+ * The most secure option: zero bytes written to any browser storage mechanism.
37
+ * Overrides exist only in JavaScript heap memory and are destroyed when the
38
+ * tab/page is closed or navigated away. Nothing appears in DevTools Storage.
39
+ */
40
+ declare class MemoryStorageAdapter implements LambaStorageAdapter {
41
+ private store;
42
+ getItem(key: string): string | null;
43
+ setItem(key: string, value: string): void;
44
+ removeItem(key: string): void;
45
+ clear(): void;
46
+ }
47
+
1
48
  interface EnvVariable {
2
49
  key: string;
3
50
  value: any;
@@ -46,6 +93,22 @@ interface LambaOptions {
46
93
  * If omitted, null, or empty, ALL environment variable keys are allowed and supported regardless of prefix.
47
94
  */
48
95
  allowedPrefixes?: string | string[] | RegExp | null;
96
+ /**
97
+ * Storage strategy for persisting overrides and presets across page reloads:
98
+ * - `'local'` — (default) Standard `localStorage`. Persists indefinitely across tabs & reloads.
99
+ * Visible in DevTools → Application → Local Storage.
100
+ * - `'session'` — `sessionStorage`. Survives page reloads within the same tab, but cleared
101
+ * when the tab is closed. Visible in DevTools → Application → Session Storage.
102
+ * - `'memory'` — In-memory only. Most secure option — zero bytes written to any browser storage.
103
+ * Overrides are destroyed when the tab closes or navigates away.
104
+ * Nothing appears in DevTools Storage.
105
+ */
106
+ storageStrategy?: 'local' | 'session' | 'memory';
107
+ /**
108
+ * Provide a fully custom storage adapter that conforms to the `LambaStorageAdapter` interface.
109
+ * When provided, this takes precedence over `storageStrategy`.
110
+ */
111
+ storage?: LambaStorageAdapter;
49
112
  }
50
113
  type EnvChangeListener = (key: string, value: any, isOverridden: boolean) => void;
51
114
  type StoreChangeListener = (variables: Record<string, EnvVariable>, presets: PresetProfile[], activePresetId: string | null) => void;
@@ -97,6 +160,15 @@ declare class LambaManager {
97
160
  * Resets all environment variable overrides.
98
161
  */
99
162
  reset(): void;
163
+ /**
164
+ * Removes ALL lamba data from storage (overrides, presets, active preset).
165
+ * Safe to call even when lamba has not been initialized.
166
+ * Useful when disabling lamba to ensure no stale data remains in the browser.
167
+ *
168
+ * @param options - Optionally pass storage options to target the correct adapter.
169
+ * Defaults to 'local' (localStorage) to cover the common case.
170
+ */
171
+ purge(options?: Pick<LambaOptions, 'storageStrategy' | 'storage'>): void;
100
172
  /**
101
173
  * Subscribes to environment variable changes.
102
174
  */
@@ -116,4 +188,4 @@ declare class LambaManager {
116
188
  }
117
189
  declare const lamba: LambaManager;
118
190
 
119
- export { type EnvChangeListener, type EnvVariable, LambaManager, type LambaOptions, type PresetProfile, type StoreChangeListener, lamba as default, lamba, parseEnvString, stringifyEnv };
191
+ export { type EnvChangeListener, type EnvVariable, LambaManager, type LambaOptions, type LambaStorageAdapter, LocalStorageAdapter, MemoryStorageAdapter, type PresetProfile, SessionStorageAdapter, type StoreChangeListener, lamba as default, lamba, parseEnvString, stringifyEnv };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,50 @@
1
+ /**
2
+ * Abstract interface for pluggable storage backends used by lamba to persist
3
+ * overrides and presets. All methods are synchronous for simplicity (async
4
+ * adapters can wrap with Promises if needed in custom implementations).
5
+ */
6
+ interface LambaStorageAdapter {
7
+ getItem(key: string): string | null;
8
+ setItem(key: string, value: string): void;
9
+ removeItem(key: string): void;
10
+ clear(): void;
11
+ }
12
+ /**
13
+ * LocalStorage-backed adapter (default).
14
+ * Overrides persist indefinitely across tabs and page reloads.
15
+ * Visible in DevTools → Application → Local Storage.
16
+ */
17
+ declare class LocalStorageAdapter implements LambaStorageAdapter {
18
+ getItem(key: string): string | null;
19
+ setItem(key: string, value: string): void;
20
+ removeItem(key: string): void;
21
+ clear(): void;
22
+ }
23
+ /**
24
+ * SessionStorage-backed adapter.
25
+ * Overrides survive page reloads within the same tab, but are automatically
26
+ * destroyed when the tab is closed. Still visible in DevTools Storage panel.
27
+ */
28
+ declare class SessionStorageAdapter implements LambaStorageAdapter {
29
+ getItem(key: string): string | null;
30
+ setItem(key: string, value: string): void;
31
+ removeItem(key: string): void;
32
+ clear(): void;
33
+ }
34
+ /**
35
+ * In-memory adapter.
36
+ * The most secure option: zero bytes written to any browser storage mechanism.
37
+ * Overrides exist only in JavaScript heap memory and are destroyed when the
38
+ * tab/page is closed or navigated away. Nothing appears in DevTools Storage.
39
+ */
40
+ declare class MemoryStorageAdapter implements LambaStorageAdapter {
41
+ private store;
42
+ getItem(key: string): string | null;
43
+ setItem(key: string, value: string): void;
44
+ removeItem(key: string): void;
45
+ clear(): void;
46
+ }
47
+
1
48
  interface EnvVariable {
2
49
  key: string;
3
50
  value: any;
@@ -46,6 +93,22 @@ interface LambaOptions {
46
93
  * If omitted, null, or empty, ALL environment variable keys are allowed and supported regardless of prefix.
47
94
  */
48
95
  allowedPrefixes?: string | string[] | RegExp | null;
96
+ /**
97
+ * Storage strategy for persisting overrides and presets across page reloads:
98
+ * - `'local'` — (default) Standard `localStorage`. Persists indefinitely across tabs & reloads.
99
+ * Visible in DevTools → Application → Local Storage.
100
+ * - `'session'` — `sessionStorage`. Survives page reloads within the same tab, but cleared
101
+ * when the tab is closed. Visible in DevTools → Application → Session Storage.
102
+ * - `'memory'` — In-memory only. Most secure option — zero bytes written to any browser storage.
103
+ * Overrides are destroyed when the tab closes or navigates away.
104
+ * Nothing appears in DevTools Storage.
105
+ */
106
+ storageStrategy?: 'local' | 'session' | 'memory';
107
+ /**
108
+ * Provide a fully custom storage adapter that conforms to the `LambaStorageAdapter` interface.
109
+ * When provided, this takes precedence over `storageStrategy`.
110
+ */
111
+ storage?: LambaStorageAdapter;
49
112
  }
50
113
  type EnvChangeListener = (key: string, value: any, isOverridden: boolean) => void;
51
114
  type StoreChangeListener = (variables: Record<string, EnvVariable>, presets: PresetProfile[], activePresetId: string | null) => void;
@@ -97,6 +160,15 @@ declare class LambaManager {
97
160
  * Resets all environment variable overrides.
98
161
  */
99
162
  reset(): void;
163
+ /**
164
+ * Removes ALL lamba data from storage (overrides, presets, active preset).
165
+ * Safe to call even when lamba has not been initialized.
166
+ * Useful when disabling lamba to ensure no stale data remains in the browser.
167
+ *
168
+ * @param options - Optionally pass storage options to target the correct adapter.
169
+ * Defaults to 'local' (localStorage) to cover the common case.
170
+ */
171
+ purge(options?: Pick<LambaOptions, 'storageStrategy' | 'storage'>): void;
100
172
  /**
101
173
  * Subscribes to environment variable changes.
102
174
  */
@@ -116,4 +188,4 @@ declare class LambaManager {
116
188
  }
117
189
  declare const lamba: LambaManager;
118
190
 
119
- export { type EnvChangeListener, type EnvVariable, LambaManager, type LambaOptions, type PresetProfile, type StoreChangeListener, lamba as default, lamba, parseEnvString, stringifyEnv };
191
+ export { type EnvChangeListener, type EnvVariable, LambaManager, type LambaOptions, type LambaStorageAdapter, LocalStorageAdapter, MemoryStorageAdapter, type PresetProfile, SessionStorageAdapter, type StoreChangeListener, lamba as default, lamba, parseEnvString, stringifyEnv };
package/dist/index.js CHANGED
@@ -21,6 +21,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  LambaManager: () => LambaManager,
24
+ LocalStorageAdapter: () => LocalStorageAdapter,
25
+ MemoryStorageAdapter: () => MemoryStorageAdapter,
26
+ SessionStorageAdapter: () => SessionStorageAdapter,
24
27
  default: () => index_default,
25
28
  lamba: () => lamba,
26
29
  parseEnvString: () => parseEnvString,
@@ -32,34 +35,33 @@ module.exports = __toCommonJS(index_exports);
32
35
  var STORAGE_PRESETS_KEY = "__lamba_presets__";
33
36
  var STORAGE_ACTIVE_PRESET_KEY = "__lamba_active_preset__";
34
37
  var PresetManager = class {
35
- constructor() {
38
+ constructor(storage) {
36
39
  this.presets = [];
37
40
  this.activePresetId = null;
41
+ this.storage = storage;
38
42
  this.loadFromStorage();
39
43
  }
40
44
  loadFromStorage() {
41
- if (typeof localStorage === "undefined") return;
42
45
  try {
43
- const rawPresets = localStorage.getItem(STORAGE_PRESETS_KEY);
46
+ const rawPresets = this.storage.getItem(STORAGE_PRESETS_KEY);
44
47
  if (rawPresets) {
45
48
  this.presets = JSON.parse(rawPresets);
46
49
  }
47
- this.activePresetId = localStorage.getItem(STORAGE_ACTIVE_PRESET_KEY);
50
+ this.activePresetId = this.storage.getItem(STORAGE_ACTIVE_PRESET_KEY);
48
51
  } catch (e) {
49
- console.warn("[lamba] Failed to parse presets from localStorage", e);
52
+ console.warn("[lamba] Failed to parse presets from storage", e);
50
53
  }
51
54
  }
52
55
  saveToStorage() {
53
- if (typeof localStorage === "undefined") return;
54
56
  try {
55
- localStorage.setItem(STORAGE_PRESETS_KEY, JSON.stringify(this.presets));
57
+ this.storage.setItem(STORAGE_PRESETS_KEY, JSON.stringify(this.presets));
56
58
  if (this.activePresetId) {
57
- localStorage.setItem(STORAGE_ACTIVE_PRESET_KEY, this.activePresetId);
59
+ this.storage.setItem(STORAGE_ACTIVE_PRESET_KEY, this.activePresetId);
58
60
  } else {
59
- localStorage.removeItem(STORAGE_ACTIVE_PRESET_KEY);
61
+ this.storage.removeItem(STORAGE_ACTIVE_PRESET_KEY);
60
62
  }
61
63
  } catch (e) {
62
- console.warn("[lamba] Failed to save presets to localStorage", e);
64
+ console.warn("[lamba] Failed to save presets to storage", e);
63
65
  }
64
66
  }
65
67
  getPresets() {
@@ -211,6 +213,99 @@ async function tryFetchRootEnvFile() {
211
213
  return {};
212
214
  }
213
215
 
216
+ // src/core/storage.ts
217
+ var LocalStorageAdapter = class {
218
+ getItem(key) {
219
+ try {
220
+ return typeof localStorage !== "undefined" ? localStorage.getItem(key) : null;
221
+ } catch {
222
+ return null;
223
+ }
224
+ }
225
+ setItem(key, value) {
226
+ try {
227
+ if (typeof localStorage !== "undefined") localStorage.setItem(key, value);
228
+ } catch {
229
+ }
230
+ }
231
+ removeItem(key) {
232
+ try {
233
+ if (typeof localStorage !== "undefined") localStorage.removeItem(key);
234
+ } catch {
235
+ }
236
+ }
237
+ clear() {
238
+ try {
239
+ if (typeof localStorage !== "undefined") {
240
+ localStorage.removeItem("__lamba_overrides__");
241
+ localStorage.removeItem("__lamba_presets__");
242
+ localStorage.removeItem("__lamba_active_preset__");
243
+ }
244
+ } catch {
245
+ }
246
+ }
247
+ };
248
+ var SessionStorageAdapter = class {
249
+ getItem(key) {
250
+ try {
251
+ return typeof sessionStorage !== "undefined" ? sessionStorage.getItem(key) : null;
252
+ } catch {
253
+ return null;
254
+ }
255
+ }
256
+ setItem(key, value) {
257
+ try {
258
+ if (typeof sessionStorage !== "undefined") sessionStorage.setItem(key, value);
259
+ } catch {
260
+ }
261
+ }
262
+ removeItem(key) {
263
+ try {
264
+ if (typeof sessionStorage !== "undefined") sessionStorage.removeItem(key);
265
+ } catch {
266
+ }
267
+ }
268
+ clear() {
269
+ try {
270
+ if (typeof sessionStorage !== "undefined") {
271
+ sessionStorage.removeItem("__lamba_overrides__");
272
+ sessionStorage.removeItem("__lamba_presets__");
273
+ sessionStorage.removeItem("__lamba_active_preset__");
274
+ }
275
+ } catch {
276
+ }
277
+ }
278
+ };
279
+ var MemoryStorageAdapter = class {
280
+ constructor() {
281
+ this.store = /* @__PURE__ */ new Map();
282
+ }
283
+ getItem(key) {
284
+ return this.store.get(key) ?? null;
285
+ }
286
+ setItem(key, value) {
287
+ this.store.set(key, value);
288
+ }
289
+ removeItem(key) {
290
+ this.store.delete(key);
291
+ }
292
+ clear() {
293
+ this.store.clear();
294
+ }
295
+ };
296
+ function createStorageAdapter(strategy = "local", custom) {
297
+ if (custom) return custom;
298
+ switch (strategy) {
299
+ case "session":
300
+ return new SessionStorageAdapter();
301
+ case "memory":
302
+ return new MemoryStorageAdapter();
303
+ case "local":
304
+ default:
305
+ return new LocalStorageAdapter();
306
+ }
307
+ }
308
+
214
309
  // src/core/store.ts
215
310
  var STORAGE_OVERRIDES_KEY = "__lamba_overrides__";
216
311
  var DEFAULT_SECRET_PATTERN = /(KEY|SECRET|TOKEN|PASSWORD|AUTH|PRIVATE|CREDENTIAL|SIGNATURE)/i;
@@ -222,7 +317,8 @@ var EnvStore = class {
222
317
  this.storeChangeListeners = /* @__PURE__ */ new Set();
223
318
  this.secretPattern = options.secretKeysPattern || DEFAULT_SECRET_PATTERN;
224
319
  this.allowedPrefixes = options.allowedPrefixes;
225
- this.presetManager = new PresetManager();
320
+ this.storage = createStorageAdapter(options.storageStrategy ?? "local", options.storage);
321
+ this.presetManager = new PresetManager(this.storage);
226
322
  this.loadOverridesFromStorage();
227
323
  if (options.env) {
228
324
  this.mergeDefaults(options.env);
@@ -239,22 +335,20 @@ var EnvStore = class {
239
335
  this.patchProcessEnv();
240
336
  }
241
337
  loadOverridesFromStorage() {
242
- if (typeof localStorage === "undefined") return;
243
338
  try {
244
- const stored = localStorage.getItem(STORAGE_OVERRIDES_KEY);
339
+ const stored = this.storage.getItem(STORAGE_OVERRIDES_KEY);
245
340
  if (stored) {
246
341
  this.overrides = JSON.parse(stored);
247
342
  }
248
343
  } catch (e) {
249
- console.warn("[lamba] Failed to parse overrides from localStorage", e);
344
+ console.warn("[lamba] Failed to parse overrides from storage", e);
250
345
  }
251
346
  }
252
347
  saveOverridesToStorage() {
253
- if (typeof localStorage === "undefined") return;
254
348
  try {
255
- localStorage.setItem(STORAGE_OVERRIDES_KEY, JSON.stringify(this.overrides));
349
+ this.storage.setItem(STORAGE_OVERRIDES_KEY, JSON.stringify(this.overrides));
256
350
  } catch (e) {
257
- console.warn("[lamba] Failed to save overrides to localStorage", e);
351
+ console.warn("[lamba] Failed to save overrides to storage", e);
258
352
  }
259
353
  }
260
354
  /**
@@ -1475,7 +1569,10 @@ var LambaManager = class {
1475
1569
  interceptNetworkRequests: true,
1476
1570
  ...options
1477
1571
  };
1478
- if (this.options.enabled === false) return this;
1572
+ if (this.options.enabled === false) {
1573
+ this.purge(options);
1574
+ return this;
1575
+ }
1479
1576
  this.store = new EnvStore(this.options);
1480
1577
  if (this.options.interceptNetworkRequests !== false) {
1481
1578
  this.networkInterceptor = new NetworkInterceptor(this.store);
@@ -1532,6 +1629,18 @@ var LambaManager = class {
1532
1629
  reset() {
1533
1630
  this.store?.resetAllOverrides();
1534
1631
  }
1632
+ /**
1633
+ * Removes ALL lamba data from storage (overrides, presets, active preset).
1634
+ * Safe to call even when lamba has not been initialized.
1635
+ * Useful when disabling lamba to ensure no stale data remains in the browser.
1636
+ *
1637
+ * @param options - Optionally pass storage options to target the correct adapter.
1638
+ * Defaults to 'local' (localStorage) to cover the common case.
1639
+ */
1640
+ purge(options) {
1641
+ const adapter = this.store?.storage ?? createStorageAdapter(options?.storageStrategy ?? "local", options?.storage);
1642
+ adapter.clear();
1643
+ }
1535
1644
  /**
1536
1645
  * Subscribes to environment variable changes.
1537
1646
  */
@@ -1571,6 +1680,9 @@ var index_default = lamba;
1571
1680
  // Annotate the CommonJS export names for ESM import in node:
1572
1681
  0 && (module.exports = {
1573
1682
  LambaManager,
1683
+ LocalStorageAdapter,
1684
+ MemoryStorageAdapter,
1685
+ SessionStorageAdapter,
1574
1686
  lamba,
1575
1687
  parseEnvString,
1576
1688
  stringifyEnv