@statezero/core 0.1.41 → 0.1.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,7 @@ import { computed, getCurrentInstance, onBeforeUnmount } from 'vue';
2
2
  import { querysetStoreRegistry } from '../../syncEngine/registries/querysetStoreRegistry';
3
3
  import { metricRegistry } from '../../syncEngine/registries/metricRegistry';
4
4
  import { syncManager } from '../../syncEngine/sync';
5
+ import { registerAdapterReset } from '../../reset';
5
6
  import { v7 } from 'uuid';
6
7
  syncManager.followAllQuerysets = false;
7
8
  export const querysets = new Map(); // Map of composableId -> queryset
@@ -34,3 +35,10 @@ export function useQueryset(querysetFactory) {
34
35
  return result;
35
36
  });
36
37
  }
38
+ registerAdapterReset(() => {
39
+ querysets.clear();
40
+ // Reset syncManager back to following all querysets since no composables are active
41
+ syncManager.followAllQuerysets = true;
42
+ syncManager.followedQuerysets.clear();
43
+ console.log("Vue composables state cleared");
44
+ });
@@ -3,7 +3,8 @@ import { modelEventEmitter, querysetEventEmitter, metricEventEmitter } from "../
3
3
  import { initEventHandler } from "../../syncEngine/stores/operationEventHandlers.js";
4
4
  import { isEqual, isNil } from 'lodash-es';
5
5
  import hash from 'object-hash';
6
- initEventHandler(); // Initialize event handler for model events
6
+ import { registerAdapterReset } from "../../reset.js";
7
+ initEventHandler();
7
8
  const wrappedQuerysetCache = new Map();
8
9
  const wrappedMetricCache = new Map();
9
10
  /**
@@ -123,3 +124,7 @@ export function MetricAdaptor(metric) {
123
124
  }
124
125
  return wrapper;
125
126
  }
127
+ registerAdapterReset(() => {
128
+ wrappedQuerysetCache.clear();
129
+ wrappedMetricCache.clear();
130
+ });
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ import { setEventReceiver } from "./core/eventReceivers.js";
4
4
  import { getEventReceiver } from "./core/eventReceivers.js";
5
5
  import { setNamespaceResolver } from "./core/eventReceivers.js";
6
6
  import { setupStateZero } from "./setup.js";
7
+ import { resetStateZero } from "./reset.js";
7
8
  import { FileObject } from "./flavours/django/files.js";
8
9
  import { querysetStoreRegistry } from "./syncEngine/registries/querysetStoreRegistry.js";
9
10
  import { modelStoreRegistry } from "./syncEngine/registries/modelStoreRegistry.js";
@@ -35,4 +36,4 @@ import { cleanupEventHandler } from "./syncEngine/stores/operationEventHandlers.
35
36
  import { setAdapters } from "./reactiveAdaptor.js";
36
37
  import { wrapReactiveModel } from "./reactiveAdaptor.js";
37
38
  import { wrapReactiveQuerySet } from "./reactiveAdaptor.js";
38
- export { EventType, PusherEventReceiver, setEventReceiver, getEventReceiver, setNamespaceResolver, setupStateZero, FileObject, querysetStoreRegistry, modelStoreRegistry, metricRegistry, syncManager, Operation, operationRegistry, Q, StateZeroError, ValidationError, DoesNotExist, PermissionDenied, MultipleObjectsReturned, ASTValidationError, ConfigError, parseStateZeroError, QuerySet, Manager, ResultTuple, Model, setConfig, getConfig, setBackendConfig, initializeEventReceiver, configInstance, getModelClass, initEventHandler, cleanupEventHandler, setAdapters, wrapReactiveModel, wrapReactiveQuerySet };
39
+ export { EventType, PusherEventReceiver, setEventReceiver, getEventReceiver, setNamespaceResolver, setupStateZero, resetStateZero, FileObject, querysetStoreRegistry, modelStoreRegistry, metricRegistry, syncManager, Operation, operationRegistry, Q, StateZeroError, ValidationError, DoesNotExist, PermissionDenied, MultipleObjectsReturned, ASTValidationError, ConfigError, parseStateZeroError, QuerySet, Manager, ResultTuple, Model, setConfig, getConfig, setBackendConfig, initializeEventReceiver, configInstance, getModelClass, initEventHandler, cleanupEventHandler, setAdapters, wrapReactiveModel, wrapReactiveQuerySet };
package/dist/index.js CHANGED
@@ -18,12 +18,13 @@ import { setConfig, getConfig, setBackendConfig, initializeEventReceiver, config
18
18
  import { setAdapters, wrapReactiveModel, wrapReactiveQuerySet, } from "./reactiveAdaptor.js";
19
19
  import { syncManager } from "./syncEngine/sync.js";
20
20
  import { initEventHandler, cleanupEventHandler, } from "./syncEngine/stores/operationEventHandlers.js";
21
+ import { resetStateZero } from "./reset.js";
21
22
  // Explicitly export everything
22
23
  export {
23
24
  // Core event receivers
24
25
  EventType, PusherEventReceiver, setEventReceiver, getEventReceiver, setNamespaceResolver,
25
26
  // Setup
26
- setupStateZero,
27
+ setupStateZero, resetStateZero,
27
28
  // Files
28
29
  FileObject,
29
30
  // Registry
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Register an adapter's reset function
3
+ * @param {Function} resetFn - Function to call during StateZero reset
4
+ */
5
+ export function registerAdapterReset(resetFn: Function): void;
6
+ /**
7
+ * Unregister an adapter's reset function
8
+ * @param {Function} resetFn - Function to remove
9
+ */
10
+ export function unregisterAdapterReset(resetFn: Function): void;
11
+ /**
12
+ * Reset StateZero completely - clears all data and reconnects with fresh auth.
13
+ * Call this after login to ensure clean authenticated state.
14
+ */
15
+ export function resetStateZero(): Promise<void>;
package/dist/reset.js ADDED
@@ -0,0 +1,97 @@
1
+ // src/reset.js
2
+ import { getConfig, initializeEventReceiver } from "./config.js";
3
+ import { operationRegistry } from "./syncEngine/stores/operation.js";
4
+ import { querysetStoreRegistry } from "./syncEngine/registries/querysetStoreRegistry.js";
5
+ import { modelStoreRegistry } from "./syncEngine/registries/modelStoreRegistry.js";
6
+ import { metricRegistry } from "./syncEngine/registries/metricRegistry.js";
7
+ import { syncManager } from "./syncEngine/sync.js";
8
+ import { getEventReceiver } from "./core/eventReceivers.js";
9
+ import { modelEventEmitter, querysetEventEmitter, metricEventEmitter, } from "./syncEngine/stores/reactivity.js";
10
+ import { tempPkMap } from "./flavours/django/tempPk.js";
11
+ // Registry for adapter reset functions
12
+ const adapterResetFunctions = new Set();
13
+ /**
14
+ * Register an adapter's reset function
15
+ * @param {Function} resetFn - Function to call during StateZero reset
16
+ */
17
+ export function registerAdapterReset(resetFn) {
18
+ if (typeof resetFn === "function") {
19
+ adapterResetFunctions.add(resetFn);
20
+ }
21
+ }
22
+ /**
23
+ * Unregister an adapter's reset function
24
+ * @param {Function} resetFn - Function to remove
25
+ */
26
+ export function unregisterAdapterReset(resetFn) {
27
+ adapterResetFunctions.delete(resetFn);
28
+ }
29
+ /**
30
+ * Reset StateZero completely - clears all data and reconnects with fresh auth.
31
+ * Call this after login to ensure clean authenticated state.
32
+ */
33
+ export async function resetStateZero() {
34
+ console.log("🔄 StateZero: Resetting...");
35
+ try {
36
+ // 1. Clear ALL operations first
37
+ operationRegistry.clear();
38
+ // 2. Clear temporary PK mappings
39
+ tempPkMap.clear();
40
+ // 3. Clear all registries and their stores
41
+ querysetStoreRegistry.clear();
42
+ modelStoreRegistry.clear();
43
+ metricRegistry.clear();
44
+ // 4. Clear all event emitters (reactivity events)
45
+ modelEventEmitter.all.clear();
46
+ querysetEventEmitter.all.clear();
47
+ metricEventEmitter.all.clear();
48
+ // 5. Clear SyncManager's internal state
49
+ syncManager.followedModels.clear();
50
+ syncManager.followedQuerysets.clear();
51
+ if (syncManager.periodicSyncTimer) {
52
+ clearInterval(syncManager.periodicSyncTimer);
53
+ syncManager.periodicSyncTimer = null;
54
+ }
55
+ // 6. Call all registered adapter reset functions
56
+ adapterResetFunctions.forEach((resetFn) => {
57
+ try {
58
+ resetFn();
59
+ }
60
+ catch (error) {
61
+ console.warn("Adapter reset function failed:", error);
62
+ }
63
+ });
64
+ // 7. Disconnect and reconnect all event receivers with fresh auth
65
+ const cfg = getConfig();
66
+ const reconnectPromises = Object.keys(cfg.backendConfigs).map(async (backendKey) => {
67
+ const currentReceiver = getEventReceiver(backendKey);
68
+ if (currentReceiver) {
69
+ // Store subscriptions before disconnecting
70
+ const existingSubscriptions = Array.from(currentReceiver.channels.keys());
71
+ // Completely disconnect
72
+ currentReceiver.disconnect();
73
+ // Create fresh receiver with updated auth headers
74
+ const newReceiver = initializeEventReceiver(backendKey);
75
+ if (newReceiver) {
76
+ // Restore subscriptions
77
+ existingSubscriptions.forEach((ns) => newReceiver.subscribe(ns));
78
+ // Reconnect to sync manager
79
+ newReceiver.addModelEventHandler(syncManager.handleEvent.bind(syncManager));
80
+ }
81
+ }
82
+ });
83
+ // Wait for all reconnections to complete
84
+ await Promise.all(reconnectPromises);
85
+ // 8. Reinitialize the sync manager completely
86
+ syncManager.initialize();
87
+ // 9. Reset the registries' internal sync manager references
88
+ querysetStoreRegistry.setSyncManager(syncManager);
89
+ modelStoreRegistry.setSyncManager(syncManager);
90
+ metricRegistry.setSyncManager(syncManager);
91
+ console.log("✅ StateZero reset complete - everything cleared");
92
+ }
93
+ catch (error) {
94
+ console.error("❌ StateZero reset failed:", error);
95
+ throw error; // Re-throw so caller knows reset failed
96
+ }
97
+ }
@@ -67,14 +67,15 @@ export class MetricRegistry {
67
67
  }
68
68
  const stores = [];
69
69
  const modelClass = queryset.ModelClass;
70
- const operationAst = queryset.build();
71
70
  for (const [key, entry] of this._stores.entries()) {
72
71
  const store = entry.store;
73
72
  // First check if model class matches
74
73
  if (store.modelClass !== modelClass) {
75
74
  continue;
76
75
  }
77
- // #TODO match queryset based on ast
76
+ if (store.queryset.semanticKey != queryset.semanticKey) {
77
+ continue;
78
+ }
78
79
  stores.push(store);
79
80
  }
80
81
  return stores;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statezero/core",
3
- "version": "0.1.41",
3
+ "version": "0.1.43",
4
4
  "type": "module",
5
5
  "module": "ESNext",
6
6
  "description": "The type-safe frontend client for StateZero - connect directly to your backend models with zero boilerplate",