These changes are meant to make it possible for new events that come in to immediately render in the components that depend on them.
This commit is contained in:
parent
74ef9a8b3a
commit
cecb9ef0f0
5 changed files with 92 additions and 59 deletions
|
|
@ -1,8 +1,8 @@
|
|||
import { defineStore } from "pinia";
|
||||
import { ref, shallowRef } from "vue";
|
||||
import { ref, shallowRef, shallowReactive } from "vue";
|
||||
|
||||
import { log } from "@/log";
|
||||
import { SSEManager, SSEMessageResource } from "@/SSEManager";
|
||||
import { useSessionStore } from "@/store/session";
|
||||
|
||||
import { apiClient } from "@/client";
|
||||
import {
|
||||
|
|
@ -23,7 +23,7 @@ function createResourceStore<dto, full extends uriHaver>(
|
|||
api_base: string,
|
||||
from_json: jsonConverter<dto, full>,
|
||||
) {
|
||||
const _resourceByURI = shallowRef<Map<string, full>>(new Map());
|
||||
const byURI = shallowReactive<Map<string, full>>(new Map());
|
||||
const _resourceFetchAll = ref<Promise<full[]> | null>(null);
|
||||
const _resourceFetchByURI = shallowRef<Map<string, Promise<full> | null>>(
|
||||
new Map(),
|
||||
|
|
@ -33,32 +33,43 @@ function createResourceStore<dto, full extends uriHaver>(
|
|||
SSEManager.subscribe((msg: SSEMessageResource) => {
|
||||
if (msg.resource.startsWith(resource_name)) {
|
||||
if (msg.type == "created") {
|
||||
console.log("New resource", resource_name, msg.resource, msg.uri);
|
||||
fetchByURI(msg.uri);
|
||||
} else if (msg.type == "updated") {
|
||||
console.log("Updated resource", resource_name, msg.resource, msg.uri);
|
||||
fetchByURI(msg.uri);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
async function byAll(): Promise<full[]> {
|
||||
const cur = _resourceFetchAll.value;
|
||||
if (cur) {
|
||||
return cur;
|
||||
}
|
||||
return fetchAll();
|
||||
}
|
||||
async function byID(id: string): Promise<full> {
|
||||
const uri = uriFromID(id);
|
||||
return byURI(uri);
|
||||
return ensureURI(uri);
|
||||
}
|
||||
async function byURI(uri: string): Promise<full> {
|
||||
let cur = _resourceFetchByURI.value.get(uri);
|
||||
if (cur) {
|
||||
return cur;
|
||||
async function ensureURI(uri: string): Promise<full> {
|
||||
// Check if we already have the data
|
||||
const existing = byURI.get(uri);
|
||||
if (existing) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
// Check if we're already fetching it
|
||||
let fetchPromise = _resourceFetchByURI.value.get(uri);
|
||||
if (fetchPromise) {
|
||||
return fetchPromise;
|
||||
}
|
||||
|
||||
// Start fetching
|
||||
fetchPromise = fetchByURI(uri);
|
||||
_resourceFetchByURI.value.set(uri, fetchPromise);
|
||||
|
||||
try {
|
||||
const result = await fetchPromise;
|
||||
return result;
|
||||
} finally {
|
||||
// Clean up the promise after it resolves
|
||||
_resourceFetchByURI.value.delete(uri);
|
||||
}
|
||||
cur = fetchByURI(uri);
|
||||
_resourceFetchByURI.value.set(uri, cur);
|
||||
return cur;
|
||||
}
|
||||
async function fetchAll(): Promise<full[]> {
|
||||
/*
|
||||
|
|
@ -71,9 +82,13 @@ function createResourceStore<dto, full extends uriHaver>(
|
|||
const url = `/api${api_base}`;
|
||||
const dtos = (await apiClient.JSONGet(url)) as dto[];
|
||||
const resources = dtos.map((m: dto) => from_json(m));
|
||||
//let new_all = new Map<string, full>();
|
||||
resources.forEach((r: full) => {
|
||||
_resourceByURI.value.set(r.uri, r);
|
||||
byURI.set(r.uri, r);
|
||||
//new_all.set(r.uri, r);
|
||||
log.info("Set", resource_name, r);
|
||||
});
|
||||
//byURI.value = new_all;
|
||||
return resources;
|
||||
}
|
||||
async function fetchByID(id: string): Promise<full> {
|
||||
|
|
@ -89,19 +104,16 @@ function createResourceStore<dto, full extends uriHaver>(
|
|||
}
|
||||
const body: dto = await response.json();
|
||||
const report = from_json(body);
|
||||
_resourceByURI.value.set(report.uri, report);
|
||||
//let new_all = new Map<string, full>(byURI.value);
|
||||
//new_all.set(report.uri, report);
|
||||
byURI.set(report.uri, report);
|
||||
//byURI.value = new_all;
|
||||
return report;
|
||||
} catch (err) {
|
||||
console.error("Error loading users:", err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
function getAll(): full[] | null {
|
||||
if (_resourceFetchAll) {
|
||||
return Array.from(_resourceByURI.value.values());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function hasAll(): boolean {
|
||||
return !!_resourceFetchAll.value;
|
||||
}
|
||||
|
|
@ -118,13 +130,12 @@ function createResourceStore<dto, full extends uriHaver>(
|
|||
return `${api_base}/${id}`;
|
||||
}
|
||||
return {
|
||||
byAll,
|
||||
byID,
|
||||
byURI,
|
||||
ensureURI,
|
||||
fetchAll,
|
||||
fetchByID,
|
||||
fetchByURI,
|
||||
getAll,
|
||||
hasAll,
|
||||
loadingAll,
|
||||
loadingURI,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue