deno.land / x / replicache@v10.0.0-beta.0 / persist / idb-databases-store.ts

idb-databases-store.ts
نووسراو ببینە
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import {assert, assertNumber, assertObject, assertString} from '../asserts';import * as kv from '../kv/mod';import {uuid} from '../uuid';
const IDB_DATABASES_VERSION = 0;const IDB_DATABASES_DB_NAME = 'replicache-dbs-v' + IDB_DATABASES_VERSION;const DBS_KEY = 'dbs';const PROFILE_ID_KEY = 'profileId';
let testNamespace = '';
/** Namespace db name in test to isolate tests' indexeddb state. */export function setupForTest(): void { testNamespace = uuid();}
export function teardownForTest(): Promise<void> { const idbDatabasesDBName = getIDBDatabasesDBName(); testNamespace = ''; return kv.dropIDBStore(idbDatabasesDBName);}
function getIDBDatabasesDBName(): string { return testNamespace + IDB_DATABASES_DB_NAME;}
// TODO: make an opaque typeexport type IndexedDBName = string;
export type IndexedDBDatabase = { readonly name: IndexedDBName; readonly replicacheName: string; readonly replicacheFormatVersion: number; readonly schemaVersion: string; readonly lastOpenedTimestampMS?: number;};
export type IndexedDBDatabaseRecord = { readonly [name: IndexedDBName]: IndexedDBDatabase;};
function assertIndexedDBDatabaseRecord( value: unknown,): asserts value is IndexedDBDatabaseRecord { assertObject(value); for (const [name, db] of Object.entries(value)) { assertString(name); assertIndexedDBDatabase(db); assert(name === db.name); }}
function assertIndexedDBDatabase( value: unknown,): asserts value is IndexedDBDatabase { assertObject(value); assertString(value.name); assertString(value.replicacheName); assertNumber(value.replicacheFormatVersion); assertString(value.schemaVersion); if (value.lastOpenedTimestampMS !== undefined) { assertNumber(value.lastOpenedTimestampMS); }}
export class IDBDatabasesStore { private readonly _kvStore: kv.Store;
constructor( createKVStore: (name: string) => kv.Store = name => new kv.IDBStore(name), ) { this._kvStore = createKVStore(IDB_DATABASES_DB_NAME); }
putDatabase(db: IndexedDBDatabase): Promise<IndexedDBDatabaseRecord> { return this._putDatabase({...db, lastOpenedTimestampMS: Date.now()}); }
putDatabaseForTesting( db: IndexedDBDatabase, ): Promise<IndexedDBDatabaseRecord> { return this._putDatabase(db); }
private _putDatabase( db: IndexedDBDatabase, ): Promise<IndexedDBDatabaseRecord> { return this._kvStore.withWrite(async write => { const oldDbRecord = await this._getDatabases(write); const dbRecord = { ...oldDbRecord, [db.name]: db, }; await write.put(DBS_KEY, dbRecord); await write.commit(); return dbRecord; }); }
clearDatabases(): Promise<void> { return this._kvStore.withWrite(async write => { await write.del(DBS_KEY); await write.commit(); }); }
deleteDatabases(names: Iterable<IndexedDBName>): Promise<void> { return this._kvStore.withWrite(async write => { const oldDbRecord = await this._getDatabases(write); const dbRecord = { ...oldDbRecord, }; for (const name of names) { delete dbRecord[name]; } await write.put(DBS_KEY, dbRecord); await write.commit(); }); }
getDatabases(): Promise<IndexedDBDatabaseRecord> { return this._kvStore.withRead(read => this._getDatabases(read)); }
close(): Promise<void> { return this._kvStore.close(); }
private async _getDatabases(read: kv.Read): Promise<IndexedDBDatabaseRecord> { let dbRecord = await read.get(DBS_KEY); if (!dbRecord) { dbRecord = {}; } assertIndexedDBDatabaseRecord(dbRecord); return dbRecord; }
async getProfileID(): Promise<string> { return this._kvStore.withWrite(async write => { let profileId = await write.get(PROFILE_ID_KEY); if (profileId === undefined) { // Profile id is 'p' followed by the guid with no dashes. profileId = `p${uuid().replace(/-/g, '')}`; await write.put(PROFILE_ID_KEY, profileId); await write.commit(); } assertString(profileId); return profileId; }); }}
replicache

Version Info

Tagged at
2 years ago