feat: reactive stores
This commit is contained in:
@ -3,6 +3,7 @@
|
||||
CloudUploadIcon,
|
||||
HandIcon,
|
||||
MapIcon,
|
||||
PackageMinusIcon,
|
||||
PackagePlusIcon,
|
||||
RefreshCcwIcon,
|
||||
SpeechIcon,
|
||||
@ -16,9 +17,11 @@
|
||||
import { view } from "../../view.svelte";
|
||||
import { m } from "$lang/messages";
|
||||
import { setOnboardingState } from "$lib/onboarding.svelte";
|
||||
import { syncStores, updateStore } from "$lib/services/stores";
|
||||
import { stores, syncStores, updateStore } from "$lib/services/stores.svelte";
|
||||
|
||||
const dev = getDeveloperToggle();
|
||||
|
||||
const locationStores = stores("location");
|
||||
</script>
|
||||
|
||||
<SidebarHeader>{m["sidebar.developer.header"]()}</SidebarHeader>
|
||||
@ -91,6 +94,21 @@
|
||||
await updateStore({ name, type }, JSON.parse(data));
|
||||
}}
|
||||
/>
|
||||
<SettingsButton
|
||||
icon={PackageMinusIcon}
|
||||
text="Delete Store"
|
||||
onclick={async () => {
|
||||
const name = prompt("Store Name?");
|
||||
if (!name) return;
|
||||
const type = prompt("Store Type? (route, location, vehicle)");
|
||||
if (type !== "route" && type !== "location" && type !== "vehicle") {
|
||||
alert("Invalid type");
|
||||
return;
|
||||
}
|
||||
await updateStore({ name, type }, null);
|
||||
}}
|
||||
/>
|
||||
<span>LOCATION STORES: {JSON.stringify(locationStores.current)}</span>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
|
||||
@ -53,6 +53,8 @@ export const db = await openDB<TCDB>("tc", 1, {
|
||||
}
|
||||
})
|
||||
|
||||
const eventTarget = new EventTarget();
|
||||
|
||||
export async function syncStores() {
|
||||
const changes = await Promise.all(await db.getAll("changes").then(changes => changes.map(async change => {
|
||||
const storeData = await db.get("stores", change.id);
|
||||
@ -82,6 +84,7 @@ export async function syncStores() {
|
||||
} else {
|
||||
await tx.objectStore("stores").put(store);
|
||||
}
|
||||
eventTarget.dispatchEvent(new CustomEvent("store-updated", { detail: store }) );
|
||||
}
|
||||
// Delete all changes
|
||||
await tx.objectStore("changes").clear();
|
||||
@ -102,12 +105,14 @@ async function createStore(info: StoreInfo, data: object) {
|
||||
await tx.objectStore("stores").add(store);
|
||||
await tx.objectStore("changes").add({ id, operation: "create" });
|
||||
await tx.done;
|
||||
eventTarget.dispatchEvent(new CustomEvent("store-updated", { detail: store }) );
|
||||
return store;
|
||||
}
|
||||
|
||||
export async function updateStore(info: StoreInfo, data: object) {
|
||||
export async function updateStore(info: StoreInfo, data: object | null) {
|
||||
const store = await db.getFromIndex("stores", "by-name-and-type", [info.name, info.type]);
|
||||
if (!store) {
|
||||
if(data === null) return;
|
||||
return await createStore(info, data);
|
||||
}
|
||||
// Update the store data
|
||||
@ -117,5 +122,49 @@ export async function updateStore(info: StoreInfo, data: object) {
|
||||
await tx.objectStore("stores").put(store);
|
||||
await tx.objectStore("changes").add({ id: store.id, operation: "update" });
|
||||
await tx.done;
|
||||
eventTarget.dispatchEvent(new CustomEvent("store-updated", { detail: store }) );
|
||||
return store;
|
||||
}
|
||||
|
||||
// export async function store<T extends object>(info: StoreInfo) {
|
||||
// const store = await db.getFromIndex("stores", "by-name-and-type", [info.name, info.type]);
|
||||
// if (!store) {
|
||||
// return null;
|
||||
// }
|
||||
// const state = $state<T>(JSON.parse(store.data) as T);
|
||||
// $effect(() => {
|
||||
// updateStore(info, state);
|
||||
// })
|
||||
// eventTarget.addEventListener("store-updated", (event) => {
|
||||
// const customEvent = event as CustomEvent;
|
||||
// if(customEvent.detail.id === store.id) {
|
||||
// const updatedStore = customEvent.detail as Store;
|
||||
// Object.assign(state, JSON.parse(updatedStore.data));
|
||||
// }
|
||||
// });
|
||||
// return state;
|
||||
// }
|
||||
|
||||
export function stores<T extends object>(type: StoreType) {
|
||||
const state = $state<T[]>([]);
|
||||
eventTarget.addEventListener("store-updated", async (event) => {
|
||||
const customEvent = event as CustomEvent;
|
||||
const updatedStore = customEvent.detail as Store;
|
||||
if(updatedStore.type === type) {
|
||||
const stores = await db.getAllFromIndex("stores", "by-type", type);
|
||||
state.splice(0, state.length, ...(stores.map(store => JSON.parse(store.data) as T).filter(store => store !== null)));
|
||||
}
|
||||
});
|
||||
(async () => {
|
||||
const stores = await db.getAllFromIndex("stores", "by-type", type);
|
||||
state.splice(0, state.length, ...(stores.map(store => JSON.parse(store.data) as T).filter(store => store !== null)));
|
||||
})();
|
||||
return {
|
||||
get current() {
|
||||
return state;
|
||||
},
|
||||
set current(newValue: T[]) {
|
||||
state.splice(0, state.length, ...newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user