@autostorejs/devtools
Advanced tools
+21
-21
| > @autostorejs/devtools@2.0.6 build /home/runner/work/autostore/autostore/packages/devTools | ||
| > @autostorejs/devtools@2.0.6 build E:\Work\Code\sources\autostore\packages\devTools | ||
| > tsup | ||
@@ -8,7 +8,7 @@ | ||
| [34mCLI[39m tsup v8.5.0 | ||
| [34mCLI[39m Using tsup config: /home/runner/work/autostore/autostore/packages/devTools/tsup.config.ts | ||
| [34mCLI[39m Using tsup config: E:\Work\Code\sources\autostore\packages\devTools\tsup.config.ts | ||
| [34mCLI[39m Building entry: src/cycleDetectExtend.ts | ||
| [34mCLI[39m Using tsconfig: tsconfig.json | ||
| [34mCLI[39m tsup v8.5.0 | ||
| [34mCLI[39m Using tsup config: /home/runner/work/autostore/autostore/packages/devTools/tsup.config.ts | ||
| [34mCLI[39m Using tsup config: E:\Work\Code\sources\autostore\packages\devTools\tsup.config.ts | ||
| [34mCLI[39m Target: es2022 | ||
@@ -22,21 +22,21 @@ [34mCLI[39m Target: es2022 | ||
| [34mCJS[39m Build start | ||
| [32mESM[39m [1mdist/cycleDetectExtend.mjs [22m[32m2.23 KB[39m | ||
| [32mESM[39m [1mdist/cycleDetectExtend.mjs.map [22m[32m12.06 KB[39m | ||
| [32mESM[39m ⚡️ Build success in 634ms | ||
| [32mCJS[39m [1mdist/cycleDetectExtend.js [22m[32m2.24 KB[39m | ||
| [32mCJS[39m [1mdist/cycleDetectExtend.js.map [22m[32m12.06 KB[39m | ||
| [32mCJS[39m ⚡️ Build success in 638ms | ||
| [32mESM[39m [1mdist/index.mjs [22m[32m3.55 KB[39m | ||
| [32mESM[39m [1mdist/index.mjs.map [22m[32m16.11 KB[39m | ||
| [32mESM[39m ⚡️ Build success in 647ms | ||
| [32mCJS[39m [1mdist/index.js [22m[32m3.57 KB[39m | ||
| [32mCJS[39m [1mdist/index.js.map [22m[32m16.11 KB[39m | ||
| [32mCJS[39m ⚡️ Build success in 646ms | ||
| [32mCJS[39m [1mdist\cycleDetectExtend.js [22m[32m2.24 KB[39m | ||
| [32mCJS[39m [1mdist\cycleDetectExtend.js.map [22m[32m12.57 KB[39m | ||
| [32mCJS[39m ⚡️ Build success in 1011ms | ||
| [32mESM[39m [1mdist\index.mjs [22m[32m3.55 KB[39m | ||
| [32mESM[39m [1mdist\index.mjs.map [22m[32m16.80 KB[39m | ||
| [32mESM[39m ⚡️ Build success in 1017ms | ||
| [32mCJS[39m [1mdist\index.js [22m[32m3.57 KB[39m | ||
| [32mCJS[39m [1mdist\index.js.map [22m[32m16.80 KB[39m | ||
| [32mCJS[39m ⚡️ Build success in 1031ms | ||
| [32mESM[39m [1mdist\cycleDetectExtend.mjs [22m[32m2.23 KB[39m | ||
| [32mESM[39m [1mdist\cycleDetectExtend.mjs.map [22m[32m12.57 KB[39m | ||
| [32mESM[39m ⚡️ Build success in 1042ms | ||
| [34mDTS[39m Build start | ||
| [34mDTS[39m Build start | ||
| [32mDTS[39m ⚡️ Build success in 2911ms | ||
| [32mDTS[39m [1mdist/cycleDetectExtend.d.mts [22m[32m1.20 KB[39m | ||
| [32mDTS[39m [1mdist/cycleDetectExtend.d.ts [22m[32m1.20 KB[39m | ||
| [32mDTS[39m ⚡️ Build success in 3112ms | ||
| [32mDTS[39m [1mdist/index.d.mts [22m[32m2.13 KB[39m | ||
| [32mDTS[39m [1mdist/index.d.ts [22m[32m2.13 KB[39m | ||
| [32mDTS[39m ⚡️ Build success in 8152ms | ||
| [32mDTS[39m [1mdist\cycleDetectExtend.d.mts [22m[32m1.20 KB[39m | ||
| [32mDTS[39m [1mdist\cycleDetectExtend.d.ts [22m[32m1.20 KB[39m | ||
| [32mDTS[39m ⚡️ Build success in 8739ms | ||
| [32mDTS[39m [1mdist\index.d.mts [22m[32m2.13 KB[39m | ||
| [32mDTS[39m [1mdist\index.d.ts [22m[32m2.13 KB[39m |
+6
-0
| # @autostorejs/devtools | ||
| ## 2.0.7 | ||
| ### Patch Changes | ||
| - 889fc70: update sync configurable support array and object | ||
| ## 2.0.6 | ||
@@ -4,0 +10,0 @@ |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../src/utils.ts","../src/cycleDetectExtend.ts"],"names":["isPathEq","a","b","item","index","pathStartsWith","basePath","destPath","p","i","analysisCyclePath","steps","curPath","indexs","prev","cur","groups","v","results","group","j","group2","gKey","n","count","paths","k","AsyncCycleDetector","computedObject","options","event","onDetected","cycleCount","result","createCycleDetectExtend","store","onObserverCreated","observerObject","oldRun","installCycleDetectExtend"],"mappings":"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","file":"cycleDetectExtend.js","sourcesContent":["\nexport class WeakObjectMap<T extends object> {\n private map: Map<string, WeakRef<T>>;\n private finalizationRegistry: FinalizationRegistry<string>;\n \n constructor() {\n this.map = new Map();\n this.finalizationRegistry = new FinalizationRegistry((key) => {\n this.map.delete(key);\n });\n }\n \n set(key: string, value: T): void {\n const weakRef = new WeakRef(value);\n this.map.set(key, weakRef);\n this.finalizationRegistry.register(value, key);\n }\n \n get(key: string): T | undefined {\n const weakRef = this.map.get(key);\n return weakRef ? weakRef.deref() : undefined;\n }\n \n delete(key: string): boolean {\n return this.map.delete(key);\n }\n \n has(key: string): boolean {\n const weakRef = this.map.get(key);\n return weakRef ? weakRef.deref() !== undefined : false;\n }\n}\n/**\n * 判定两个值是否相等\n * \n * 如果两个值都是对象,则判断两个对象是否相等\n * 如果两个值都是数组,则判断两个数组的值是否相等\n * \n */\n\nexport function isPathEq(a:string[] | undefined,b:string[] | undefined):boolean{\n if(!a) return false\n if(!b) return false\n if(a.length!==b.length) return false\n return a.every((item,index)=>item===b[index])\n}\n/**\n * 判断一个路径destPath是否包含另一个路径basePath判断\n * @param basePath \n * @param destPath \n */\nexport function pathStartsWith(basePath:string[],destPath:string[]){\n if(basePath.length>destPath.length) return false\n return basePath.every((p,i)=>{\n return p===destPath[i]\n })\n}\n\nexport function analysisCyclePath(steps:string[],curPath:string):[string | undefined,number] {\n // 使用curPath将steps分割为多个数组\n const indexs = steps.reduce((prev,cur,index)=>{\n if(cur===curPath) prev.push(index) \n return prev\n },[] as number[])\n\n const groups = indexs.map((v,i)=>{\n if(i<indexs.length-1){\n return steps.slice(v,indexs[i+1])\n }else{\n return steps.slice(v)\n } \n })\n\n // 找到groups相同的分组\n const results = new Map<string,number>()\n for(let i=0;i<groups.length;i++){\n const group = groups[i]\n if(group.length<2) continue\n for(let j=i+1;j<groups.length;j++){\n const group2 = groups[j]\n if(isPathEq(group,group2) || pathStartsWith(group,group2)){\n const gKey = group.join('->')\n if(!results.has(gKey)){\n results.set(gKey,1)\n }\n const n = results.get(gKey)! \n results.set(gKey,n+1)\n }\n }\n }\n // 找到results里面路径最长的\n let count = 0\n let paths = undefined\n results.forEach((v,k)=>{\n if(v<3) return\n if(k.length>count){\n paths = k\n count = v \n }\n }) \n return [paths,count]\n\n}\n","/**\n * \n * import { installCycleDetectExtend } from \"@autostore/devtools\"\n * \n * installCycleDetectExtend({....})\n * \n * \n */\nimport { analysisCyclePath } from \"./utils\"\n\n\nexport type CycleDetectExtendOptions = { \n /**\n * 当检测到多少个循环时视为循环依赖 \n */\n cycleCount?:number\n /**\n * \n * 当检测时间操作数量达到此值时,停止检测\n * \n */\n maxOpereates?:number\n /**\n * 指定仅作用于指定的store\n * =[]代表所有store均生效\n */\n stores?:string[]\n /**\n * \n */\n onDetected?:(paths:string[],computedObject:any)=>'ignore'|'throw'|'disable' \n\n}\n\n/**\n * \n * - 在异步计算第一次执行时调用\n * cycleDetector.start()\n * \n * \n * \n */\nexport class AsyncCycleDetector{\n steps:string[] = []\n running:boolean = false \n private _watcher:any\n path:string\n options: Record<string,any>\n constructor(public computedObject:any,options?:Record<string,any>){\n this.path = computedObject.path.join('.')\n this.steps.push(this.path)\n this.options = Object.assign({\n cycleCount : 8,\n maxOpereates: 200,\n stores:[]\n },options)\n } \n /**\n * 本方法应该在异步函数第一次运行时调用\n */\n start(){\n this.running = true\n this.steps.push(this.path)\n this._watcher = this.computedObject.store.watch((event:any)=>{\n if(this.steps.length<500){\n this.steps.push(event.path.join('.'))\n }\n },{operates:'read'}) \n }\n /**\n * \n * 开始检测是否存在循环依赖\n * \n * \n * [\"a\",'d','c','b','a','d','c','b','a']\n * \n * \n * 编写一个函数,检测是否存在循环依赖\n * \n * 逻辑如下:\n * \n * 对this.steps里面是否存在连续的相同的路径,如果存在,则表示存在循环依赖\n * \n * \n * @returns \n */\n private analysisCycleSteps(){\n const [paths,count] = analysisCyclePath(this.steps,this.path)\n const { onDetected,cycleCount } = this.options\n if(count<cycleCount) return\n this.computedObject.store.log(`CycleDepend detected in <${this.computedObject.toString()}>: ${paths}`,'warn')\n if(typeof(onDetected )==='function'){\n const result = onDetected(paths,this.computedObject)\n if(result==='ignore'){\n return\n }else if(result==='disable') {\n this.computedObject.enable = false\n }else{\n throw new Error(`CycleDepend found in <${this.computedObject.toString()}>: ${paths}`)\n }\n } \n } \n detect(){\n if(this.steps.length>this.options.maxOpereates){\n this._watcher.off()\n try{\n this.analysisCycleSteps()\n }finally{ \n this.steps=[]\n }\n }\n }\n}\n\n\nfunction createCycleDetectExtend(options?:CycleDetectExtendOptions){\n return function cycleDetectExtend(store:any){\n const { onObserverCreated } = store.options\n if(typeof(onObserverCreated) ==='function'){ \n // 当store的onObserverCreated选项已经配置时,cycleDetectExtend不能生效\n store.log(`Store<${store.id}> onObserverCreated is already configured, cycleDetectExtend is disabled`,\"warn\")\n }else{\n store.options.onObserverCreated = (observerObject:any)=>{\n // 只对异步计算属性进行循环依赖检测\n if(observerObject.type==='computed' && observerObject.async){\n observerObject._cycleDetector = new AsyncCycleDetector(observerObject,options)\n const oldRun = observerObject.run\n // 封装原始的run方法\n observerObject.run = (async function(options:any){\n // 在第一次运行时启动循环依赖检测\n if(options && options.first===true){\n observerObject._cycleDetector.start()\n }else{\n observerObject._cycleDetector.detect() \n }\n return await oldRun.apply(observerObject,options)\n }).bind(observerObject)\n }\n }\n store.log(\"cycleDetectExtend is already installed\")\n }\n } \n\n}\n\n\nexport function installCycleDetectExtend(options?:CycleDetectExtendOptions){\n // @ts-ignore\n if(!globalThis.__AUTOSTORE_EXTENDS__){\n // @ts-ignore\n globalThis.__AUTOSTORE_EXTENDS__=[]\n }\n // @ts-ignore\n globalThis.__AUTOSTORE_EXTENDS__.push(createCycleDetectExtend(options))\n \n}\n "]} | ||
| {"version":3,"sources":["../src/utils.ts","../src/cycleDetectExtend.ts"],"names":["isPathEq","a","b","item","index","pathStartsWith","basePath","destPath","p","i","analysisCyclePath","steps","curPath","indexs","prev","cur","groups","v","results","group","j","group2","gKey","n","count","paths","k","AsyncCycleDetector","computedObject","options","event","onDetected","cycleCount","result","createCycleDetectExtend","store","onObserverCreated","observerObject","oldRun","installCycleDetectExtend"],"mappings":"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","file":"cycleDetectExtend.js","sourcesContent":["\r\nexport class WeakObjectMap<T extends object> {\r\n private map: Map<string, WeakRef<T>>;\r\n private finalizationRegistry: FinalizationRegistry<string>;\r\n \r\n constructor() {\r\n this.map = new Map();\r\n this.finalizationRegistry = new FinalizationRegistry((key) => {\r\n this.map.delete(key);\r\n });\r\n }\r\n \r\n set(key: string, value: T): void {\r\n const weakRef = new WeakRef(value);\r\n this.map.set(key, weakRef);\r\n this.finalizationRegistry.register(value, key);\r\n }\r\n \r\n get(key: string): T | undefined {\r\n const weakRef = this.map.get(key);\r\n return weakRef ? weakRef.deref() : undefined;\r\n }\r\n \r\n delete(key: string): boolean {\r\n return this.map.delete(key);\r\n }\r\n \r\n has(key: string): boolean {\r\n const weakRef = this.map.get(key);\r\n return weakRef ? weakRef.deref() !== undefined : false;\r\n }\r\n}\r\n/**\r\n * 判定两个值是否相等\r\n * \r\n * 如果两个值都是对象,则判断两个对象是否相等\r\n * 如果两个值都是数组,则判断两个数组的值是否相等\r\n * \r\n */\r\n\r\nexport function isPathEq(a:string[] | undefined,b:string[] | undefined):boolean{\r\n if(!a) return false\r\n if(!b) return false\r\n if(a.length!==b.length) return false\r\n return a.every((item,index)=>item===b[index])\r\n}\r\n/**\r\n * 判断一个路径destPath是否包含另一个路径basePath判断\r\n * @param basePath \r\n * @param destPath \r\n */\r\nexport function pathStartsWith(basePath:string[],destPath:string[]){\r\n if(basePath.length>destPath.length) return false\r\n return basePath.every((p,i)=>{\r\n return p===destPath[i]\r\n })\r\n}\r\n\r\nexport function analysisCyclePath(steps:string[],curPath:string):[string | undefined,number] {\r\n // 使用curPath将steps分割为多个数组\r\n const indexs = steps.reduce((prev,cur,index)=>{\r\n if(cur===curPath) prev.push(index) \r\n return prev\r\n },[] as number[])\r\n\r\n const groups = indexs.map((v,i)=>{\r\n if(i<indexs.length-1){\r\n return steps.slice(v,indexs[i+1])\r\n }else{\r\n return steps.slice(v)\r\n } \r\n })\r\n\r\n // 找到groups相同的分组\r\n const results = new Map<string,number>()\r\n for(let i=0;i<groups.length;i++){\r\n const group = groups[i]\r\n if(group.length<2) continue\r\n for(let j=i+1;j<groups.length;j++){\r\n const group2 = groups[j]\r\n if(isPathEq(group,group2) || pathStartsWith(group,group2)){\r\n const gKey = group.join('->')\r\n if(!results.has(gKey)){\r\n results.set(gKey,1)\r\n }\r\n const n = results.get(gKey)! \r\n results.set(gKey,n+1)\r\n }\r\n }\r\n }\r\n // 找到results里面路径最长的\r\n let count = 0\r\n let paths = undefined\r\n results.forEach((v,k)=>{\r\n if(v<3) return\r\n if(k.length>count){\r\n paths = k\r\n count = v \r\n }\r\n }) \r\n return [paths,count]\r\n\r\n}\r\n","/**\r\n * \r\n * import { installCycleDetectExtend } from \"@autostore/devtools\"\r\n * \r\n * installCycleDetectExtend({....})\r\n * \r\n * \r\n */\r\nimport { analysisCyclePath } from \"./utils\"\r\n\r\n\r\nexport type CycleDetectExtendOptions = { \r\n /**\r\n * 当检测到多少个循环时视为循环依赖 \r\n */\r\n cycleCount?:number\r\n /**\r\n * \r\n * 当检测时间操作数量达到此值时,停止检测\r\n * \r\n */\r\n maxOpereates?:number\r\n /**\r\n * 指定仅作用于指定的store\r\n * =[]代表所有store均生效\r\n */\r\n stores?:string[]\r\n /**\r\n * \r\n */\r\n onDetected?:(paths:string[],computedObject:any)=>'ignore'|'throw'|'disable' \r\n\r\n}\r\n\r\n/**\r\n * \r\n * - 在异步计算第一次执行时调用\r\n * cycleDetector.start()\r\n * \r\n * \r\n * \r\n */\r\nexport class AsyncCycleDetector{\r\n steps:string[] = []\r\n running:boolean = false \r\n private _watcher:any\r\n path:string\r\n options: Record<string,any>\r\n constructor(public computedObject:any,options?:Record<string,any>){\r\n this.path = computedObject.path.join('.')\r\n this.steps.push(this.path)\r\n this.options = Object.assign({\r\n cycleCount : 8,\r\n maxOpereates: 200,\r\n stores:[]\r\n },options)\r\n } \r\n /**\r\n * 本方法应该在异步函数第一次运行时调用\r\n */\r\n start(){\r\n this.running = true\r\n this.steps.push(this.path)\r\n this._watcher = this.computedObject.store.watch((event:any)=>{\r\n if(this.steps.length<500){\r\n this.steps.push(event.path.join('.'))\r\n }\r\n },{operates:'read'}) \r\n }\r\n /**\r\n * \r\n * 开始检测是否存在循环依赖\r\n * \r\n * \r\n * [\"a\",'d','c','b','a','d','c','b','a']\r\n * \r\n * \r\n * 编写一个函数,检测是否存在循环依赖\r\n * \r\n * 逻辑如下:\r\n * \r\n * 对this.steps里面是否存在连续的相同的路径,如果存在,则表示存在循环依赖\r\n * \r\n * \r\n * @returns \r\n */\r\n private analysisCycleSteps(){\r\n const [paths,count] = analysisCyclePath(this.steps,this.path)\r\n const { onDetected,cycleCount } = this.options\r\n if(count<cycleCount) return\r\n this.computedObject.store.log(`CycleDepend detected in <${this.computedObject.toString()}>: ${paths}`,'warn')\r\n if(typeof(onDetected )==='function'){\r\n const result = onDetected(paths,this.computedObject)\r\n if(result==='ignore'){\r\n return\r\n }else if(result==='disable') {\r\n this.computedObject.enable = false\r\n }else{\r\n throw new Error(`CycleDepend found in <${this.computedObject.toString()}>: ${paths}`)\r\n }\r\n } \r\n } \r\n detect(){\r\n if(this.steps.length>this.options.maxOpereates){\r\n this._watcher.off()\r\n try{\r\n this.analysisCycleSteps()\r\n }finally{ \r\n this.steps=[]\r\n }\r\n }\r\n }\r\n}\r\n\r\n\r\nfunction createCycleDetectExtend(options?:CycleDetectExtendOptions){\r\n return function cycleDetectExtend(store:any){\r\n const { onObserverCreated } = store.options\r\n if(typeof(onObserverCreated) ==='function'){ \r\n // 当store的onObserverCreated选项已经配置时,cycleDetectExtend不能生效\r\n store.log(`Store<${store.id}> onObserverCreated is already configured, cycleDetectExtend is disabled`,\"warn\")\r\n }else{\r\n store.options.onObserverCreated = (observerObject:any)=>{\r\n // 只对异步计算属性进行循环依赖检测\r\n if(observerObject.type==='computed' && observerObject.async){\r\n observerObject._cycleDetector = new AsyncCycleDetector(observerObject,options)\r\n const oldRun = observerObject.run\r\n // 封装原始的run方法\r\n observerObject.run = (async function(options:any){\r\n // 在第一次运行时启动循环依赖检测\r\n if(options && options.first===true){\r\n observerObject._cycleDetector.start()\r\n }else{\r\n observerObject._cycleDetector.detect() \r\n }\r\n return await oldRun.apply(observerObject,options)\r\n }).bind(observerObject)\r\n }\r\n }\r\n store.log(\"cycleDetectExtend is already installed\")\r\n }\r\n } \r\n\r\n}\r\n\r\n\r\nexport function installCycleDetectExtend(options?:CycleDetectExtendOptions){\r\n // @ts-ignore\r\n if(!globalThis.__AUTOSTORE_EXTENDS__){\r\n // @ts-ignore\r\n globalThis.__AUTOSTORE_EXTENDS__=[]\r\n }\r\n // @ts-ignore\r\n globalThis.__AUTOSTORE_EXTENDS__.push(createCycleDetectExtend(options))\r\n \r\n}\r\n "]} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../src/utils.ts","../src/cycleDetectExtend.ts"],"names":["isPathEq","a","b","item","index","pathStartsWith","basePath","destPath","p","i","analysisCyclePath","steps","curPath","indexs","prev","cur","groups","v","results","group","j","group2","gKey","n","count","paths","k","AsyncCycleDetector","computedObject","options","event","onDetected","cycleCount","result","createCycleDetectExtend","store","onObserverCreated","observerObject","oldRun","installCycleDetectExtend"],"mappings":"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","file":"cycleDetectExtend.mjs","sourcesContent":["\nexport class WeakObjectMap<T extends object> {\n private map: Map<string, WeakRef<T>>;\n private finalizationRegistry: FinalizationRegistry<string>;\n \n constructor() {\n this.map = new Map();\n this.finalizationRegistry = new FinalizationRegistry((key) => {\n this.map.delete(key);\n });\n }\n \n set(key: string, value: T): void {\n const weakRef = new WeakRef(value);\n this.map.set(key, weakRef);\n this.finalizationRegistry.register(value, key);\n }\n \n get(key: string): T | undefined {\n const weakRef = this.map.get(key);\n return weakRef ? weakRef.deref() : undefined;\n }\n \n delete(key: string): boolean {\n return this.map.delete(key);\n }\n \n has(key: string): boolean {\n const weakRef = this.map.get(key);\n return weakRef ? weakRef.deref() !== undefined : false;\n }\n}\n/**\n * 判定两个值是否相等\n * \n * 如果两个值都是对象,则判断两个对象是否相等\n * 如果两个值都是数组,则判断两个数组的值是否相等\n * \n */\n\nexport function isPathEq(a:string[] | undefined,b:string[] | undefined):boolean{\n if(!a) return false\n if(!b) return false\n if(a.length!==b.length) return false\n return a.every((item,index)=>item===b[index])\n}\n/**\n * 判断一个路径destPath是否包含另一个路径basePath判断\n * @param basePath \n * @param destPath \n */\nexport function pathStartsWith(basePath:string[],destPath:string[]){\n if(basePath.length>destPath.length) return false\n return basePath.every((p,i)=>{\n return p===destPath[i]\n })\n}\n\nexport function analysisCyclePath(steps:string[],curPath:string):[string | undefined,number] {\n // 使用curPath将steps分割为多个数组\n const indexs = steps.reduce((prev,cur,index)=>{\n if(cur===curPath) prev.push(index) \n return prev\n },[] as number[])\n\n const groups = indexs.map((v,i)=>{\n if(i<indexs.length-1){\n return steps.slice(v,indexs[i+1])\n }else{\n return steps.slice(v)\n } \n })\n\n // 找到groups相同的分组\n const results = new Map<string,number>()\n for(let i=0;i<groups.length;i++){\n const group = groups[i]\n if(group.length<2) continue\n for(let j=i+1;j<groups.length;j++){\n const group2 = groups[j]\n if(isPathEq(group,group2) || pathStartsWith(group,group2)){\n const gKey = group.join('->')\n if(!results.has(gKey)){\n results.set(gKey,1)\n }\n const n = results.get(gKey)! \n results.set(gKey,n+1)\n }\n }\n }\n // 找到results里面路径最长的\n let count = 0\n let paths = undefined\n results.forEach((v,k)=>{\n if(v<3) return\n if(k.length>count){\n paths = k\n count = v \n }\n }) \n return [paths,count]\n\n}\n","/**\n * \n * import { installCycleDetectExtend } from \"@autostore/devtools\"\n * \n * installCycleDetectExtend({....})\n * \n * \n */\nimport { analysisCyclePath } from \"./utils\"\n\n\nexport type CycleDetectExtendOptions = { \n /**\n * 当检测到多少个循环时视为循环依赖 \n */\n cycleCount?:number\n /**\n * \n * 当检测时间操作数量达到此值时,停止检测\n * \n */\n maxOpereates?:number\n /**\n * 指定仅作用于指定的store\n * =[]代表所有store均生效\n */\n stores?:string[]\n /**\n * \n */\n onDetected?:(paths:string[],computedObject:any)=>'ignore'|'throw'|'disable' \n\n}\n\n/**\n * \n * - 在异步计算第一次执行时调用\n * cycleDetector.start()\n * \n * \n * \n */\nexport class AsyncCycleDetector{\n steps:string[] = []\n running:boolean = false \n private _watcher:any\n path:string\n options: Record<string,any>\n constructor(public computedObject:any,options?:Record<string,any>){\n this.path = computedObject.path.join('.')\n this.steps.push(this.path)\n this.options = Object.assign({\n cycleCount : 8,\n maxOpereates: 200,\n stores:[]\n },options)\n } \n /**\n * 本方法应该在异步函数第一次运行时调用\n */\n start(){\n this.running = true\n this.steps.push(this.path)\n this._watcher = this.computedObject.store.watch((event:any)=>{\n if(this.steps.length<500){\n this.steps.push(event.path.join('.'))\n }\n },{operates:'read'}) \n }\n /**\n * \n * 开始检测是否存在循环依赖\n * \n * \n * [\"a\",'d','c','b','a','d','c','b','a']\n * \n * \n * 编写一个函数,检测是否存在循环依赖\n * \n * 逻辑如下:\n * \n * 对this.steps里面是否存在连续的相同的路径,如果存在,则表示存在循环依赖\n * \n * \n * @returns \n */\n private analysisCycleSteps(){\n const [paths,count] = analysisCyclePath(this.steps,this.path)\n const { onDetected,cycleCount } = this.options\n if(count<cycleCount) return\n this.computedObject.store.log(`CycleDepend detected in <${this.computedObject.toString()}>: ${paths}`,'warn')\n if(typeof(onDetected )==='function'){\n const result = onDetected(paths,this.computedObject)\n if(result==='ignore'){\n return\n }else if(result==='disable') {\n this.computedObject.enable = false\n }else{\n throw new Error(`CycleDepend found in <${this.computedObject.toString()}>: ${paths}`)\n }\n } \n } \n detect(){\n if(this.steps.length>this.options.maxOpereates){\n this._watcher.off()\n try{\n this.analysisCycleSteps()\n }finally{ \n this.steps=[]\n }\n }\n }\n}\n\n\nfunction createCycleDetectExtend(options?:CycleDetectExtendOptions){\n return function cycleDetectExtend(store:any){\n const { onObserverCreated } = store.options\n if(typeof(onObserverCreated) ==='function'){ \n // 当store的onObserverCreated选项已经配置时,cycleDetectExtend不能生效\n store.log(`Store<${store.id}> onObserverCreated is already configured, cycleDetectExtend is disabled`,\"warn\")\n }else{\n store.options.onObserverCreated = (observerObject:any)=>{\n // 只对异步计算属性进行循环依赖检测\n if(observerObject.type==='computed' && observerObject.async){\n observerObject._cycleDetector = new AsyncCycleDetector(observerObject,options)\n const oldRun = observerObject.run\n // 封装原始的run方法\n observerObject.run = (async function(options:any){\n // 在第一次运行时启动循环依赖检测\n if(options && options.first===true){\n observerObject._cycleDetector.start()\n }else{\n observerObject._cycleDetector.detect() \n }\n return await oldRun.apply(observerObject,options)\n }).bind(observerObject)\n }\n }\n store.log(\"cycleDetectExtend is already installed\")\n }\n } \n\n}\n\n\nexport function installCycleDetectExtend(options?:CycleDetectExtendOptions){\n // @ts-ignore\n if(!globalThis.__AUTOSTORE_EXTENDS__){\n // @ts-ignore\n globalThis.__AUTOSTORE_EXTENDS__=[]\n }\n // @ts-ignore\n globalThis.__AUTOSTORE_EXTENDS__.push(createCycleDetectExtend(options))\n \n}\n "]} | ||
| {"version":3,"sources":["../src/utils.ts","../src/cycleDetectExtend.ts"],"names":["isPathEq","a","b","item","index","pathStartsWith","basePath","destPath","p","i","analysisCyclePath","steps","curPath","indexs","prev","cur","groups","v","results","group","j","group2","gKey","n","count","paths","k","AsyncCycleDetector","computedObject","options","event","onDetected","cycleCount","result","createCycleDetectExtend","store","onObserverCreated","observerObject","oldRun","installCycleDetectExtend"],"mappings":"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","file":"cycleDetectExtend.mjs","sourcesContent":["\r\nexport class WeakObjectMap<T extends object> {\r\n private map: Map<string, WeakRef<T>>;\r\n private finalizationRegistry: FinalizationRegistry<string>;\r\n \r\n constructor() {\r\n this.map = new Map();\r\n this.finalizationRegistry = new FinalizationRegistry((key) => {\r\n this.map.delete(key);\r\n });\r\n }\r\n \r\n set(key: string, value: T): void {\r\n const weakRef = new WeakRef(value);\r\n this.map.set(key, weakRef);\r\n this.finalizationRegistry.register(value, key);\r\n }\r\n \r\n get(key: string): T | undefined {\r\n const weakRef = this.map.get(key);\r\n return weakRef ? weakRef.deref() : undefined;\r\n }\r\n \r\n delete(key: string): boolean {\r\n return this.map.delete(key);\r\n }\r\n \r\n has(key: string): boolean {\r\n const weakRef = this.map.get(key);\r\n return weakRef ? weakRef.deref() !== undefined : false;\r\n }\r\n}\r\n/**\r\n * 判定两个值是否相等\r\n * \r\n * 如果两个值都是对象,则判断两个对象是否相等\r\n * 如果两个值都是数组,则判断两个数组的值是否相等\r\n * \r\n */\r\n\r\nexport function isPathEq(a:string[] | undefined,b:string[] | undefined):boolean{\r\n if(!a) return false\r\n if(!b) return false\r\n if(a.length!==b.length) return false\r\n return a.every((item,index)=>item===b[index])\r\n}\r\n/**\r\n * 判断一个路径destPath是否包含另一个路径basePath判断\r\n * @param basePath \r\n * @param destPath \r\n */\r\nexport function pathStartsWith(basePath:string[],destPath:string[]){\r\n if(basePath.length>destPath.length) return false\r\n return basePath.every((p,i)=>{\r\n return p===destPath[i]\r\n })\r\n}\r\n\r\nexport function analysisCyclePath(steps:string[],curPath:string):[string | undefined,number] {\r\n // 使用curPath将steps分割为多个数组\r\n const indexs = steps.reduce((prev,cur,index)=>{\r\n if(cur===curPath) prev.push(index) \r\n return prev\r\n },[] as number[])\r\n\r\n const groups = indexs.map((v,i)=>{\r\n if(i<indexs.length-1){\r\n return steps.slice(v,indexs[i+1])\r\n }else{\r\n return steps.slice(v)\r\n } \r\n })\r\n\r\n // 找到groups相同的分组\r\n const results = new Map<string,number>()\r\n for(let i=0;i<groups.length;i++){\r\n const group = groups[i]\r\n if(group.length<2) continue\r\n for(let j=i+1;j<groups.length;j++){\r\n const group2 = groups[j]\r\n if(isPathEq(group,group2) || pathStartsWith(group,group2)){\r\n const gKey = group.join('->')\r\n if(!results.has(gKey)){\r\n results.set(gKey,1)\r\n }\r\n const n = results.get(gKey)! \r\n results.set(gKey,n+1)\r\n }\r\n }\r\n }\r\n // 找到results里面路径最长的\r\n let count = 0\r\n let paths = undefined\r\n results.forEach((v,k)=>{\r\n if(v<3) return\r\n if(k.length>count){\r\n paths = k\r\n count = v \r\n }\r\n }) \r\n return [paths,count]\r\n\r\n}\r\n","/**\r\n * \r\n * import { installCycleDetectExtend } from \"@autostore/devtools\"\r\n * \r\n * installCycleDetectExtend({....})\r\n * \r\n * \r\n */\r\nimport { analysisCyclePath } from \"./utils\"\r\n\r\n\r\nexport type CycleDetectExtendOptions = { \r\n /**\r\n * 当检测到多少个循环时视为循环依赖 \r\n */\r\n cycleCount?:number\r\n /**\r\n * \r\n * 当检测时间操作数量达到此值时,停止检测\r\n * \r\n */\r\n maxOpereates?:number\r\n /**\r\n * 指定仅作用于指定的store\r\n * =[]代表所有store均生效\r\n */\r\n stores?:string[]\r\n /**\r\n * \r\n */\r\n onDetected?:(paths:string[],computedObject:any)=>'ignore'|'throw'|'disable' \r\n\r\n}\r\n\r\n/**\r\n * \r\n * - 在异步计算第一次执行时调用\r\n * cycleDetector.start()\r\n * \r\n * \r\n * \r\n */\r\nexport class AsyncCycleDetector{\r\n steps:string[] = []\r\n running:boolean = false \r\n private _watcher:any\r\n path:string\r\n options: Record<string,any>\r\n constructor(public computedObject:any,options?:Record<string,any>){\r\n this.path = computedObject.path.join('.')\r\n this.steps.push(this.path)\r\n this.options = Object.assign({\r\n cycleCount : 8,\r\n maxOpereates: 200,\r\n stores:[]\r\n },options)\r\n } \r\n /**\r\n * 本方法应该在异步函数第一次运行时调用\r\n */\r\n start(){\r\n this.running = true\r\n this.steps.push(this.path)\r\n this._watcher = this.computedObject.store.watch((event:any)=>{\r\n if(this.steps.length<500){\r\n this.steps.push(event.path.join('.'))\r\n }\r\n },{operates:'read'}) \r\n }\r\n /**\r\n * \r\n * 开始检测是否存在循环依赖\r\n * \r\n * \r\n * [\"a\",'d','c','b','a','d','c','b','a']\r\n * \r\n * \r\n * 编写一个函数,检测是否存在循环依赖\r\n * \r\n * 逻辑如下:\r\n * \r\n * 对this.steps里面是否存在连续的相同的路径,如果存在,则表示存在循环依赖\r\n * \r\n * \r\n * @returns \r\n */\r\n private analysisCycleSteps(){\r\n const [paths,count] = analysisCyclePath(this.steps,this.path)\r\n const { onDetected,cycleCount } = this.options\r\n if(count<cycleCount) return\r\n this.computedObject.store.log(`CycleDepend detected in <${this.computedObject.toString()}>: ${paths}`,'warn')\r\n if(typeof(onDetected )==='function'){\r\n const result = onDetected(paths,this.computedObject)\r\n if(result==='ignore'){\r\n return\r\n }else if(result==='disable') {\r\n this.computedObject.enable = false\r\n }else{\r\n throw new Error(`CycleDepend found in <${this.computedObject.toString()}>: ${paths}`)\r\n }\r\n } \r\n } \r\n detect(){\r\n if(this.steps.length>this.options.maxOpereates){\r\n this._watcher.off()\r\n try{\r\n this.analysisCycleSteps()\r\n }finally{ \r\n this.steps=[]\r\n }\r\n }\r\n }\r\n}\r\n\r\n\r\nfunction createCycleDetectExtend(options?:CycleDetectExtendOptions){\r\n return function cycleDetectExtend(store:any){\r\n const { onObserverCreated } = store.options\r\n if(typeof(onObserverCreated) ==='function'){ \r\n // 当store的onObserverCreated选项已经配置时,cycleDetectExtend不能生效\r\n store.log(`Store<${store.id}> onObserverCreated is already configured, cycleDetectExtend is disabled`,\"warn\")\r\n }else{\r\n store.options.onObserverCreated = (observerObject:any)=>{\r\n // 只对异步计算属性进行循环依赖检测\r\n if(observerObject.type==='computed' && observerObject.async){\r\n observerObject._cycleDetector = new AsyncCycleDetector(observerObject,options)\r\n const oldRun = observerObject.run\r\n // 封装原始的run方法\r\n observerObject.run = (async function(options:any){\r\n // 在第一次运行时启动循环依赖检测\r\n if(options && options.first===true){\r\n observerObject._cycleDetector.start()\r\n }else{\r\n observerObject._cycleDetector.detect() \r\n }\r\n return await oldRun.apply(observerObject,options)\r\n }).bind(observerObject)\r\n }\r\n }\r\n store.log(\"cycleDetectExtend is already installed\")\r\n }\r\n } \r\n\r\n}\r\n\r\n\r\nexport function installCycleDetectExtend(options?:CycleDetectExtendOptions){\r\n // @ts-ignore\r\n if(!globalThis.__AUTOSTORE_EXTENDS__){\r\n // @ts-ignore\r\n globalThis.__AUTOSTORE_EXTENDS__=[]\r\n }\r\n // @ts-ignore\r\n globalThis.__AUTOSTORE_EXTENDS__.push(createCycleDetectExtend(options))\r\n \r\n}\r\n "]} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../src/utils.ts","../src/cycleDetectExtend.ts","../src/devTools.ts"],"names":["WeakObjectMap","key","value","weakRef","isPathEq","a","b","item","index","pathStartsWith","basePath","destPath","p","i","analysisCyclePath","steps","curPath","indexs","prev","cur","groups","v","results","group","j","group2","gKey","n","count","paths","k","AsyncCycleDetector","computedObject","options","event","onDetected","cycleCount","result","createCycleDetectExtend","store","onObserverCreated","observerObject","oldRun","installCycleDetectExtend","initialState","AutoStoreDevTools","payload","type","state","action","createStore","install"],"mappings":"wCACO,IAAMA,EAAN,KAAsC,CACjC,IACA,oBAAA,CAER,WAAA,EAAc,CACZ,IAAA,CAAK,GAAA,CAAM,IAAI,GAAA,CACf,IAAA,CAAK,qBAAuB,IAAI,oBAAA,CAAsBC,GAAQ,CAC5D,IAAA,CAAK,IAAI,MAAA,CAAOA,CAAG,EACrB,CAAC,EACH,CAEA,GAAA,CAAIA,CAAAA,CAAaC,EAAgB,CAC/B,IAAMC,EAAU,IAAI,OAAA,CAAQD,CAAK,CAAA,CACjC,IAAA,CAAK,IAAI,GAAA,CAAID,CAAAA,CAAKE,CAAO,CAAA,CACzB,IAAA,CAAK,qBAAqB,QAAA,CAASD,CAAAA,CAAOD,CAAG,EAC/C,CAEA,IAAIA,CAAAA,CAA4B,CAC9B,IAAME,CAAAA,CAAU,IAAA,CAAK,IAAI,GAAA,CAAIF,CAAG,EAChC,OAAOE,CAAAA,CAAUA,EAAQ,KAAA,EAAM,CAAI,MACrC,CAEA,MAAA,CAAOF,EAAsB,CAC3B,OAAO,KAAK,GAAA,CAAI,MAAA,CAAOA,CAAG,CAC5B,CAEA,IAAIA,CAAAA,CAAsB,CACxB,IAAME,CAAAA,CAAU,IAAA,CAAK,IAAI,GAAA,CAAIF,CAAG,EAChC,OAAOE,CAAAA,CAAUA,EAAQ,KAAA,EAAM,GAAM,OAAY,KACnD,CACJ,EASO,SAASC,CAAAA,CAASC,EAAuBC,CAAAA,CAA+B,CAG7E,OAFG,CAACD,CAAAA,EACD,CAACC,CAAAA,EACDD,CAAAA,CAAE,SAASC,CAAAA,CAAE,MAAA,CAAe,MACxBD,CAAAA,CAAE,KAAA,CAAM,CAACE,CAAAA,CAAKC,CAAAA,GAAQD,IAAOD,CAAAA,CAAEE,CAAK,CAAC,CAC9C,CAMO,SAASC,CAAAA,CAAeC,CAAAA,CAAkBC,EAAkB,CACjE,OAAGD,EAAS,MAAA,CAAOC,CAAAA,CAAS,OAAe,KAAA,CACpCD,CAAAA,CAAS,MAAM,CAACE,CAAAA,CAAEC,IACdD,CAAAA,GAAID,CAAAA,CAASE,CAAC,CACxB,CACH,CAEO,SAASC,CAAAA,CAAkBC,EAAeC,CAAAA,CAA4C,CAE3F,IAAMC,CAAAA,CAASF,CAAAA,CAAM,OAAO,CAACG,CAAAA,CAAKC,EAAIX,CAAAA,IAC/BW,CAAAA,GAAMH,GAASE,CAAAA,CAAK,IAAA,CAAKV,CAAK,CAAA,CAC1BU,CAAAA,CAAAA,CACT,EAAc,CAAA,CAEVE,EAASH,CAAAA,CAAO,GAAA,CAAI,CAACI,CAAAA,CAAER,CAAAA,GACtBA,EAAEI,CAAAA,CAAO,MAAA,CAAO,EACRF,CAAAA,CAAM,KAAA,CAAMM,EAAEJ,CAAAA,CAAOJ,CAAAA,CAAE,CAAC,CAAC,CAAA,CAEzBE,EAAM,KAAA,CAAMM,CAAC,CAE3B,CAAA,CAGKC,CAAAA,CAAU,IAAI,GAAA,CACpB,QAAQT,CAAAA,CAAE,CAAA,CAAEA,EAAEO,CAAAA,CAAO,MAAA,CAAOP,IAAI,CAC5B,IAAMU,EAAQH,CAAAA,CAAOP,CAAC,EACtB,GAAG,EAAAU,EAAM,MAAA,CAAO,CAAA,CAAA,CAChB,QAAQC,CAAAA,CAAEX,CAAAA,CAAE,EAAEW,CAAAA,CAAEJ,CAAAA,CAAO,OAAOI,CAAAA,EAAAA,CAAI,CAC9B,IAAMC,CAAAA,CAASL,CAAAA,CAAOI,CAAC,CAAA,CACvB,GAAGpB,EAASmB,CAAAA,CAAME,CAAM,GAAKhB,CAAAA,CAAec,CAAAA,CAAME,CAAM,CAAA,CAAE,CACtD,IAAMC,CAAAA,CAAOH,CAAAA,CAAM,KAAK,IAAI,CAAA,CACxBD,EAAQ,GAAA,CAAII,CAAI,GAChBJ,CAAAA,CAAQ,GAAA,CAAII,EAAK,CAAC,CAAA,CAEtB,IAAMC,CAAAA,CAAIL,CAAAA,CAAQ,IAAII,CAAI,CAAA,CAC1BJ,EAAQ,GAAA,CAAII,CAAAA,CAAKC,EAAE,CAAC,EACxB,CACJ,CACJ,CAEA,IAAIC,CAAAA,CAAQ,CAAA,CACRC,EACJ,OAAAP,CAAAA,CAAQ,QAAQ,CAACD,CAAAA,CAAES,IAAI,CAChBT,CAAAA,CAAE,GACFS,CAAAA,CAAE,MAAA,CAAOF,IACVC,CAAAA,CAAQC,CAAAA,CACRF,EAAQP,CAAAA,EAEd,CAAC,EACM,CAACQ,CAAAA,CAAMD,CAAK,CAErB,KC5DaG,CAAAA,CAAN,KAAwB,CAM3B,WAAA,CAAmBC,CAAAA,CAAmBC,EAA4B,CAA/C,IAAA,CAAA,cAAA,CAAAD,EACf,IAAA,CAAK,IAAA,CAAOA,EAAe,IAAA,CAAK,IAAA,CAAK,GAAG,CAAA,CACxC,IAAA,CAAK,MAAM,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA,CACzB,IAAA,CAAK,QAAU,MAAA,CAAO,MAAA,CAAO,CACzB,UAAA,CAAc,CAAA,CACd,aAAc,GAAA,CACd,MAAA,CAAO,EACX,CAAA,CAAEC,CAAO,EACb,CAbA,MAAiB,EAAC,CAClB,QAAkB,KAAA,CACV,QAAA,CACR,KACA,OAAA,CAaA,KAAA,EAAO,CACH,IAAA,CAAK,OAAA,CAAU,KACf,IAAA,CAAK,KAAA,CAAM,KAAK,IAAA,CAAK,IAAI,EACzB,IAAA,CAAK,QAAA,CAAW,KAAK,cAAA,CAAe,KAAA,CAAM,MAAOC,CAAAA,EAAY,CACtD,KAAK,KAAA,CAAM,MAAA,CAAO,KACjB,IAAA,CAAK,KAAA,CAAM,KAAKA,CAAAA,CAAM,IAAA,CAAK,KAAK,GAAG,CAAC,EAE5C,CAAA,CAAE,CAAC,SAAS,MAAM,CAAC,EACvB,CAkBQ,kBAAA,EAAoB,CACxB,GAAM,CAACL,CAAAA,CAAMD,CAAK,EAAId,CAAAA,CAAkB,IAAA,CAAK,MAAM,IAAA,CAAK,IAAI,EACtD,CAAE,UAAA,CAAAqB,EAAW,UAAA,CAAAC,CAAW,EAAI,IAAA,CAAK,OAAA,CACvC,GAAG,EAAAR,CAAAA,CAAMQ,KACT,IAAA,CAAK,cAAA,CAAe,MAAM,GAAA,CAAI,CAAA,yBAAA,EAA4B,KAAK,cAAA,CAAe,QAAA,EAAU,CAAA,GAAA,EAAMP,CAAK,GAAG,MAAM,CAAA,CACzG,OAAOM,CAAAA,EAAe,UAAA,CAAA,CAAW,CAChC,IAAME,CAAAA,CAASF,EAAWN,CAAAA,CAAM,IAAA,CAAK,cAAc,CAAA,CACnD,GAAGQ,IAAS,QAAA,CACR,OACE,GAAGA,CAAAA,GAAS,SAAA,CACd,KAAK,cAAA,CAAe,MAAA,CAAS,WAE7B,MAAM,IAAI,MAAM,CAAA,sBAAA,EAAyB,IAAA,CAAK,eAAe,QAAA,EAAU,MAAMR,CAAK,CAAA,CAAE,CAE5F,CACJ,CACA,QAAQ,CACJ,GAAG,KAAK,KAAA,CAAM,MAAA,CAAO,KAAK,OAAA,CAAQ,YAAA,CAAa,CAC3C,IAAA,CAAK,QAAA,CAAS,KAAI,CAClB,GAAG,CACC,IAAA,CAAK,kBAAA,GACT,CAAA,OAAC,CACG,KAAK,KAAA,CAAM,GACf,CACJ,CACJ,CACJ,EAGA,SAASS,EAAwBL,CAAAA,CAAkC,CAC/D,OAAO,SAA2BM,CAAAA,CAAU,CACxC,GAAM,CAAE,kBAAAC,CAAkB,CAAA,CAAID,EAAM,OAAA,CACjC,OAAOC,GAAsB,UAAA,CAE5BD,CAAAA,CAAM,IAAI,CAAA,MAAA,EAASA,CAAAA,CAAM,EAAE,CAAA,wEAAA,CAAA,CAA2E,MAAM,GAE5GA,CAAAA,CAAM,OAAA,CAAQ,kBAAqBE,CAAAA,EAAqB,CAEpD,GAAGA,CAAAA,CAAe,IAAA,GAAO,YAAcA,CAAAA,CAAe,KAAA,CAAM,CACxDA,CAAAA,CAAe,cAAA,CAAiB,IAAIV,CAAAA,CAAmBU,CAAAA,CAAeR,CAAO,CAAA,CAC7E,IAAMS,EAASD,CAAAA,CAAe,GAAA,CAE9BA,EAAe,GAAA,CAAA,CAAO,eAAeR,EAAY,CAE7C,OAAGA,GAAWA,CAAAA,CAAQ,KAAA,GAAQ,KAC1BQ,CAAAA,CAAe,cAAA,CAAe,OAAM,CAEpCA,CAAAA,CAAe,eAAe,MAAA,EAAO,CAElC,MAAMC,CAAAA,CAAO,KAAA,CAAMD,EAAeR,CAAO,CACpD,GAAG,IAAA,CAAKQ,CAAc,EAC1B,CACJ,CAAA,CACAF,EAAM,GAAA,CAAI,wCAAwC,GAE1D,CAEJ,CAGO,SAASI,CAAAA,CAAyBV,CAAAA,CAAkC,CAEnE,UAAA,CAAW,qBAAA,GAEX,UAAA,CAAW,qBAAA,CAAsB,EAAC,CAAA,CAGtC,UAAA,CAAW,sBAAsB,IAAA,CAAKK,CAAAA,CAAwBL,CAAO,CAAC,EAE1E,CCrIA,IAAMW,EAAe,EAErB,CAGaC,EAAN,KAAuB,CAClB,WACA,UAAA,CAAqB,KAAA,CAC7B,OAAS,IAAI7C,CAAAA,CACb,aAAa,CACT,IAAA,CAAK,UACT,CACA,IAAIuC,CAAAA,CAAU,CACV,KAAK,MAAA,CAAO,GAAA,CAAIA,EAAM,EAAA,CAAGA,CAAK,EAC9BA,CAAAA,CAAM,QAAA,CAAS,MAAM,CAACO,CAAAA,CAAYC,IAAW,CACtCD,CAAAA,CAAQ,OAAO,KAAA,EAClB,IAAA,CAAK,WAAW,QAAA,CAAS,CACrB,KAAK,CAAA,EAAGA,CAAAA,CAAQ,IAAI,CAAA,CAAA,EAAIC,CAAI,GAC5B,KAAA,CAAAR,CAAAA,CACA,QAAAO,CACJ,CAAC,EACL,CAAC,CAAA,CACD,KAAK,UAAA,CAAW,QAAA,CAAS,CACrB,IAAA,CAAK,eAAA,CACL,MAAAP,CACJ,CAAC,EACL,CACA,MAAA,CAAOA,EAAU,CACT,IAAA,CAAK,OAAO,GAAA,CAAIA,CAAAA,CAAM,EAAE,CAAA,EACxB,IAAA,CAAK,OAAO,MAAA,CAAOA,CAAAA,CAAM,EAAE,EAEnC,CACQ,QAAQS,CAAAA,CAAeJ,CAAAA,CAAcK,EAAW,CACpD,OAAGA,EAAO,IAAA,CAAK,UAAA,CAAW,IAAI,CAAA,CAAUD,CAAAA,CACrCC,EAAO,IAAA,GAAO,eAAA,CACN,CACH,GAAGD,CAAAA,CACH,CAAC,CAAA,UAAA,EAAaC,CAAAA,CAAO,MAAM,EAAE,CAAA,CAAA,CAAG,EAAE,CAAC,GAAGA,EAAO,KAAA,CAAM,OAAA,EAAS,CAChE,CAAA,CAEO,CACH,GAAGD,CAAAA,CACH,CAAC,CAAA,UAAA,EAAaC,CAAAA,CAAO,MAAM,EAAE,CAAA,CAAA,CAAG,EAAE,CAAC,GAAGA,EAAO,KAAA,CAAM,OAAA,EAAS,CAChE,CAER,CACQ,OAAA,EAAS,CACV,KAAK,UAAA,GACR,IAAA,CAAK,WAAaC,wBAAAA,CACd,IAAA,CAAK,QAEL,MAAA,CAAO,4BAAA,EAAgC,OAAO,4BAAA,EAClD,EACA,IAAA,CAAK,UAAA,CAAa,KAClB,OAAA,CAAQ,IAAA,CAAK,2EAA2E,YAAA,CAAa,EAAE,GAC3G,CACJ,EAEO,SAASC,CAAAA,EAAS,CAEjB,WAAW,sBAAA,GAAwB,UAAA,CAAW,uBAAyB,IAAIN,CAAAA,EACnF,CAQAM,CAAAA,EAAQ","file":"index.js","sourcesContent":["\nexport class WeakObjectMap<T extends object> {\n private map: Map<string, WeakRef<T>>;\n private finalizationRegistry: FinalizationRegistry<string>;\n \n constructor() {\n this.map = new Map();\n this.finalizationRegistry = new FinalizationRegistry((key) => {\n this.map.delete(key);\n });\n }\n \n set(key: string, value: T): void {\n const weakRef = new WeakRef(value);\n this.map.set(key, weakRef);\n this.finalizationRegistry.register(value, key);\n }\n \n get(key: string): T | undefined {\n const weakRef = this.map.get(key);\n return weakRef ? weakRef.deref() : undefined;\n }\n \n delete(key: string): boolean {\n return this.map.delete(key);\n }\n \n has(key: string): boolean {\n const weakRef = this.map.get(key);\n return weakRef ? weakRef.deref() !== undefined : false;\n }\n}\n/**\n * 判定两个值是否相等\n * \n * 如果两个值都是对象,则判断两个对象是否相等\n * 如果两个值都是数组,则判断两个数组的值是否相等\n * \n */\n\nexport function isPathEq(a:string[] | undefined,b:string[] | undefined):boolean{\n if(!a) return false\n if(!b) return false\n if(a.length!==b.length) return false\n return a.every((item,index)=>item===b[index])\n}\n/**\n * 判断一个路径destPath是否包含另一个路径basePath判断\n * @param basePath \n * @param destPath \n */\nexport function pathStartsWith(basePath:string[],destPath:string[]){\n if(basePath.length>destPath.length) return false\n return basePath.every((p,i)=>{\n return p===destPath[i]\n })\n}\n\nexport function analysisCyclePath(steps:string[],curPath:string):[string | undefined,number] {\n // 使用curPath将steps分割为多个数组\n const indexs = steps.reduce((prev,cur,index)=>{\n if(cur===curPath) prev.push(index) \n return prev\n },[] as number[])\n\n const groups = indexs.map((v,i)=>{\n if(i<indexs.length-1){\n return steps.slice(v,indexs[i+1])\n }else{\n return steps.slice(v)\n } \n })\n\n // 找到groups相同的分组\n const results = new Map<string,number>()\n for(let i=0;i<groups.length;i++){\n const group = groups[i]\n if(group.length<2) continue\n for(let j=i+1;j<groups.length;j++){\n const group2 = groups[j]\n if(isPathEq(group,group2) || pathStartsWith(group,group2)){\n const gKey = group.join('->')\n if(!results.has(gKey)){\n results.set(gKey,1)\n }\n const n = results.get(gKey)! \n results.set(gKey,n+1)\n }\n }\n }\n // 找到results里面路径最长的\n let count = 0\n let paths = undefined\n results.forEach((v,k)=>{\n if(v<3) return\n if(k.length>count){\n paths = k\n count = v \n }\n }) \n return [paths,count]\n\n}\n","/**\n * \n * import { installCycleDetectExtend } from \"@autostore/devtools\"\n * \n * installCycleDetectExtend({....})\n * \n * \n */\nimport { analysisCyclePath } from \"./utils\"\n\n\nexport type CycleDetectExtendOptions = { \n /**\n * 当检测到多少个循环时视为循环依赖 \n */\n cycleCount?:number\n /**\n * \n * 当检测时间操作数量达到此值时,停止检测\n * \n */\n maxOpereates?:number\n /**\n * 指定仅作用于指定的store\n * =[]代表所有store均生效\n */\n stores?:string[]\n /**\n * \n */\n onDetected?:(paths:string[],computedObject:any)=>'ignore'|'throw'|'disable' \n\n}\n\n/**\n * \n * - 在异步计算第一次执行时调用\n * cycleDetector.start()\n * \n * \n * \n */\nexport class AsyncCycleDetector{\n steps:string[] = []\n running:boolean = false \n private _watcher:any\n path:string\n options: Record<string,any>\n constructor(public computedObject:any,options?:Record<string,any>){\n this.path = computedObject.path.join('.')\n this.steps.push(this.path)\n this.options = Object.assign({\n cycleCount : 8,\n maxOpereates: 200,\n stores:[]\n },options)\n } \n /**\n * 本方法应该在异步函数第一次运行时调用\n */\n start(){\n this.running = true\n this.steps.push(this.path)\n this._watcher = this.computedObject.store.watch((event:any)=>{\n if(this.steps.length<500){\n this.steps.push(event.path.join('.'))\n }\n },{operates:'read'}) \n }\n /**\n * \n * 开始检测是否存在循环依赖\n * \n * \n * [\"a\",'d','c','b','a','d','c','b','a']\n * \n * \n * 编写一个函数,检测是否存在循环依赖\n * \n * 逻辑如下:\n * \n * 对this.steps里面是否存在连续的相同的路径,如果存在,则表示存在循环依赖\n * \n * \n * @returns \n */\n private analysisCycleSteps(){\n const [paths,count] = analysisCyclePath(this.steps,this.path)\n const { onDetected,cycleCount } = this.options\n if(count<cycleCount) return\n this.computedObject.store.log(`CycleDepend detected in <${this.computedObject.toString()}>: ${paths}`,'warn')\n if(typeof(onDetected )==='function'){\n const result = onDetected(paths,this.computedObject)\n if(result==='ignore'){\n return\n }else if(result==='disable') {\n this.computedObject.enable = false\n }else{\n throw new Error(`CycleDepend found in <${this.computedObject.toString()}>: ${paths}`)\n }\n } \n } \n detect(){\n if(this.steps.length>this.options.maxOpereates){\n this._watcher.off()\n try{\n this.analysisCycleSteps()\n }finally{ \n this.steps=[]\n }\n }\n }\n}\n\n\nfunction createCycleDetectExtend(options?:CycleDetectExtendOptions){\n return function cycleDetectExtend(store:any){\n const { onObserverCreated } = store.options\n if(typeof(onObserverCreated) ==='function'){ \n // 当store的onObserverCreated选项已经配置时,cycleDetectExtend不能生效\n store.log(`Store<${store.id}> onObserverCreated is already configured, cycleDetectExtend is disabled`,\"warn\")\n }else{\n store.options.onObserverCreated = (observerObject:any)=>{\n // 只对异步计算属性进行循环依赖检测\n if(observerObject.type==='computed' && observerObject.async){\n observerObject._cycleDetector = new AsyncCycleDetector(observerObject,options)\n const oldRun = observerObject.run\n // 封装原始的run方法\n observerObject.run = (async function(options:any){\n // 在第一次运行时启动循环依赖检测\n if(options && options.first===true){\n observerObject._cycleDetector.start()\n }else{\n observerObject._cycleDetector.detect() \n }\n return await oldRun.apply(observerObject,options)\n }).bind(observerObject)\n }\n }\n store.log(\"cycleDetectExtend is already installed\")\n }\n } \n\n}\n\n\nexport function installCycleDetectExtend(options?:CycleDetectExtendOptions){\n // @ts-ignore\n if(!globalThis.__AUTOSTORE_EXTENDS__){\n // @ts-ignore\n globalThis.__AUTOSTORE_EXTENDS__=[]\n }\n // @ts-ignore\n globalThis.__AUTOSTORE_EXTENDS__.push(createCycleDetectExtend(options))\n \n}\n ","/**\n * \n * 基于开发工具\n * \n * Redux DevTools 是一个实用工具,用于开发和调试 Redux 应用程序。\n * AutoStore是基于Redux DevTools 的简单包装,可以让开发者使用Redux DevTools\n * 来查看AutoStore的状态变化 \n * \n * import { createStore } from \"@autostorejs/react\"\n * import { install } from \"@autostorejs/devtools\"\n * \n * \n * const store = createStore({})\n * \n * install()\n * \n */\n\n//@ts-ignore\nimport { legacy_createStore as createStore } from \"redux\"\nimport { WeakObjectMap } from \"./utils\"\n \nconst initialState = {\n \n}\n\n\nexport class AutoStoreDevTools{\n private reduxStore:any\n private _installed:boolean = false\n stores = new WeakObjectMap()\n constructor(){\n this.install()\n }\n add(store:any){ \n this.stores.set(store.id,store)\n store.operates.onAny((payload:any,type:any)=>{ \n if(payload.type==='get') return \n this.reduxStore.dispatch({\n type:`${payload.type}@${type}`,\n store,\n payload \n })\n })\n this.reduxStore.dispatch({\n type:\"__ADD_STORE__\",\n store\n })\n }\n remove(store:any){ \n if( this.stores.has(store.id)){\n this.stores.delete(store.id)\n }\n }\n private reducer(state:object = initialState, action:any){\n if(action.type.startsWith(\"@@\")) return state\n if(action.type==='__ADD_STORE__') {\n return {\n ...state,\n [`AutoStore<${action.store.id}>`]:{...action.store.getSnap()}\n }\n }else{\n return {\n ...state,\n [`AutoStore<${action.store.id}>`]:{...action.store.getSnap()}\n }\n } \n }\n private install(){\n if(this._installed) return \n this.reduxStore = createStore(\n this.reducer,\n // @ts-ignore\n window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()\n ); \n this._installed = true\n console.info('%c AutoStoreDevTools installed. Please open <Redux devtools> to view. %c',\"color:red;\",'')\n }\n}\n\nexport function install(){\n // @ts-ignore\n if(!globalThis.__AUTOSTORE_DEVTOOLS__) globalThis.__AUTOSTORE_DEVTOOLS__ = new AutoStoreDevTools() \n} \n\ndeclare global{\n // @ts-ignore\n var __AUTOSTORE_DEVTOOLS__ : AutoStoreDevTools\n}\n\n\ninstall()\n\n"]} | ||
| {"version":3,"sources":["../src/utils.ts","../src/cycleDetectExtend.ts","../src/devTools.ts"],"names":["WeakObjectMap","key","value","weakRef","isPathEq","a","b","item","index","pathStartsWith","basePath","destPath","p","i","analysisCyclePath","steps","curPath","indexs","prev","cur","groups","v","results","group","j","group2","gKey","n","count","paths","k","AsyncCycleDetector","computedObject","options","event","onDetected","cycleCount","result","createCycleDetectExtend","store","onObserverCreated","observerObject","oldRun","installCycleDetectExtend","initialState","AutoStoreDevTools","payload","type","state","action","createStore","install"],"mappings":"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","file":"index.js","sourcesContent":["\r\nexport class WeakObjectMap<T extends object> {\r\n private map: Map<string, WeakRef<T>>;\r\n private finalizationRegistry: FinalizationRegistry<string>;\r\n \r\n constructor() {\r\n this.map = new Map();\r\n this.finalizationRegistry = new FinalizationRegistry((key) => {\r\n this.map.delete(key);\r\n });\r\n }\r\n \r\n set(key: string, value: T): void {\r\n const weakRef = new WeakRef(value);\r\n this.map.set(key, weakRef);\r\n this.finalizationRegistry.register(value, key);\r\n }\r\n \r\n get(key: string): T | undefined {\r\n const weakRef = this.map.get(key);\r\n return weakRef ? weakRef.deref() : undefined;\r\n }\r\n \r\n delete(key: string): boolean {\r\n return this.map.delete(key);\r\n }\r\n \r\n has(key: string): boolean {\r\n const weakRef = this.map.get(key);\r\n return weakRef ? weakRef.deref() !== undefined : false;\r\n }\r\n}\r\n/**\r\n * 判定两个值是否相等\r\n * \r\n * 如果两个值都是对象,则判断两个对象是否相等\r\n * 如果两个值都是数组,则判断两个数组的值是否相等\r\n * \r\n */\r\n\r\nexport function isPathEq(a:string[] | undefined,b:string[] | undefined):boolean{\r\n if(!a) return false\r\n if(!b) return false\r\n if(a.length!==b.length) return false\r\n return a.every((item,index)=>item===b[index])\r\n}\r\n/**\r\n * 判断一个路径destPath是否包含另一个路径basePath判断\r\n * @param basePath \r\n * @param destPath \r\n */\r\nexport function pathStartsWith(basePath:string[],destPath:string[]){\r\n if(basePath.length>destPath.length) return false\r\n return basePath.every((p,i)=>{\r\n return p===destPath[i]\r\n })\r\n}\r\n\r\nexport function analysisCyclePath(steps:string[],curPath:string):[string | undefined,number] {\r\n // 使用curPath将steps分割为多个数组\r\n const indexs = steps.reduce((prev,cur,index)=>{\r\n if(cur===curPath) prev.push(index) \r\n return prev\r\n },[] as number[])\r\n\r\n const groups = indexs.map((v,i)=>{\r\n if(i<indexs.length-1){\r\n return steps.slice(v,indexs[i+1])\r\n }else{\r\n return steps.slice(v)\r\n } \r\n })\r\n\r\n // 找到groups相同的分组\r\n const results = new Map<string,number>()\r\n for(let i=0;i<groups.length;i++){\r\n const group = groups[i]\r\n if(group.length<2) continue\r\n for(let j=i+1;j<groups.length;j++){\r\n const group2 = groups[j]\r\n if(isPathEq(group,group2) || pathStartsWith(group,group2)){\r\n const gKey = group.join('->')\r\n if(!results.has(gKey)){\r\n results.set(gKey,1)\r\n }\r\n const n = results.get(gKey)! \r\n results.set(gKey,n+1)\r\n }\r\n }\r\n }\r\n // 找到results里面路径最长的\r\n let count = 0\r\n let paths = undefined\r\n results.forEach((v,k)=>{\r\n if(v<3) return\r\n if(k.length>count){\r\n paths = k\r\n count = v \r\n }\r\n }) \r\n return [paths,count]\r\n\r\n}\r\n","/**\r\n * \r\n * import { installCycleDetectExtend } from \"@autostore/devtools\"\r\n * \r\n * installCycleDetectExtend({....})\r\n * \r\n * \r\n */\r\nimport { analysisCyclePath } from \"./utils\"\r\n\r\n\r\nexport type CycleDetectExtendOptions = { \r\n /**\r\n * 当检测到多少个循环时视为循环依赖 \r\n */\r\n cycleCount?:number\r\n /**\r\n * \r\n * 当检测时间操作数量达到此值时,停止检测\r\n * \r\n */\r\n maxOpereates?:number\r\n /**\r\n * 指定仅作用于指定的store\r\n * =[]代表所有store均生效\r\n */\r\n stores?:string[]\r\n /**\r\n * \r\n */\r\n onDetected?:(paths:string[],computedObject:any)=>'ignore'|'throw'|'disable' \r\n\r\n}\r\n\r\n/**\r\n * \r\n * - 在异步计算第一次执行时调用\r\n * cycleDetector.start()\r\n * \r\n * \r\n * \r\n */\r\nexport class AsyncCycleDetector{\r\n steps:string[] = []\r\n running:boolean = false \r\n private _watcher:any\r\n path:string\r\n options: Record<string,any>\r\n constructor(public computedObject:any,options?:Record<string,any>){\r\n this.path = computedObject.path.join('.')\r\n this.steps.push(this.path)\r\n this.options = Object.assign({\r\n cycleCount : 8,\r\n maxOpereates: 200,\r\n stores:[]\r\n },options)\r\n } \r\n /**\r\n * 本方法应该在异步函数第一次运行时调用\r\n */\r\n start(){\r\n this.running = true\r\n this.steps.push(this.path)\r\n this._watcher = this.computedObject.store.watch((event:any)=>{\r\n if(this.steps.length<500){\r\n this.steps.push(event.path.join('.'))\r\n }\r\n },{operates:'read'}) \r\n }\r\n /**\r\n * \r\n * 开始检测是否存在循环依赖\r\n * \r\n * \r\n * [\"a\",'d','c','b','a','d','c','b','a']\r\n * \r\n * \r\n * 编写一个函数,检测是否存在循环依赖\r\n * \r\n * 逻辑如下:\r\n * \r\n * 对this.steps里面是否存在连续的相同的路径,如果存在,则表示存在循环依赖\r\n * \r\n * \r\n * @returns \r\n */\r\n private analysisCycleSteps(){\r\n const [paths,count] = analysisCyclePath(this.steps,this.path)\r\n const { onDetected,cycleCount } = this.options\r\n if(count<cycleCount) return\r\n this.computedObject.store.log(`CycleDepend detected in <${this.computedObject.toString()}>: ${paths}`,'warn')\r\n if(typeof(onDetected )==='function'){\r\n const result = onDetected(paths,this.computedObject)\r\n if(result==='ignore'){\r\n return\r\n }else if(result==='disable') {\r\n this.computedObject.enable = false\r\n }else{\r\n throw new Error(`CycleDepend found in <${this.computedObject.toString()}>: ${paths}`)\r\n }\r\n } \r\n } \r\n detect(){\r\n if(this.steps.length>this.options.maxOpereates){\r\n this._watcher.off()\r\n try{\r\n this.analysisCycleSteps()\r\n }finally{ \r\n this.steps=[]\r\n }\r\n }\r\n }\r\n}\r\n\r\n\r\nfunction createCycleDetectExtend(options?:CycleDetectExtendOptions){\r\n return function cycleDetectExtend(store:any){\r\n const { onObserverCreated } = store.options\r\n if(typeof(onObserverCreated) ==='function'){ \r\n // 当store的onObserverCreated选项已经配置时,cycleDetectExtend不能生效\r\n store.log(`Store<${store.id}> onObserverCreated is already configured, cycleDetectExtend is disabled`,\"warn\")\r\n }else{\r\n store.options.onObserverCreated = (observerObject:any)=>{\r\n // 只对异步计算属性进行循环依赖检测\r\n if(observerObject.type==='computed' && observerObject.async){\r\n observerObject._cycleDetector = new AsyncCycleDetector(observerObject,options)\r\n const oldRun = observerObject.run\r\n // 封装原始的run方法\r\n observerObject.run = (async function(options:any){\r\n // 在第一次运行时启动循环依赖检测\r\n if(options && options.first===true){\r\n observerObject._cycleDetector.start()\r\n }else{\r\n observerObject._cycleDetector.detect() \r\n }\r\n return await oldRun.apply(observerObject,options)\r\n }).bind(observerObject)\r\n }\r\n }\r\n store.log(\"cycleDetectExtend is already installed\")\r\n }\r\n } \r\n\r\n}\r\n\r\n\r\nexport function installCycleDetectExtend(options?:CycleDetectExtendOptions){\r\n // @ts-ignore\r\n if(!globalThis.__AUTOSTORE_EXTENDS__){\r\n // @ts-ignore\r\n globalThis.__AUTOSTORE_EXTENDS__=[]\r\n }\r\n // @ts-ignore\r\n globalThis.__AUTOSTORE_EXTENDS__.push(createCycleDetectExtend(options))\r\n \r\n}\r\n ","/**\r\n * \r\n * 基于开发工具\r\n * \r\n * Redux DevTools 是一个实用工具,用于开发和调试 Redux 应用程序。\r\n * AutoStore是基于Redux DevTools 的简单包装,可以让开发者使用Redux DevTools\r\n * 来查看AutoStore的状态变化 \r\n * \r\n * import { createStore } from \"@autostorejs/react\"\r\n * import { install } from \"@autostorejs/devtools\"\r\n * \r\n * \r\n * const store = createStore({})\r\n * \r\n * install()\r\n * \r\n */\r\n\r\n//@ts-ignore\r\nimport { legacy_createStore as createStore } from \"redux\"\r\nimport { WeakObjectMap } from \"./utils\"\r\n \r\nconst initialState = {\r\n \r\n}\r\n\r\n\r\nexport class AutoStoreDevTools{\r\n private reduxStore:any\r\n private _installed:boolean = false\r\n stores = new WeakObjectMap()\r\n constructor(){\r\n this.install()\r\n }\r\n add(store:any){ \r\n this.stores.set(store.id,store)\r\n store.operates.onAny((payload:any,type:any)=>{ \r\n if(payload.type==='get') return \r\n this.reduxStore.dispatch({\r\n type:`${payload.type}@${type}`,\r\n store,\r\n payload \r\n })\r\n })\r\n this.reduxStore.dispatch({\r\n type:\"__ADD_STORE__\",\r\n store\r\n })\r\n }\r\n remove(store:any){ \r\n if( this.stores.has(store.id)){\r\n this.stores.delete(store.id)\r\n }\r\n }\r\n private reducer(state:object = initialState, action:any){\r\n if(action.type.startsWith(\"@@\")) return state\r\n if(action.type==='__ADD_STORE__') {\r\n return {\r\n ...state,\r\n [`AutoStore<${action.store.id}>`]:{...action.store.getSnap()}\r\n }\r\n }else{\r\n return {\r\n ...state,\r\n [`AutoStore<${action.store.id}>`]:{...action.store.getSnap()}\r\n }\r\n } \r\n }\r\n private install(){\r\n if(this._installed) return \r\n this.reduxStore = createStore(\r\n this.reducer,\r\n // @ts-ignore\r\n window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()\r\n ); \r\n this._installed = true\r\n console.info('%c AutoStoreDevTools installed. Please open <Redux devtools> to view. %c',\"color:red;\",'')\r\n }\r\n}\r\n\r\nexport function install(){\r\n // @ts-ignore\r\n if(!globalThis.__AUTOSTORE_DEVTOOLS__) globalThis.__AUTOSTORE_DEVTOOLS__ = new AutoStoreDevTools() \r\n} \r\n\r\ndeclare global{\r\n // @ts-ignore\r\n var __AUTOSTORE_DEVTOOLS__ : AutoStoreDevTools\r\n}\r\n\r\n\r\ninstall()\r\n\r\n"]} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../src/utils.ts","../src/cycleDetectExtend.ts","../src/devTools.ts"],"names":["WeakObjectMap","key","value","weakRef","isPathEq","a","b","item","index","pathStartsWith","basePath","destPath","p","i","analysisCyclePath","steps","curPath","indexs","prev","cur","groups","v","results","group","j","group2","gKey","n","count","paths","k","AsyncCycleDetector","computedObject","options","event","onDetected","cycleCount","result","createCycleDetectExtend","store","onObserverCreated","observerObject","oldRun","installCycleDetectExtend","initialState","AutoStoreDevTools","payload","type","state","action","createStore","install"],"mappings":"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","file":"index.mjs","sourcesContent":["\nexport class WeakObjectMap<T extends object> {\n private map: Map<string, WeakRef<T>>;\n private finalizationRegistry: FinalizationRegistry<string>;\n \n constructor() {\n this.map = new Map();\n this.finalizationRegistry = new FinalizationRegistry((key) => {\n this.map.delete(key);\n });\n }\n \n set(key: string, value: T): void {\n const weakRef = new WeakRef(value);\n this.map.set(key, weakRef);\n this.finalizationRegistry.register(value, key);\n }\n \n get(key: string): T | undefined {\n const weakRef = this.map.get(key);\n return weakRef ? weakRef.deref() : undefined;\n }\n \n delete(key: string): boolean {\n return this.map.delete(key);\n }\n \n has(key: string): boolean {\n const weakRef = this.map.get(key);\n return weakRef ? weakRef.deref() !== undefined : false;\n }\n}\n/**\n * 判定两个值是否相等\n * \n * 如果两个值都是对象,则判断两个对象是否相等\n * 如果两个值都是数组,则判断两个数组的值是否相等\n * \n */\n\nexport function isPathEq(a:string[] | undefined,b:string[] | undefined):boolean{\n if(!a) return false\n if(!b) return false\n if(a.length!==b.length) return false\n return a.every((item,index)=>item===b[index])\n}\n/**\n * 判断一个路径destPath是否包含另一个路径basePath判断\n * @param basePath \n * @param destPath \n */\nexport function pathStartsWith(basePath:string[],destPath:string[]){\n if(basePath.length>destPath.length) return false\n return basePath.every((p,i)=>{\n return p===destPath[i]\n })\n}\n\nexport function analysisCyclePath(steps:string[],curPath:string):[string | undefined,number] {\n // 使用curPath将steps分割为多个数组\n const indexs = steps.reduce((prev,cur,index)=>{\n if(cur===curPath) prev.push(index) \n return prev\n },[] as number[])\n\n const groups = indexs.map((v,i)=>{\n if(i<indexs.length-1){\n return steps.slice(v,indexs[i+1])\n }else{\n return steps.slice(v)\n } \n })\n\n // 找到groups相同的分组\n const results = new Map<string,number>()\n for(let i=0;i<groups.length;i++){\n const group = groups[i]\n if(group.length<2) continue\n for(let j=i+1;j<groups.length;j++){\n const group2 = groups[j]\n if(isPathEq(group,group2) || pathStartsWith(group,group2)){\n const gKey = group.join('->')\n if(!results.has(gKey)){\n results.set(gKey,1)\n }\n const n = results.get(gKey)! \n results.set(gKey,n+1)\n }\n }\n }\n // 找到results里面路径最长的\n let count = 0\n let paths = undefined\n results.forEach((v,k)=>{\n if(v<3) return\n if(k.length>count){\n paths = k\n count = v \n }\n }) \n return [paths,count]\n\n}\n","/**\n * \n * import { installCycleDetectExtend } from \"@autostore/devtools\"\n * \n * installCycleDetectExtend({....})\n * \n * \n */\nimport { analysisCyclePath } from \"./utils\"\n\n\nexport type CycleDetectExtendOptions = { \n /**\n * 当检测到多少个循环时视为循环依赖 \n */\n cycleCount?:number\n /**\n * \n * 当检测时间操作数量达到此值时,停止检测\n * \n */\n maxOpereates?:number\n /**\n * 指定仅作用于指定的store\n * =[]代表所有store均生效\n */\n stores?:string[]\n /**\n * \n */\n onDetected?:(paths:string[],computedObject:any)=>'ignore'|'throw'|'disable' \n\n}\n\n/**\n * \n * - 在异步计算第一次执行时调用\n * cycleDetector.start()\n * \n * \n * \n */\nexport class AsyncCycleDetector{\n steps:string[] = []\n running:boolean = false \n private _watcher:any\n path:string\n options: Record<string,any>\n constructor(public computedObject:any,options?:Record<string,any>){\n this.path = computedObject.path.join('.')\n this.steps.push(this.path)\n this.options = Object.assign({\n cycleCount : 8,\n maxOpereates: 200,\n stores:[]\n },options)\n } \n /**\n * 本方法应该在异步函数第一次运行时调用\n */\n start(){\n this.running = true\n this.steps.push(this.path)\n this._watcher = this.computedObject.store.watch((event:any)=>{\n if(this.steps.length<500){\n this.steps.push(event.path.join('.'))\n }\n },{operates:'read'}) \n }\n /**\n * \n * 开始检测是否存在循环依赖\n * \n * \n * [\"a\",'d','c','b','a','d','c','b','a']\n * \n * \n * 编写一个函数,检测是否存在循环依赖\n * \n * 逻辑如下:\n * \n * 对this.steps里面是否存在连续的相同的路径,如果存在,则表示存在循环依赖\n * \n * \n * @returns \n */\n private analysisCycleSteps(){\n const [paths,count] = analysisCyclePath(this.steps,this.path)\n const { onDetected,cycleCount } = this.options\n if(count<cycleCount) return\n this.computedObject.store.log(`CycleDepend detected in <${this.computedObject.toString()}>: ${paths}`,'warn')\n if(typeof(onDetected )==='function'){\n const result = onDetected(paths,this.computedObject)\n if(result==='ignore'){\n return\n }else if(result==='disable') {\n this.computedObject.enable = false\n }else{\n throw new Error(`CycleDepend found in <${this.computedObject.toString()}>: ${paths}`)\n }\n } \n } \n detect(){\n if(this.steps.length>this.options.maxOpereates){\n this._watcher.off()\n try{\n this.analysisCycleSteps()\n }finally{ \n this.steps=[]\n }\n }\n }\n}\n\n\nfunction createCycleDetectExtend(options?:CycleDetectExtendOptions){\n return function cycleDetectExtend(store:any){\n const { onObserverCreated } = store.options\n if(typeof(onObserverCreated) ==='function'){ \n // 当store的onObserverCreated选项已经配置时,cycleDetectExtend不能生效\n store.log(`Store<${store.id}> onObserverCreated is already configured, cycleDetectExtend is disabled`,\"warn\")\n }else{\n store.options.onObserverCreated = (observerObject:any)=>{\n // 只对异步计算属性进行循环依赖检测\n if(observerObject.type==='computed' && observerObject.async){\n observerObject._cycleDetector = new AsyncCycleDetector(observerObject,options)\n const oldRun = observerObject.run\n // 封装原始的run方法\n observerObject.run = (async function(options:any){\n // 在第一次运行时启动循环依赖检测\n if(options && options.first===true){\n observerObject._cycleDetector.start()\n }else{\n observerObject._cycleDetector.detect() \n }\n return await oldRun.apply(observerObject,options)\n }).bind(observerObject)\n }\n }\n store.log(\"cycleDetectExtend is already installed\")\n }\n } \n\n}\n\n\nexport function installCycleDetectExtend(options?:CycleDetectExtendOptions){\n // @ts-ignore\n if(!globalThis.__AUTOSTORE_EXTENDS__){\n // @ts-ignore\n globalThis.__AUTOSTORE_EXTENDS__=[]\n }\n // @ts-ignore\n globalThis.__AUTOSTORE_EXTENDS__.push(createCycleDetectExtend(options))\n \n}\n ","/**\n * \n * 基于开发工具\n * \n * Redux DevTools 是一个实用工具,用于开发和调试 Redux 应用程序。\n * AutoStore是基于Redux DevTools 的简单包装,可以让开发者使用Redux DevTools\n * 来查看AutoStore的状态变化 \n * \n * import { createStore } from \"@autostorejs/react\"\n * import { install } from \"@autostorejs/devtools\"\n * \n * \n * const store = createStore({})\n * \n * install()\n * \n */\n\n//@ts-ignore\nimport { legacy_createStore as createStore } from \"redux\"\nimport { WeakObjectMap } from \"./utils\"\n \nconst initialState = {\n \n}\n\n\nexport class AutoStoreDevTools{\n private reduxStore:any\n private _installed:boolean = false\n stores = new WeakObjectMap()\n constructor(){\n this.install()\n }\n add(store:any){ \n this.stores.set(store.id,store)\n store.operates.onAny((payload:any,type:any)=>{ \n if(payload.type==='get') return \n this.reduxStore.dispatch({\n type:`${payload.type}@${type}`,\n store,\n payload \n })\n })\n this.reduxStore.dispatch({\n type:\"__ADD_STORE__\",\n store\n })\n }\n remove(store:any){ \n if( this.stores.has(store.id)){\n this.stores.delete(store.id)\n }\n }\n private reducer(state:object = initialState, action:any){\n if(action.type.startsWith(\"@@\")) return state\n if(action.type==='__ADD_STORE__') {\n return {\n ...state,\n [`AutoStore<${action.store.id}>`]:{...action.store.getSnap()}\n }\n }else{\n return {\n ...state,\n [`AutoStore<${action.store.id}>`]:{...action.store.getSnap()}\n }\n } \n }\n private install(){\n if(this._installed) return \n this.reduxStore = createStore(\n this.reducer,\n // @ts-ignore\n window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()\n ); \n this._installed = true\n console.info('%c AutoStoreDevTools installed. Please open <Redux devtools> to view. %c',\"color:red;\",'')\n }\n}\n\nexport function install(){\n // @ts-ignore\n if(!globalThis.__AUTOSTORE_DEVTOOLS__) globalThis.__AUTOSTORE_DEVTOOLS__ = new AutoStoreDevTools() \n} \n\ndeclare global{\n // @ts-ignore\n var __AUTOSTORE_DEVTOOLS__ : AutoStoreDevTools\n}\n\n\ninstall()\n\n"]} | ||
| {"version":3,"sources":["../src/utils.ts","../src/cycleDetectExtend.ts","../src/devTools.ts"],"names":["WeakObjectMap","key","value","weakRef","isPathEq","a","b","item","index","pathStartsWith","basePath","destPath","p","i","analysisCyclePath","steps","curPath","indexs","prev","cur","groups","v","results","group","j","group2","gKey","n","count","paths","k","AsyncCycleDetector","computedObject","options","event","onDetected","cycleCount","result","createCycleDetectExtend","store","onObserverCreated","observerObject","oldRun","installCycleDetectExtend","initialState","AutoStoreDevTools","payload","type","state","action","createStore","install"],"mappings":"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","file":"index.mjs","sourcesContent":["\r\nexport class WeakObjectMap<T extends object> {\r\n private map: Map<string, WeakRef<T>>;\r\n private finalizationRegistry: FinalizationRegistry<string>;\r\n \r\n constructor() {\r\n this.map = new Map();\r\n this.finalizationRegistry = new FinalizationRegistry((key) => {\r\n this.map.delete(key);\r\n });\r\n }\r\n \r\n set(key: string, value: T): void {\r\n const weakRef = new WeakRef(value);\r\n this.map.set(key, weakRef);\r\n this.finalizationRegistry.register(value, key);\r\n }\r\n \r\n get(key: string): T | undefined {\r\n const weakRef = this.map.get(key);\r\n return weakRef ? weakRef.deref() : undefined;\r\n }\r\n \r\n delete(key: string): boolean {\r\n return this.map.delete(key);\r\n }\r\n \r\n has(key: string): boolean {\r\n const weakRef = this.map.get(key);\r\n return weakRef ? weakRef.deref() !== undefined : false;\r\n }\r\n}\r\n/**\r\n * 判定两个值是否相等\r\n * \r\n * 如果两个值都是对象,则判断两个对象是否相等\r\n * 如果两个值都是数组,则判断两个数组的值是否相等\r\n * \r\n */\r\n\r\nexport function isPathEq(a:string[] | undefined,b:string[] | undefined):boolean{\r\n if(!a) return false\r\n if(!b) return false\r\n if(a.length!==b.length) return false\r\n return a.every((item,index)=>item===b[index])\r\n}\r\n/**\r\n * 判断一个路径destPath是否包含另一个路径basePath判断\r\n * @param basePath \r\n * @param destPath \r\n */\r\nexport function pathStartsWith(basePath:string[],destPath:string[]){\r\n if(basePath.length>destPath.length) return false\r\n return basePath.every((p,i)=>{\r\n return p===destPath[i]\r\n })\r\n}\r\n\r\nexport function analysisCyclePath(steps:string[],curPath:string):[string | undefined,number] {\r\n // 使用curPath将steps分割为多个数组\r\n const indexs = steps.reduce((prev,cur,index)=>{\r\n if(cur===curPath) prev.push(index) \r\n return prev\r\n },[] as number[])\r\n\r\n const groups = indexs.map((v,i)=>{\r\n if(i<indexs.length-1){\r\n return steps.slice(v,indexs[i+1])\r\n }else{\r\n return steps.slice(v)\r\n } \r\n })\r\n\r\n // 找到groups相同的分组\r\n const results = new Map<string,number>()\r\n for(let i=0;i<groups.length;i++){\r\n const group = groups[i]\r\n if(group.length<2) continue\r\n for(let j=i+1;j<groups.length;j++){\r\n const group2 = groups[j]\r\n if(isPathEq(group,group2) || pathStartsWith(group,group2)){\r\n const gKey = group.join('->')\r\n if(!results.has(gKey)){\r\n results.set(gKey,1)\r\n }\r\n const n = results.get(gKey)! \r\n results.set(gKey,n+1)\r\n }\r\n }\r\n }\r\n // 找到results里面路径最长的\r\n let count = 0\r\n let paths = undefined\r\n results.forEach((v,k)=>{\r\n if(v<3) return\r\n if(k.length>count){\r\n paths = k\r\n count = v \r\n }\r\n }) \r\n return [paths,count]\r\n\r\n}\r\n","/**\r\n * \r\n * import { installCycleDetectExtend } from \"@autostore/devtools\"\r\n * \r\n * installCycleDetectExtend({....})\r\n * \r\n * \r\n */\r\nimport { analysisCyclePath } from \"./utils\"\r\n\r\n\r\nexport type CycleDetectExtendOptions = { \r\n /**\r\n * 当检测到多少个循环时视为循环依赖 \r\n */\r\n cycleCount?:number\r\n /**\r\n * \r\n * 当检测时间操作数量达到此值时,停止检测\r\n * \r\n */\r\n maxOpereates?:number\r\n /**\r\n * 指定仅作用于指定的store\r\n * =[]代表所有store均生效\r\n */\r\n stores?:string[]\r\n /**\r\n * \r\n */\r\n onDetected?:(paths:string[],computedObject:any)=>'ignore'|'throw'|'disable' \r\n\r\n}\r\n\r\n/**\r\n * \r\n * - 在异步计算第一次执行时调用\r\n * cycleDetector.start()\r\n * \r\n * \r\n * \r\n */\r\nexport class AsyncCycleDetector{\r\n steps:string[] = []\r\n running:boolean = false \r\n private _watcher:any\r\n path:string\r\n options: Record<string,any>\r\n constructor(public computedObject:any,options?:Record<string,any>){\r\n this.path = computedObject.path.join('.')\r\n this.steps.push(this.path)\r\n this.options = Object.assign({\r\n cycleCount : 8,\r\n maxOpereates: 200,\r\n stores:[]\r\n },options)\r\n } \r\n /**\r\n * 本方法应该在异步函数第一次运行时调用\r\n */\r\n start(){\r\n this.running = true\r\n this.steps.push(this.path)\r\n this._watcher = this.computedObject.store.watch((event:any)=>{\r\n if(this.steps.length<500){\r\n this.steps.push(event.path.join('.'))\r\n }\r\n },{operates:'read'}) \r\n }\r\n /**\r\n * \r\n * 开始检测是否存在循环依赖\r\n * \r\n * \r\n * [\"a\",'d','c','b','a','d','c','b','a']\r\n * \r\n * \r\n * 编写一个函数,检测是否存在循环依赖\r\n * \r\n * 逻辑如下:\r\n * \r\n * 对this.steps里面是否存在连续的相同的路径,如果存在,则表示存在循环依赖\r\n * \r\n * \r\n * @returns \r\n */\r\n private analysisCycleSteps(){\r\n const [paths,count] = analysisCyclePath(this.steps,this.path)\r\n const { onDetected,cycleCount } = this.options\r\n if(count<cycleCount) return\r\n this.computedObject.store.log(`CycleDepend detected in <${this.computedObject.toString()}>: ${paths}`,'warn')\r\n if(typeof(onDetected )==='function'){\r\n const result = onDetected(paths,this.computedObject)\r\n if(result==='ignore'){\r\n return\r\n }else if(result==='disable') {\r\n this.computedObject.enable = false\r\n }else{\r\n throw new Error(`CycleDepend found in <${this.computedObject.toString()}>: ${paths}`)\r\n }\r\n } \r\n } \r\n detect(){\r\n if(this.steps.length>this.options.maxOpereates){\r\n this._watcher.off()\r\n try{\r\n this.analysisCycleSteps()\r\n }finally{ \r\n this.steps=[]\r\n }\r\n }\r\n }\r\n}\r\n\r\n\r\nfunction createCycleDetectExtend(options?:CycleDetectExtendOptions){\r\n return function cycleDetectExtend(store:any){\r\n const { onObserverCreated } = store.options\r\n if(typeof(onObserverCreated) ==='function'){ \r\n // 当store的onObserverCreated选项已经配置时,cycleDetectExtend不能生效\r\n store.log(`Store<${store.id}> onObserverCreated is already configured, cycleDetectExtend is disabled`,\"warn\")\r\n }else{\r\n store.options.onObserverCreated = (observerObject:any)=>{\r\n // 只对异步计算属性进行循环依赖检测\r\n if(observerObject.type==='computed' && observerObject.async){\r\n observerObject._cycleDetector = new AsyncCycleDetector(observerObject,options)\r\n const oldRun = observerObject.run\r\n // 封装原始的run方法\r\n observerObject.run = (async function(options:any){\r\n // 在第一次运行时启动循环依赖检测\r\n if(options && options.first===true){\r\n observerObject._cycleDetector.start()\r\n }else{\r\n observerObject._cycleDetector.detect() \r\n }\r\n return await oldRun.apply(observerObject,options)\r\n }).bind(observerObject)\r\n }\r\n }\r\n store.log(\"cycleDetectExtend is already installed\")\r\n }\r\n } \r\n\r\n}\r\n\r\n\r\nexport function installCycleDetectExtend(options?:CycleDetectExtendOptions){\r\n // @ts-ignore\r\n if(!globalThis.__AUTOSTORE_EXTENDS__){\r\n // @ts-ignore\r\n globalThis.__AUTOSTORE_EXTENDS__=[]\r\n }\r\n // @ts-ignore\r\n globalThis.__AUTOSTORE_EXTENDS__.push(createCycleDetectExtend(options))\r\n \r\n}\r\n ","/**\r\n * \r\n * 基于开发工具\r\n * \r\n * Redux DevTools 是一个实用工具,用于开发和调试 Redux 应用程序。\r\n * AutoStore是基于Redux DevTools 的简单包装,可以让开发者使用Redux DevTools\r\n * 来查看AutoStore的状态变化 \r\n * \r\n * import { createStore } from \"@autostorejs/react\"\r\n * import { install } from \"@autostorejs/devtools\"\r\n * \r\n * \r\n * const store = createStore({})\r\n * \r\n * install()\r\n * \r\n */\r\n\r\n//@ts-ignore\r\nimport { legacy_createStore as createStore } from \"redux\"\r\nimport { WeakObjectMap } from \"./utils\"\r\n \r\nconst initialState = {\r\n \r\n}\r\n\r\n\r\nexport class AutoStoreDevTools{\r\n private reduxStore:any\r\n private _installed:boolean = false\r\n stores = new WeakObjectMap()\r\n constructor(){\r\n this.install()\r\n }\r\n add(store:any){ \r\n this.stores.set(store.id,store)\r\n store.operates.onAny((payload:any,type:any)=>{ \r\n if(payload.type==='get') return \r\n this.reduxStore.dispatch({\r\n type:`${payload.type}@${type}`,\r\n store,\r\n payload \r\n })\r\n })\r\n this.reduxStore.dispatch({\r\n type:\"__ADD_STORE__\",\r\n store\r\n })\r\n }\r\n remove(store:any){ \r\n if( this.stores.has(store.id)){\r\n this.stores.delete(store.id)\r\n }\r\n }\r\n private reducer(state:object = initialState, action:any){\r\n if(action.type.startsWith(\"@@\")) return state\r\n if(action.type==='__ADD_STORE__') {\r\n return {\r\n ...state,\r\n [`AutoStore<${action.store.id}>`]:{...action.store.getSnap()}\r\n }\r\n }else{\r\n return {\r\n ...state,\r\n [`AutoStore<${action.store.id}>`]:{...action.store.getSnap()}\r\n }\r\n } \r\n }\r\n private install(){\r\n if(this._installed) return \r\n this.reduxStore = createStore(\r\n this.reducer,\r\n // @ts-ignore\r\n window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()\r\n ); \r\n this._installed = true\r\n console.info('%c AutoStoreDevTools installed. Please open <Redux devtools> to view. %c',\"color:red;\",'')\r\n }\r\n}\r\n\r\nexport function install(){\r\n // @ts-ignore\r\n if(!globalThis.__AUTOSTORE_DEVTOOLS__) globalThis.__AUTOSTORE_DEVTOOLS__ = new AutoStoreDevTools() \r\n} \r\n\r\ndeclare global{\r\n // @ts-ignore\r\n var __AUTOSTORE_DEVTOOLS__ : AutoStoreDevTools\r\n}\r\n\r\n\r\ninstall()\r\n\r\n"]} |
+1
-1
| { | ||
| "name": "@autostorejs/devtools", | ||
| "version": "2.0.6", | ||
| "version": "2.0.7", | ||
| "description": "devtools for autostore", | ||
@@ -5,0 +5,0 @@ "repository": { |
112947
2.82%