/* * proxy.ts * Copyright (C) 2024 veypi * 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(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(target, handler); } export default { Watch, Listen, ForceUpdate }