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

@feng3d/watcher

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@feng3d/watcher - npm Package Compare versions

Comparing version 0.8.0 to 0.8.1

dist/.nojekyll

361

dist/index.umd.js

@@ -1,2 +0,361 @@

(function(d,g){typeof exports=="object"&&typeof module<"u"?g(exports):typeof define=="function"&&define.amd?define(["exports"],g):(d=typeof globalThis<"u"?globalThis:d||self,g(d.feng3d={}))})(this,function(d){"use strict";class g{constructor(){this._binds=[]}watch(t,n,e,h){Object.getOwnPropertyDescriptor(t,w)||Object.defineProperty(t,w,{value:{},enumerable:!1,configurable:!0,writable:!1});const s=n,c=t[w];if(!c[s]){const l=Object.getOwnPropertyDescriptor(t,s);c[s]={value:t[s],oldPropertyDescriptor:l,handlers:[]};let i=P(t,s);if(i&&i.set&&i.get){i={enumerable:i.enumerable,configurable:!0,get:i.get,set:i.set};const u=i.set;i.set=function(o){const _=this[s];_!==o&&(u&&u.call(this,o),v(o,_,this,s))}}else if(!i||!i.get&&!i.set)i={enumerable:!0,configurable:!0},i.get=function(){return this[w][s].value},i.set=function(u){const o=this[w][s].value;o!==u&&(this[w][s].value=u,v(u,o,this,s))};else{console.warn(`watch ${t} . ${s} 失败!`);return}Object.defineProperty(t,s,i)}const a=c[s];a.handlers.reduce((l,i)=>l||i.handler===e&&i.thisObject===h,!1)||a.handlers.push({handler:e,thisObject:h})}unwatch(t,n,e,h){const s=t[w];if(!s)return;const c=n;if(s[c]){const a=s[c].handlers;e===void 0&&(a.length=0);for(let r=a.length-1;r>=0;r--)a[r].handler===e&&(a[r].thisObject===h||h===void 0)&&a.splice(r,1);if(a.length===0){const r=t[c];delete t[c],s[c].oldPropertyDescriptor&&Object.defineProperty(t,c,s[c].oldPropertyDescriptor),t[c]=r,delete s[c]}Object.keys(s).length===0&&delete t[w]}}watchs(t,n,e,h){n.forEach(s=>{this.watch(t,s,e,h)})}unwatchs(t,n,e,h){n.forEach(s=>{this.unwatch(t,s,e,h)})}bind(t,n,e,h){const s=()=>{e[h]=t[n]},c=()=>{t[n]=e[h]};this.watch(t,n,s),this.watch(e,h,c),this._binds.push([t,n,s,e,h,c])}unbind(t,n,e,h){const s=this._binds;for(let c=s.length-1;c>=0;c--){const a=s[c];if((a[1]===n&&a[4]===h||a[1]===h&&a[4]===n)&&(a[0]===t&&a[3]===e||a[0]===e&&a[3]===t)){this.unwatch(a[0],a[1],a[2]),this.unwatch(a[3],a[4],a[5]),s.splice(c,1);break}}}watchchain(t,n,e,h){const s=n.indexOf(".");if(s===-1){this.watch(t,n,e,h);return}Object.getOwnPropertyDescriptor(t,O)||Object.defineProperty(t,O,{value:{},enumerable:!1,writable:!1,configurable:!0});const c=t[O];c[n]||(c[n]=[]);const a=c[n];if(!a.reduce((l,i)=>l||i.handler===e&&i.thisObject===h,!1)){const l=n.substr(0,s),i=n.substr(s+1);t[l]&&this.watchchain(t[l],i,e,h);const u=(o,_)=>{_&&this.unwatchchain(_,i,e,h),o&&this.watchchain(o,i,e,h);const x=y(_,i),D=y(o,i);x!==D&&e.call(h,D,x,o,i)};this.watch(t,l,u),a.push({handler:e,thisObject:h,watchchainFun:u})}}unwatchchain(t,n,e,h){const s=n.indexOf(".");if(s===-1){this.unwatch(t,n,e,h);return}const c=n.substr(0,s),a=n.substr(s+1),r=t[O];if(!r||!r[n])return;const l=r[n];for(let i=l.length-1;i>=0;i--){const u=l[i];(p(e)||e===u.handler&&h===u.thisObject)&&(t[c]&&this.unwatchchain(t[c],a,u.handler,u.thisObject),this.unwatch(t,c,u.watchchainFun),l.splice(i,1))}l.length===0&&delete r[n],Object.keys(r).length===0&&delete t[O]}watchobject(t,n,e,h){m(n).forEach(c=>{this.watchchain(t,c,e,h)})}unwatchobject(t,n,e,h){m(n).forEach(c=>{this.unwatchchain(t,c,e,h)})}}const E=new g,w="__watchs__",O="__watchchains__";function v(f,t,n,e){n[w][e].handlers.forEach(c=>{c.handler.call(c.thisObject,f,t,n,e)})}function P(f,t){const n=Object.getOwnPropertyDescriptor(f,t);if(n)return n;const e=Object.getPrototypeOf(f);if(e)return P(e,t)}function p(f){return f==null}function y(f,t){typeof t=="string"&&(t=t.split("."));let n=f;for(let e=0;e<t.length;e++){if(p(n))return;n=n[t[e]]}return n}function m(f){const t=[],n=Object.keys(f),e=new Array(n.length).fill(f),h=new Array(n.length).fill(-1);let s=0;for(;s<n.length;){const c=e[s],a=n[s],r=c[a];let l;if(p(r)||k(r)||(l=Object.keys(r)).length===0){const i=[a];let u=s;for(;(u=h[u])!==-1;)i.push(n[u]);i.reverse(),t.push(i.join("."))}else l.forEach(i=>{n.push(i),e.push(r),h.push(s)});s++}return t}function k(f){return f==null||typeof f=="boolean"||typeof f=="string"||typeof f=="number"}d.Watcher=g,d.watcher=E,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});
(function(global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.feng3d = {}));
})(this, function(exports2) {
"use strict";
class Watcher {
constructor() {
this._binds = [];
}
/**
* 监听对象属性的变化
*
* 注意:使用watch后获取该属性值的性能将会是原来的1/60,避免在运算密集处使用该函数。
*
* @param object 被监听对象
* @param property 被监听属性
* @param handler 变化回调函数 (newValue: V, oldValue: V, object: T, property: string) => void
* @param thisObject 变化回调函数 this值
*/
watch(object, property, handler, thisObject) {
if (!Object.getOwnPropertyDescriptor(object, __watchs__)) {
Object.defineProperty(object, __watchs__, {
value: {},
enumerable: false,
configurable: true,
writable: false
});
}
const _property = property;
const watchs = object[__watchs__];
if (!watchs[_property]) {
const oldPropertyDescriptor = Object.getOwnPropertyDescriptor(object, _property);
watchs[_property] = { value: object[_property], oldPropertyDescriptor, handlers: [] };
let data = getPropertyDescriptor(object, _property);
if (data && data.set && data.get) {
data = { enumerable: data.enumerable, configurable: true, get: data.get, set: data.set };
const orgSet = data.set;
data.set = function(value) {
const oldValue = this[_property];
if (oldValue !== value) {
orgSet && orgSet.call(this, value);
notifyListener(value, oldValue, this, _property);
}
};
} else if (!data || !data.get && !data.set) {
data = { enumerable: true, configurable: true };
data.get = function() {
return this[__watchs__][_property].value;
};
data.set = function(value) {
const oldValue = this[__watchs__][_property].value;
if (oldValue !== value) {
this[__watchs__][_property].value = value;
notifyListener(value, oldValue, this, _property);
}
};
} else {
console.warn(`watch ${object} . ${_property} 失败!`);
return;
}
Object.defineProperty(object, _property, data);
}
const propertywatchs = watchs[_property];
const has = propertywatchs.handlers.reduce((v, item) => v || item.handler === handler && item.thisObject === thisObject, false);
if (!has) {
propertywatchs.handlers.push({ handler, thisObject });
}
}
/**
* 取消监听对象属性的变化
*
* @param object 被监听对象
* @param property 被监听属性
* @param handler 变化回调函数 (newValue: V, oldValue: V, object: T, property: string) => void
* @param thisObject 变化回调函数 this值
*/
unwatch(object, property, handler, thisObject) {
const watchs = object[__watchs__];
if (!watchs)
return;
const _property = property;
if (watchs[_property]) {
const handlers = watchs[_property].handlers;
if (handler === void 0) {
handlers.length = 0;
}
for (let i = handlers.length - 1; i >= 0; i--) {
if (handlers[i].handler === handler && (handlers[i].thisObject === thisObject || thisObject === void 0)) {
handlers.splice(i, 1);
}
}
if (handlers.length === 0) {
const value = object[_property];
delete object[_property];
if (watchs[_property].oldPropertyDescriptor) {
Object.defineProperty(object, _property, watchs[_property].oldPropertyDescriptor);
}
object[_property] = value;
delete watchs[_property];
}
if (Object.keys(watchs).length === 0) {
delete object[__watchs__];
}
}
}
/**
* 监听对象属性的变化
*
* 注意:使用watch后获取该属性值的性能将会是原来的1/60,避免在运算密集处使用该函数。
*
* @param object 被监听对象
* @param property 被监听属性
* @param handler 变化回调函数 (newValue: V, oldValue: V, object: T, property: string) => void
* @param thisObject 变化回调函数 this值
*/
watchs(object, propertys, handler, thisObject) {
propertys.forEach((v) => {
this.watch(object, v, handler, thisObject);
});
}
/**
* 取消监听对象属性的变化
*
* @param object 被监听对象
* @param property 被监听属性
* @param handler 变化回调函数 (newValue: V, oldValue: V, object: T, property: string) => void
* @param thisObject 变化回调函数 this值
*/
unwatchs(object, propertys, handler, thisObject) {
propertys.forEach((v) => {
this.unwatch(object, v, handler, thisObject);
});
}
/**
* 绑定两个对象的指定属性,保存两个属性值同步。
*
* @param object0 第一个对象。
* @param property0 第一个对象的属性名称。
* @param object1 第二个对象。
* @param property1 第二个对象的属性名称。
*/
bind(object0, property0, object1, property1) {
const fun0 = () => {
object1[property1] = object0[property0];
};
const fun1 = () => {
object0[property0] = object1[property1];
};
this.watch(object0, property0, fun0);
this.watch(object1, property1, fun1);
this._binds.push([object0, property0, fun0, object1, property1, fun1]);
}
/**
* 解除两个对象的指定属性的绑定。
*
* @param object0 第一个对象。
* @param property0 第一个对象的属性名称。
* @param object1 第二个对象。
* @param property1 第二个对象的属性名称。
*/
unbind(object0, property0, object1, property1) {
const binds = this._binds;
for (let i = binds.length - 1; i >= 0; i--) {
const v = binds[i];
if (v[1] === property0 && v[4] === property1 || v[1] === property1 && v[4] === property0) {
if (v[0] === object0 && v[3] === object1 || v[0] === object1 && v[3] === object0) {
this.unwatch(v[0], v[1], v[2]);
this.unwatch(v[3], v[4], v[5]);
binds.splice(i, 1);
break;
}
}
}
}
/**
* 监听对象属性链值变化
*
* @param object 被监听对象
* @param property 被监听属性 例如:"a.b"
* @param handler 变化回调函数 (newValue: any, oldValue: any, object: any, property: string) => void
* @param thisObject 变化回调函数 this值
*/
watchchain(object, property, handler, thisObject) {
const notIndex = property.indexOf(".");
if (notIndex === -1) {
this.watch(object, property, handler, thisObject);
return;
}
if (!Object.getOwnPropertyDescriptor(object, __watchchains__)) {
Object.defineProperty(object, __watchchains__, { value: {}, enumerable: false, writable: false, configurable: true });
}
const watchchains = object[__watchchains__];
if (!watchchains[property]) {
watchchains[property] = [];
}
const propertywatchs = watchchains[property];
const has = propertywatchs.reduce((v, item) => v || item.handler === handler && item.thisObject === thisObject, false);
if (!has) {
const currentp = property.substr(0, notIndex);
const nextp = property.substr(notIndex + 1);
if (object[currentp]) {
this.watchchain(object[currentp], nextp, handler, thisObject);
}
const watchchainFun = (newValue, oldValue) => {
if (oldValue)
this.unwatchchain(oldValue, nextp, handler, thisObject);
if (newValue)
this.watchchain(newValue, nextp, handler, thisObject);
const ov = getObjectPropertyValue(oldValue, nextp);
const nv = getObjectPropertyValue(newValue, nextp);
if (ov !== nv) {
handler.call(thisObject, nv, ov, newValue, nextp);
}
};
this.watch(object, currentp, watchchainFun);
propertywatchs.push({ handler, thisObject, watchchainFun });
}
}
/**
* 取消监听对象属性链值变化
*
* @param object 被监听对象
* @param property 被监听属性 例如:"a.b"
* @param handler 变化回调函数 (object: T, property: string, oldValue: V) => void
* @param thisObject 变化回调函数 this值
*/
unwatchchain(object, property, handler, thisObject) {
const notIndex = property.indexOf(".");
if (notIndex === -1) {
this.unwatch(object, property, handler, thisObject);
return;
}
const currentp = property.substr(0, notIndex);
const nextp = property.substr(notIndex + 1);
const watchchains = object[__watchchains__];
if (!watchchains || !watchchains[property])
return;
const propertywatchs = watchchains[property];
for (let i = propertywatchs.length - 1; i >= 0; i--) {
const element = propertywatchs[i];
if (objectIsEmpty(handler) || handler === element.handler && thisObject === element.thisObject) {
if (object[currentp]) {
this.unwatchchain(object[currentp], nextp, element.handler, element.thisObject);
}
this.unwatch(object, currentp, element.watchchainFun);
propertywatchs.splice(i, 1);
}
}
if (propertywatchs.length === 0)
delete watchchains[property];
if (Object.keys(watchchains).length === 0) {
delete object[__watchchains__];
}
}
/**
* 监听对象属性链值变化
*
* @param object 被监听对象
* @param property 被监听属性 例如:{a:{b:null,d:null}} 表示监听 object.a.b 与 object.a.d 值得变化,如果property===object时表示监听对象中所有叶子属性变化。
* @param handler 变化回调函数 (newValue: any, oldValue: any, host: any, property: string) => void
* @param thisObject 变化回调函数 this值
*/
watchobject(object, property, handler, thisObject) {
const chains = getObjectPropertyChains(property);
chains.forEach((v) => {
this.watchchain(object, v, handler, thisObject);
});
}
/**
* 取消监听对象属性链值变化
*
* @param object 被监听对象
* @param property 被监听属性 例如:{a:{b:null,d:null}} 表示监听 object.a.b 与 object.a.d 值得变化,如果property===object时表示监听对象中所有叶子属性变化。
* @param handler 变化回调函数 newValue: any, oldValue: any, host: any, property: string => void
* @param thisObject 变化回调函数 this值
*/
unwatchobject(object, property, handler, thisObject) {
const chains = getObjectPropertyChains(property);
chains.forEach((v) => {
this.unwatchchain(object, v, handler, thisObject);
});
}
}
const watcher = new Watcher();
const __watchs__ = "__watchs__";
const __watchchains__ = "__watchchains__";
function notifyListener(newValue, oldValue, host, property) {
const watchs = host[__watchs__];
const handlers = watchs[property].handlers;
handlers.forEach((element) => {
element.handler.call(element.thisObject, newValue, oldValue, host, property);
});
}
function getPropertyDescriptor(object, property) {
const data = Object.getOwnPropertyDescriptor(object, property);
if (data) {
return data;
}
const prototype = Object.getPrototypeOf(object);
if (prototype) {
return getPropertyDescriptor(prototype, property);
}
return void 0;
}
function objectIsEmpty(obj) {
if (obj === void 0 || obj === null) {
return true;
}
return false;
}
function getObjectPropertyValue(object, property) {
if (typeof property === "string")
property = property.split(".");
let value = object;
for (let i = 0; i < property.length; i++) {
if (objectIsEmpty(value))
return void 0;
value = value[property[i]];
}
return value;
}
function getObjectPropertyChains(object) {
const result = [];
const propertys = Object.keys(object);
const hosts = new Array(propertys.length).fill(object);
const parentPropertyIndices = new Array(propertys.length).fill(-1);
let index = 0;
while (index < propertys.length) {
const host = hosts[index];
const cp = propertys[index];
const cv = host[cp];
let vks;
if (objectIsEmpty(cv) || isBaseType(cv) || (vks = Object.keys(cv)).length === 0) {
const ps = [cp];
let ci = index;
while ((ci = parentPropertyIndices[ci]) !== -1) {
ps.push(propertys[ci]);
}
ps.reverse();
result.push(ps.join("."));
} else {
vks.forEach((k) => {
propertys.push(k);
hosts.push(cv);
parentPropertyIndices.push(index);
});
}
index++;
}
return result;
}
function isBaseType(object) {
if (object === void 0 || object === null || typeof object === "boolean" || typeof object === "string" || typeof object === "number") {
return true;
}
return false;
}
exports2.Watcher = Watcher;
exports2.watcher = watcher;
Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
});
//# sourceMappingURL=index.umd.js.map

5

package.json
{
"name": "@feng3d/watcher",
"version": "0.8.0",
"version": "0.8.1",
"description": "对象属性监听器",

@@ -35,3 +35,4 @@ "main": "dist/index.umd.js",

"src",
"readme"
"readme",
"tsconfig.json"
],

@@ -38,0 +39,0 @@ "devDependencies": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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