Skip to content

Commit

Permalink
Objects, arrays and models changes deep checks when checking if a mod…
Browse files Browse the repository at this point in the history
…el is dirty.
  • Loading branch information
Madeorsk committed Oct 5, 2024
1 parent ff9cb91 commit 8f8dafe
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 10 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
2 changes: 1 addition & 1 deletion src/Model/Model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
});
}
Expand Down
34 changes: 34 additions & 0 deletions src/Model/Types/ArrayType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}
}

/**
Expand Down
9 changes: 9 additions & 0 deletions src/Model/Types/ModelType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}

/**
Expand Down
40 changes: 40 additions & 0 deletions src/Model/Types/ObjectType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}
}

/**
Expand Down
12 changes: 5 additions & 7 deletions tests/Model.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,23 +142,21 @@ it("save with modified submodels", () => {
title: "this is a test",
authors: [
{ name: "DOE", firstName: "John", email: "[email protected]", createdAt: (new Date()).toISOString(), active: true, },
{ name: "TEST", firstName: "Another", email: "[email protected]", createdAt: (new Date()).toISOString(), active: false, },
{ name: "TEST", firstName: "Another", email: "[email protected]", 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: "[email protected]" },
{ name: "TEST" },
{ createdAt: (new Date("1997-10-09")).toISOString() }, //{ name: "TEST", firstName: "Another", email: "[email protected]" },
],
});
});
Expand Down

0 comments on commit 8f8dafe

Please sign in to comment.