Skip to content

Commit df9feef

Browse files
committed
Require localStorage or custom storage
1 parent 95322d7 commit df9feef

2 files changed

Lines changed: 17 additions & 60 deletions

File tree

packages/browser-sdk/src/flag/flags.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ReflagContext } from "../context";
55
import { HttpClient } from "../httpClient";
66
import { Logger, loggerWithPrefix } from "../logger";
77
import RateLimiter from "../rateLimiter";
8-
import { resolveStorageAdapter, StorageAdapter } from "../storage";
8+
import { getLocalStorageAdapter, StorageAdapter } from "../storage";
99
import { createEventTarget } from "../utils/eventTarget";
1010

1111
import { FlagCache, isObject, parseAPIFlagsResponse } from "./flagCache";
@@ -234,11 +234,7 @@ export class FlagsClient {
234234
this.logger = loggerWithPrefix(logger, "[Flags]");
235235
this.rateLimiter =
236236
rateLimiter ?? new RateLimiter(FLAG_EVENTS_PER_MIN, this.logger);
237-
const { adapter, type } = resolveStorageAdapter(
238-
cache ? undefined : storage,
239-
);
240-
this.storage = adapter;
241-
this.logger.debug(`storage adapter: ${type}`);
237+
this.storage = (cache ? undefined : storage) ?? getLocalStorageAdapter();
242238
this.cache =
243239
cache ??
244240
this.setupCache(this.config.staleTimeMs, this.config.expireTimeMs);

packages/browser-sdk/src/storage.ts

Lines changed: 15 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,62 +4,23 @@ export type StorageAdapter = {
44
removeItem?(key: string): Promise<void>;
55
};
66

7-
export type StorageAdapterType =
8-
| "custom"
9-
| "localStorage"
10-
| "asyncStorage"
11-
| "memory";
12-
13-
export const createMemoryStorageAdapter = (): StorageAdapter => {
14-
let value: string | null = null;
7+
export function getLocalStorageAdapter(): StorageAdapter {
8+
if (
9+
typeof localStorage === "undefined" ||
10+
!("setItem" in localStorage) ||
11+
!("removeItem" in localStorage)
12+
) {
13+
throw new Error(
14+
"localStorage is not available. Provide a custom storage adapter.",
15+
);
16+
}
1517
return {
16-
getItem: async () => value,
17-
setItem: async (_key, nextValue) => {
18-
value = nextValue;
18+
getItem: async (key) => localStorage.getItem(key),
19+
setItem: async (key, value) => {
20+
localStorage.setItem(key, value);
1921
},
20-
removeItem: async () => {
21-
value = null;
22+
removeItem: async (key) => {
23+
localStorage.removeItem(key);
2224
},
2325
};
24-
};
25-
26-
function isLocalStorageUsable() {
27-
return (
28-
typeof localStorage !== "undefined" &&
29-
"setItem" in localStorage &&
30-
"removeItem" in localStorage
31-
);
32-
}
33-
34-
export function resolveStorageAdapter(storage?: StorageAdapter): {
35-
adapter: StorageAdapter;
36-
type: StorageAdapterType;
37-
} {
38-
if (storage) return { adapter: storage, type: "custom" };
39-
if (isLocalStorageUsable()) {
40-
return {
41-
adapter: {
42-
getItem: async (key) => localStorage.getItem(key),
43-
setItem: async (key, value) => {
44-
localStorage.setItem(key, value);
45-
},
46-
removeItem: async (key) => {
47-
localStorage.removeItem(key);
48-
},
49-
},
50-
type: "localStorage",
51-
};
52-
}
53-
// React Native: try AsyncStorage if available.
54-
try {
55-
// eslint-disable-next-line @typescript-eslint/no-require-imports
56-
const asyncStorage = require("@react-native-async-storage/async-storage");
57-
const adapter = asyncStorage?.default ?? asyncStorage;
58-
if (adapter?.getItem && adapter?.setItem) {
59-
return { adapter: adapter as StorageAdapter, type: "asyncStorage" };
60-
}
61-
} catch {
62-
// ignore - not running in React Native or AsyncStorage not installed
63-
}
64-
return { adapter: createMemoryStorageAdapter(), type: "memory" };
6526
}

0 commit comments

Comments
 (0)