alerte-secours/src/stores/tree.js

93 lines
2.3 KiB
JavaScript

import { createAtom } from "~/lib/atomic-zustand";
import { createLogger } from "~/lib/logger";
import { SYSTEM_SCOPES } from "~/lib/logger/scopes";
const treeLogger = createLogger({
module: SYSTEM_SCOPES.APP,
feature: "tree-reload",
});
const reloadCallbacks = [];
export default createAtom(({ merge, getActions }) => {
const sessionActions = getActions("session");
const networkActions = getActions("network");
const alertActions = getActions("alert");
const navActions = getActions("alert");
const fcmActions = getActions("fcm");
const paramsActions = getActions("params");
const notificationsActions = getActions("notifications");
const resetStores = () => {
navActions.reset();
paramsActions.reset();
fcmActions.reset();
alertActions.reset();
notificationsActions.reset();
};
const triggerReload = (callback) => {
if (callback) {
reloadCallbacks.push(callback);
}
// Clear session/store state first to stop user-level queries/subscriptions
// while we swap identity tokens.
sessionActions.clear();
resetStores();
merge({
triggerReload: true,
// Keep the tree suspended until we've run reload callbacks.
suspend: true,
});
};
const onReload = async () => {
merge({
triggerReload: false,
});
// Run all reload callbacks sequentially and await them.
// This ensures auth identity swap completes BEFORE the network layer is recreated.
while (reloadCallbacks.length > 0) {
let callback = reloadCallbacks.shift();
if (callback) {
try {
await Promise.resolve(callback());
} catch (error) {
treeLogger.error("Reload callback threw", {
error: error?.message,
});
}
}
}
networkActions.triggerReload();
// Allow tree to render again; NetworkProviders will show its loader until ready.
merge({ suspend: false });
};
const suspendTree = () => {
merge({ suspend: true });
};
const splashScreenHidden = () => {
merge({ splashScreenHidden: true });
};
return {
default: {
triggerReload: false,
suspend: false,
splashScreenHidden: false,
},
actions: {
triggerReload,
suspendTree,
onReload,
splashScreenHidden,
},
};
});