fix(core): preserve data integrity and bound shared UI and response work
Module Package Release / publish-packages (push) Successful in 13s

Release v0.1.46. Coordinated integrity review: GovOPlaN/govoplan-core#298.
This commit is contained in:
2026-09-08 12:30:38 +02:00
parent dc1f244f17
commit 6591aaa3fd
33 changed files with 1889 additions and 114 deletions
+14 -24
View File
@@ -1,6 +1,7 @@
import { Navigate, Route, Routes, useLocation } from "react-router";
import { lazy, useEffect, useMemo, useState } from "react";
import { fetchSession, fetchShellAuth, logout, updateProfile } from "./api/auth";
import { createModuleRefresh } from "./platform/moduleRefresh";
import type { AuthActionUiCapability } from "./types";
import { fetchPlatformModules, fetchPlatformPublicModules, fetchPlatformStatus } from "./api/platform";
import { AUTH_REQUIRED_EVENT, apiSettingsForAuthUpdate, clearApiReadCache, isApiError, loadApiSettings, saveApiSettings, type AuthRequiredEventDetail } from "./api/client";
@@ -303,45 +304,34 @@ export default function App() {
return;
}
let cancelled = false;
let inFlight = false;
let lastRefreshAt = 0;
function loadModules() {
inFlight = true;
lastRefreshAt = Date.now();
return fetchPlatformModules(settings).
then((response) => {if (!cancelled) setPlatformModules(response.modules);}).
catch(() => {
if (!cancelled) {
setPlatformModules(null);
setWebModulesLoading(false);
}
}).
finally(() => {inFlight = false;});
}
void loadModules();
const refresh = createModuleRefresh({
load: () => fetchPlatformModules(settings),
accept: (response) => setPlatformModules(response.modules),
reject: () => {
setPlatformModules(null);
setWebModulesLoading(false);
}
});
refresh.invalidate();
function handleModulesChanged() {
void loadModules();
refresh.invalidate();
}
function refreshVisibleModules() {
if (document.visibilityState === "hidden" || inFlight) return;
if (Date.now() - lastRefreshAt < 5_000) return;
void loadModules();
refresh.refreshVisible(document.visibilityState !== "hidden");
}
window.addEventListener(PLATFORM_MODULES_CHANGED_EVENT, handleModulesChanged);
window.addEventListener("focus", refreshVisibleModules);
document.addEventListener("visibilitychange", refreshVisibleModules);
return () => {
cancelled = true;
refresh.dispose();
window.removeEventListener(PLATFORM_MODULES_CHANGED_EVENT, handleModulesChanged);
window.removeEventListener("focus", refreshVisibleModules);
document.removeEventListener("visibilitychange", refreshVisibleModules);
};
}, [auth?.user?.id, auth?.active_tenant?.id, auth?.tenant.id, requiredAuthAction, settings.apiBaseUrl, settings.apiKey]);
}, [auth, requiredAuthAction, settings.apiBaseUrl, settings.apiKey, settings.accessToken]);
useEffect(() => {
let cancelled = false;