@statezero/core 0.1.52 → 0.1.54

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.
@@ -44,7 +44,7 @@ export class Model {
44
44
  */
45
45
  static validate(data: Object, validateType?: string, partial?: boolean): Promise<boolean>;
46
46
  constructor(data?: {});
47
- _data: {};
47
+ _data: any;
48
48
  _pk: any;
49
49
  __version: number;
50
50
  touch(): void;
@@ -60,6 +60,11 @@ export class Model {
60
60
  * @returns {number|undefined} The primary key.
61
61
  */
62
62
  get pk(): number | undefined;
63
+ /**
64
+ * STANDARDIZATION: Convert rich objects to plain JS data for internal storage
65
+ */
66
+ _standardizeIncomingData(data: any): any;
67
+ _standardizeFieldValue(field: any, value: any): any;
63
68
  /**
64
69
  * Gets a field value from the internal data store
65
70
  *
@@ -67,6 +72,14 @@ export class Model {
67
72
  * @returns {any} The field value
68
73
  */
69
74
  getField(field: string): any;
75
+ /**
76
+ * HYDRATION: Convert plain stored data back to rich objects
77
+ *
78
+ * @param {string} field - The field name
79
+ * @param {any} value - The plain stored value
80
+ * @returns {any} The hydrated rich object
81
+ */
82
+ _hydrateFieldValue(field: string, value: any): any;
70
83
  /**
71
84
  * Sets a field value in the internal data store
72
85
  *
@@ -9,7 +9,7 @@ import { isNil } from "lodash-es";
9
9
  import { QueryExecutor } from "./queryExecutor";
10
10
  import { wrapReactiveModel } from "../../reactiveAdaptor.js";
11
11
  import { DateParsingHelpers } from "./dates.js";
12
- import { FileObject } from './files.js';
12
+ import { FileObject } from "./files.js";
13
13
  import { configInstance } from "../../config.js";
14
14
  import { parseStateZeroError, MultipleObjectsReturned, DoesNotExist, } from "./errors.js";
15
15
  import axios from "axios";
@@ -32,8 +32,8 @@ import axios from "axios";
32
32
  */
33
33
  export class Model {
34
34
  constructor(data = {}) {
35
- // Initialize internal data store
36
- this._data = data;
35
+ // Initialize internal data store with standardized data
36
+ this._data = this._standardizeIncomingData(data);
37
37
  this._pk = data[this.constructor.primaryKeyField] || undefined;
38
38
  this.__version = 0;
39
39
  return wrapReactiveModel(this);
@@ -71,6 +71,43 @@ export class Model {
71
71
  }
72
72
  return this.instanceCache.get(key);
73
73
  }
74
+ /**
75
+ * STANDARDIZATION: Convert rich objects to plain JS data for internal storage
76
+ */
77
+ _standardizeIncomingData(data) {
78
+ if (!data || typeof data !== "object")
79
+ return data;
80
+ const standardized = {};
81
+ for (const [field, value] of Object.entries(data)) {
82
+ standardized[field] = this._standardizeFieldValue(field, value);
83
+ }
84
+ return standardized;
85
+ }
86
+ _standardizeFieldValue(field, value) {
87
+ if (isNil(value))
88
+ return value;
89
+ const ModelClass = this.constructor;
90
+ // Handle Date objects -> formatted strings
91
+ if (value instanceof Date) {
92
+ return DateParsingHelpers.serializeDate(value, field, ModelClass.schema);
93
+ }
94
+ // Handle FileObject -> simple file path/data
95
+ if (value instanceof FileObject) {
96
+ return value.filePath || value.file_path || value;
97
+ }
98
+ // Handle Model instances -> primary keys
99
+ if (value &&
100
+ typeof value === "object" &&
101
+ value.constructor &&
102
+ value.constructor.primaryKeyField) {
103
+ return value.pk;
104
+ }
105
+ // Handle arrays (for many-to-many relationships)
106
+ if (Array.isArray(value)) {
107
+ return value.map((item) => this._standardizeFieldValue(field, item));
108
+ }
109
+ return value;
110
+ }
74
111
  /**
75
112
  * Gets a field value from the internal data store
76
113
  *
@@ -78,7 +115,6 @@ export class Model {
78
115
  * @returns {any} The field value
79
116
  */
80
117
  getField(field) {
81
- var _a;
82
118
  // Access the reactive __version property to establish dependency for vue integration
83
119
  const trackVersion = this.__version;
84
120
  const ModelClass = this.constructor;
@@ -92,6 +128,21 @@ export class Model {
92
128
  if (storedValue)
93
129
  value = storedValue[field]; // if stops null -> undefined
94
130
  }
131
+ // Convert plain stored data back to rich objects
132
+ return this._hydrateFieldValue(field, value);
133
+ }
134
+ /**
135
+ * HYDRATION: Convert plain stored data back to rich objects
136
+ *
137
+ * @param {string} field - The field name
138
+ * @param {any} value - The plain stored value
139
+ * @returns {any} The hydrated rich object
140
+ */
141
+ _hydrateFieldValue(field, value) {
142
+ var _a;
143
+ if (isNil(value))
144
+ return value;
145
+ const ModelClass = this.constructor;
95
146
  // Date/DateTime fields need special handling - convert to Date objects
96
147
  const dateFormats = ["date", "datetime", "date-time"];
97
148
  if (ModelClass.schema &&
@@ -105,10 +156,6 @@ export class Model {
105
156
  if (ModelClass.schema &&
106
157
  fileFormats.includes(ModelClass.schema.properties[field]?.format) &&
107
158
  value) {
108
- // Check if it's already a FileObject
109
- if (value instanceof FileObject) {
110
- return value;
111
- }
112
159
  // If it's stored file data from API, wrap it as FileObject
113
160
  if (typeof value === "object" && value.file_path) {
114
161
  // Create anonymous subclass with correct configKey
@@ -152,11 +199,13 @@ export class Model {
152
199
  */
153
200
  setField(field, value) {
154
201
  const ModelClass = this.constructor;
202
+ // Standardize the value before storing
203
+ const standardizedValue = this._standardizeFieldValue(field, value);
155
204
  if (ModelClass.primaryKeyField === field) {
156
- this._pk = value;
205
+ this._pk = standardizedValue;
157
206
  }
158
207
  else {
159
- this._data[field] = value;
208
+ this._data[field] = standardizedValue;
160
209
  }
161
210
  }
162
211
  /**
@@ -202,14 +251,7 @@ export class Model {
202
251
  if (storedValue)
203
252
  value = storedValue[field];
204
253
  }
205
- // Date/DateTime fields need special handling - convert Date objects to strings for API
206
- const dateFormats = ["date", "date-time"];
207
- if (ModelClass.schema &&
208
- dateFormats.includes(ModelClass.schema.properties[field]?.format) &&
209
- value instanceof Date) {
210
- // Let DateParsingHelpers.serializeDate throw if it fails
211
- return DateParsingHelpers.serializeDate(value, field, ModelClass.schema);
212
- }
254
+ // Since internal data is already standardized, just return it
213
255
  return value;
214
256
  }
215
257
  /**
@@ -17,6 +17,11 @@ export class ModelStore {
17
17
  _loadOperations(operationsData: any): void;
18
18
  get cacheKey(): string;
19
19
  onHydrated(): void;
20
+ /**
21
+ * Convert raw data objects to standardized format for caching
22
+ * Creates temporary model instances to leverage the standardization logic
23
+ */
24
+ _standardizeForCache(items: any): any;
20
25
  setCache(result: any): void;
21
26
  clearCache(): void;
22
27
  updateCache(items: any, requestedPks: any): void;
@@ -117,6 +117,18 @@ export class ModelStore {
117
117
  }
118
118
  }
119
119
  }
120
+ /**
121
+ * Convert raw data objects to standardized format for caching
122
+ * Creates temporary model instances to leverage the standardization logic
123
+ */
124
+ _standardizeForCache(items) {
125
+ return items.map((item) => {
126
+ // Create a temporary model instance with the raw data
127
+ const tempInstance = new this.modelClass(item);
128
+ // Use the serialize method to get standardized data
129
+ return tempInstance.serialize();
130
+ });
131
+ }
120
132
  setCache(result) {
121
133
  const pkField = this.pkField;
122
134
  let nonTempPkItems = [];
@@ -131,7 +143,8 @@ export class ModelStore {
131
143
  item[pkField] = pk;
132
144
  nonTempPkItems.push(item);
133
145
  });
134
- this.modelCache.set(this.cacheKey, nonTempPkItems);
146
+ const standardizedItems = this._standardizeForCache(nonTempPkItems);
147
+ this.modelCache.set(this.cacheKey, standardizedItems);
135
148
  }
136
149
  clearCache() {
137
150
  this.modelCache.delete(this.cacheKey);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statezero/core",
3
- "version": "0.1.52",
3
+ "version": "0.1.54",
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",