@statezero/core
Version:
The type-safe frontend client for StateZero - connect directly to your backend models with zero boilerplate
98 lines (97 loc) • 4.24 kB
JavaScript
// src/reset.js
import { getConfig, initializeEventReceiver } from "./config.js";
import { operationRegistry } from "./syncEngine/stores/operation.js";
import { querysetStoreRegistry } from "./syncEngine/registries/querysetStoreRegistry.js";
import { modelStoreRegistry } from "./syncEngine/registries/modelStoreRegistry.js";
import { metricRegistry } from "./syncEngine/registries/metricRegistry.js";
import { syncManager } from "./syncEngine/sync.js";
import { getEventReceiver } from "./core/eventReceivers.js";
import { modelEventEmitter, querysetEventEmitter, metricEventEmitter, } from "./syncEngine/stores/reactivity.js";
import { tempPkMap } from "./flavours/django/tempPk.js";
// Registry for adapter reset functions
const adapterResetFunctions = new Set();
/**
* Register an adapter's reset function
* @param {Function} resetFn - Function to call during StateZero reset
*/
export function registerAdapterReset(resetFn) {
if (typeof resetFn === "function") {
adapterResetFunctions.add(resetFn);
}
}
/**
* Unregister an adapter's reset function
* @param {Function} resetFn - Function to remove
*/
export function unregisterAdapterReset(resetFn) {
adapterResetFunctions.delete(resetFn);
}
/**
* Reset StateZero completely - clears all data and reconnects with fresh auth.
* Call this after login to ensure clean authenticated state.
*/
export async function resetStateZero() {
console.log("🔄 StateZero: Resetting...");
try {
// 1. Clear ALL operations first
operationRegistry.clear();
// 2. Clear temporary PK mappings
tempPkMap.clear();
// 3. Clear all registries and their stores
querysetStoreRegistry.clear();
modelStoreRegistry.clear();
metricRegistry.clear();
// 4. Clear all event emitters (reactivity events)
modelEventEmitter.all.clear();
querysetEventEmitter.all.clear();
metricEventEmitter.all.clear();
// 5. Clear SyncManager's internal state
syncManager.followedModels.clear();
syncManager.followedQuerysets.clear();
if (syncManager.periodicSyncTimer) {
clearInterval(syncManager.periodicSyncTimer);
syncManager.periodicSyncTimer = null;
}
// 6. Call all registered adapter reset functions
adapterResetFunctions.forEach((resetFn) => {
try {
resetFn();
}
catch (error) {
console.warn("Adapter reset function failed:", error);
}
});
// 7. Disconnect and reconnect all event receivers with fresh auth
const cfg = getConfig();
const reconnectPromises = Object.keys(cfg.backendConfigs).map(async (backendKey) => {
const currentReceiver = getEventReceiver(backendKey);
if (currentReceiver) {
// Store subscriptions before disconnecting
const existingSubscriptions = Array.from(currentReceiver.channels.keys());
// Completely disconnect
currentReceiver.disconnect();
// Create fresh receiver with updated auth headers
const newReceiver = initializeEventReceiver(backendKey);
if (newReceiver) {
// Restore subscriptions
existingSubscriptions.forEach((ns) => newReceiver.subscribe(ns));
// Reconnect to sync manager
newReceiver.addModelEventHandler(syncManager.handleEvent.bind(syncManager));
}
}
});
// Wait for all reconnections to complete
await Promise.all(reconnectPromises);
// 8. Reinitialize the sync manager completely
syncManager.initialize();
// 9. Reset the registries' internal sync manager references
querysetStoreRegistry.setSyncManager(syncManager);
modelStoreRegistry.setSyncManager(syncManager);
metricRegistry.setSyncManager(syncManager);
console.log("✅ StateZero reset complete - everything cleared");
}
catch (error) {
console.error("❌ StateZero reset failed:", error);
throw error; // Re-throw so caller knows reset failed
}
}