Skip to content

Commit 8a15634

Browse files
author
Patrick Corbett
committed
Allow unserialised data to be written to store
This PR: #388 stops the cache being written as anything other than a string. The CachePersistor accepts an option "serialize: boolean" that can allow for data to be written to the store without being serialised to a string first. However with the .toString() coercion, when serialize is true, all that gets written to the store is [object object], rather than the object. This change makes sense, to bring the api inline with the web storage api. However, it means all data must be stored as JSON, which, when there is a large data set, is very expensive in memory and cpu. So this resolves the issue by putting the generic back in, removing the coercion, and assigning the appropriate generic to each of the storage wrappers (I think everything is string apart from localForage, but perhaps other wrappers can support non-string values)
1 parent 06b4d7c commit 8a15634

File tree

9 files changed

+31
-13
lines changed

9 files changed

+31
-13
lines changed

src/Storage.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
} from './types';
66

77
export default class Storage<T> {
8-
storage: PersistentStorage;
8+
storage: PersistentStorage<PersistedData<T>>;
99
key: string;
1010

1111
constructor(options: ApolloPersistOptions<T>) {
@@ -20,7 +20,7 @@ export default class Storage<T> {
2020
}
2121

2222
async write(data: PersistedData<T>): Promise<void> {
23-
await this.storage.setItem(this.key, data.toString());
23+
await this.storage.setItem(this.key, data);
2424
}
2525

2626
async purge(): Promise<void> {

src/__tests__/Storage.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,22 @@ describe('Storage', () => {
1212
await storage.purge();
1313
await expect(storage.read()).resolves.toBe(undefined);
1414
});
15+
16+
describe('when data is an object', () => {
17+
it ('writes an object to persistent storage', async () => {
18+
const obj = {
19+
yo: 'yo yo'
20+
}
21+
22+
await expect(storage.write(obj)).resolves.toBe(undefined);
23+
await expect(storage.read()).resolves.toBe(obj);
24+
})
25+
})
26+
27+
describe('when data is a string', () => {
28+
it ('writes a string to persistent storage', async () => {
29+
await expect(storage.write('yo yo yo')).resolves.toBe(undefined);
30+
await expect(storage.read()).resolves.toBe('yo yo yo');
31+
})
32+
})
1533
});

src/storageWrappers/AsyncStorageWrapper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { PersistentStorage } from '../types';
1212
* });
1313
*
1414
*/
15-
export class AsyncStorageWrapper implements PersistentStorage {
15+
export class AsyncStorageWrapper implements PersistentStorage<string> {
1616
// Actual type definition: https://github.com/react-native-async-storage/async-storage/blob/master/types/index.d.ts
1717
private storage;
1818

src/storageWrappers/IonicStorageWrapper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { PersistentStorage } from '../types';
22

3-
export class IonicStorageWrapper implements PersistentStorage {
3+
export class IonicStorageWrapper implements PersistentStorage<string> {
44
// Actual type definition: https://github.com/ionic-team/ionic-storage/blob/main/src/storage.ts#L102
55
private storage;
66

src/storageWrappers/LocalForageWrapper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { PersistentStorage } from '../types';
22

3-
export class LocalForageWrapper implements PersistentStorage {
3+
export class LocalForageWrapper implements PersistentStorage<string | object> {
44
// Actual type definition: https://github.com/localForage/localForage/blob/master/typings/localforage.d.ts#L17
55
private storage;
66

src/storageWrappers/LocalStorageWrapper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { PersistentStorage } from '../types';
22

3-
export class LocalStorageWrapper implements PersistentStorage {
3+
export class LocalStorageWrapper implements PersistentStorage<string> {
44
// Actual type definition: https://github.com/microsoft/TypeScript/blob/master/lib/lib.dom.d.ts#L15286
55
private storage;
66

src/storageWrappers/MMKVStorageWrapper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { PersistentStorage } from '../types';
1111
* });
1212
*
1313
*/
14-
export class MMKVStorageWrapper implements PersistentStorage {
14+
export class MMKVStorageWrapper implements PersistentStorage<string> {
1515
// Actual type definition: https://github.com/ammarahm-ed/react-native-mmkv-storage/blob/master/index.d.ts#L27
1616
private storage;
1717

src/storageWrappers/SessionStorageWrapper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { PersistentStorage } from '../types';
22

3-
export class SessionStorageWrapper implements PersistentStorage {
3+
export class SessionStorageWrapper implements PersistentStorage<string> {
44
// Actual type definition: https://github.com/microsoft/TypeScript/blob/master/lib/lib.dom.d.ts#L15286
55
private storage;
66

src/types/index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ export type TriggerFunction = (persist: () => void) => TriggerUninstallFunction;
1010

1111
export type PersistedData<T> = T | string | null;
1212

13-
export interface PersistentStorage {
14-
getItem: (key: string) => string | null | Promise<string | null>;
15-
setItem: (key: string, value: string) => void | Promise<void>;
16-
removeItem: (key: string) => void | Promise<void>;
13+
export interface PersistentStorage<T> {
14+
getItem: (key: string) => Promise<T | null> | T | null;
15+
setItem: (key: string, value: T) => Promise<T> | Promise<void> | void | T;
16+
removeItem: (key: string) => Promise<T> | Promise<void> | void;
1717
}
1818

1919
export interface ApolloPersistOptions<TSerialized> {
2020
cache: ApolloCache<TSerialized>;
21-
storage: PersistentStorage;
21+
storage: PersistentStorage<PersistedData<TSerialized>>;
2222
trigger?: 'write' | 'background' | TriggerFunction | false;
2323
debounce?: number;
2424
key?: string;

0 commit comments

Comments
 (0)