Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

on-change

Package Overview
Dependencies
Maintainers
2
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

on-change - npm Package Compare versions

Comparing version 2.0.2 to 2.1.0

26

index.d.ts

@@ -115,3 +115,3 @@ declare namespace onChange {

let i = 0;
const watchedObject = onChange(object, function (path, value, previousValue) {
const watchedObject = onChange(object, function (path, value, previousValue, name) {
console.log('Object changed:', ++i);

@@ -122,2 +122,3 @@ console.log('this:', this);

console.log('previousValue:', previousValue);
console.log('name:', name);
});

@@ -140,2 +141,3 @@

//=> 'previousValue: false'
//=> 'name: undefined'

@@ -157,3 +159,22 @@ watchedObject.a.b[0].c = true;

//=> 'previousValue: false'
//=> 'name: undefined'
watchedObject.a.b.push(3);
//=> 'Object changed: 3'
//=> 'this: {
// foo: true,
// a: {
// b: [
// {
// c: true
// },
// 3
// ]
// }
// }'
//=> 'path: "a.b"'
//=> 'value: [{c: true}, 3]'
//=> 'previousValue: [{c: true}]'
//=> 'name: "push"'
// Access the original object

@@ -175,3 +196,4 @@ onChange.target(watchedObject).foo = false;

value: unknown,
previousValue: unknown
previousValue: unknown,
name: string
) => void,

@@ -178,0 +200,0 @@ options?: onChange.Options

31

index.js

@@ -24,7 +24,8 @@ 'use strict';

const handleChange = (changePath, property, previous, value) => {
// eslint-disable-next-line max-params
const handleChange = (changePath, property, previous, value, name) => {
if (smartClone.isCloning) {
smartClone.update(changePath, property, previous);
} else {
onChange(path.concat(changePath, property), value, previous);
onChange(path.concat(changePath, property), value, previous, name);
}

@@ -54,3 +55,3 @@ };

property === 'constructor' ||
options.isShallow === true ||
(options.isShallow === true && !smartClone.isHandledMethod(target, property)) ||
ignoreProperty(cache, options, property) ||

@@ -66,4 +67,8 @@ cache.isGetInvariant(target, property)

set(target, property, value, receiver) {
if (value && value[proxyTarget] !== undefined) {
value = value[proxyTarget];
if (value) {
const valueProxyTarget = value[proxyTarget];
if (valueProxyTarget !== undefined) {
value = valueProxyTarget;
}
}

@@ -116,5 +121,6 @@

const isMutable = isBuiltin.withMutableMethods(thisArg);
const thisProxyTarget = thisArg[proxyTarget] || thisArg;
if (isMutable) {
thisArg = thisArg[proxyTarget];
thisArg = thisProxyTarget;
}

@@ -133,11 +139,14 @@

) {
smartClone.start(thisArg[proxyTarget] || thisArg, applyPath);
smartClone.start(thisProxyTarget, applyPath);
}
const result = Reflect.apply(target, thisArg, argumentsList);
const result = Reflect.apply(
target,
smartClone.preferredThisArg(target, thisArg, thisProxyTarget),
argumentsList
);
if (smartClone.isChanged(isMutable, thisArg, equals)) {
const {clone} = smartClone;
smartClone.done();
handleChange(applyPath, '', clone, thisArg[proxyTarget] || thisArg);
const clone = smartClone.done();
handleChange(applyPath, '', clone, thisProxyTarget, target.name);
}

@@ -144,0 +153,0 @@

@@ -6,2 +6,37 @@ 'use strict';

const shallowEqual = (clone, value) => {
return clone.length !== value.length || clone.some((item, index) => value[index] !== item);
};
const IMMUTABLE_OBJECT_METHODS = new Set([
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'toLocaleString',
'toString',
'valueOf'
]);
const IMMUTABLE_ARRAY_METHODS = new Set([
'includes',
'indexOf',
'join',
'keys',
'lastIndexOf'
]);
const SHALLOW_MUTABLE_ARRAY_METHODS = {
push: () => true,
pop: () => true,
shift: () => true,
unshift: () => true,
concat: (clone, value) => clone.length !== value.length,
copyWithin: shallowEqual,
reverse: shallowEqual,
sort: shallowEqual,
splice: shallowEqual,
flat: shallowEqual,
fill: shallowEqual
};
class smartClone {

@@ -38,2 +73,26 @@ constructor() {

isHandledMethod(target, name) {
if (isArray(target) && (IMMUTABLE_OBJECT_METHODS.has(name) ||
IMMUTABLE_ARRAY_METHODS.has(name) ||
name in SHALLOW_MUTABLE_ARRAY_METHODS)) {
return true;
}
return toString.call(target) === '[object Object]' && IMMUTABLE_OBJECT_METHODS.has(name);
}
preferredThisArg(target, thisArg, thisProxyTarget) {
const {name} = target;
if (this.isHandledMethod(thisProxyTarget, name)) {
if (isArray(thisProxyTarget)) {
this._onIsChanged = SHALLOW_MUTABLE_ARRAY_METHODS[name];
}
return thisProxyTarget;
}
return thisArg;
}
update(fullPath, property, value) {

@@ -58,2 +117,4 @@ if (value !== undefined && property !== 'length') {

done() {
const {clone} = this;
if (this._cache !== undefined) {

@@ -66,3 +127,6 @@ this._cache.clear();

this._path = null;
this._onIsChanged = null;
this._isChanged = false;
return clone;
}

@@ -75,3 +139,5 @@

return this._isChanged;
return this._onIsChanged ?
this._onIsChanged(this.clone, value) :
this._isChanged;
}

@@ -78,0 +144,0 @@ }

{
"name": "on-change",
"version": "2.0.2",
"version": "2.1.0",
"description": "Watch an object or array for changes",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -32,3 +32,3 @@ # on-change [![Build Status](https://travis-ci.org/sindresorhus/on-change.svg?branch=master)](https://travis-ci.org/sindresorhus/on-change)

let i = 0;
const watchedObject = onChange(object, function (path, value, previousValue) {
const watchedObject = onChange(object, function (path, value, previousValue, name) {
console.log('Object changed:', ++i);

@@ -39,2 +39,3 @@ console.log('this:', this);

console.log('previousValue:', previousValue);
console.log('name:', name);
});

@@ -57,2 +58,3 @@

//=> 'previousValue: false'
//=> 'name: undefined'

@@ -74,3 +76,22 @@ watchedObject.a.b[0].c = true;

//=> 'previousValue: false'
//=> 'name: undefined'
watchedObject.a.b.push(3);
//=> 'Object changed: 3'
//=> 'this: {
// foo: true,
// a: {
// b: [
// {
// c: true
// },
// 3
// ]
// }
// }'
//=> 'path: "a.b"'
//=> 'value: [{c: true}, 3]'
//=> 'previousValue: [{c: true}]'
//=> 'name: "push"'
// Access the original object

@@ -104,6 +125,7 @@ onChange.target(watchedObject).foo = false;

The function receives three arguments:
The function receives four arguments:
1. A path to the value that was changed. A change to `c` in the above example would return `a.b.0.c`.
2. The new value at the path.
3. The previous value at the path.
4. The name of the method that produced the change.

@@ -110,0 +132,0 @@ The context (this) is set to the original object passed to `onChange` (with Proxy).

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc