Skip to content

Commit 95df4e4

Browse files
Refactor setCustomSignals storage API
- Add new `getWithTransaction` and `setWithTransaction` APIs - Refactor generic `get` and `set` APIs for code reuse - Update `setCustomSignals` to perform upsert operation in a single transaction.
1 parent 3f7a55c commit 95df4e4

File tree

2 files changed

+55
-53
lines changed

2 files changed

+55
-53
lines changed

packages/remote-config/src/storage/storage.ts

Lines changed: 54 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -188,58 +188,38 @@ export class Storage {
188188

189189
async setCustomSignals(customSignals: CustomSignals): Promise<void> {
190190
const db = await this.openDbPromise;
191-
return new Promise((resolve, reject) => {
192-
const transaction = db.transaction([APP_NAMESPACE_STORE], 'readwrite');
193-
const objectStore = transaction.objectStore(APP_NAMESPACE_STORE);
194-
const compositeKey = this.createCompositeKey('custom_signals');
195-
try {
196-
const storedSignalsRequest = objectStore.get(compositeKey);
197-
storedSignalsRequest.onerror = event => {
198-
reject(toFirebaseError(event, ErrorCode.STORAGE_GET));
199-
};
200-
storedSignalsRequest.onsuccess = event => {
201-
const storedSignals =
202-
(event.target as IDBRequest).result?.value || {};
203-
const combinedSignals = {
204-
...storedSignals,
205-
...customSignals
206-
};
207-
// Filter out key-value assignments with null values since they are signals being unset
208-
const signalsToUpdate = Object.fromEntries(
209-
Object.entries(combinedSignals).filter(([_, v]) => v !== null)
210-
);
211-
if (signalsToUpdate) {
212-
const setSignalsRequest = objectStore.put({
213-
compositeKey,
214-
value: signalsToUpdate
215-
});
216-
setSignalsRequest.onerror = event => {
217-
reject(toFirebaseError(event, ErrorCode.STORAGE_SET));
218-
};
219-
setSignalsRequest.onsuccess = event => {
220-
const result = (event.target as IDBRequest).result;
221-
if (result) {
222-
resolve(result.value);
223-
} else {
224-
resolve(undefined);
225-
}
226-
};
227-
}
228-
};
229-
} catch (e) {
230-
reject(
231-
ERROR_FACTORY.create(ErrorCode.STORAGE_SET, {
232-
originalErrorMessage: (e as Error)?.message
233-
})
234-
);
235-
}
236-
});
191+
const transaction = db.transaction([APP_NAMESPACE_STORE], 'readwrite');
192+
const storedSignals = await this.getWithTransaction<CustomSignals>(
193+
'custom_signals',
194+
transaction
195+
);
196+
const combinedSignals = {
197+
...storedSignals,
198+
...customSignals
199+
};
200+
// Filter out key-value assignments with null values since they are signals being unset
201+
const signalsToUpdate = Object.fromEntries(
202+
Object.entries(combinedSignals).filter(([_, v]) => v !== null)
203+
);
204+
return this.setWithTransaction<CustomSignals>(
205+
'custom_signals',
206+
signalsToUpdate,
207+
transaction
208+
);
237209
}
238210

239-
async get<T>(key: ProjectNamespaceKeyFieldValue): Promise<T | undefined> {
240-
const db = await this.openDbPromise;
211+
/**
212+
* Gets a value from the database using the provided transaction.
213+
*
214+
* @param key The key of the value to get.
215+
* @param transaction The transaction to use for the operation.
216+
* @returns The value associated with the key, or undefined if no such value exists.
217+
*/
218+
async getWithTransaction<T>(
219+
key: ProjectNamespaceKeyFieldValue,
220+
transaction: IDBTransaction
221+
): Promise<T | undefined> {
241222
return new Promise((resolve, reject) => {
242-
const transaction = db.transaction([APP_NAMESPACE_STORE], 'readonly');
243223
const objectStore = transaction.objectStore(APP_NAMESPACE_STORE);
244224
const compositeKey = this.createCompositeKey(key);
245225
try {
@@ -265,10 +245,20 @@ export class Storage {
265245
});
266246
}
267247

268-
async set<T>(key: ProjectNamespaceKeyFieldValue, value: T): Promise<void> {
269-
const db = await this.openDbPromise;
248+
/**
249+
* Sets a value in the database using the provided transaction.
250+
*
251+
* @param key The key of the value to set.
252+
* @param value The value to set.
253+
* @param transaction The transaction to use for the operation.
254+
* @returns A promise that resolves when the operation is complete.
255+
*/
256+
async setWithTransaction<T>(
257+
key: ProjectNamespaceKeyFieldValue,
258+
value: T,
259+
transaction: IDBTransaction
260+
): Promise<void> {
270261
return new Promise((resolve, reject) => {
271-
const transaction = db.transaction([APP_NAMESPACE_STORE], 'readwrite');
272262
const objectStore = transaction.objectStore(APP_NAMESPACE_STORE);
273263
const compositeKey = this.createCompositeKey(key);
274264
try {
@@ -292,6 +282,18 @@ export class Storage {
292282
});
293283
}
294284

285+
async get<T>(key: ProjectNamespaceKeyFieldValue): Promise<T | undefined> {
286+
const db = await this.openDbPromise;
287+
const transaction = db.transaction([APP_NAMESPACE_STORE], 'readonly');
288+
return this.getWithTransaction<T>(key, transaction);
289+
}
290+
291+
async set<T>(key: ProjectNamespaceKeyFieldValue, value: T): Promise<void> {
292+
const db = await this.openDbPromise;
293+
const transaction = db.transaction([APP_NAMESPACE_STORE], 'readwrite');
294+
return this.setWithTransaction<T>(key, value, transaction);
295+
}
296+
295297
async delete(key: ProjectNamespaceKeyFieldValue): Promise<void> {
296298
const db = await this.openDbPromise;
297299
return new Promise((resolve, reject) => {

packages/remote-config/test/client/rest_client.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ describe('RestClient', () => {
114114
expect(fetchStub).to.be.calledWith(
115115
sinon.match.string,
116116
sinon.match({
117-
body: '{"sdk_version":"sdk-version","app_instance_id":"fis-id","app_instance_id_token":"fis-token","app_id":"app-id","language_code":"en-GB"}'
117+
body: '{"sdk_version":"sdk-version","app_instance_id":"fis-id","app_instance_id_token":"fis-token","app_id":"app-id","language_code":"en-US"}'
118118
})
119119
);
120120
});

0 commit comments

Comments
 (0)