{"version":3,"sources":["../src/object/observable.ts"],"names":["observable","target","options","onRead","onWrite","onDelete","trigger","callReadCallback","key","value","r","createObjectProxy","parentKey","receiver","ABORT"],"mappings":";;;;AAqCO,SAASA,CAAAA,CAAoCC,EAAWC,CAA8B,CAAA,CAEzF,GAAM,CAAC,MAAA,CAAAC,CAAO,CAAA,OAAA,CAAAC,CAAQ,CAAA,QAAA,CAAAC,EAAS,OAAAC,CAAAA,CAAO,EAAI,MAAO,CAAA,MAAA,CAAO,CACpD,OAAQ,CAAA,SACZ,CAAEJ,CAAAA,CAAO,CAET,CAAA,SAASK,EAAiBC,CAAaC,CAAAA,CAAAA,CAAU,CAC7C,GAAG,OAAON,GAAU,UAChB,CAAA,GAAG,CACC,IAAMO,CAAIP,CAAAA,CAAAA,CAAOK,EAAIC,CAAK,CAAA,CAC1B,GAAGC,CAAAA,GAAI,KACH,CAAA,CAAA,OAAOA,CAEf,CAAO,MAAA,CAAA,CAAE,CACL,OAAA,CAAQ,KAAM,CAAA,CAAC,EACnB,CAEJ,OAAOD,CACX,CACA,SAASE,EAAkBV,CAAgBW,CAAAA,CAAAA,CAAmB,EAAC,CAAU,CACrE,OAAO,IAAI,KAAMX,CAAAA,CAAAA,CAAQ,CACrB,GAAIA,CAAAA,CAAAA,CAAQO,EAAKK,CAAU,CAAA,CACvB,IAAMJ,CAAAA,CAAQ,OAAQ,CAAA,GAAA,CAAIR,EAAQO,CAAKK,CAAAA,CAAQ,EAE/C,OAAGL,CAAAA,IAAOP,GAAQ,SACNQ,CAAAA,CAAAA,CAGR,OAAOA,CAAAA,EAAU,QAAYA,EAAAA,CAAAA,GAAU,KACpCH,CAAS,EAAA,SAAA,CACDK,CAAkBF,CAAAA,CAAAA,CAAM,CAAC,GAAGG,EAAUJ,CAAa,CAAC,CAEpDD,CAAAA,CAAAA,CAAiB,CAAC,GAAGK,EAAUJ,CAAa,CAAA,CAAEG,EAAkBF,CAAM,CAAA,CAAC,GAAGG,CAAUJ,CAAAA,CAAa,CAAC,CAAC,CAG3GD,CAAAA,CAAAA,CAAiB,CAAC,GAAGK,CAAAA,CAAUJ,CAAa,CAAEC,CAAAA,CAAK,CAC9D,CACA,CAAA,GAAA,CAAIR,CAAQO,CAAAA,CAAAA,CAAKC,CAAOI,CAAAA,CAAAA,CAAU,CAC9B,GAAG,OAAOT,GAAU,UAEb,EAAA,EAAEI,KAAOP,CAAQ,EAAA,SAAA,CAAA,CAAW,CAC3B,IAAMS,CAAIN,CAAAA,CAAAA,CAAQ,CAAC,GAAGQ,CAAAA,CAAUJ,CAAa,CAAA,CAAEC,CAAK,CAAA,CACpD,GAAGC,CAAI,GAAA,MAAA,CACH,OAAO,OAAA,CAAQ,GAAIT,CAAAA,CAAAA,CAAQO,EAAKE,CAAGG,CAAAA,CAAQ,CAEnD,CAEJ,OAAO,QAAQ,GAAIZ,CAAAA,CAAAA,CAAQO,CAAKC,CAAAA,CAAAA,CAAOI,CAAQ,CACnD,EACA,cAAeZ,CAAAA,CAAAA,CAAQO,CAAK,CAAA,CACxB,GAAG,OAAOH,GAAW,UAEd,EAAA,EAAEG,CAAOP,IAAAA,CAAAA,EAAQ,SACbI,CAAAA,EAAAA,CAAAA,CAAS,CAAC,GAAGO,CAAAA,CAAUJ,CAAa,CAAC,CAAA,EAAGM,EACvC,MAAM,IAAI,KAAM,CAAA,cAAc,CAI1C,CAAA,OAAO,QAAQ,cAAeb,CAAAA,CAAAA,CAAQO,CAAG,CAC7C,CACJ,CAAC,CAEL,CAEA,OAAOG,CAAkBV,CAAAA,CAAM,CAEnC","file":"chunk-ZSD25NYJ.mjs","sourcesContent":["import { ABORT } from \"../consts\"\n\n\n\nexport type ObservableOptions= {\n    onRead?:(key:string[],value:any)=>any\n    onWrite?:(key:string[],newValue:any)=>any\n    onDelete?:(key:string[])=>any\n    // 触发方式\n    // default: 只有读取值是非对象时才会触发\n    // full: 读取任何值都会触发,这可能会导致性能问题,慎用\n    trigger?: 'default' | 'full'\n}\n\n/**\n * \n * 创建对象的可观察代理\n * \n * 如\n * obj = observable({a:1,b:2,C:{c1:1,c2:2},d:[1,2,3]},{\n *      onRead:(key)=>{console.log('read',key)},\n *      onWrite:(key,value)=>{\n * })\n * \n * 当读取obj.a时，会触发onRead(['a'])\n * 当读取obj.C.c1时，会触发onRead(['C','c1'])\n * 当写入obj.a时，会触发onWrite(['a'],value)\n * 当写入obj.C.c1时，会触发onWrite(['C','c1'],value)\n * \n * onRead和onWrite的返回值会作为读取或写入的结果\n * 支持嵌套对象和数组\n * \n * \n * @param target \n * @param options \n */\n\nexport function observable<T extends object=object>(target: T, options?:ObservableOptions):T {\n\n    const {onRead,onWrite,onDelete,trigger} = Object.assign({\n        trigger:'default'\n    },options)\n\n    function callReadCallback(key:string[],value:any){\n        if(typeof(onRead)==='function'){\n            try{\n                const r = onRead(key,value)\n                if(r!==undefined){\n                    return r\n                }\n            }catch(e){\n                console.error(e)\n            }  \n        }\n        return value\n    }\n    function createObjectProxy(target: object, parentKey:string[]=[]):object {\n        return new Proxy(target, {\n            get(target, key, receiver) {\n                const value = Reflect.get(target, key, receiver)\n                // @ts-ignore\n                if(key in target?.__proto__){\n                    return  value                    \n                }\n                \n                if (typeof value === 'object' && value !== null) {\n                    if(trigger=='default'){\n                        return createObjectProxy(value,[...parentKey,key as string])\n                    }else{\n                        return callReadCallback([...parentKey,key as string],createObjectProxy(value,[...parentKey,key as string]))\n                    }                    \n                }       \n                return callReadCallback([...parentKey,key as string],value)\n            },\n            set(target, key, value, receiver) {                \n                if(typeof(onWrite)=='function'){\n                    // @ts-ignore\n                    if(!(key in target?.__proto__)){\n                        const r = onWrite([...parentKey,key as string],value)\n                        if(r!==undefined){\n                            return Reflect.set(target, key, r, receiver)\n                        }\n                    }\n                }\n                return Reflect.set(target, key, value, receiver)\n            },\n            deleteProperty(target, key) {\n                if(typeof(onDelete)=='function'){\n                    // @ts-ignore\n                    if(!(key in target?.__proto__)){\n                        if(onDelete([...parentKey,key as string])==ABORT){\n                            throw new Error('Abort delete')\n                        }          \n                    }   \n                }\n                return Reflect.deleteProperty(target, key)\n            }\n        })\n\n    }\n\n    return createObjectProxy(target) as T\n\n}\n\n// const obj = observable({a:1,b:2,c:{c1:1,c2:2},d:[1,2,3],e:null,f:()=>{}},{\n//     onRead:(key:string[])=>{\n//         console.log('Read:',`[${key.join()}]`)\n//     },\n//     onWrite:(key:string[],value:any)=>{\n//         console.log('Write:',`[${key.join()}]`,value)\n//     },\n//     onDelete:(key:string[])=>{\n//         console.log('Delete:',`[${key.join()}]`)\n//     }\n// })\n\n// obj.d.length\n\n\n// obj.c\n// obj.a\n// obj.b\n// obj.c\n// obj.c.c1\n// obj.d\n// obj.d[0]\n// obj.d[1]\n// obj.d[2]\n// obj.d[3]\n// obj.f\n\n// obj.a = 2\n// console.log(obj.a)\n\n// obj.d[0] = 2\n\n// // @ts-ignore\n// delete obj.a\n// // @ts-ignore\n// delete obj.c\n// obj.d.pop()\n\n\n// console.log(Object.assign({},obj))"]}