Objects, arrays and models changes deep checks when checking if a model is dirty.
This commit is contained in:
		
							parent
							
								
									ff9cb91f73
								
							
						
					
					
						commit
						8f8dafed5b
					
				
					 7 changed files with 91 additions and 10 deletions
				
			
		|  | @ -19,7 +19,7 @@ | |||
| </p> | ||||
| 
 | ||||
| <p align="center"> | ||||
| 	<img alt="Version 3.2.1" src="https://img.shields.io/badge/version-3.2.1-blue" /> | ||||
| 	<img alt="Version 3.2.2" src="https://img.shields.io/badge/version-3.2.2-blue" /> | ||||
| </p> | ||||
| 
 | ||||
| ## Introduction | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| { | ||||
| 	"name": "@sharkitek/core", | ||||
| 	"version": "3.2.1", | ||||
| 	"version": "3.2.2", | ||||
| 	"description": "TypeScript library for well-designed model architectures.", | ||||
| 	"keywords": [ | ||||
| 		"deserialization", | ||||
|  |  | |||
|  | @ -243,7 +243,7 @@ export function model<ModelType extends Model<Shape, IdentifierType<Shape, Ident | |||
| 			{ | ||||
| 				this.forEachModelProperty((propertyName, propertyDefinition) => { | ||||
| 					// For each property, set its original value to its current property value.
 | ||||
| 					this._originalProperties[propertyName] = (this as PropertiesModel<Shape>)[propertyName]; | ||||
| 					this._originalProperties[propertyName] = structuredClone(this as PropertiesModel<Shape>)[propertyName]; | ||||
| 					propertyDefinition.type.resetDiff((this as PropertiesModel<Shape>)[propertyName]); | ||||
| 				}); | ||||
| 			} | ||||
|  |  | |||
|  | @ -54,6 +54,40 @@ export class ArrayType<SerializedValueType, SharkitekValueType> extends Type<Ser | |||
| 		// Reset diff of all elements.
 | ||||
| 		value.forEach((value) => this.valueDefinition.type.resetDiff(value)); | ||||
| 	} | ||||
| 
 | ||||
| 	propertyHasChanged(originalValue: SharkitekValueType[]|null|undefined, currentValue: SharkitekValueType[]|null|undefined): boolean | ||||
| 	{ | ||||
| 		// If any array length is different, arrays are different.
 | ||||
| 		if (originalValue?.length != currentValue?.length) return true; | ||||
| 		// If length is undefined, values are probably not arrays.
 | ||||
| 		if (originalValue?.length == undefined) return false; | ||||
| 
 | ||||
| 		for (const key of originalValue.keys()) | ||||
| 		{ // Check for any change for each value in the array.
 | ||||
| 			if (this.valueDefinition.type.propertyHasChanged(originalValue[key], currentValue[key])) | ||||
| 				// The value has changed, the array is different.
 | ||||
| 				return true; | ||||
| 		} | ||||
| 
 | ||||
| 		return false; // No change detected.
 | ||||
| 	} | ||||
| 
 | ||||
| 	serializedPropertyHasChanged(originalValue: SerializedValueType[] | null | undefined, currentValue: SerializedValueType[] | null | undefined): boolean | ||||
| 	{ | ||||
| 		// If any array length is different, arrays are different.
 | ||||
| 		if (originalValue?.length != currentValue?.length) return true; | ||||
| 		// If length is undefined, values are probably not arrays.
 | ||||
| 		if (originalValue?.length == undefined) return false; | ||||
| 
 | ||||
| 		for (const key of originalValue.keys()) | ||||
| 		{ // Check for any change for each value in the array.
 | ||||
| 			if (this.valueDefinition.type.serializedPropertyHasChanged(originalValue[key], currentValue[key])) | ||||
| 				// The value has changed, the array is different.
 | ||||
| 				return true; | ||||
| 		} | ||||
| 
 | ||||
| 		return false; // No change detected.
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  |  | |||
|  | @ -48,6 +48,15 @@ export class ModelType<Shape extends ModelShape> extends Type<SerializedModel<Sh | |||
| 		// Reset diff of the given model.
 | ||||
| 		value?.resetDiff(); | ||||
| 	} | ||||
| 
 | ||||
| 	propertyHasChanged(originalValue: Model<Shape>|null|undefined, currentValue: Model<Shape>|null|undefined): boolean | ||||
| 	{ | ||||
| 		if (originalValue === undefined) return currentValue !== undefined; | ||||
| 		if (originalValue === null) return currentValue !== null; | ||||
| 
 | ||||
| 		// If the current value is dirty, property has changed.
 | ||||
| 		return currentValue.isDirty(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  |  | |||
|  | @ -66,6 +66,46 @@ export class ObjectType<Shape extends ModelShape> extends Type<SerializedModel<S | |||
| 			fieldDefinition.type.resetDiff(value?.[fieldName]); | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	propertyHasChanged(originalValue: PropertiesModel<Shape>|null|undefined, currentValue: PropertiesModel<Shape>|null|undefined): boolean | ||||
| 	{ | ||||
| 		// Get keys arrays.
 | ||||
| 		const originalKeys = Object.keys(originalValue) as (keyof Shape)[]; | ||||
| 		const currentKeys = Object.keys(currentValue) as (keyof Shape)[]; | ||||
| 
 | ||||
| 		if (originalKeys.join(",") != currentKeys.join(",")) | ||||
| 			// Keys have changed, objects are different.
 | ||||
| 			return true; | ||||
| 
 | ||||
| 		for (const key of originalKeys) | ||||
| 		{ // Check for any change for each value in the object.
 | ||||
| 			if (this.shape[key].type.propertyHasChanged(originalValue[key], currentValue[key])) | ||||
| 				// The value has changed, the object is different.
 | ||||
| 				return true; | ||||
| 		} | ||||
| 
 | ||||
| 		return false; // No change detected.
 | ||||
| 	} | ||||
| 
 | ||||
| 	serializedPropertyHasChanged(originalValue: SerializedModel<Shape>|null|undefined, currentValue: SerializedModel<Shape>|null|undefined): boolean | ||||
| 	{ | ||||
| 		// Get keys arrays.
 | ||||
| 		const originalKeys = Object.keys(originalValue) as (keyof Shape)[]; | ||||
| 		const currentKeys = Object.keys(currentValue) as (keyof Shape)[]; | ||||
| 
 | ||||
| 		if (originalKeys.join(",") != currentKeys.join(",")) | ||||
| 			// Keys have changed, objects are different.
 | ||||
| 			return true; | ||||
| 
 | ||||
| 		for (const key of originalKeys) | ||||
| 		{ // Check for any change for each value in the object.
 | ||||
| 			if (this.shape[key].type.serializedPropertyHasChanged(originalValue[key], currentValue[key])) | ||||
| 				// The value has changed, the object is different.
 | ||||
| 				return true; | ||||
| 		} | ||||
| 
 | ||||
| 		return false; // No change detected.
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  |  | |||
|  | @ -142,23 +142,21 @@ it("save with modified submodels", () => { | |||
| 		title: "this is a test", | ||||
| 		authors: [ | ||||
| 			{ name: "DOE", firstName: "John", email: "test@test.test", createdAt: (new Date()).toISOString(), active: true, }, | ||||
| 			{ name: "TEST", firstName: "Another", email: "another@test.test", createdAt: (new Date()).toISOString(), active: false, }, | ||||
| 			{ name: "TEST", firstName: "Another", email: "another@test.test", createdAt: (new Date("1997-09-09")).toISOString(), active: false, }, | ||||
| 		], | ||||
| 		text: "this is a long test.", | ||||
| 		evaluation: "25.23", | ||||
| 		tags: [ {name: "test"}, {name: "foo"} ], | ||||
| 	}); | ||||
| 
 | ||||
| 	article.authors = article.authors.map((author) => { | ||||
| 		author.name = "TEST"; | ||||
| 		return author; | ||||
| 	}); | ||||
| 	article.authors[0].name = "TEST"; | ||||
| 	article.authors[1].createdAt.setMonth(9); | ||||
| 
 | ||||
| 	expect(article.save()).toStrictEqual({ | ||||
| 		id: 1, | ||||
| 		authors: [ | ||||
| 			{ name: "TEST", }, | ||||
| 			{}, //{ name: "TEST", firstName: "Another", email: "another@test.test" },
 | ||||
| 			{ name: "TEST" }, | ||||
| 			{ createdAt: (new Date("1997-10-09")).toISOString() }, //{ name: "TEST", firstName: "Another", email: "another@test.test" },
 | ||||
| 		], | ||||
| 	}); | ||||
| }); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue