Skip to content

Commit 20167e2

Browse files
fix: Add localStorage fallback for storage when OfficeRuntime unavailable
- Enables taskpane to work outside Excel environment for testing - Falls back to localStorage when OfficeRuntime.storage not available - Fixes 'Storage not available' error in browser testing - Maintains OfficeRuntime as primary storage method in Excel
1 parent 3ab7710 commit 20167e2

1 file changed

Lines changed: 77 additions & 16 deletions

File tree

src/shared/storage.ts

Lines changed: 77 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,42 +11,74 @@ export interface StoredKey {
1111
}
1212

1313
export async function getStoredApiKey(): Promise<StoredKey> {
14-
if (typeof OfficeRuntime === 'undefined' || !OfficeRuntime.storage) {
15-
return { key: null, supported: false };
14+
// Try OfficeRuntime first (Excel environment)
15+
if (typeof OfficeRuntime !== 'undefined' && OfficeRuntime.storage) {
16+
try {
17+
const key = await OfficeRuntime.storage.getItem(STORAGE_KEY);
18+
return { key: key ?? null, supported: true };
19+
} catch (_err) {
20+
return { key: null, supported: false };
21+
}
1622
}
23+
24+
// Fallback to localStorage for testing/development
1725
try {
18-
const key = await OfficeRuntime.storage.getItem(STORAGE_KEY);
26+
const key = localStorage.getItem(STORAGE_KEY);
1927
return { key: key ?? null, supported: true };
2028
} catch (_err) {
2129
return { key: null, supported: false };
2230
}
2331
}
2432

2533
export async function setStoredApiKey(key: string): Promise<void> {
26-
if (typeof OfficeRuntime === 'undefined' || !OfficeRuntime.storage) {
34+
// Try OfficeRuntime first (Excel environment)
35+
if (typeof OfficeRuntime !== 'undefined' && OfficeRuntime.storage) {
36+
await OfficeRuntime.storage.setItem(STORAGE_KEY, key);
37+
return;
38+
}
39+
40+
// Fallback to localStorage for testing/development
41+
try {
42+
localStorage.setItem(STORAGE_KEY, key);
43+
} catch (_err) {
2744
throw new Error('Storage not available');
2845
}
29-
await OfficeRuntime.storage.setItem(STORAGE_KEY, key);
3046
}
3147

3248
export async function clearStoredApiKey(): Promise<void> {
33-
if (typeof OfficeRuntime === 'undefined' || !OfficeRuntime.storage) {
49+
// Try OfficeRuntime first (Excel environment)
50+
if (typeof OfficeRuntime !== 'undefined' && OfficeRuntime.storage) {
51+
try {
52+
await OfficeRuntime.storage.removeItem(STORAGE_KEY);
53+
} catch (_err) {
54+
// ignore
55+
}
3456
return;
3557
}
58+
59+
// Fallback to localStorage for testing/development
3660
try {
37-
await OfficeRuntime.storage.removeItem(STORAGE_KEY);
61+
localStorage.removeItem(STORAGE_KEY);
3862
} catch (_err) {
3963
// ignore
4064
}
4165
}
4266

4367
// Favorites management
4468
export async function getFavorites(): Promise<string[]> {
45-
if (typeof OfficeRuntime === 'undefined' || !OfficeRuntime.storage) {
46-
return [];
69+
// Try OfficeRuntime first (Excel environment)
70+
if (typeof OfficeRuntime !== 'undefined' && OfficeRuntime.storage) {
71+
try {
72+
const data = await OfficeRuntime.storage.getItem(FAVORITES_KEY);
73+
return data ? JSON.parse(data) : [];
74+
} catch (_err) {
75+
return [];
76+
}
4777
}
78+
79+
// Fallback to localStorage for testing/development
4880
try {
49-
const data = await OfficeRuntime.storage.getItem(FAVORITES_KEY);
81+
const data = localStorage.getItem(FAVORITES_KEY);
5082
return data ? JSON.parse(data) : [];
5183
} catch (_err) {
5284
return [];
@@ -57,23 +89,45 @@ export async function addFavorite(seriesId: string): Promise<void> {
5789
const favorites = await getFavorites();
5890
if (!favorites.includes(seriesId)) {
5991
favorites.unshift(seriesId);
60-
await OfficeRuntime.storage.setItem(FAVORITES_KEY, JSON.stringify(favorites.slice(0, 50)));
92+
const updated = JSON.stringify(favorites.slice(0, 50));
93+
94+
// Try OfficeRuntime first
95+
if (typeof OfficeRuntime !== 'undefined' && OfficeRuntime.storage) {
96+
await OfficeRuntime.storage.setItem(FAVORITES_KEY, updated);
97+
} else {
98+
localStorage.setItem(FAVORITES_KEY, updated);
99+
}
61100
}
62101
}
63102

64103
export async function removeFavorite(seriesId: string): Promise<void> {
65104
const favorites = await getFavorites();
66105
const filtered = favorites.filter(id => id !== seriesId);
67-
await OfficeRuntime.storage.setItem(FAVORITES_KEY, JSON.stringify(filtered));
106+
const updated = JSON.stringify(filtered);
107+
108+
// Try OfficeRuntime first
109+
if (typeof OfficeRuntime !== 'undefined' && OfficeRuntime.storage) {
110+
await OfficeRuntime.storage.setItem(FAVORITES_KEY, updated);
111+
} else {
112+
localStorage.setItem(FAVORITES_KEY, updated);
113+
}
68114
}
69115

70116
// Recent series management
71117
export async function getRecent(): Promise<string[]> {
72-
if (typeof OfficeRuntime === 'undefined' || !OfficeRuntime.storage) {
73-
return [];
118+
// Try OfficeRuntime first (Excel environment)
119+
if (typeof OfficeRuntime !== 'undefined' && OfficeRuntime.storage) {
120+
try {
121+
const data = await OfficeRuntime.storage.getItem(RECENT_KEY);
122+
return data ? JSON.parse(data) : [];
123+
} catch (_err) {
124+
return [];
125+
}
74126
}
127+
128+
// Fallback to localStorage for testing/development
75129
try {
76-
const data = await OfficeRuntime.storage.getItem(RECENT_KEY);
130+
const data = localStorage.getItem(RECENT_KEY);
77131
return data ? JSON.parse(data) : [];
78132
} catch (_err) {
79133
return [];
@@ -84,5 +138,12 @@ export async function addRecent(seriesId: string): Promise<void> {
84138
const recent = await getRecent();
85139
const filtered = recent.filter(id => id !== seriesId);
86140
filtered.unshift(seriesId);
87-
await OfficeRuntime.storage.setItem(RECENT_KEY, JSON.stringify(filtered.slice(0, 20)));
141+
const updated = JSON.stringify(filtered.slice(0, 20));
142+
143+
// Try OfficeRuntime first
144+
if (typeof OfficeRuntime !== 'undefined' && OfficeRuntime.storage) {
145+
await OfficeRuntime.storage.setItem(RECENT_KEY, updated);
146+
} else {
147+
localStorage.setItem(RECENT_KEY, updated);
148+
}
88149
}

0 commit comments

Comments
 (0)