Skip to content

Commit

Permalink
Change where and how the "mods last updated" timestamp is updated
Browse files Browse the repository at this point in the history
Old approach used to read the timestamp from the package list table
since it wasn't available elsewhere. This approach no longer works
when we don't update the package list into database if it didn't
change. Instead, store the information in the same table as the
community's last seen index chunk hash. This timestamp is updated
whenever the same index hash is seen again, or when the hash changes
AND the new package list is successfully written to DB.

Old approach loaded the timestamp into Vuex when the package list was
read to Vuex state. With the new approach we need to take into account
that UtilityMixin skips updating the package list in memory if the list
didn't change. Instead, we need to update the timestamp manually.
  • Loading branch information
anttimaki committed Sep 26, 2024
1 parent fb41f15 commit d4c5311
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 17 deletions.
1 change: 1 addition & 0 deletions src/components/mixins/UtilityMixin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default class UtilityMixin extends Vue {
const packageListIndex: PackageListIndex = await this.$store.dispatch("tsMods/fetchPackageListIndex");
if (packageListIndex.isLatest) {
await this.$store.dispatch("tsMods/updateModsLastUpdated");
return;
}
Expand Down
14 changes: 2 additions & 12 deletions src/r2mm/manager/PackageDexieStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,19 +123,9 @@ export async function getPackagesByNames(community: string, packageNames: string
return packages.map(ThunderstoreMod.parseFromThunderstoreData);
}

// TODO: Dexie v3 doesn't support combining .where() and .orderBy() in a
// way that would utilize the DB indexes. The current implementation
// bypasses this by assuming that outside the updateFromApiResponse
// transaction, all the packages have the same date_fetched value.
// Moving to Dexie v4 might improve things, but if that doesn't turn out
// to be true, filter or order the result set on JS side instead.
export async function getLastPackageListUpdateTime(community: string) {
const fetched = await db.packages
.where('[community+date_fetched]')
.between([community, Dexie.minKey], [community, Dexie.maxKey])
.first();

return fetched ? fetched.date_fetched : undefined;
const hash = await db.indexHashes.where({community}).first();
return hash ? hash.date_updated : undefined;
}

export async function isLatestPackageListIndex(community: string, hash: string) {
Expand Down
26 changes: 21 additions & 5 deletions src/store/modules/TsModsModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export const TsModsModule = {
},

actions: <ActionTree<State, RootState>>{
async fetchPackageListIndex({rootState}): Promise<PackageListIndex> {
async fetchPackageListIndex({dispatch, rootState}): Promise<PackageListIndex> {
const indexUrl = rootState.activeGame.thunderstoreUrl;
const index = await retry(() => fetchAndProcessBlobFile(indexUrl));

Expand All @@ -176,6 +176,13 @@ export const TsModsModule = {
const community = rootState.activeGame.internalFolderName;
const isLatest = await PackageDb.isLatestPackageListIndex(community, index.hash);

// Normally the hash would be updated after the mod list is successfully
// fetched and written to IndexedDB, but if the list hasn't changed,
// those step are skipped, so update the "last seen" timestamp now.
if (isLatest) {
await dispatch('updateIndexHash', index.hash);
}

return {...index, isLatest};
},

Expand Down Expand Up @@ -222,13 +229,17 @@ export const TsModsModule = {
commit('setExclusions', exclusions);
},

async updateMods({commit, rootState}) {
async updateMods({commit, dispatch, rootState}) {
const modList = await PackageDb.getPackagesAsThunderstoreMods(rootState.activeGame.internalFolderName);
const updated = await PackageDb.getLastPackageListUpdateTime(rootState.activeGame.internalFolderName);
commit('setMods', modList);
commit('setModsLastUpdated', updated);
commit('updateDeprecated', modList);
commit('clearModCache');
await dispatch('updateModsLastUpdated');
},

async updateModsLastUpdated({commit, rootState}) {
const updated = await PackageDb.getLastPackageListUpdateTime(rootState.activeGame.internalFolderName);
commit('setModsLastUpdated', updated);
},

/*** Save a mod list received from the Thunderstore API to IndexedDB */
Expand All @@ -245,7 +256,12 @@ export const TsModsModule = {
));
const community = rootState.activeGame.internalFolderName;
await PackageDb.updateFromApiResponse(community, filtered);
await dispatch('updateIndexHash', indexHash);
},

async updateIndexHash({rootState}, indexHash: string) {
const community = rootState.activeGame.internalFolderName;
await PackageDb.setLatestPackageListIndex(community, indexHash);
}
},
}
}

0 comments on commit d4c5311

Please sign in to comment.