Skip to content

Commit

Permalink
Merge pull request #24 from creately/improve-change-tracking
Browse files Browse the repository at this point in the history
improved change tracking not to track if value is same
  • Loading branch information
chandika authored Mar 17, 2021
2 parents 633dfd1 + 0a438f6 commit 4826dad
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 11 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
dist
coverage
node_modules
5 changes: 5 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# 2021-03-16 - v2.4.3

- improved change tracking. now if the value of a property is updated with the same value it will not track as a change.
- es getters/setters configuration.

# 2019-06-18 - v2.4.2

- Cache getters and property descriptors using weakmaps to reduce property lookup overhead.
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@creately/sakota",
"version": "2.4.2",
"version": "2.4.3",
"description": "Proxies js objects and records all changes made on an object without modifying the object.",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
Expand Down
13 changes: 10 additions & 3 deletions src/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { Sakota } from '../';

Sakota.enableESGetters();
Sakota.enableESSetters();

/**
* Function returns an array of different types of values.
*/
Expand Down Expand Up @@ -585,6 +582,16 @@ describe('Sakota', () => {
expect(proxy.__sakota__.getChanges('', /a/)).toEqual({ $set: { a: 1000 } });
expect(proxy.__sakota__.getChanges('', /c/)).toEqual({ $unset: { c: true } });
});

it('should not track changes if value is not changed', () => {
const proxy = Sakota.create({ a: 10, b: 20, c: 30 });
proxy.a = 10;
expect(proxy.__sakota__.getChanges()).toEqual({});
proxy.a = 12;
expect(proxy.__sakota__.getChanges()).toEqual({ $set: { a: 12 } });
proxy.a = 10;
expect(proxy.__sakota__.getChanges()).toEqual({});
});
});

describe('hasChanges', () => {
Expand Down
26 changes: 26 additions & 0 deletions src/deep-equal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// ref: https://stackoverflow.com/a/25456134

const deepEqual = (x: any, y: any) => {
if (x === y) {
return true;
} else if (typeof x == 'object' && x != null && (typeof y == 'object' && y != null)) {
if (Object.keys(x).length != Object.keys(y).length) {
return false;
}

for (var prop in x) {
if (y.hasOwnProperty(prop)) {
if (!deepEqual(x[prop], y[prop])) {
return false;
}
} else {
return false;
}
}

return true;
}
return false;
};

export default deepEqual;
22 changes: 16 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import deepEqual from './deep-equal';

/**
* The key used to get the handler.
*/
Expand Down Expand Up @@ -41,8 +43,8 @@ export class Sakota<T extends object> implements ProxyHandler<T> {
*/
private static config = {
prodmode: false,
esgetter: false,
essetter: false,
esgetter: true,
essetter: true,
};

/**
Expand All @@ -55,15 +57,15 @@ export class Sakota<T extends object> implements ProxyHandler<T> {
/**
* Makes Sakota support javascript getters (expensive!).
*/
public static enableESGetters(): void {
this.config.esgetter = true;
public static disableESGetters(): void {
this.config.esgetter = false;
}

/**
* Makes Sakota support javascript getters (expensive!).
*/
public static enableESSetters(): void {
this.config.essetter = true;
public static disableESSetters(): void {
this.config.essetter = false;
}

/**
Expand Down Expand Up @@ -237,6 +239,14 @@ export class Sakota<T extends object> implements ProxyHandler<T> {
if (!this.diff) {
this.diff = { $set: {}, $unset: {} };
}
if (key in obj && deepEqual(obj[key], val)) {
if (this.diff.$unset[key] || this.diff.$set[key]) {
delete this.diff.$unset[key];
delete this.diff.$set[key];
this.onChange();
}
return true;
}
delete this.diff.$unset[key];
delete this.kids[key];
this.diff.$set[key] = val;
Expand Down

0 comments on commit 4826dad

Please sign in to comment.