Skip to content

Commit ca135bb

Browse files
sam-gcavolkovi
authored andcommitted
Add a persistence manager class (#2925)
1 parent de58736 commit ca135bb

14 files changed

+540
-69
lines changed

packages-exp/auth-exp/src/core/persistence/browser.test.ts

+12-16
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
* limitations under the License.
1616
*/
1717

18-
import * as sinon from 'sinon';
19-
import { PersistenceType } from '.';
2018
import { expect } from 'chai';
21-
import { browserLocalPersistence, browserSessionPersistence } from './browser';
22-
import { User } from '../../model/user';
19+
import * as sinon from 'sinon';
20+
2321
import { testUser } from '../../../test/mock_auth';
22+
import { PersistedBlob, PersistenceType } from './';
23+
import { browserLocalPersistence, browserSessionPersistence } from './browser';
2424

2525
describe('core/persistence/browser', () => {
2626
beforeEach(() => {
@@ -44,16 +44,14 @@ describe('core/persistence/browser', () => {
4444
expect(await persistence.get(key)).to.be.null;
4545
});
4646

47-
it('should call instantiator function if provided', async () => {
47+
it('should return persistedblob from user', async () => {
4848
const key = 'my-super-special-user';
4949
const value = testUser('some-uid');
5050

5151
expect(await persistence.get(key)).to.be.null;
52-
await persistence.set(key, value);
53-
const out = await persistence.get<User>(key, blob =>
54-
testUser(`test-${blob.uid}`)
55-
);
56-
expect(out?.uid).to.eql('test-some-uid');
52+
await persistence.set(key, value.toPlainObject());
53+
const out = await persistence.get<PersistedBlob>(key);
54+
expect(out!['uid']).to.eql(value.uid);
5755
await persistence.remove(key);
5856
expect(await persistence.get(key)).to.be.null;
5957
});
@@ -89,16 +87,14 @@ describe('core/persistence/browser', () => {
8987
expect(await persistence.get(key)).to.be.null;
9088
});
9189

92-
it('should call instantiator function if provided', async () => {
90+
it('should emit blobified persisted user', async () => {
9391
const key = 'my-super-special-user';
9492
const value = testUser('some-uid');
9593

9694
expect(await persistence.get(key)).to.be.null;
97-
await persistence.set(key, value);
98-
const out = await persistence.get<User>(key, blob =>
99-
testUser(`test-${blob.uid}`)
100-
);
101-
expect(out?.uid).to.eql('test-some-uid');
95+
await persistence.set(key, value.toPlainObject());
96+
const out = await persistence.get<PersistedBlob>(key);
97+
expect(out!['uid']).to.eql(value.uid);
10298
await persistence.remove(key);
10399
expect(await persistence.get(key)).to.be.null;
104100
});

packages-exp/auth-exp/src/core/persistence/browser.ts

+6-12
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ import {
1919
Persistence,
2020
PersistenceType,
2121
PersistenceValue,
22-
Instantiator
23-
} from '.';
24-
25-
const STORAGE_AVAILABLE_KEY_ = '__sak';
22+
STORAGE_AVAILABLE_KEY
23+
} from './';
2624

2725
class BrowserPersistence implements Persistence {
2826
type: PersistenceType = PersistenceType.LOCAL;
@@ -34,8 +32,8 @@ class BrowserPersistence implements Persistence {
3432
if (!this.storage) {
3533
return false;
3634
}
37-
this.storage.setItem(STORAGE_AVAILABLE_KEY_, '1');
38-
this.storage.removeItem(STORAGE_AVAILABLE_KEY_);
35+
this.storage.setItem(STORAGE_AVAILABLE_KEY, '1');
36+
this.storage.removeItem(STORAGE_AVAILABLE_KEY);
3937
return true;
4038
} catch {
4139
return false;
@@ -46,13 +44,9 @@ class BrowserPersistence implements Persistence {
4644
this.storage.setItem(key, JSON.stringify(value));
4745
}
4846

49-
async get<T extends PersistenceValue>(
50-
key: string,
51-
instantiator?: Instantiator<T>
52-
): Promise<T | null> {
47+
async get<T extends PersistenceValue>(key: string): Promise<T | null> {
5348
const json = this.storage.getItem(key);
54-
const obj = json ? JSON.parse(json) : null;
55-
return instantiator && obj ? instantiator(obj) : obj;
49+
return json ? JSON.parse(json) : null;
5650
}
5751

5852
async remove(key: string): Promise<void> {

packages-exp/auth-exp/src/core/persistence/in_memory.test.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515
* limitations under the License.
1616
*/
1717

18-
import { inMemoryPersistence as persistence } from './in_memory';
19-
import { PersistenceType } from '.';
2018
import { expect } from 'chai';
21-
import { User } from '../../model/user';
19+
2220
import { testUser } from '../../../test/mock_auth';
21+
import { PersistenceType } from './';
22+
import { inMemoryPersistence as persistence } from './in_memory';
2323

2424
describe('core/persistence/in_memory', () => {
2525
it('should work with persistence type', async () => {
@@ -38,8 +38,8 @@ describe('core/persistence/in_memory', () => {
3838
const value = testUser('uid');
3939

4040
expect(await persistence.get(key)).to.be.null;
41-
await persistence.set(key, value);
42-
expect(await persistence.get<User>(key)).to.eql(value);
41+
await persistence.set(key, value.toPlainObject());
42+
expect(await persistence.get(key)).to.eql(value.toPlainObject());
4343
expect(await persistence.get('other-key')).to.be.null;
4444
await persistence.remove(key);
4545
expect(await persistence.get(key)).to.be.null;

packages-exp/auth-exp/src/core/persistence/index.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,28 @@
1515
* limitations under the License.
1616
*/
1717

18-
import { User } from '../../model/user';
19-
2018
export enum PersistenceType {
2119
SESSION = 'SESSION',
2220
LOCAL = 'LOCAL',
2321
NONE = 'NONE'
2422
}
2523

24+
export interface PersistedBlob {
25+
[key: string]: unknown;
26+
}
27+
2628
export interface Instantiator<T> {
27-
(blob: { [key: string]: unknown }): T;
29+
(blob: PersistedBlob): T;
2830
}
2931

30-
export type PersistenceValue = PersistenceType | User;
32+
export type PersistenceValue = PersistedBlob | string;
33+
34+
export const STORAGE_AVAILABLE_KEY = '__sak';
3135

3236
export interface Persistence {
3337
type: PersistenceType;
3438
isAvailable(): Promise<boolean>;
3539
set(key: string, value: PersistenceValue): Promise<void>;
36-
get<T extends PersistenceValue>(
37-
key: string,
38-
instantiator?: Instantiator<T>
39-
): Promise<T | null>;
40+
get<T extends PersistenceValue>(key: string): Promise<T | null>;
4041
remove(key: string): Promise<void>;
4142
}

packages-exp/auth-exp/src/core/persistence/indexed_db.test.ts

+8-10
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
* limitations under the License.
1616
*/
1717

18-
import * as sinon from 'sinon';
19-
import { PersistenceType } from '.';
2018
import { expect } from 'chai';
21-
import { indexedDBLocalPersistence as persistence } from './indexed_db';
22-
import { User } from '../../model/user';
19+
import * as sinon from 'sinon';
20+
2321
import { testUser } from '../../../test/mock_auth';
22+
import { PersistenceType } from './';
23+
import { indexedDBLocalPersistence as persistence } from './indexed_db';
2424

2525
describe('core/persistence/indexed_db', () => {
2626
afterEach(sinon.restore);
@@ -36,16 +36,14 @@ describe('core/persistence/indexed_db', () => {
3636
expect(await persistence.get(key)).to.be.null;
3737
});
3838

39-
it('should call instantiator function if provided', async () => {
39+
it('should return blobified user value', async () => {
4040
const key = 'my-super-special-user';
4141
const value = testUser('some-uid');
4242

4343
expect(await persistence.get(key)).to.be.null;
44-
await persistence.set(key, value);
45-
const out = await persistence.get<User>(key, blob =>
46-
testUser(`test-${blob.uid}`)
47-
);
48-
expect(out?.uid).to.eql('test-some-uid');
44+
await persistence.set(key, value.toPlainObject());
45+
const out = await persistence.get(key);
46+
expect(out).to.eql(value.toPlainObject());
4947
await persistence.remove(key);
5048
expect(await persistence.get(key)).to.be.null;
5149
});

packages-exp/auth-exp/src/core/persistence/indexed_db.ts

+9-18
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,21 @@
1616
*/
1717

1818
import {
19+
PersistedBlob,
1920
Persistence,
2021
PersistenceType,
2122
PersistenceValue,
22-
Instantiator
23-
} from '.';
24-
25-
const STORAGE_AVAILABLE_KEY_ = '__sak';
23+
STORAGE_AVAILABLE_KEY
24+
} from './';
2625

2726
export const DB_NAME = 'firebaseLocalStorageDb';
2827
const DB_VERSION = 1;
2928
const DB_OBJECTSTORE_NAME = 'firebaseLocalStorage';
3029
const DB_DATA_KEYPATH = 'fbase_key';
3130

32-
type DBValue = { [key: string]: unknown } | string;
33-
3431
interface DBObject {
3532
[DB_DATA_KEYPATH]: string;
36-
value: DBValue;
33+
value: PersistedBlob;
3734
}
3835

3936
/**
@@ -110,7 +107,7 @@ async function putObject(
110107
const data = await new DBPromise<DBObject | null>(getRequest).toPromise();
111108
if (data) {
112109
// Force an index signature on the user object
113-
data.value = value as DBValue;
110+
data.value = value as PersistedBlob;
114111
const request = getObjectStore(db, true).put(data);
115112
return new DBPromise<void>(request).toPromise();
116113
} else {
@@ -125,7 +122,7 @@ async function putObject(
125122
async function getObject(
126123
db: IDBDatabase,
127124
key: string
128-
): Promise<DBValue | null> {
125+
): Promise<PersistedBlob | null> {
129126
const request = getObjectStore(db, false).get(key);
130127
const data = await new DBPromise<DBObject | undefined>(request).toPromise();
131128
return data === undefined ? null : data.value;
@@ -154,8 +151,8 @@ class IndexedDBLocalPersistence implements Persistence {
154151
return false;
155152
}
156153
const db = await openDatabase();
157-
await putObject(db, STORAGE_AVAILABLE_KEY_, '1');
158-
await deleteObject(db, STORAGE_AVAILABLE_KEY_);
154+
await putObject(db, STORAGE_AVAILABLE_KEY, '1');
155+
await deleteObject(db, STORAGE_AVAILABLE_KEY);
159156
return true;
160157
} catch {}
161158
return false;
@@ -166,15 +163,9 @@ class IndexedDBLocalPersistence implements Persistence {
166163
return putObject(db, key, value);
167164
}
168165

169-
async get<T extends PersistenceValue>(
170-
key: string,
171-
instantiator?: Instantiator<T>
172-
): Promise<T | null> {
166+
async get<T extends PersistenceValue>(key: string): Promise<T | null> {
173167
const db = await this.initialize();
174168
const obj = await getObject(db, key);
175-
if (instantiator && obj && typeof obj !== 'string') {
176-
return instantiator(obj);
177-
}
178169
return obj as T;
179170
}
180171

0 commit comments

Comments
 (0)