@autostorejs/devtools
Advanced tools
+21
-24
@@ -1,13 +0,10 @@ | ||
| > @autostorejs/devtools@2.0.4 build /home/runner/work/autostore/autostore/packages/devTools | ||
| > tsup | ||
| $ tsup | ||
| [34mCLI[39m Building entry: src/index.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 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 | ||
@@ -21,21 +18,21 @@ [34mCLI[39m Target: es2022 | ||
| [34mCJS[39m Build start | ||
| [32mCJS[39m [1mdist/cycleDetectExtend.js [22m[32m2.24 KB[39m | ||
| [32mCJS[39m [1mdist/cycleDetectExtend.js.map [22m[32m12.03 KB[39m | ||
| [32mCJS[39m ⚡️ Build success in 684ms | ||
| [32mESM[39m [1mdist/cycleDetectExtend.mjs [22m[32m2.22 KB[39m | ||
| [32mESM[39m [1mdist/cycleDetectExtend.mjs.map [22m[32m12.04 KB[39m | ||
| [32mESM[39m ⚡️ Build success in 684ms | ||
| [32mESM[39m [1mdist/index.mjs [22m[32m3.55 KB[39m | ||
| [32mESM[39m [1mdist/index.mjs.map [22m[32m16.10 KB[39m | ||
| [32mESM[39m ⚡️ Build success in 694ms | ||
| [32mCJS[39m [1mdist/index.js [22m[32m3.57 KB[39m | ||
| [32mCJS[39m [1mdist/index.js.map [22m[32m16.10 KB[39m | ||
| [32mCJS[39m ⚡️ Build success in 697ms | ||
| [32mESM[39m [1mdist\index.mjs [22m[32m3.55 KB[39m | ||
| [32mESM[39m [1mdist\index.mjs.map [22m[32m16.79 KB[39m | ||
| [32mESM[39m ⚡️ Build success in 930ms | ||
| [34mDTS[39m Build start | ||
| [34mDTS[39m Build start | ||
| [32mDTS[39m ⚡️ Build success in 2886ms | ||
| [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 2960ms | ||
| [32mDTS[39m [1mdist/cycleDetectExtend.d.mts [22m[32m1.20 KB[39m | ||
| [32mDTS[39m [1mdist/cycleDetectExtend.d.ts [22m[32m1.20 KB[39m | ||
| [32mESM[39m [1mdist\cycleDetectExtend.mjs [22m[32m2.22 KB[39m | ||
| [32mESM[39m [1mdist\cycleDetectExtend.mjs.map [22m[32m12.54 KB[39m | ||
| [32mESM[39m ⚡️ Build success in 1002ms | ||
| [32mCJS[39m [1mdist\cycleDetectExtend.js [22m[32m2.24 KB[39m | ||
| [32mCJS[39m [1mdist\cycleDetectExtend.js.map [22m[32m12.54 KB[39m | ||
| [32mCJS[39m ⚡️ Build success in 1004ms | ||
| [32mCJS[39m [1mdist\index.js [22m[32m3.57 KB[39m | ||
| [32mCJS[39m [1mdist\index.js.map [22m[32m16.78 KB[39m | ||
| [32mCJS[39m ⚡️ Build success in 1014ms | ||
| [32mDTS[39m ⚡️ Build success in 5267ms | ||
| [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 5388ms | ||
| [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.5 | ||
| ### Patch Changes | ||
| - 3257305: fix errors | ||
| ## 2.0.4 | ||
@@ -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,oBAER,CAAA,WAAA,EAAc,CACZ,IAAK,CAAA,GAAA,CAAM,IAAI,GACf,CAAA,IAAA,CAAK,qBAAuB,IAAI,oBAAA,CAAsBC,GAAQ,CAC5D,IAAA,CAAK,IAAI,MAAOA,CAAAA,CAAG,EACrB,CAAC,EACH,CAEA,GAAIA,CAAAA,CAAAA,CAAaC,EAAgB,CAC/B,IAAMC,EAAU,IAAI,OAAA,CAAQD,CAAK,CACjC,CAAA,IAAA,CAAK,IAAI,GAAID,CAAAA,CAAAA,CAAKE,CAAO,CACzB,CAAA,IAAA,CAAK,qBAAqB,QAASD,CAAAA,CAAAA,CAAOD,CAAG,EAC/C,CAEA,IAAIA,CAA4B,CAAA,CAC9B,IAAME,CAAU,CAAA,IAAA,CAAK,IAAI,GAAIF,CAAAA,CAAG,EAChC,OAAOE,CAAAA,CAAUA,EAAQ,KAAM,EAAA,CAAI,MACrC,CAEA,MAAA,CAAOF,EAAsB,CAC3B,OAAO,KAAK,GAAI,CAAA,MAAA,CAAOA,CAAG,CAC5B,CAEA,IAAIA,CAAsB,CAAA,CACxB,IAAME,CAAU,CAAA,IAAA,CAAK,IAAI,GAAIF,CAAAA,CAAG,EAChC,OAAOE,CAAAA,CAAUA,EAAQ,KAAM,EAAA,GAAM,OAAY,KACnD,CACJ,EASO,SAASC,CAAAA,CAASC,EAAuBC,CAA+B,CAAA,CAG7E,OAFG,CAACD,CAAAA,EACD,CAACC,CACDD,EAAAA,CAAAA,CAAE,SAASC,CAAE,CAAA,MAAA,CAAe,MACxBD,CAAE,CAAA,KAAA,CAAM,CAACE,CAAKC,CAAAA,CAAAA,GAAQD,IAAOD,CAAEE,CAAAA,CAAK,CAAC,CAC9C,CAMO,SAASC,CAAeC,CAAAA,CAAAA,CAAkBC,EAAkB,CACjE,OAAGD,EAAS,MAAOC,CAAAA,CAAAA,CAAS,OAAe,KACpCD,CAAAA,CAAAA,CAAS,MAAM,CAACE,CAAAA,CAAEC,IACdD,CAAID,GAAAA,CAAAA,CAASE,CAAC,CACxB,CACH,CAEO,SAASC,CAAAA,CAAkBC,EAAeC,CAA4C,CAAA,CAE3F,IAAMC,CAASF,CAAAA,CAAAA,CAAM,OAAO,CAACG,CAAAA,CAAKC,EAAIX,CAC/BW,IAAAA,CAAAA,GAAMH,GAASE,CAAK,CAAA,IAAA,CAAKV,CAAK,CAC1BU,CAAAA,CAAAA,CAAAA,CACT,EAAc,CAAA,CAEVE,EAASH,CAAO,CAAA,GAAA,CAAI,CAACI,CAAER,CAAAA,CAAAA,GACtBA,EAAEI,CAAO,CAAA,MAAA,CAAO,EACRF,CAAM,CAAA,KAAA,CAAMM,EAAEJ,CAAOJ,CAAAA,CAAAA,CAAE,CAAC,CAAC,CAAA,CAEzBE,EAAM,KAAMM,CAAAA,CAAC,CAE3B,CAGKC,CAAAA,CAAAA,CAAU,IAAI,GAAA,CACpB,QAAQT,CAAE,CAAA,CAAA,CAAEA,EAAEO,CAAO,CAAA,MAAA,CAAOP,IAAI,CAC5B,IAAMU,EAAQH,CAAOP,CAAAA,CAAC,EACtB,GAAG,EAAAU,EAAM,MAAO,CAAA,CAAA,CAAA,CAChB,QAAQC,CAAEX,CAAAA,CAAAA,CAAE,EAAEW,CAAEJ,CAAAA,CAAAA,CAAO,OAAOI,CAAI,EAAA,CAAA,CAC9B,IAAMC,CAASL,CAAAA,CAAAA,CAAOI,CAAC,CACvB,CAAA,GAAGpB,EAASmB,CAAME,CAAAA,CAAM,GAAKhB,CAAec,CAAAA,CAAAA,CAAME,CAAM,CAAE,CAAA,CACtD,IAAMC,CAAOH,CAAAA,CAAAA,CAAM,KAAK,IAAI,CAAA,CACxBD,EAAQ,GAAII,CAAAA,CAAI,GAChBJ,CAAQ,CAAA,GAAA,CAAII,EAAK,CAAC,CAAA,CAEtB,IAAMC,CAAIL,CAAAA,CAAAA,CAAQ,IAAII,CAAI,CAAA,CAC1BJ,EAAQ,GAAII,CAAAA,CAAAA,CAAKC,EAAE,CAAC,EACxB,CACJ,CACJ,CAEA,IAAIC,CAAQ,CAAA,CAAA,CACRC,EACJ,OAAAP,CAAAA,CAAQ,QAAQ,CAACD,CAAAA,CAAES,IAAI,CAChBT,CAAAA,CAAE,GACFS,CAAE,CAAA,MAAA,CAAOF,IACVC,CAAQC,CAAAA,CAAAA,CACRF,EAAQP,CAEd,EAAA,CAAC,EACM,CAACQ,CAAAA,CAAMD,CAAK,CAErB,KC5DaG,CAAN,CAAA,KAAwB,CAM3B,WAAmBC,CAAAA,CAAAA,CAAmBC,EAA4B,CAA/C,IAAA,CAAA,cAAA,CAAAD,EACf,IAAK,CAAA,IAAA,CAAOA,EAAe,IAAK,CAAA,IAAA,CAAK,GAAG,CACxC,CAAA,IAAA,CAAK,MAAM,IAAK,CAAA,IAAA,CAAK,IAAI,CACzB,CAAA,IAAA,CAAK,QAAU,MAAO,CAAA,MAAA,CAAO,CACzB,UAAc,CAAA,CAAA,CACd,aAAc,GACd,CAAA,MAAA,CAAO,EACX,CAAA,CAAEC,CAAO,EACb,CAbA,MAAiB,EAAC,CAClB,QAAkB,KACV,CAAA,QAAA,CACR,KACA,OAaA,CAAA,KAAA,EAAO,CACH,IAAK,CAAA,OAAA,CAAU,KACf,IAAK,CAAA,KAAA,CAAM,KAAK,IAAK,CAAA,IAAI,EACzB,IAAK,CAAA,QAAA,CAAW,KAAK,cAAe,CAAA,KAAA,CAAM,MAAOC,CAAY,EAAA,CACtD,KAAK,KAAM,CAAA,MAAA,CAAO,KACjB,IAAK,CAAA,KAAA,CAAM,KAAKA,CAAM,CAAA,IAAA,CAAK,KAAK,GAAG,CAAC,EAE5C,CAAE,CAAA,CAAC,SAAS,MAAM,CAAC,EACvB,CAkBQ,kBAAA,EAAoB,CACxB,GAAM,CAACL,CAAMD,CAAAA,CAAK,EAAId,CAAkB,CAAA,IAAA,CAAK,MAAM,IAAK,CAAA,IAAI,EACtD,CAAE,UAAA,CAAAqB,EAAW,UAAAC,CAAAA,CAAW,EAAI,IAAK,CAAA,OAAA,CACvC,GAAG,EAAAR,CAAAA,CAAMQ,KACT,IAAK,CAAA,cAAA,CAAe,MAAM,GAAI,CAAA,CAAA,yBAAA,EAA4B,KAAK,cAAe,CAAA,QAAA,EAAU,CAAMP,GAAAA,EAAAA,CAAK,GAAG,MAAM,CAAA,CACzG,OAAOM,CAAe,EAAA,UAAA,CAAA,CAAW,CAChC,IAAME,CAAAA,CAASF,EAAWN,CAAM,CAAA,IAAA,CAAK,cAAc,CACnD,CAAA,GAAGQ,IAAS,QACR,CAAA,OACE,GAAGA,CAAS,GAAA,SAAA,CACd,KAAK,cAAe,CAAA,MAAA,CAAS,WAEvB,MAAA,IAAI,MAAM,CAAyB,sBAAA,EAAA,IAAA,CAAK,eAAe,QAAS,EAAC,MAAMR,CAAK,CAAA,CAAE,CAE5F,CACJ,CACA,QAAQ,CACJ,GAAG,KAAK,KAAM,CAAA,MAAA,CAAO,KAAK,OAAQ,CAAA,YAAA,CAAa,CAC3C,IAAK,CAAA,QAAA,CAAS,KACd,CAAA,GAAG,CACC,IAAK,CAAA,kBAAA,GACT,CAAC,OAAA,CACG,KAAK,KAAM,CAAA,GACf,CACJ,CACJ,CACJ,EAGA,SAASS,EAAwBL,CAAkC,CAAA,CAC/D,OAAO,SAA2BM,CAAAA,CAAU,CACxC,GAAM,CAAE,kBAAAC,CAAkB,CAAA,CAAID,EAAM,OACjC,CAAA,OAAOC,GAAsB,UAE5BD,CAAAA,CAAAA,CAAM,IAAI,CAASA,MAAAA,EAAAA,CAAAA,CAAM,EAAE,CAA2E,wEAAA,CAAA,CAAA,MAAM,GAE5GA,CAAM,CAAA,OAAA,CAAQ,kBAAqBE,CAAqB,EAAA,CAEpD,GAAGA,CAAe,CAAA,IAAA,GAAO,YAAcA,CAAe,CAAA,KAAA,CAAM,CACxDA,CAAe,CAAA,cAAA,CAAiB,IAAIV,CAAmBU,CAAAA,CAAAA,CAAeR,CAAO,CAC7E,CAAA,IAAMS,EAASD,CAAe,CAAA,GAAA,CAE9BA,EAAe,GAAO,CAAA,eAAeR,EAAY,CAE7C,OAAGA,GAAWA,CAAQ,CAAA,KAAA,GAAQ,KAC1BQ,CAAe,CAAA,cAAA,CAAe,OAE9BA,CAAAA,CAAAA,CAAe,eAAe,MAAO,EAAA,CAElC,MAAMC,CAAO,CAAA,KAAA,CAAMD,EAAeR,CAAO,CACpD,EAAG,IAAKQ,CAAAA,CAAc,EAC1B,CACJ,CAAA,CACAF,EAAM,GAAI,CAAA,wCAAwC,GAE1D,CAEJ,CAGO,SAASI,CAAyBV,CAAAA,CAAAA,CAAkC,CAEnE,UAAW,CAAA,qBAAA,GAEX,UAAW,CAAA,qBAAA,CAAsB,EAGrC,CAAA,CAAA,UAAA,CAAW,sBAAsB,IAAKK,CAAAA,CAAAA,CAAwBL,CAAO,CAAC,EAE1E,CCrIA,IAAMW,EAAe,EAErB,CAGaC,EAAN,KAAuB,CAClB,WACA,UAAqB,CAAA,KAAA,CAC7B,OAAS,IAAI7C,CAAAA,CACb,aAAa,CACT,IAAA,CAAK,UACT,CACA,IAAIuC,CAAU,CAAA,CACV,KAAK,MAAO,CAAA,GAAA,CAAIA,EAAM,EAAGA,CAAAA,CAAK,EAC9BA,CAAM,CAAA,QAAA,CAAS,MAAM,CAACO,CAAAA,CAAYC,IAAW,CACtCD,CAAAA,CAAQ,OAAO,KAClB,EAAA,IAAA,CAAK,WAAW,QAAS,CAAA,CACrB,KAAK,CAAGA,EAAAA,CAAAA,CAAQ,IAAI,CAAIC,CAAAA,EAAAA,CAAI,GAC5B,KAAAR,CAAAA,CAAAA,CACA,QAAAO,CACJ,CAAC,EACL,CAAC,CAAA,CACD,KAAK,UAAW,CAAA,QAAA,CAAS,CACrB,IAAK,CAAA,eAAA,CACL,MAAAP,CACJ,CAAC,EACL,CACA,MAAA,CAAOA,EAAU,CACT,IAAA,CAAK,OAAO,GAAIA,CAAAA,CAAAA,CAAM,EAAE,CACxB,EAAA,IAAA,CAAK,OAAO,MAAOA,CAAAA,CAAAA,CAAM,EAAE,EAEnC,CACQ,QAAQS,CAAeJ,CAAAA,CAAAA,CAAcK,EAAW,CACpD,OAAGA,EAAO,IAAK,CAAA,UAAA,CAAW,IAAI,CAAUD,CAAAA,CAAAA,CACrCC,EAAO,IAAO,GAAA,eAAA,CACN,CACH,GAAGD,CAAAA,CACH,CAAC,CAAaC,UAAAA,EAAAA,CAAAA,CAAO,MAAM,EAAE,CAAA,CAAA,CAAG,EAAE,CAAC,GAAGA,EAAO,KAAM,CAAA,OAAA,EAAS,CAChE,CAAA,CAEO,CACH,GAAGD,CAAAA,CACH,CAAC,CAAaC,UAAAA,EAAAA,CAAAA,CAAO,MAAM,EAAE,CAAA,CAAA,CAAG,EAAE,CAAC,GAAGA,EAAO,KAAM,CAAA,OAAA,EAAS,CAChE,CAER,CACQ,OAAS,EAAA,CACV,KAAK,UACR,GAAA,IAAA,CAAK,WAAaC,wBACd,CAAA,IAAA,CAAK,QAEL,MAAO,CAAA,4BAAA,EAAgC,OAAO,4BAA6B,EAC/E,EACA,IAAK,CAAA,UAAA,CAAa,KAClB,OAAQ,CAAA,IAAA,CAAK,2EAA2E,YAAa,CAAA,EAAE,GAC3G,CACJ,EAEO,SAASC,CAAS,EAAA,CAEjB,WAAW,sBAAwB,GAAA,UAAA,CAAW,uBAAyB,IAAIN,CAAAA,EACnF,CAQAM,CAAQ,EAAA","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"]} |
+20
-14
| { | ||
| "name": "@autostorejs/devtools", | ||
| "version": "2.0.4", | ||
| "version": "2.0.5", | ||
| "description": "devtools for autostore", | ||
@@ -10,12 +10,21 @@ "repository": { | ||
| "exports": { | ||
| ".": { | ||
| "import": "./dist/index.mjs", | ||
| "require": "./dist/index.js" | ||
| }, | ||
| "./cycleDetect": { | ||
| "import": "./dist/cycleDetect.mjs", | ||
| "require": "./dist/cycleDetect.js" | ||
| ".": "./src/index.ts", | ||
| "./cycleDetect": "./src/cycleDetect.ts" | ||
| }, | ||
| "main": "src/index.ts", | ||
| "publishConfig": { | ||
| "exports": { | ||
| ".": { | ||
| "import": "./dist/index.mjs", | ||
| "require": "./dist/index.js" | ||
| }, | ||
| "./cycleDetect": { | ||
| "import": "./dist/cycleDetect.mjs", | ||
| "require": "./dist/cycleDetect.js" | ||
| } | ||
| } | ||
| }, | ||
| "main": "src/index.ts", | ||
| "scripts": { | ||
| "build": "tsup" | ||
| }, | ||
| "keywords": [], | ||
@@ -28,8 +37,5 @@ "author": "", | ||
| "devDependencies": { | ||
| "@types/node": "^22.7.4", | ||
| "@types/node": "^24.5.2", | ||
| "tsup": "^8.5.0" | ||
| }, | ||
| "scripts": { | ||
| "build": "tsup" | ||
| } | ||
| } | ||
| } |
-21
| MIT License | ||
| Copyright (c) 2024 fisher | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. |
Mixed license
LicensePackage contains multiple licenses.
111653
1.83%0
-100%21
-4.55%