Move the logic that converts the EntityClass of a map to a string and then back into the class to the payload plugin in order to avoid a circular dependency where the ClientMap needs to know the entity classes and the entity classes needs to know the ClientMap. The only place that doesn't know the type of the entities stored in the client map is the payload reviver, so it makes sense to keep this logic contained to the payload plugin.
78 lines
2 KiB
TypeScript
78 lines
2 KiB
TypeScript
import { Info } from "~/shared/utils/luxon";
|
|
import { defineStore } from 'pinia'
|
|
|
|
interface SyncOperation {
|
|
controller: AbortController,
|
|
promise: Promise<Ref<ClientMap<ClientUser>>>,
|
|
}
|
|
|
|
export const useUsersStore = defineStore("users", () => {
|
|
const accountStore = useAccountStore();
|
|
|
|
const state = {
|
|
fetched: ref<boolean>(false),
|
|
pendingSync: ref<SyncOperation>(),
|
|
users: ref<ClientMap<ClientUser>>(new ClientMap(ClientUser, new Map(), new Map())),
|
|
}
|
|
const getters = {
|
|
}
|
|
const actions = {
|
|
async fetch() {
|
|
if (state.fetched.value) {
|
|
return state.users;
|
|
}
|
|
const pending = state.pendingSync.value;
|
|
if (pending) {
|
|
return pending.promise;
|
|
}
|
|
|
|
const requestFetch = useRequestFetch();
|
|
const controller = new AbortController();
|
|
const zone = Info.normalizeZone(accountStore.activeTimezone);
|
|
const locale = accountStore.activeLocale;
|
|
const promise = (async () => {
|
|
try {
|
|
const apiUsers = await requestFetch("/api/users", { signal: controller.signal });
|
|
state.users.value.apiUpdate(apiUsers, { zone, locale });
|
|
state.pendingSync.value = undefined;
|
|
state.fetched.value = true;
|
|
return state.users;
|
|
} catch (err: any) {
|
|
if (err.name !== "AbortError")
|
|
state.pendingSync.value = undefined;
|
|
throw err;
|
|
}
|
|
})();
|
|
state.pendingSync.value = {
|
|
controller,
|
|
promise,
|
|
};
|
|
return promise;
|
|
},
|
|
async resync(id: number) {
|
|
const pending = state.pendingSync.value;
|
|
if (pending) {
|
|
pending.controller.abort();
|
|
}
|
|
state.pendingSync.value = undefined;
|
|
state.fetched.value = false;
|
|
await actions.fetch();
|
|
},
|
|
}
|
|
|
|
appEventSource?.addEventListener("update", (event) => {
|
|
if (event.data.type !== "user-update") {
|
|
return;
|
|
}
|
|
console.log("appyling", event.data)
|
|
const zone = Info.normalizeZone(accountStore.activeTimezone);
|
|
const locale = accountStore.activeLocale;
|
|
state.users.value.apiUpdate([event.data.data], { zone, locale });
|
|
});
|
|
|
|
return {
|
|
...state,
|
|
...getters,
|
|
...actions,
|
|
};
|
|
})
|