@statezero/core 0.1.53 → 0.1.55
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
|
|
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,48 @@ 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
|
+
const fileFormats = ["file-path", "image-path"];
|
|
96
|
+
if (ModelClass.schema?.properties[field]?.format &&
|
|
97
|
+
fileFormats.includes(ModelClass.schema.properties[field].format) &&
|
|
98
|
+
value &&
|
|
99
|
+
typeof value.toJSON === "function") {
|
|
100
|
+
// Return a serializable JSON representation of the FileObject.
|
|
101
|
+
return value.toJSON();
|
|
102
|
+
}
|
|
103
|
+
// Handle Model instances -> primary keys
|
|
104
|
+
if (value &&
|
|
105
|
+
typeof value === "object" &&
|
|
106
|
+
value.constructor &&
|
|
107
|
+
value.constructor.primaryKeyField) {
|
|
108
|
+
return value.pk;
|
|
109
|
+
}
|
|
110
|
+
// Handle arrays (for many-to-many relationships)
|
|
111
|
+
if (Array.isArray(value)) {
|
|
112
|
+
return value.map((item) => this._standardizeFieldValue(field, item));
|
|
113
|
+
}
|
|
114
|
+
return value;
|
|
115
|
+
}
|
|
74
116
|
/**
|
|
75
117
|
* Gets a field value from the internal data store
|
|
76
118
|
*
|
|
@@ -78,7 +120,6 @@ export class Model {
|
|
|
78
120
|
* @returns {any} The field value
|
|
79
121
|
*/
|
|
80
122
|
getField(field) {
|
|
81
|
-
var _a;
|
|
82
123
|
// Access the reactive __version property to establish dependency for vue integration
|
|
83
124
|
const trackVersion = this.__version;
|
|
84
125
|
const ModelClass = this.constructor;
|
|
@@ -92,6 +133,21 @@ export class Model {
|
|
|
92
133
|
if (storedValue)
|
|
93
134
|
value = storedValue[field]; // if stops null -> undefined
|
|
94
135
|
}
|
|
136
|
+
// Convert plain stored data back to rich objects
|
|
137
|
+
return this._hydrateFieldValue(field, value);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* HYDRATION: Convert plain stored data back to rich objects
|
|
141
|
+
*
|
|
142
|
+
* @param {string} field - The field name
|
|
143
|
+
* @param {any} value - The plain stored value
|
|
144
|
+
* @returns {any} The hydrated rich object
|
|
145
|
+
*/
|
|
146
|
+
_hydrateFieldValue(field, value) {
|
|
147
|
+
var _a;
|
|
148
|
+
if (isNil(value))
|
|
149
|
+
return value;
|
|
150
|
+
const ModelClass = this.constructor;
|
|
95
151
|
// Date/DateTime fields need special handling - convert to Date objects
|
|
96
152
|
const dateFormats = ["date", "datetime", "date-time"];
|
|
97
153
|
if (ModelClass.schema &&
|
|
@@ -105,10 +161,6 @@ export class Model {
|
|
|
105
161
|
if (ModelClass.schema &&
|
|
106
162
|
fileFormats.includes(ModelClass.schema.properties[field]?.format) &&
|
|
107
163
|
value) {
|
|
108
|
-
// Check if it's already a FileObject
|
|
109
|
-
if (value instanceof FileObject) {
|
|
110
|
-
return value;
|
|
111
|
-
}
|
|
112
164
|
// If it's stored file data from API, wrap it as FileObject
|
|
113
165
|
if (typeof value === "object" && value.file_path) {
|
|
114
166
|
// Create anonymous subclass with correct configKey
|
|
@@ -152,11 +204,13 @@ export class Model {
|
|
|
152
204
|
*/
|
|
153
205
|
setField(field, value) {
|
|
154
206
|
const ModelClass = this.constructor;
|
|
207
|
+
// Standardize the value before storing
|
|
208
|
+
const standardizedValue = this._standardizeFieldValue(field, value);
|
|
155
209
|
if (ModelClass.primaryKeyField === field) {
|
|
156
|
-
this._pk =
|
|
210
|
+
this._pk = standardizedValue;
|
|
157
211
|
}
|
|
158
212
|
else {
|
|
159
|
-
this._data[field] =
|
|
213
|
+
this._data[field] = standardizedValue;
|
|
160
214
|
}
|
|
161
215
|
}
|
|
162
216
|
/**
|
|
@@ -202,20 +256,7 @@ export class Model {
|
|
|
202
256
|
if (storedValue)
|
|
203
257
|
value = storedValue[field];
|
|
204
258
|
}
|
|
205
|
-
//
|
|
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
|
-
}
|
|
213
|
-
const fileFormats = ["file-path", "image-path"];
|
|
214
|
-
if (ModelClass.schema &&
|
|
215
|
-
fileFormats.includes(ModelClass.schema.properties[field]?.format) &&
|
|
216
|
-
value) {
|
|
217
|
-
return value.filePath || value.file_path || value;
|
|
218
|
-
}
|
|
259
|
+
// Since internal data is already standardized, just return it
|
|
219
260
|
return value;
|
|
220
261
|
}
|
|
221
262
|
/**
|
|
@@ -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.
|
|
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