refactor: 💡 reduce network requests & call indexedDB directly (#2217)

* refactor: 💡 reduce network requests & call indexedDB directly

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-13251
This commit is contained in:
Lisbet Alvarez authored and Zhihe Li committed 2024-04-12 14:55:34 -04:00
1 parent c2c0b38187
commit 6c59baa413
9 files changed
+88 -69

No files matched your search

+58 -52
View File
@@ -19,7 +19,11 @@ export default class IndexedDbHandler {
switch (context.request.op) {
case 'query': {
const { store, data } = context.request;
const { type, query, options: { pushToStore = true } = {} } = data;
const {
type,
query,
options: { pushToStore = true, peekIndexedDB = false } = {},
} = data;
const supportedModels = Object.keys(modelIndexes);
const { db: indexedDb } = this.indexedDb ?? {};
@@ -31,66 +35,68 @@ export default class IndexedDbHandler {
let { page, pageSize, query: queryObj, ...remainingQuery } = query;
const listToken = await indexedDb.token.get(type);
const adapter = store.adapterFor(type);
const schema = store.modelFor(type);
let payload;
try {
payload = await adapter.query(store, schema, {
...remainingQuery,
scope_id: 'global',
recursive: true,
list_token: listToken?.token,
});
} catch (e) {
// If we get any error that's not a rate limiting error,
// assume the token is not good anymore. We'll delete the token and
// clear the DB and try again without a token.
// TODO: Probably should check for 400 and bad token error specifically instead?
if (e?.errors[0].status !== 429) {
await indexedDb[type].clear();
await indexedDb.token.delete(type);
if (!peekIndexedDB) {
const listToken = await indexedDb.token.get(type);
const adapter = store.adapterFor(type);
const schema = store.modelFor(type);
let payload;
try {
payload = await adapter.query(store, schema, {
...remainingQuery,
scope_id: 'global',
recursive: true,
list_token: null,
list_token: listToken?.token,
});
} else {
throw e;
} catch (e) {
// If we get any error that's not a rate limiting error,
// assume the token is not good anymore. We'll delete the token and
// clear the DB and try again without a token.
// TODO: Probably should check for 400 and bad token error specifically instead?
if (e?.errors[0].status !== 429) {
await indexedDb[type].clear();
await indexedDb.token.delete(type);
payload = await adapter.query(store, schema, {
...remainingQuery,
scope_id: 'global',
recursive: true,
list_token: null,
});
} else {
throw e;
}
}
// Store the token we just got back from the payload
await indexedDb.token.put({
id: type,
token: payload.list_token,
});
// Remove any records from the DB if the API indicates they've been deleted
if (payload.removed_ids?.length > 0) {
await indexedDb[type].bulkDelete(payload.removed_ids);
}
const serializer = store.serializerFor(type);
const normalizedPayload = serializer.normalizeResponse(
store,
schema,
payload,
null,
'query',
);
const { data: payloadData } = normalizedPayload;
// Store the new data we just got back from the API refresh
const items = payloadData.map((datum) =>
this.indexedDb.normalizeData(datum, true),
);
await indexedDb[type].bulkPut(items);
}
// Store the token we just got back from the payload
await indexedDb.token.put({
id: type,
token: payload.list_token,
});
// Remove any records from the DB if the API indicates they've been deleted
if (payload.removed_ids?.length > 0) {
await indexedDb[type].bulkDelete(payload.removed_ids);
}
const serializer = store.serializerFor(type);
const normalizedPayload = serializer.normalizeResponse(
store,
schema,
payload,
null,
'query',
);
const { data: payloadData } = normalizedPayload;
// Store the new data we just got back from the API refresh
const items = payloadData.map((datum) =>
this.indexedDb.normalizeData(datum, true),
);
await indexedDb[type].bulkPut(items);
const indexedDbResults = await queryIndexedDb(
indexedDb,
type,