New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

on-change

Package Overview
Dependencies
Maintainers
1
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 0.2.0 to 1.0.0

117

index.js
'use strict';
const blacklist = [
'sort',
'reverse',
'splice',
'pop',
'unshift',
'shift',
'push'
];
const isPrimitive = value => value === null || (typeof value !== 'object' && typeof value !== 'function');
const proxyTarget = Symbol('ProxyTarget');
module.exports = (object, onChange) => {
let isBlocked = false;
let inApply = false;
let changed = false;
const propCache = new WeakMap();
const handleChange = () => {
if (!inApply) {
onChange();
} else if (!changed) {
changed = true;
}
};
const getOwnPropertyDescriptor = (target, property) => {
if (!propCache.has(target)) {
propCache.set(target, new Map());
}
const props = propCache.get(target);
if (props.has(property)) {
return props.get(property);
}
const prop = Reflect.getOwnPropertyDescriptor(target, property);
props.set(property, prop);
return prop;
};
const invalidateCachedDescriptor = (target, property) => {
if (!propCache.has(target)) {
return;
}
const props = propCache.get(target);
props.delete(property);
};
const handler = {
get(target, property, receiver) {
try {
return new Proxy(target[property], handler);
} catch (_) {
return Reflect.get(target, property, receiver);
if (property === proxyTarget) {
return target;
}
const value = Reflect.get(target, property, receiver);
if (isPrimitive(value)) {
return value;
}
// Preserve invariants
const descriptor = getOwnPropertyDescriptor(target, property);
if (descriptor && !descriptor.configurable) {
if (descriptor.set && !descriptor.get) {
return undefined;
}
if (descriptor.writable === false) {
return value;
}
}
return new Proxy(value, handler);
},
set(target, property, value, receiver) {
if (value && value[proxyTarget] !== undefined) {
value = value[proxyTarget];
}
const previous = Reflect.get(target, property, value, receiver);
const result = Reflect.set(target, property, value);
if (previous !== value) {
handleChange();
}
return result;
},
defineProperty(target, property, descriptor) {
const result = Reflect.defineProperty(target, property, descriptor);
invalidateCachedDescriptor(target, property);
if (!isBlocked) {
onChange();
}
handleChange();
return result;
},
deleteProperty(target, property) {
const result = Reflect.deleteProperty(target, property);
invalidateCachedDescriptor(target, property);
if (!isBlocked) {
onChange();
}
handleChange();
return result;
},
apply(target, thisArg, argumentsList) {
if (blacklist.includes(target.name)) {
isBlocked = true;
if (!inApply) {
inApply = true;
const result = Reflect.apply(target, thisArg, argumentsList);
onChange();
isBlocked = false;
if (changed) {
onChange();
}
inApply = false;
changed = false;
return result;

@@ -49,0 +118,0 @@ }

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

@@ -39,3 +39,3 @@ "license": "MIT",

"devDependencies": {
"ava": "^0.25.0",
"ava": "^1.0.1",
"matcha": "^0.7.0",

@@ -42,0 +42,0 @@ "xo": "^0.23.0"

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