You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OneAuth/oaer/lib/components/proxy.ts

74 lines
1.7 KiB
TypeScript

1 month ago
/*
* proxy.ts
* Copyright (C) 2024 veypi <i@veypi.com>
* 2024-10-23 17:20
* Distributed under terms of the GPL license.
*/
type voidFn = () => void
const callbackCache: voidFn[] = []
function ForceUpdate() {
for (let c of callbackCache) {
c()
}
}
var listen_tag = -1
function Listen(callback: voidFn) {
if (listen_tag >= 0) {
console.warn('it shuold not happen')
return
}
listen_tag = callbackCache.length
callbackCache.push(callback)
callback()
listen_tag = -1
}
function Watch<T extends Object>(target: T) {
const listeners: { [key: string]: number[] } = {}
const handler = {
get(target: Object, key: string, receiver: any) {
console.log(`get ${key} ${listen_tag}`)
const value = Reflect.get(target, key, receiver);
if (typeof value === 'object' && value !== null) {
return new Proxy(value, handler);
}
if (listen_tag >= 0) {
if (!listeners[key]) {
listeners[key] = []
}
listeners[key].push(listen_tag)
}
return value;
},
set(target: Object, key: string, newValue: any, receiver: any) {
console.log(`set ${key} ${newValue}`)
const result = Reflect.set(target, key, newValue, receiver);
if (result) {
if (listeners[key]) {
console.log(listeners[key])
for (let cb of listeners[key]) {
callbackCache[cb]()
}
}
}
return result;
},
deleteProperty(target: Object, key: string) {
console.log(`del ${key}`)
const result = Reflect.deleteProperty(target, key);
if (result) {
}
return result
}
};
return new Proxy<T>(target, handler);
}
export default { Watch, Listen, ForceUpdate }