@statezero/core 0.1.86 → 0.1.88

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.
@@ -22,8 +22,9 @@ export function createTempPk(uuid) {
22
22
  * Register a real PK for a temporary PK
23
23
  */
24
24
  export function setRealPk(uuid, realPk) {
25
- const key = `TempPK_${uuid}`;
26
- tempPkMap.set(key, realPk);
25
+ const key = `"TempPK_${uuid}"`;
26
+ const value = typeof realPk === 'string' ? `"${realPk}"` : String(realPk);
27
+ tempPkMap.set(key, value);
27
28
  }
28
29
  /**
29
30
  * Replace all temporary PKs in an object (or string) with their real values
@@ -37,6 +37,7 @@ function relatedQuerysets(queryset) {
37
37
  }
38
38
  /**
39
39
  * Process an operation in the model store
40
+ * Only processes if the model store doesn't already have the operation.
40
41
  *
41
42
  * @param {Operation} operation - The operation to process
42
43
  * @param {string} actionType - The action to perform ('add', 'update', 'confirm', 'reject')
@@ -46,6 +47,10 @@ function processModelStore(operation, actionType) {
46
47
  const modelStore = modelStoreRegistry.getStore(ModelClass);
47
48
  if (!modelStore)
48
49
  return;
50
+ // Skip if the model store already has this operation
51
+ if (modelStore.operationsMap.has(operation.operationId)) {
52
+ return;
53
+ }
49
54
  switch (actionType) {
50
55
  case 'add':
51
56
  modelStore.addOperation(operation);
@@ -113,7 +118,12 @@ function processQuerysetStores(operation, actionType) {
113
118
  querysetStoreMap = relatedQuerysets(queryset);
114
119
  break;
115
120
  }
116
- Array.from(querysetStoreMap.values()).forEach(applyAction);
121
+ // Filter to only stores that DON'T already have this operation
122
+ const storesToRoute = Array.from(querysetStoreMap.values()).filter(store => {
123
+ return !store.operationsMap.has(operation.operationId);
124
+ });
125
+ // Route only to stores that don't have the operation yet
126
+ storesToRoute.forEach(applyAction);
117
127
  }
118
128
  /**
119
129
  * Process an operation in the metric stores based on operation type
@@ -16,16 +16,16 @@ export class EventPayload {
16
16
  this.operation_id = data.operation_id;
17
17
  this.pk_field_name = data.pk_field_name;
18
18
  this.configKey = data.configKey;
19
- const pkType = getModelClass(data.model, data.configKey)?.schema
20
- ?.properties?.[data.pk_field_name]?.type;
21
- this.instances =
22
- data.instances?.map((inst) => {
23
- const pk = inst?.[data.pk_field_name];
24
- if (pk != null && pkType === "integer" && typeof pk === "string") {
25
- inst[data.pk_field_name] = parseInt(pk, 10);
26
- }
27
- return inst;
28
- }) || [];
19
+ // Parse PK fields to numbers in instances
20
+ this.instances = data.instances?.map(instance => {
21
+ if (instance && this.pk_field_name && instance[this.pk_field_name] != null) {
22
+ return {
23
+ ...instance,
24
+ [this.pk_field_name]: Number(instance[this.pk_field_name])
25
+ };
26
+ }
27
+ return instance;
28
+ }) || data.instances;
29
29
  this._cachedInstances = null;
30
30
  }
31
31
  get modelClass() {
@@ -55,7 +55,19 @@ export class SyncManager {
55
55
  this.processMetrics(payload);
56
56
  }
57
57
  if (isLocalOperation) {
58
- return;
58
+ // Check if any stores for this model class DON'T have the operation yet
59
+ const modelStore = modelStoreRegistry.getStore(payload.modelClass);
60
+ const querysetStores = querysetStoreRegistry.getAllStoresForModel(payload.modelClass);
61
+ // If model store and all queryset stores already have the operation, skip
62
+ // Note: getStore() always returns a store (creates if needed)
63
+ // and operationsMap is always initialized in constructors
64
+ const modelStoreHasIt = modelStore.operationsMap.has(payload.operation_id);
65
+ const allQuerysetStoresHaveIt = querysetStores.length === 0 ||
66
+ querysetStores.every(store => store.operationsMap.has(payload.operation_id));
67
+ if (modelStoreHasIt && allQuerysetStoresHaveIt) {
68
+ return; // All stores already have it, no need to process
69
+ }
70
+ // Otherwise, continue to process for stores that don't have it yet
59
71
  }
60
72
  // Add to batch for queryset/model processing
61
73
  const key = `${event.model}::${event.configKey}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statezero/core",
3
- "version": "0.1.86",
3
+ "version": "0.1.88",
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",