Skip to content

Commit

Permalink
feat(local-storage): enhance local storage availability checks FE-1221 (
Browse files Browse the repository at this point in the history
  • Loading branch information
nelitow authored Dec 25, 2024
1 parent 1707ed9 commit 5a9cf49
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/curvy-news-work.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@fuels/react-xstore': minor
---

Update tests to handle the new local-storage checks.
5 changes: 5 additions & 0 deletions .changeset/flat-keys-melt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@fuels/local-storage': minor
---

Check for localStorage availability
1 change: 0 additions & 1 deletion .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
# need this to get full git-history/clone in order to build changelogs and check changesets
fetch-depth: 0

- name: CI Setup
Expand Down
46 changes: 38 additions & 8 deletions packages/local-storage/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,24 @@ import { EventEmitter } from 'events';
export class LocalStorage {
private prefix!: string;
private emitter!: EventEmitter;
private isAvailable: boolean;

constructor(prefix: string, emitter?: EventEmitter) {
this.prefix = prefix;
this.emitter = emitter ?? new EventEmitter();
this.isAvailable = this.checkLocalStorageAvailability();
}

private checkLocalStorageAvailability(): boolean {
try {
if (typeof window === 'undefined' || !window.localStorage) return false;
const testKey = '__storage_test__';
localStorage.setItem(testKey, testKey);
localStorage.removeItem(testKey);
return true;
} catch {
return false;
}
}

subscribe = (listener: <T extends unknown[]>(...args: T) => void) => {
Expand All @@ -18,11 +32,17 @@ export class LocalStorage {
};

setItem = <T>(key: string, value: T) => {
localStorage.setItem(this.createKey(key), JSON.stringify(value));
this.dispatchChange(key, value);
if (!this.isAvailable) return;
try {
localStorage.setItem(this.createKey(key), JSON.stringify(value));
this.dispatchChange(key, value);
} catch (error) {
// Silently fail if localStorage is not available or quota is exceeded
}
};

getItem = <T>(key: string): T | null => {
if (!this.isAvailable) return null;
try {
const data = localStorage.getItem(this.createKey(key));
return data ? JSON.parse(data) : null;
Expand All @@ -32,15 +52,25 @@ export class LocalStorage {
};

clear = () => {
Object.keys(localStorage)
.filter((key) => key.startsWith(this.prefix))
.forEach((key) => localStorage.removeItem(key));
this.dispatchChange();
if (!this.isAvailable) return;
try {
Object.keys(localStorage)
.filter((key) => key.startsWith(this.prefix))
.forEach((key) => localStorage.removeItem(key));
this.dispatchChange();
} catch (error) {
// Silently fail if localStorage operations fail
}
};

removeItem = (key: string) => {
localStorage.removeItem(this.createKey(key));
this.dispatchChange();
if (!this.isAvailable) return;
try {
localStorage.removeItem(this.createKey(key));
this.dispatchChange();
} catch (error) {
// Silently fail if localStorage operations fail
}
};

// ---------------------------------------------------------------------------
Expand Down
12 changes: 11 additions & 1 deletion packages/react-xstore/src/ReactFactory.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,17 @@ describe('ReactFactory', () => {
}, opts);

expect(result.current).toEqual([payload]);
expect(spy).toBeCalledTimes(1);
expect(
spy.mock.calls.filter((call) => !call[0].includes('__storage_test__'))
.length,
).toBe(1);
expect(
spy.mock.calls.some(
(call) =>
call[0] === '@xstate/store_todos' &&
JSON.parse(call[1]).context.todos[0].id === payload.id,
),
).toBe(true);

let storageState: ReturnType<typeof store.services.todos.getSnapshot>;
expect(() => {
Expand Down

0 comments on commit 5a9cf49

Please sign in to comment.