From c36440c34ec4ffe1234b7b841073d33e1a812021 Mon Sep 17 00:00:00 2001 From: unadlib Date: Mon, 16 Dec 2024 00:31:38 +0800 Subject: [PATCH 01/20] docs(readme): update --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fc025de..574b69e 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ An efficient and flexible state management library for building high-performance Modern web applications are becoming increasingly complex, pushing the boundaries of what's possible in the browser. Single-threaded JavaScript, while powerful, often struggles to keep up with the demands of sophisticated UIs, real-time interactions, and data-intensive computations. This bottleneck leads to performance issues, laggy or unresponsive interfaces, limitations in request connections, and ultimately, a compromised user experience. -While Web Workers offer a path towards parallelism and improved performance, they introduce a new set of challenges. Managing state across threads, synchronizing data efficiently, and maintaining coherent application logic can quickly become a daunting task. Existing state management solutions often fall short in addressing these specific needs, either by being too tightly coupled to the worker thread or by introducing complex abstractions that hinder developer productivity. +While Web Workers (or SharedWorker) offer a path towards parallelism and improved performance, they introduce a new set of challenges. Managing state across threads, synchronizing data efficiently, and maintaining coherent application logic can quickly become a daunting task. Existing state management solutions often fall short in addressing these specific needs, either by being too tightly coupled to the worker thread or by introducing complex abstractions that hinder developer productivity. ![Coaction Concept](./coaction-concept.svg) @@ -92,7 +92,7 @@ TBD ## Installation -You can install the library for React application via npm, yarn, or pnpm. +You can install `@coaction/react` for React application via npm, yarn, or pnpm. ```bash npm install @coaction/react @@ -102,7 +102,7 @@ yarn add @coaction/react pnpm add @coaction/react ``` -If you want to use the core library without any framework, you can install it via npm, yarn, or pnpm. +If you want to use the core library without any framework, you can install `coaction` via npm, yarn, or pnpm. ```bash npm install coaction @@ -224,7 +224,7 @@ Coaction is designed to be compatible with a wide range of libraries and framewo ## Middlewares -- [ ] logger +- [x] logger - [ ] persist - [ ] undoRedo From 07d20eca154aa3870865396f94a3d5535adda936 Mon Sep 17 00:00:00 2001 From: unadlib Date: Mon, 16 Dec 2024 00:34:10 +0800 Subject: [PATCH 02/20] docs(readme): update --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 574b69e..0bd3179 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,11 @@ import { create } from '@coaction/react'; const counter = (set) => ({ count: 0, - // derived data + // derived data without cache + get tripleCount() { + return this.count * 3; + }, + // derived data with cache doubleCount: get( (state) => [state.counter.count], (count) => count * 2 From 2d7b44ddee6803d59ba3e5ee9c8e79e9068682eb Mon Sep 17 00:00:00 2001 From: unadlib Date: Mon, 16 Dec 2024 19:51:43 +0800 Subject: [PATCH 03/20] docs(readme): update --- README.md | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 0bd3179..df5f4a7 100644 --- a/README.md +++ b/README.md @@ -209,28 +209,35 @@ Coaction is designed to be compatible with a wide range of libraries and framewo ### Supported Libraries and Frameworks -- [x] React -- [ ] Vue -- [ ] Angular -- [ ] Svelte -- [ ] Solid +| Framework | Package | Status | +| --------- | ---------------- | ------- | +| React | @coaction/react | ✅Done | +| Vue | @coaction/vue | Ongoing | +| Angular | @coaction/ng | | +| Svelte | @coaction/svelte | | +| Solid | @coaction/solid | | +| Yjs | @coaction/yjs | | ### State Management Libraries -- [x] MobX -- [x] Pinia -- [ ] Zustand -- [ ] Redux Toolkit -- [ ] Jotai -- [ ] XState -- [ ] Valtio -- [ ] alien-signals +| State Management | Package | Status | +| ---------------- | ----------------- | ------- | +| MobX | @coaction/mobx | ✅ Done | +| Pinia | @coaction/pinia | ✅ Done | +| Zustand | @coaction/zustand | Ongoing | +| Redux Toolkit | @coaction/redux | | +| Jotai | @coaction/jotai | | +| XState | @coaction/xstate | | +| Valtio | @coaction/valtio | | +| alien-signals | @coaction/alien | | ## Middlewares -- [x] logger -- [ ] persist -- [ ] undoRedo +| Feature | Package | Status | +| --------- | ----------------- | ------- | +| Logger | @coaction/logger | ✅ Done | +| Persist | @coaction/persist | | +| Undo/Redo | @coaction/history | | ## Difference between Coaction and Zustand From 6943c98c33a47dfd851b9c507746afb6534a20b7 Mon Sep 17 00:00:00 2001 From: unadlib Date: Mon, 16 Dec 2024 21:17:55 +0800 Subject: [PATCH 04/20] docs(readme): update --- README.md | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index df5f4a7..0e51fc0 100644 --- a/README.md +++ b/README.md @@ -95,21 +95,13 @@ TBD You can install `@coaction/react` for React application via npm, yarn, or pnpm. ```bash -npm install @coaction/react -# or -yarn add @coaction/react -# or -pnpm add @coaction/react +npm install coaction @coaction/react ``` If you want to use the core library without any framework, you can install `coaction` via npm, yarn, or pnpm. ```bash npm install coaction -# or -yarn add coaction -# or -pnpm add coaction ``` ## Usage @@ -211,7 +203,7 @@ Coaction is designed to be compatible with a wide range of libraries and framewo | Framework | Package | Status | | --------- | ---------------- | ------- | -| React | @coaction/react | ✅Done | +| React | @coaction/react | ✅ Done | | Vue | @coaction/vue | Ongoing | | Angular | @coaction/ng | | | Svelte | @coaction/svelte | | @@ -229,15 +221,15 @@ Coaction is designed to be compatible with a wide range of libraries and framewo | Jotai | @coaction/jotai | | | XState | @coaction/xstate | | | Valtio | @coaction/valtio | | -| alien-signals | @coaction/alien | | +| alien-signals | @coaction/alien | Ongoing | ## Middlewares | Feature | Package | Status | | --------- | ----------------- | ------- | | Logger | @coaction/logger | ✅ Done | -| Persist | @coaction/persist | | -| Undo/Redo | @coaction/history | | +| Persist | @coaction/persist | Ongoing | +| Undo/Redo | @coaction/history | Ongoing | ## Difference between Coaction and Zustand From 2cbc5bffcb963cf37ced85bc6eaa5343cb9cfc8e Mon Sep 17 00:00:00 2001 From: unadlib Date: Mon, 16 Dec 2024 22:58:20 +0800 Subject: [PATCH 05/20] docs(readme): update benchmark --- README.md | 51 ++- benchmark.jpg | Bin 0 -> 55453 bytes package.json | 6 +- .../test/benchmark/coaction-mobx.ts | 112 ++++++ .../coaction-mobx/test/benchmark/coaction.ts | 119 +++++++ .../coaction-mobx/test/benchmark/index.ts | 329 ++++++++++++++++++ .../test/benchmark/mobx-keystone.ts | 123 +++++++ packages/coaction-mobx/test/benchmark/mobx.ts | 100 ++++++ .../test/branchmark/coaction-mobx.ts | 109 ------ .../coaction-mobx/test/branchmark/coaction.ts | 116 ------ .../test/branchmark/mobx-keystone.ts | 120 ------- .../coaction-mobx/test/branchmark/mobx.ts | 97 ------ yarn.lock | 57 ++- 13 files changed, 883 insertions(+), 456 deletions(-) create mode 100644 benchmark.jpg create mode 100644 packages/coaction-mobx/test/benchmark/coaction-mobx.ts create mode 100644 packages/coaction-mobx/test/benchmark/coaction.ts create mode 100644 packages/coaction-mobx/test/benchmark/index.ts create mode 100644 packages/coaction-mobx/test/benchmark/mobx-keystone.ts create mode 100644 packages/coaction-mobx/test/benchmark/mobx.ts delete mode 100644 packages/coaction-mobx/test/branchmark/coaction-mobx.ts delete mode 100644 packages/coaction-mobx/test/branchmark/coaction.ts delete mode 100644 packages/coaction-mobx/test/branchmark/mobx-keystone.ts delete mode 100644 packages/coaction-mobx/test/branchmark/mobx.ts diff --git a/README.md b/README.md index 0e51fc0..0a8c044 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,36 @@ sequenceDiagram ## Performance -TBD +![Benchmark](benchmark.jpg) + +Measure(ops/sec) to update 10K arrays, bigger is better([view source](https://github.com/unadlib/mutative/blob/main/test/performance/benchmark.ts)). + +| Library | Test Name | Ops/sec | +| -------------- | ------------------------------- | ------- | +| @coaction/mobx | bigInitWithoutRefsWithoutAssign | 37.07 | +| mobx | bigInitWithoutRefsWithoutAssign | 37.50 | +| **coaction** | bigInitWithoutRefsWithoutAssign | 19,910 | +| mobx-keystone | bigInitWithoutRefsWithoutAssign | 7.88 | +| @coaction/mobx | bigInitWithoutRefsWithAssign | 1.53 | +| mobx | bigInitWithoutRefsWithAssign | 10.77 | +| **coaction** | bigInitWithoutRefsWithAssign | 3.01 | +| mobx-keystone | bigInitWithoutRefsWithAssign | 0.13 | +| @coaction/mobx | bigInitWithRefsWithoutAssign | 14.66 | +| mobx | bigInitWithRefsWithoutAssign | 16.11 | +| **coaction** | bigInitWithRefsWithoutAssign | 152 | +| mobx-keystone | bigInitWithRefsWithoutAssign | 2.44 | +| @coaction/mobx | bigInitWithRefsWithAssign | 0.98 | +| mobx | bigInitWithRefsWithAssign | 8.81 | +| **coaction** | bigInitWithRefsWithAssign | 3.83 | +| mobx-keystone | bigInitWithRefsWithAssign | 0.11 | +| @coaction/mobx | init | 37.34 | +| mobx | init | 42.98 | +| **coaction** | init | 3,524 | +| mobx-keystone | init | 40.48 | + +This table benchmarks various state management libraries on large initialization tasks. Coaction stands out dramatically, performing at least hundreds of times faster in certain scenarios. For example, in the “bigInitWithoutRefsWithoutAssign” test, Coaction achieves about 19,910 ops/sec compared to Mobx’s 37.5 ops/sec—over 500 times faster. Similarly, in the “init” test, Coaction reaches around 3,524 ops/sec versus Mobx’s 42.98 ops/sec—an increase of roughly 80 times. These results highlight Coaction’s exceptional efficiency in handling large-scale data initialization. + +> We will also provide more complete benchmarking. ## Installation @@ -233,16 +262,16 @@ Coaction is designed to be compatible with a wide range of libraries and framewo ## Difference between Coaction and Zustand -| Feature | Coaction | Zustand | -| --------------------------------- | -------- | ------- | -| Built-in multithreading | ✅ | ❌ | -| Support getter accessor | ✅ | ❌ | -| Built-in computed properties | ✅ | ❌ | -| Built-in namespace Slice | ✅ | ❌ | -| Built-in auto selector for state | ✅ | ❌ | -| Built-in multiple stores selector | ✅ | ❌ | -| Easy to implement middleware | ✅ | ❌ | -| Support `this` in getter/action | ✅ | ❌ | +| Feature | **coaction** | Zustand | +| --------------------------------- | ------------ | ------- | +| Built-in multithreading | ✅ | ❌ | +| Support getter accessor | ✅ | ❌ | +| Built-in computed properties | ✅ | ❌ | +| Built-in namespace Slice | ✅ | ❌ | +| Built-in auto selector for state | ✅ | ❌ | +| Built-in multiple stores selector | ✅ | ❌ | +| Easy to implement middleware | ✅ | ❌ | +| Support `this` in getter/action | ✅ | ❌ | ## Credits diff --git a/benchmark.jpg b/benchmark.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4cd6874043374a59bd0ae3ed88206e1c33eb7d4a GIT binary patch literal 55453 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 (https://github.com/unadlib)" @@ -68,12 +69,14 @@ "@preconstruct/cli": "^2.8.1", "@testing-library/jest-dom": "^6.1.4", "@testing-library/vue": "^6.6.1", + "@types/benchmark": "^2.1.5", "@types/jest": "^29.5.10", "@types/node": "^12.11.1", "@vue/compiler-sfc": "^3.0.11", "@vue/vue3-jest": "^29.2.6", "babel-jest": "^29.7.0", "babel-preset-solid": "^1.8.4", + "benchmark": "^2.1.4", "commitizen": "^4.3.0", "cz-conventional-changelog": "^3.3.0", "husky": "^3.1.0", @@ -85,6 +88,7 @@ "lerna": "^8.1.3", "lint-staged": "^8.2.1", "prettier": "^3.3.3", + "quickchart-js": "^3.1.3", "ts-node": "^10.9.2", "tslib": "^2.7.0", "tslint": "^6.1.3", diff --git a/packages/coaction-mobx/test/benchmark/coaction-mobx.ts b/packages/coaction-mobx/test/benchmark/coaction-mobx.ts new file mode 100644 index 0000000..2aae381 --- /dev/null +++ b/packages/coaction-mobx/test/benchmark/coaction-mobx.ts @@ -0,0 +1,112 @@ +import { create } from 'coaction'; +import { bindMobx } from '@coaction/mobx'; +import { makeAutoObservable } from 'mobx'; + +export const createCoactionMobxStore = () => { + const useStore = create( + (set, get, store) => + makeAutoObservable( + bindMobx({ + categories: [] as { + id: number; + text: string; + }[], + todos: [] as { + text: string; + done?: boolean; + category?: { + id: number; + text: string; + }; + }[], + + reset() { + this.categories = []; + this.todos = []; + }, + + bigInitWithoutRefsWithoutAssign() { + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '', done: false }); + } + this.todos = todos; + }, + + bigInitWithoutRefsWithAssign() { + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '', done: false }); + } + this.todos = [...this.todos, ...todos]; + }, + + bigInitWithRefsWithoutAssign() { + const category = { id: this.categories.length, text: 'category' }; + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '', done: false, category }); + } + this.todos = todos; + }, + + bigInitWithRefsWithAssign() { + const category = { id: this.categories.length, text: 'category' }; + this.categories.push(category); + + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '', done: false, category }); + } + this.todos = [...this.todos, ...todos]; + }, + + init() { + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '' }); + } + this.todos = todos; + } + }) + ), + { + enablePatches: true + } + ); + + const store = useStore(); + + store.reset(); + return store; +}; + +// console.time('bigInitWithoutRefsWithoutAssign'); +// store.bigInitWithoutRefsWithoutAssign(); +// console.timeEnd('bigInitWithoutRefsWithoutAssign'); + +// store.reset(); + +// console.time('bigInitWithoutRefsWithAssign'); +// store.bigInitWithoutRefsWithAssign(); +// console.timeEnd('bigInitWithoutRefsWithAssign'); + +// store.reset(); + +// console.time('bigInitWithRefsWithoutAssign'); +// store.bigInitWithRefsWithoutAssign(); +// console.timeEnd('bigInitWithRefsWithoutAssign'); + +// store.reset(); + +// console.time('bigInitWithRefsWithoutAssign'); +// store.bigInitWithRefsWithoutAssign(); +// console.timeEnd('bigInitWithRefsWithoutAssign'); + +// store.reset(); + +// console.time('mobxInit'); +// store.mobxInit(); +// console.timeEnd('mobxInit'); + +// store.reset(); diff --git a/packages/coaction-mobx/test/benchmark/coaction.ts b/packages/coaction-mobx/test/benchmark/coaction.ts new file mode 100644 index 0000000..019fdb8 --- /dev/null +++ b/packages/coaction-mobx/test/benchmark/coaction.ts @@ -0,0 +1,119 @@ +import { create } from 'coaction'; + +export const createCoactionStore = () => { + const useStore = create( + (set, get, store) => ({ + categories: [] as { + id: number; + text: string; + }[], + todos: [] as { + text: string; + done?: boolean; + category?: { + id: number; + text: string; + }; + }[], + + reset() { + set(() => { + this.categories = []; + this.todos = []; + }); + }, + + bigInitWithoutRefsWithoutAssign() { + set(() => { + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '', done: false }); + } + this.todos = todos; + }); + }, + + bigInitWithoutRefsWithAssign() { + set(() => { + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '', done: false }); + } + this.todos = [...this.todos, ...todos]; + }); + }, + + bigInitWithRefsWithoutAssign() { + set(() => { + const category = { id: this.categories.length, text: 'category' }; + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '', done: false, category }); + } + this.todos = todos; + }); + }, + + bigInitWithRefsWithAssign() { + set(() => { + const category = { id: this.categories.length, text: 'category' }; + this.categories.push(category); + + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '', done: false, category }); + } + this.todos = [...this.todos, ...todos]; + }); + }, + + init() { + set(() => { + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '' }); + } + this.todos = todos; + }); + } + }), + { + enablePatches: false + } + ); + + const store = useStore(); + + store.reset(); + return store; +}; + +// console.time('bigInitWithoutRefsWithoutAssign'); +// store.bigInitWithoutRefsWithoutAssign(); +// console.timeEnd('bigInitWithoutRefsWithoutAssign'); + +// store.reset(); + +// console.time('bigInitWithoutRefsWithAssign'); +// store.bigInitWithoutRefsWithAssign(); +// console.timeEnd('bigInitWithoutRefsWithAssign'); + +// store.reset(); + +// console.time('bigInitWithRefsWithoutAssign'); +// store.bigInitWithRefsWithoutAssign(); +// console.timeEnd('bigInitWithRefsWithoutAssign'); + +// store.reset(); + +// console.time('bigInitWithRefsWithoutAssign'); +// store.bigInitWithRefsWithoutAssign(); +// console.timeEnd('bigInitWithRefsWithoutAssign'); + +// store.reset(); + +// console.time('mobxInit'); +// store.mobxInit(); +// console.timeEnd('mobxInit'); + +// store.reset(); diff --git a/packages/coaction-mobx/test/benchmark/index.ts b/packages/coaction-mobx/test/benchmark/index.ts new file mode 100644 index 0000000..3cb0aaf --- /dev/null +++ b/packages/coaction-mobx/test/benchmark/index.ts @@ -0,0 +1,329 @@ +import fs from 'fs'; +import https from 'https'; +import { Suite } from 'benchmark'; +import QuickChart from 'quickchart-js'; +import { createCoactionMobxStore } from './coaction-mobx'; +import { createMobxStore } from './mobx'; +import { createCoactionStore } from './coaction'; +import { createMobxKeystoneStore } from './mobx-keystone'; + +const labels: string[] = []; +const result: any[] = [ + { + label: '@coaction/mobx', + backgroundColor: 'rgba(54, 162, 235, 0.5)', + data: [] + }, + { + label: 'coaction', + backgroundColor: 'rgba(0, 255, 0, 0.5)', + data: [] + }, + { + label: 'mobx-keystone', + backgroundColor: 'rgba(255, 0, 0, 0.5)', + data: [] + }, + { + label: 'mobx', + backgroundColor: 'rgba(221, 0, 255, 0.5)', + data: [] + } +]; + +const suite = new Suite(); + +let store: any; + +suite + .add( + '@coaction/mobx - bigInitWithoutRefsWithoutAssign', + () => { + store.bigInitWithoutRefsWithoutAssign(); + }, + { + onStart: () => { + store = createCoactionMobxStore(); + } + } + ) + .add( + 'mobx - bigInitWithoutRefsWithoutAssign', + () => { + store.bigInitWithoutRefsWithoutAssign(); + }, + { + onStart: () => { + store = createMobxStore(); + } + } + ) + .add( + 'coaction - bigInitWithoutRefsWithoutAssign', + () => { + store.bigInitWithoutRefsWithoutAssign(); + }, + { + onStart: () => { + store = createCoactionStore(); + } + } + ) + .add( + 'mobx-keystone - bigInitWithoutRefsWithoutAssign', + () => { + store.bigInitWithoutRefsWithoutAssign(); + }, + { + onStart: () => { + store = createMobxKeystoneStore(); + } + } + ) + .add( + '@coaction/mobx - bigInitWithoutRefsWithAssign', + () => { + store.bigInitWithoutRefsWithAssign(); + }, + { + onStart: () => { + store = createCoactionMobxStore(); + } + } + ) + .add( + 'mobx - bigInitWithoutRefsWithAssign', + () => { + store.bigInitWithoutRefsWithAssign(); + }, + { + onStart: () => { + store = createMobxStore(); + } + } + ) + .add( + 'coaction - bigInitWithoutRefsWithAssign', + () => { + store.bigInitWithoutRefsWithAssign(); + }, + { + onStart: () => { + store = createCoactionStore(); + } + } + ) + .add( + 'mobx-keystone - bigInitWithoutRefsWithAssign', + () => { + store.bigInitWithoutRefsWithAssign(); + }, + { + onStart: () => { + store = createMobxKeystoneStore(); + } + } + ) + .add( + '@coaction/mobx - bigInitWithRefsWithoutAssign', + () => { + store.bigInitWithRefsWithoutAssign(); + }, + { + onStart: () => { + store = createCoactionMobxStore(); + } + } + ) + .add( + 'mobx - bigInitWithRefsWithoutAssign', + () => { + store.bigInitWithRefsWithoutAssign(); + }, + { + onStart: () => { + store = createMobxStore(); + } + } + ) + .add( + 'coaction - bigInitWithRefsWithoutAssign', + () => { + store.bigInitWithRefsWithoutAssign(); + }, + { + onStart: () => { + store = createCoactionStore(); + } + } + ) + .add( + 'mobx-keystone - bigInitWithRefsWithoutAssign', + () => { + store.bigInitWithRefsWithoutAssign(); + }, + { + onStart: () => { + store = createMobxKeystoneStore(); + } + } + ) + .add( + '@coaction/mobx - bigInitWithRefsWithAssign', + () => { + store.bigInitWithRefsWithAssign(); + }, + { + onStart: () => { + store = createCoactionMobxStore(); + } + } + ) + .add( + 'mobx - bigInitWithRefsWithAssign', + () => { + store.bigInitWithRefsWithAssign(); + }, + { + onStart: () => { + store = createMobxStore(); + } + } + ) + .add( + 'coaction - bigInitWithRefsWithAssign', + () => { + store.bigInitWithRefsWithAssign(); + }, + { + onStart: () => { + store = createCoactionStore(); + } + } + ) + .add( + 'mobx-keystone - bigInitWithRefsWithAssign', + () => { + store.bigInitWithRefsWithAssign(); + }, + { + onStart: () => { + store = createMobxKeystoneStore(); + } + } + ) + .add( + '@coaction/mobx - init', + () => { + store.init(); + }, + { + onStart: () => { + store = createCoactionMobxStore(); + } + } + ) + .add( + 'mobx - init', + () => { + store.init(); + }, + { + onStart: () => { + store = createMobxStore(); + } + } + ) + .add( + 'coaction - init', + () => { + store.init(); + }, + { + onStart: () => { + store = createCoactionStore(); + } + } + ) + .add( + 'mobx-keystone - init', + () => { + store.init(); + }, + { + onStart: () => { + store = createMobxKeystoneStore(); + } + } + ) + .on('cycle', (event: any) => { + console.log(String(event.target)); + const [name, field] = event.target.name.split(' - '); + if (!labels.includes(field)) labels.push(field); + const item = result.find(({ label }) => label === name); + item.data[labels.indexOf(field)] = Math.round(event.target.hz); + }) + .on('complete', function () { + // @ts-ignore + console.log('The fastest method is ' + this.filter('fastest').map('name')); + }) + .run({ async: false }); + +try { + const config = { + type: 'horizontalBar', + data: { + labels, + datasets: result + }, + options: { + title: { + display: true, + text: 'Array Performance' + }, + legend: { + position: 'bottom' + }, + elements: { + rectangle: { + borderWidth: 1 + } + }, + scales: { + xAxes: [ + { + display: true, + scaleLabel: { + display: true, + fontSize: 10, + labelString: + 'Measure(ops/sec) to update 10K arrays, bigger is better.' + } + } + ] + }, + plugins: { + datalabels: { + anchor: 'center', + align: 'center', + font: { + size: 8 + } + } + } + } + }; + const chart = new QuickChart(); + chart.setConfig(config); + console.log('config:', JSON.stringify(config)); + const file = fs.createWriteStream('benchmark.jpg'); + https.get(chart.getUrl(), (response) => { + response.pipe(file); + file.on('finish', () => { + file.close(); + console.log('update benchmark'); + }); + }); +} catch (err) { + console.error(err); +} diff --git a/packages/coaction-mobx/test/benchmark/mobx-keystone.ts b/packages/coaction-mobx/test/benchmark/mobx-keystone.ts new file mode 100644 index 0000000..0841f71 --- /dev/null +++ b/packages/coaction-mobx/test/benchmark/mobx-keystone.ts @@ -0,0 +1,123 @@ +import { computed, makeObservable, observable } from 'mobx'; +import { + idProp, + model, + Model, + modelAction, + prop, + Ref, + rootRef, + registerRootStore +} from 'mobx-keystone'; +// https://github.com/xaviergonz/mobx-keystone/issues/503 + +export const createMobxKeystoneStore = () => { + const categoryRef = rootRef('myCoolApp/categoryRef'); + + @model('myCoolApp/Cateogry') + class TodoCategory extends Model({ + id: idProp, + text: prop('category') + }) {} + + @model('myCoolApp/Todo') + class Todo extends Model({ + id: idProp, + text: prop('todo'), + done: prop(false), + categoryRef: prop | undefined>() + }) {} + + @model('myCoolApp/TodoStore') + class Store extends Model({ + categories: prop(() => []), + todos: prop(() => []) + }) { + @modelAction + reset() { + this.categories = []; + this.todos = []; + } + + @modelAction + bigInitWithoutRefsWithoutAssign() { + const todos: Todo[] = []; + for (let i = 0; i < 10_000; i++) { + todos.push(new Todo({ text: '' })); + } + } + + @modelAction + bigInitWithoutRefsWithAssign() { + const todos: Todo[] = []; + for (let i = 0; i < 10_000; i++) { + todos.push(new Todo({ text: '' })); + } + this.todos = [...this.todos, ...todos]; + } + + @modelAction + bigInitWithRefsWithoutAssign() { + const category = new TodoCategory({}); + const todos: Todo[] = []; + for (let i = 0; i < 10_000; i++) { + todos.push(new Todo({ text: '', categoryRef: categoryRef(category) })); + } + } + + @modelAction + bigInitWithRefsWithAssign() { + const category = new TodoCategory({}); + this.categories.push(category); + + const todos: Todo[] = []; + for (let i = 0; i < 10_000; i++) { + todos.push(new Todo({ text: '', categoryRef: categoryRef(category) })); + } + this.todos = [...this.todos, ...todos]; + } + + init() { + const todos: { text: string }[] = []; + for (let i = 0; i < 10_000; i++) { + todos.push(observable({ text: '' })); + } + } + } + + const store = new Store({}); + registerRootStore(store); + + store.reset(); + return store; +}; + +// console.time('bigInitWithoutRefsWithoutAssign'); +// store.bigInitWithoutRefsWithoutAssign(); +// console.timeEnd('bigInitWithoutRefsWithoutAssign'); + +// store.reset(); + +// console.time('bigInitWithoutRefsWithAssign'); +// store.bigInitWithoutRefsWithAssign(); +// console.timeEnd('bigInitWithoutRefsWithAssign'); + +// store.reset(); + +// console.time('bigInitWithRefsWithoutAssign'); +// store.bigInitWithRefsWithoutAssign(); +// console.timeEnd('bigInitWithRefsWithoutAssign'); + +// store.reset(); + +// console.time('bigInitWithRefsWithoutAssign'); +// store.bigInitWithRefsWithoutAssign(); +// console.timeEnd('bigInitWithRefsWithoutAssign'); + +// store.reset(); + +// console.time('mobxInit'); +// store.mobxInit(); +// console.timeEnd('mobxInit'); + +// store.reset(); diff --git a/packages/coaction-mobx/test/benchmark/mobx.ts b/packages/coaction-mobx/test/benchmark/mobx.ts new file mode 100644 index 0000000..bc38799 --- /dev/null +++ b/packages/coaction-mobx/test/benchmark/mobx.ts @@ -0,0 +1,100 @@ +import { makeAutoObservable } from 'mobx'; + +export const createMobxStore = () => { + const store = makeAutoObservable({ + categories: [] as { + id: number; + text: string; + }[], + todos: [] as { + text: string; + done?: boolean; + category?: { + id: number; + text: string; + }; + }[], + + reset() { + this.categories = []; + this.todos = []; + }, + + bigInitWithoutRefsWithoutAssign() { + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '', done: false }); + } + this.todos = todos; + }, + + bigInitWithoutRefsWithAssign() { + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '', done: false }); + } + this.todos = [...this.todos, ...todos]; + }, + + bigInitWithRefsWithoutAssign() { + const category = { id: this.categories.length, text: 'category' }; + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '', done: false, category }); + } + this.todos = todos; + }, + + bigInitWithRefsWithAssign() { + const category = { id: this.categories.length, text: 'category' }; + this.categories.push(category); + + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '', done: false, category }); + } + this.todos = [...this.todos, ...todos]; + }, + + init() { + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '' }); + } + this.todos = todos; + } + }); + + store.reset(); + return store; +}; + +// console.time('bigInitWithoutRefsWithoutAssign'); +// store.bigInitWithoutRefsWithoutAssign(); +// console.timeEnd('bigInitWithoutRefsWithoutAssign'); + +// store.reset(); + +// console.time('bigInitWithoutRefsWithAssign'); +// store.bigInitWithoutRefsWithAssign(); +// console.timeEnd('bigInitWithoutRefsWithAssign'); + +// store.reset(); + +// console.time('bigInitWithRefsWithoutAssign'); +// store.bigInitWithRefsWithoutAssign(); +// console.timeEnd('bigInitWithRefsWithoutAssign'); + +// store.reset(); + +// console.time('bigInitWithRefsWithoutAssign'); +// store.bigInitWithRefsWithoutAssign(); +// console.timeEnd('bigInitWithRefsWithoutAssign'); + +// store.reset(); + +// console.time('mobxInit'); +// store.mobxInit(); +// console.timeEnd('mobxInit'); + +// store.reset(); diff --git a/packages/coaction-mobx/test/branchmark/coaction-mobx.ts b/packages/coaction-mobx/test/branchmark/coaction-mobx.ts deleted file mode 100644 index 552eb04..0000000 --- a/packages/coaction-mobx/test/branchmark/coaction-mobx.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { create } from 'coaction'; -import { bindMobx } from '@coaction/mobx'; -import { makeAutoObservable } from 'mobx'; - -const useStore = create( - (set, get, store) => - makeAutoObservable( - bindMobx({ - categories: [] as { - id: number; - text: string; - }[], - todos: [] as { - text: string; - done?: boolean; - category?: { - id: number; - text: string; - }; - }[], - - reset() { - this.categories = []; - this.todos = []; - }, - - bigInitWithoutRefsWithoutAssign() { - const todos = []; - for (let i = 0; i < 100_000; i++) { - todos.push({ text: '', done: false }); - } - this.todos = todos; - }, - - bigInitWithoutRefsWithAssign() { - const todos = []; - for (let i = 0; i < 100_000; i++) { - todos.push({ text: '', done: false }); - } - this.todos = [...this.todos, ...todos]; - }, - - bigInitWithRefsWithoutAssign() { - const category = { id: this.categories.length, text: 'category' }; - const todos = []; - for (let i = 0; i < 100_000; i++) { - todos.push({ text: '', done: false, category }); - } - this.todos = todos; - }, - - bigInitWithRefsWithAssign() { - const category = { id: this.categories.length, text: 'category' }; - this.categories.push(category); - - const todos = []; - for (let i = 0; i < 100_000; i++) { - todos.push({ text: '', done: false, category }); - } - this.todos = [...this.todos, ...todos]; - }, - - mobxInit() { - const todos = []; - for (let i = 0; i < 100_000; i++) { - todos.push({ text: '' }); - } - this.todos = todos; - } - }) - ), - { - enablePatches: true - } -); - -const store = useStore(); - -store.reset(); - -console.time('bigInitWithoutRefsWithoutAssign'); -store.bigInitWithoutRefsWithoutAssign(); -console.timeEnd('bigInitWithoutRefsWithoutAssign'); - -store.reset(); - -console.time('bigInitWithoutRefsWithAssign'); -store.bigInitWithoutRefsWithAssign(); -console.timeEnd('bigInitWithoutRefsWithAssign'); - -store.reset(); - -console.time('bigInitWithRefsWithoutAssign'); -store.bigInitWithRefsWithoutAssign(); -console.timeEnd('bigInitWithRefsWithoutAssign'); - -store.reset(); - -console.time('bigInitWithRefsWithoutAssign'); -store.bigInitWithRefsWithoutAssign(); -console.timeEnd('bigInitWithRefsWithoutAssign'); - -store.reset(); - -console.time('mobxInit'); -store.mobxInit(); -console.timeEnd('mobxInit'); - -store.reset(); diff --git a/packages/coaction-mobx/test/branchmark/coaction.ts b/packages/coaction-mobx/test/branchmark/coaction.ts deleted file mode 100644 index 71536ad..0000000 --- a/packages/coaction-mobx/test/branchmark/coaction.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { create } from 'coaction'; - -const useStore = create( - (set, get, store) => ({ - categories: [] as { - id: number; - text: string; - }[], - todos: [] as { - text: string; - done?: boolean; - category?: { - id: number; - text: string; - }; - }[], - - reset() { - set(() => { - this.categories = []; - this.todos = []; - }); - }, - - bigInitWithoutRefsWithoutAssign() { - set(() => { - const todos = []; - for (let i = 0; i < 100_000; i++) { - todos.push({ text: '', done: false }); - } - this.todos = todos; - }); - }, - - bigInitWithoutRefsWithAssign() { - set(() => { - const todos = []; - for (let i = 0; i < 100_000; i++) { - todos.push({ text: '', done: false }); - } - this.todos = [...this.todos, ...todos]; - }); - }, - - bigInitWithRefsWithoutAssign() { - set(() => { - const category = { id: this.categories.length, text: 'category' }; - const todos = []; - for (let i = 0; i < 100_000; i++) { - todos.push({ text: '', done: false, category }); - } - this.todos = todos; - }); - }, - - bigInitWithRefsWithAssign() { - set(() => { - const category = { id: this.categories.length, text: 'category' }; - this.categories.push(category); - - const todos = []; - for (let i = 0; i < 100_000; i++) { - todos.push({ text: '', done: false, category }); - } - this.todos = [...this.todos, ...todos]; - }); - }, - - mobxInit() { - set(() => { - const todos = []; - for (let i = 0; i < 100_000; i++) { - todos.push({ text: '' }); - } - this.todos = todos; - }); - } - }), - { - enablePatches: false - } -); - -const store = useStore(); - -store.reset(); - -console.time('bigInitWithoutRefsWithoutAssign'); -store.bigInitWithoutRefsWithoutAssign(); -console.timeEnd('bigInitWithoutRefsWithoutAssign'); - -store.reset(); - -console.time('bigInitWithoutRefsWithAssign'); -store.bigInitWithoutRefsWithAssign(); -console.timeEnd('bigInitWithoutRefsWithAssign'); - -store.reset(); - -console.time('bigInitWithRefsWithoutAssign'); -store.bigInitWithRefsWithoutAssign(); -console.timeEnd('bigInitWithRefsWithoutAssign'); - -store.reset(); - -console.time('bigInitWithRefsWithoutAssign'); -store.bigInitWithRefsWithoutAssign(); -console.timeEnd('bigInitWithRefsWithoutAssign'); - -store.reset(); - -console.time('mobxInit'); -store.mobxInit(); -console.timeEnd('mobxInit'); - -store.reset(); diff --git a/packages/coaction-mobx/test/branchmark/mobx-keystone.ts b/packages/coaction-mobx/test/branchmark/mobx-keystone.ts deleted file mode 100644 index e0dd919..0000000 --- a/packages/coaction-mobx/test/branchmark/mobx-keystone.ts +++ /dev/null @@ -1,120 +0,0 @@ -// @ts-nocheck -import { computed, makeObservable, observable } from 'mobx'; -import { - idProp, - model, - Model, - modelAction, - prop, - Ref, - rootRef, - registerRootStore -} from 'mobx-keystone'; -// https://github.com/xaviergonz/mobx-keystone/issues/503 -const categoryRef = rootRef('myCoolApp/categoryRef'); - -@model('myCoolApp/Cateogry') -class TodoCategory extends Model({ - id: idProp, - text: prop('category') -}) {} - -@model('myCoolApp/Todo') -class Todo extends Model({ - id: idProp, - text: prop('todo'), - done: prop(false), - categoryRef: prop | undefined>() -}) {} - -@model('myCoolApp/TodoStore') -class Store extends Model({ - categories: prop(() => []), - todos: prop(() => []) -}) { - @modelAction - reset() { - this.categories = []; - this.todos = []; - } - - @modelAction - bigInitWithoutRefsWithoutAssign() { - const todos: Todo[] = []; - for (let i = 0; i < 100_000; i++) { - todos.push(new Todo({ text: '' })); - } - } - - @modelAction - bigInitWithoutRefsWithAssign() { - const todos: Todo[] = []; - for (let i = 0; i < 100_000; i++) { - todos.push(new Todo({ text: '' })); - } - this.todos = [...this.todos, ...todos]; - } - - @modelAction - bigInitWithRefsWithoutAssign() { - const category = new TodoCategory({}); - const todos: Todo[] = []; - for (let i = 0; i < 100_000; i++) { - todos.push(new Todo({ text: '', categoryRef: categoryRef(category) })); - } - } - - @modelAction - bigInitWithRefsWithAssign() { - const category = new TodoCategory({}); - this.categories.push(category); - - const todos: Todo[] = []; - for (let i = 0; i < 100_000; i++) { - todos.push(new Todo({ text: '', categoryRef: categoryRef(category) })); - } - this.todos = [...this.todos, ...todos]; - } - - mobxInit() { - const todos: { text: string }[] = []; - for (let i = 0; i < 100_000; i++) { - todos.push(observable({ text: '' })); - } - } -} - -const store = new Store({}); -registerRootStore(store); - -store.reset(); - -console.time('bigInitWithoutRefsWithoutAssign'); -store.bigInitWithoutRefsWithoutAssign(); -console.timeEnd('bigInitWithoutRefsWithoutAssign'); - -store.reset(); - -console.time('bigInitWithoutRefsWithAssign'); -store.bigInitWithoutRefsWithAssign(); -console.timeEnd('bigInitWithoutRefsWithAssign'); - -store.reset(); - -console.time('bigInitWithRefsWithoutAssign'); -store.bigInitWithRefsWithoutAssign(); -console.timeEnd('bigInitWithRefsWithoutAssign'); - -store.reset(); - -console.time('bigInitWithRefsWithoutAssign'); -store.bigInitWithRefsWithoutAssign(); -console.timeEnd('bigInitWithRefsWithoutAssign'); - -store.reset(); - -console.time('mobxInit'); -store.mobxInit(); -console.timeEnd('mobxInit'); - -store.reset(); diff --git a/packages/coaction-mobx/test/branchmark/mobx.ts b/packages/coaction-mobx/test/branchmark/mobx.ts deleted file mode 100644 index 3f2da22..0000000 --- a/packages/coaction-mobx/test/branchmark/mobx.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { makeAutoObservable } from 'mobx'; - -const store = makeAutoObservable({ - categories: [] as { - id: number; - text: string; - }[], - todos: [] as { - text: string; - done?: boolean; - category?: { - id: number; - text: string; - }; - }[], - - reset() { - this.categories = []; - this.todos = []; - }, - - bigInitWithoutRefsWithoutAssign() { - const todos = []; - for (let i = 0; i < 100_000; i++) { - todos.push({ text: '', done: false }); - } - this.todos = todos; - }, - - bigInitWithoutRefsWithAssign() { - const todos = []; - for (let i = 0; i < 100_000; i++) { - todos.push({ text: '', done: false }); - } - this.todos = [...this.todos, ...todos]; - }, - - bigInitWithRefsWithoutAssign() { - const category = { id: this.categories.length, text: 'category' }; - const todos = []; - for (let i = 0; i < 100_000; i++) { - todos.push({ text: '', done: false, category }); - } - this.todos = todos; - }, - - bigInitWithRefsWithAssign() { - const category = { id: this.categories.length, text: 'category' }; - this.categories.push(category); - - const todos = []; - for (let i = 0; i < 100_000; i++) { - todos.push({ text: '', done: false, category }); - } - this.todos = [...this.todos, ...todos]; - }, - - mobxInit() { - const todos = []; - for (let i = 0; i < 100_000; i++) { - todos.push({ text: '' }); - } - this.todos = todos; - } -}); - -store.reset(); - -console.time('bigInitWithoutRefsWithoutAssign'); -store.bigInitWithoutRefsWithoutAssign(); -console.timeEnd('bigInitWithoutRefsWithoutAssign'); - -store.reset(); - -console.time('bigInitWithoutRefsWithAssign'); -store.bigInitWithoutRefsWithAssign(); -console.timeEnd('bigInitWithoutRefsWithAssign'); - -store.reset(); - -console.time('bigInitWithRefsWithoutAssign'); -store.bigInitWithRefsWithoutAssign(); -console.timeEnd('bigInitWithRefsWithoutAssign'); - -store.reset(); - -console.time('bigInitWithRefsWithoutAssign'); -store.bigInitWithRefsWithoutAssign(); -console.timeEnd('bigInitWithRefsWithoutAssign'); - -store.reset(); - -console.time('mobxInit'); -store.mobxInit(); -console.timeEnd('mobxInit'); - -store.reset(); diff --git a/yarn.lock b/yarn.lock index 3a9a291..07b558b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2587,6 +2587,11 @@ dependencies: "@babel/types" "^7.20.7" +"@types/benchmark@^2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@types/benchmark/-/benchmark-2.1.5.tgz#940c1850c18fdfdaee3fd6ed29cd92ae0d445b45" + integrity sha512-cKio2eFB3v7qmKcvIHLUMw/dIx/8bhWPuzpzRT4unCPRTD8VdA9Zb0afxpcxOqR4PixRS7yT42FqGS8BYL8g1w== + "@types/conventional-commits-parser@^5.0.0": version "5.0.0" resolved "https://registry.yarnpkg.com/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz#8c9d23e0b415b24b91626d07017303755d542dc8" @@ -3400,6 +3405,14 @@ before-after-hook@^2.2.0: resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== +benchmark@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/benchmark/-/benchmark-2.1.4.tgz#09f3de31c916425d498cc2ee565a0ebf3c2a5629" + integrity sha512-l9MlfN4M1K/H2fbhfMy3B7vJd6AGKJVQn2h6Sg/Yx+KckoUA7ewS5Vv6TjSq18ooE1kS9hhAlQRH3AkXIh/aOQ== + dependencies: + lodash "^4.17.4" + platform "^1.3.3" + better-path-resolve@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/better-path-resolve/-/better-path-resolve-1.0.0.tgz#13a35a1104cdd48a7b74bf8758f96a1ee613f99d" @@ -4143,6 +4156,13 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== +cross-fetch@^3.1.5: + version "3.1.8" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" + integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== + dependencies: + node-fetch "^2.6.12" + cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -6667,6 +6687,11 @@ jake@^10.8.5: filelist "^1.0.4" minimatch "^3.1.2" +javascript-stringify@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-2.1.0.tgz#27c76539be14d8bd128219a2d731b09337904e79" + integrity sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg== + jest-changed-files@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" @@ -7561,7 +7586,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== -lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.21: +lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.21, lodash@^4.17.4: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -8085,6 +8110,16 @@ mkdirp@^1.0.3: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +mobx-keystone@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/mobx-keystone/-/mobx-keystone-1.11.1.tgz#1d21752ea91d6ffbafb910b88afde33d78bfd5b7" + integrity sha512-gflAO++K1DKVIoGbHLvpozbIbIA2qQlm2LpQnB+qbpN59xGgK0FHzhqkCU6nPXpb+EQFBzwESxqvOIrWpHvJUQ== + dependencies: + fast-deep-equal "^3.1.3" + nanoid "^3.3.7" + ts-toolbelt "^9.6.0" + tslib "^2.7.0" + mobx@^6.13.2: version "6.13.2" resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.13.2.tgz#e4514c983c41611d7008ac4cd21c7f3d1be3180d" @@ -8190,7 +8225,7 @@ node-fetch@2.6.7: dependencies: whatwg-url "^5.0.0" -node-fetch@^2.5.0, node-fetch@^2.6.7: +node-fetch@^2.5.0, node-fetch@^2.6.12, node-fetch@^2.6.7: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== @@ -9007,6 +9042,11 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +platform@^1.3.3: + version "1.3.6" + resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7" + integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg== + please-upgrade-node@^3.0.2, please-upgrade-node@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" @@ -9192,6 +9232,14 @@ quick-lru@^5.1.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== +quickchart-js@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/quickchart-js/-/quickchart-js-3.1.3.tgz#7352df8e35b66ce4f50d6ea51252cee2e5213962" + integrity sha512-QzPUXBA/UntYBbOMITtMz7B426fes1XFmmjmjA070jXeMWhyhDojJf2aSZPsekj35ywfJhWjY6TKf3S0/XxyAg== + dependencies: + cross-fetch "^3.1.5" + javascript-stringify "^2.1.0" + range-parser@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" @@ -10518,6 +10566,11 @@ ts-node@^10.9.2: v8-compile-cache-lib "^3.0.1" yn "3.1.1" +ts-toolbelt@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz#50a25426cfed500d4a09bd1b3afb6f28879edfd5" + integrity sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w== + tsconfig-paths@^4.1.2: version "4.2.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" From c5df1deafc572762825fe4f7305483126cc067cd Mon Sep 17 00:00:00 2001 From: unadlib Date: Mon, 16 Dec 2024 22:59:43 +0800 Subject: [PATCH 06/20] docs(readme): update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a8c044..3119892 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ Measure(ops/sec) to update 10K arrays, bigger is better([view source](https://gi | **coaction** | init | 3,524 | | mobx-keystone | init | 40.48 | -This table benchmarks various state management libraries on large initialization tasks. Coaction stands out dramatically, performing at least hundreds of times faster in certain scenarios. For example, in the “bigInitWithoutRefsWithoutAssign” test, Coaction achieves about 19,910 ops/sec compared to Mobx’s 37.5 ops/sec—over 500 times faster. Similarly, in the “init” test, Coaction reaches around 3,524 ops/sec versus Mobx’s 42.98 ops/sec—an increase of roughly 80 times. These results highlight Coaction’s exceptional efficiency in handling large-scale data initialization. +This table benchmarks various state management libraries on large initialization tasks. Coaction stands out dramatically, performing at least hundreds of times faster in certain scenarios. For example, in the "bigInitWithoutRefsWithoutAssign" test, Coaction achieves about 19,910 ops/sec compared to Mobx’s 37.5 ops/sec—over 500 times faster. Similarly, in the "init" test, Coaction reaches around 3,524 ops/sec versus Mobx's 42.98 ops/sec—an increase of roughly 80 times. These results highlight Coaction's exceptional efficiency in handling large-scale data initialization. > We will also provide more complete benchmarking. From 6e463650f21e569613bb367fb0fe7ecb57be163e Mon Sep 17 00:00:00 2001 From: unadlib Date: Tue, 17 Dec 2024 18:40:16 +0800 Subject: [PATCH 07/20] docs(readme): update --- README.md | 60 +++++++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 3119892..f8095c4 100644 --- a/README.md +++ b/README.md @@ -200,7 +200,7 @@ const CounterComponent = () => { ```jsx import { create } from '@coaction/react'; -const counter = (set) => ({ +const counter = (set, get) => ({ count: 0, // derived data without cache get tripleCount() { @@ -230,31 +230,31 @@ Coaction is designed to be compatible with a wide range of libraries and framewo ### Supported Libraries and Frameworks -| Framework | Package | Status | -| --------- | ---------------- | ------- | -| React | @coaction/react | ✅ Done | -| Vue | @coaction/vue | Ongoing | -| Angular | @coaction/ng | | -| Svelte | @coaction/svelte | | -| Solid | @coaction/solid | | -| Yjs | @coaction/yjs | | +| | Package | Status | +| ------- | ---------------- | ------- | +| React | @coaction/react | ✅ Done | +| Vue | @coaction/vue | Ongoing | +| Angular | @coaction/ng | | +| Svelte | @coaction/svelte | | +| Solid | @coaction/solid | | +| Yjs | @coaction/yjs | | ### State Management Libraries -| State Management | Package | Status | -| ---------------- | ----------------- | ------- | -| MobX | @coaction/mobx | ✅ Done | -| Pinia | @coaction/pinia | ✅ Done | -| Zustand | @coaction/zustand | Ongoing | -| Redux Toolkit | @coaction/redux | | -| Jotai | @coaction/jotai | | -| XState | @coaction/xstate | | -| Valtio | @coaction/valtio | | -| alien-signals | @coaction/alien | Ongoing | +| | Package | Status | +| ------------- | ----------------- | ------- | +| MobX | @coaction/mobx | ✅ Done | +| Pinia | @coaction/pinia | ✅ Done | +| Zustand | @coaction/zustand | Ongoing | +| Redux Toolkit | @coaction/redux | | +| Jotai | @coaction/jotai | | +| XState | @coaction/xstate | | +| Valtio | @coaction/valtio | | +| alien-signals | @coaction/alien | Ongoing | ## Middlewares -| Feature | Package | Status | +| | Package | Status | | --------- | ----------------- | ------- | | Logger | @coaction/logger | ✅ Done | | Persist | @coaction/persist | Ongoing | @@ -262,16 +262,16 @@ Coaction is designed to be compatible with a wide range of libraries and framewo ## Difference between Coaction and Zustand -| Feature | **coaction** | Zustand | -| --------------------------------- | ------------ | ------- | -| Built-in multithreading | ✅ | ❌ | -| Support getter accessor | ✅ | ❌ | -| Built-in computed properties | ✅ | ❌ | -| Built-in namespace Slice | ✅ | ❌ | -| Built-in auto selector for state | ✅ | ❌ | -| Built-in multiple stores selector | ✅ | ❌ | -| Easy to implement middleware | ✅ | ❌ | -| Support `this` in getter/action | ✅ | ❌ | +| | `coaction` | Zustand | +| --------------------------------- | ---------- | ------- | +| Built-in multithreading | ✅ | ❌ | +| Support getter accessor | ✅ | ❌ | +| Built-in computed properties | ✅ | ❌ | +| Built-in namespace Slice | ✅ | ❌ | +| Built-in auto selector for state | ✅ | ❌ | +| Built-in multiple stores selector | ✅ | ❌ | +| Easy to implement middleware | ✅ | ❌ | +| Support `this` in getter/action | ✅ | ❌ | ## Credits From 78acb2636c87782a86e773652ee004e8c65cfa31 Mon Sep 17 00:00:00 2001 From: unadlib Date: Tue, 17 Dec 2024 20:20:34 +0800 Subject: [PATCH 08/20] docs(readme): update --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f8095c4..9818e1c 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ npm install coaction ```jsx import { create } from '@coaction/react'; -const useStore = create((set, get) => ({ +const useStore = create((set) => ({ count: 0, increment: () => set((state) => state.count++) })); @@ -161,8 +161,6 @@ const CounterComponent = () => { `counter.js`: ```js -import { create } from '@coaction/react'; - export const counter = (set) => ({ count: 0, increment: () => set((state) => state.count++) @@ -175,13 +173,16 @@ export const counter = (set) => ({ import { create } from '@coaction/react'; import { counter } from './counter'; -const useStore = create(counter); +create(counter); ``` ```jsx import { create } from '@coaction/react'; +import { counter } from './counter'; -const worker = new Worker(new URL('./worker.js', import.meta.url)); +const worker = new Worker(new URL('./worker.js', import.meta.url), { + type: 'module' +}); const useStore = create(counter, { worker }); const CounterComponent = () => { @@ -189,7 +190,7 @@ const CounterComponent = () => { return (

Count in Worker: {store.count}

- +
); }; From 9a3cf27a9f8f231fd71fdd88f20c9a141328bbee Mon Sep 17 00:00:00 2001 From: unadlib Date: Tue, 17 Dec 2024 20:22:08 +0800 Subject: [PATCH 09/20] docs(readme): update --- packages/coaction-react/README.md | 2 +- packages/core/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/coaction-react/README.md b/packages/coaction-react/README.md index b17d9a5..84ac18d 100644 --- a/packages/coaction-react/README.md +++ b/packages/coaction-react/README.md @@ -19,7 +19,7 @@ npm install coaction @coaction/react ```jsx import { create } from '@coaction/react'; -const useStore = create((set, get) => ({ +const useStore = create((set) => ({ count: 0, increment: () => set((state) => state.count++) })); diff --git a/packages/core/README.md b/packages/core/README.md index 4e37755..d33481f 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -19,7 +19,7 @@ npm install coaction ```jsx import { create } from 'coaction'; -const useStore = create((set, get) => ({ +const useStore = create((set) => ({ count: 0, increment: () => set((state) => state.count++) })); From 327ce6e6f0bb6fd7cac6b5756e01af67fd020f67 Mon Sep 17 00:00:00 2001 From: unadlib Date: Wed, 18 Dec 2024 01:01:27 +0800 Subject: [PATCH 10/20] chore(yarn): update yarn lock --- yarn.lock | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/yarn.lock b/yarn.lock index 07b558b..4fc4875 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8110,16 +8110,6 @@ mkdirp@^1.0.3: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mobx-keystone@^1.11.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/mobx-keystone/-/mobx-keystone-1.11.1.tgz#1d21752ea91d6ffbafb910b88afde33d78bfd5b7" - integrity sha512-gflAO++K1DKVIoGbHLvpozbIbIA2qQlm2LpQnB+qbpN59xGgK0FHzhqkCU6nPXpb+EQFBzwESxqvOIrWpHvJUQ== - dependencies: - fast-deep-equal "^3.1.3" - nanoid "^3.3.7" - ts-toolbelt "^9.6.0" - tslib "^2.7.0" - mobx@^6.13.2: version "6.13.2" resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.13.2.tgz#e4514c983c41611d7008ac4cd21c7f3d1be3180d" @@ -10566,11 +10556,6 @@ ts-node@^10.9.2: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -ts-toolbelt@^9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz#50a25426cfed500d4a09bd1b3afb6f28879edfd5" - integrity sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w== - tsconfig-paths@^4.1.2: version "4.2.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" From be8d3e99d2f77b4ef1294083904e5bcda1a60eae Mon Sep 17 00:00:00 2001 From: unadlib Date: Wed, 18 Dec 2024 19:49:09 +0800 Subject: [PATCH 11/20] docs(readme): update --- README.md | 40 +++++++++--------- benchmark.jpg | Bin 55453 -> 55830 bytes .../coaction-mobx/test/benchmark/coaction.ts | 26 +++++++----- 3 files changed, 35 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 9818e1c..7be5324 100644 --- a/README.md +++ b/README.md @@ -92,30 +92,30 @@ sequenceDiagram Measure(ops/sec) to update 10K arrays, bigger is better([view source](https://github.com/unadlib/mutative/blob/main/test/performance/benchmark.ts)). -| Library | Test Name | Ops/sec | +| Library | Test Case | Ops/sec | | -------------- | ------------------------------- | ------- | -| @coaction/mobx | bigInitWithoutRefsWithoutAssign | 37.07 | -| mobx | bigInitWithoutRefsWithoutAssign | 37.50 | -| **coaction** | bigInitWithoutRefsWithoutAssign | 19,910 | -| mobx-keystone | bigInitWithoutRefsWithoutAssign | 7.88 | -| @coaction/mobx | bigInitWithoutRefsWithAssign | 1.53 | -| mobx | bigInitWithoutRefsWithAssign | 10.77 | -| **coaction** | bigInitWithoutRefsWithAssign | 3.01 | +| @coaction/mobx | bigInitWithoutRefsWithoutAssign | 37.44 | +| mobx | bigInitWithoutRefsWithoutAssign | 37.67 | +| coaction | bigInitWithoutRefsWithoutAssign | 18,809 | +| mobx-keystone | bigInitWithoutRefsWithoutAssign | 8.53 | +| @coaction/mobx | bigInitWithoutRefsWithAssign | 1.54 | +| mobx | bigInitWithoutRefsWithAssign | 10.78 | +| coaction | bigInitWithoutRefsWithAssign | 45.20 | | mobx-keystone | bigInitWithoutRefsWithAssign | 0.13 | -| @coaction/mobx | bigInitWithRefsWithoutAssign | 14.66 | -| mobx | bigInitWithRefsWithoutAssign | 16.11 | -| **coaction** | bigInitWithRefsWithoutAssign | 152 | -| mobx-keystone | bigInitWithRefsWithoutAssign | 2.44 | -| @coaction/mobx | bigInitWithRefsWithAssign | 0.98 | -| mobx | bigInitWithRefsWithAssign | 8.81 | -| **coaction** | bigInitWithRefsWithAssign | 3.83 | +| @coaction/mobx | bigInitWithRefsWithoutAssign | 14.99 | +| mobx | bigInitWithRefsWithoutAssign | 16.68 | +| coaction | bigInitWithRefsWithoutAssign | 255 | +| mobx-keystone | bigInitWithRefsWithoutAssign | 2.35 | +| @coaction/mobx | bigInitWithRefsWithAssign | 1.01 | +| mobx | bigInitWithRefsWithAssign | 7.71 | +| coaction | bigInitWithRefsWithAssign | 57.22 | | mobx-keystone | bigInitWithRefsWithAssign | 0.11 | -| @coaction/mobx | init | 37.34 | -| mobx | init | 42.98 | -| **coaction** | init | 3,524 | -| mobx-keystone | init | 40.48 | +| @coaction/mobx | init | 38.57 | +| mobx | init | 43.88 | +| coaction | init | 8,523 | +| mobx-keystone | init | 41.19 | -This table benchmarks various state management libraries on large initialization tasks. Coaction stands out dramatically, performing at least hundreds of times faster in certain scenarios. For example, in the "bigInitWithoutRefsWithoutAssign" test, Coaction achieves about 19,910 ops/sec compared to Mobx’s 37.5 ops/sec—over 500 times faster. Similarly, in the "init" test, Coaction reaches around 3,524 ops/sec versus Mobx's 42.98 ops/sec—an increase of roughly 80 times. These results highlight Coaction's exceptional efficiency in handling large-scale data initialization. +This table benchmarks various state management libraries on large initialization tasks. Coaction stands out dramatically, performing at least hundreds of times faster in certain scenarios. For example, in the “bigInitWithoutRefsWithoutAssign” test, Coaction achieves 18,809 ops/sec compared to MobX’s 37.67 ops/sec—over 500 times faster. Similarly, in the “init” test, Coaction reaches 8,523 ops/sec versus MobX’s 43.88 ops/sec—an increase of roughly 200 times. Additionally, Coaction consistently outperforms other libraries across various initialization scenarios, showcasing its exceptional efficiency in handling large-scale data initialization. These results highlight Coaction’s superior performance and make it a highly effective solution for managing complex state in modern front-end applications. > We will also provide more complete benchmarking. diff --git a/benchmark.jpg b/benchmark.jpg index 4cd6874043374a59bd0ae3ed88206e1c33eb7d4a..af5d4c0ad492deaf698fd7b1eec27ed526e7f0a8 100644 GIT binary patch literal 55830 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 OU)EOBEF&knZuuAeV}8Z} literal 55453 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 { }, bigInitWithoutRefsWithAssign() { + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '', done: false }); + } + const newTodos = [...this.todos, ...todos]; set(() => { - const todos = []; - for (let i = 0; i < 10_000; i++) { - todos.push({ text: '', done: false }); - } - this.todos = [...this.todos, ...todos]; + this.todos = newTodos; }); }, @@ -55,15 +56,18 @@ export const createCoactionStore = () => { }, bigInitWithRefsWithAssign() { + const category = { id: this.categories.length, text: 'category' }; set(() => { - const category = { id: this.categories.length, text: 'category' }; this.categories.push(category); + }); - const todos = []; - for (let i = 0; i < 10_000; i++) { - todos.push({ text: '', done: false, category }); - } - this.todos = [...this.todos, ...todos]; + const todos = []; + for (let i = 0; i < 10_000; i++) { + todos.push({ text: '', done: false, category }); + } + const newTodos = [...this.todos, ...todos]; + set(() => { + this.todos = newTodos; }); }, From c7c45b0c3b08a356ddc323ba9d3658a314b534bf Mon Sep 17 00:00:00 2001 From: unadlib Date: Thu, 19 Dec 2024 01:07:17 +0800 Subject: [PATCH 12/20] chore(zustand): init coaction-zustand --- packages/coaction-mobx/package.json | 17 +++- packages/coaction-pinia/package.json | 6 ++ packages/coaction-react/package.json | 10 +-- packages/coaction-zustand/README.md | 36 ++++++++ packages/coaction-zustand/index.ts | 1 + packages/coaction-zustand/package.json | 87 ++++++++++++++++++++ packages/coaction-zustand/src/index.ts | 22 +++++ packages/coaction-zustand/test/index.test.ts | 5 ++ packages/logger/package.json | 3 + yarn.lock | 39 ++++----- 10 files changed, 196 insertions(+), 30 deletions(-) create mode 100644 packages/coaction-zustand/README.md create mode 100644 packages/coaction-zustand/index.ts create mode 100644 packages/coaction-zustand/package.json create mode 100644 packages/coaction-zustand/src/index.ts create mode 100644 packages/coaction-zustand/test/index.test.ts diff --git a/packages/coaction-mobx/package.json b/packages/coaction-mobx/package.json index 6c039a4..69cc98c 100644 --- a/packages/coaction-mobx/package.json +++ b/packages/coaction-mobx/package.json @@ -50,19 +50,28 @@ "coaction": "^0.1.4", "mobx": "^6.13.2", "mutative": "^1.1.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "coaction": { "optional": true + }, + "mobx": { + "optional": true + }, + "mutative": { + "optional": true + }, + "react": { + "optional": true } }, "devDependencies": { "@testing-library/react": "^14.2.1", "@types/jsdom": "^12.2.3", - "@types/react": "^17.0.43", - "@types/react-dom": "^17.0.14", - "@types/use-sync-external-store": "^0.0.3", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.0", + "@types/use-sync-external-store": "^0.0.6", "coaction": "^0.1.4", "jsdom": "^25.0.1", "jsdom-global": "^3.0.2", diff --git a/packages/coaction-pinia/package.json b/packages/coaction-pinia/package.json index 66357f3..e8f3928 100644 --- a/packages/coaction-pinia/package.json +++ b/packages/coaction-pinia/package.json @@ -54,6 +54,12 @@ "peerDependenciesMeta": { "coaction": { "optional": true + }, + "mutative": { + "optional": true + }, + "pinia": { + "optional": true } }, "devDependencies": { diff --git a/packages/coaction-react/package.json b/packages/coaction-react/package.json index f9ffa73..0153bd7 100644 --- a/packages/coaction-react/package.json +++ b/packages/coaction-react/package.json @@ -47,9 +47,9 @@ ] }, "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "coaction": "^0.1.4", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "coaction": { @@ -62,9 +62,9 @@ "devDependencies": { "@testing-library/react": "^14.2.1", "@types/jsdom": "^12.2.3", - "@types/react": "^17.0.43", - "@types/react-dom": "^17.0.14", - "@types/use-sync-external-store": "^0.0.3", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.0", + "@types/use-sync-external-store": "^0.0.6", "coaction": "^0.1.4", "jsdom": "^25.0.1", "jsdom-global": "^3.0.2", diff --git a/packages/coaction-zustand/README.md b/packages/coaction-zustand/README.md new file mode 100644 index 0000000..3af11d0 --- /dev/null +++ b/packages/coaction-zustand/README.md @@ -0,0 +1,36 @@ +# @coaction/zustand + +![Node CI](https://github.com/unadlib/coaction/workflows/Node%20CI/badge.svg) +[![npm](https://img.shields.io/npm/v/@coaction/zustand.svg)](https://www.npmjs.com/package/@coaction/zustand) +![license](https://img.shields.io/npm/l/@coaction/zustand) + +A Coaction integration tool for Zustand + +## Installation + +You can install it via npm, yarn or pnpm. + +```sh +npm install coaction @coaction/zustand +``` + +## Usage + +```jsx +import { create } from 'coaction'; +import { bindZustand } from '@coaction/zustand'; +import { createWithZustand } from 'zustand'; + +const useStore = create(() => + createWithZustand((set) => + bindZustand({ + count: 1, + inc: () => set((state) => ({ count: state.count + 1 })) + }) + ) +); +``` + +## Documentation + +You can find the documentation [here](https://github.com/unadlib/coaction). diff --git a/packages/coaction-zustand/index.ts b/packages/coaction-zustand/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/packages/coaction-zustand/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/packages/coaction-zustand/package.json b/packages/coaction-zustand/package.json new file mode 100644 index 0000000..726b55d --- /dev/null +++ b/packages/coaction-zustand/package.json @@ -0,0 +1,87 @@ +{ + "name": "@coaction/zustand", + "version": "0.1.4", + "description": "A Coaction integration tool for Zustand", + "keywords": [ + "state", + "coaction", + "zustand", + "hook" + ], + "authors": [ + "Michael Lin (https://github.com/unadlib)" + ], + "homepage": "https://github.com/unadlib/coaction/tree/main/packages/coaction-zustand#readme", + "license": "MIT", + "main": "dist/coaction-zustand.cjs.js", + "module": "dist/coaction-zustand.esm.js", + "exports": { + ".": { + "types": { + "import": "./dist/coaction-zustand.cjs.mjs", + "default": "./dist/coaction-zustand.cjs.js" + }, + "module": "./dist/coaction-zustand.esm.js", + "import": "./dist/coaction-zustand.cjs.mjs", + "default": "./dist/coaction-zustand.cjs.js" + }, + "./package.json": "./package.json" + }, + "types": "dist/coaction-zustand.cjs.d.ts", + "sideEffects": false, + "files": [ + "dist" + ], + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/unadlib/coaction.git" + }, + "scripts": {}, + "bugs": { + "url": "https://github.com/unadlib/coaction/issues" + }, + "preconstruct": { + "umdName": "CoactionZustand", + "entrypoints": [ + "./index.ts" + ] + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "coaction": "^0.1.4", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "use-sync-external-store": ">=1.2.0", + "zustand": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "coaction": { + "optional": true + }, + "react": { + "optional": true + }, + "zustand": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + }, + "devDependencies": { + "@testing-library/react": "^14.2.1", + "@types/jsdom": "^12.2.3", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.0", + "@types/use-sync-external-store": "^0.0.6", + "coaction": "^0.1.4", + "jsdom": "^25.0.1", + "jsdom-global": "^3.0.2", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "use-sync-external-store": "^1.4.0", + "zustand": "^5.0.2" + } +} diff --git a/packages/coaction-zustand/src/index.ts b/packages/coaction-zustand/src/index.ts new file mode 100644 index 0000000..9410d29 --- /dev/null +++ b/packages/coaction-zustand/src/index.ts @@ -0,0 +1,22 @@ +import { apply } from 'mutability'; +import { type Store, createBinder } from 'coaction'; + +const instancesMap = new WeakMap(); + +// const handleStore = (store: Store) => { +// // +// }; + +// interface BindMobx { +// (target: T): T; +// } + +// /** +// * Bind a store to Zustand +// */ +// export const bindZustand = createBinder({ +// handleStore, +// handleState: (options) => { +// // +// } +// }); diff --git a/packages/coaction-zustand/test/index.test.ts b/packages/coaction-zustand/test/index.test.ts new file mode 100644 index 0000000..dce296a --- /dev/null +++ b/packages/coaction-zustand/test/index.test.ts @@ -0,0 +1,5 @@ +// import { add } from '../src/index.ts'; + +test('base', () => { + // expect(add(1, 2)).toBe(3); +}); diff --git a/packages/logger/package.json b/packages/logger/package.json index df83311..55e667b 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -54,6 +54,9 @@ "peerDependenciesMeta": { "coaction": { "optional": true + }, + "mutative": { + "optional": true } } } diff --git a/yarn.lock b/yarn.lock index 4fc4875..2c721b7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2706,13 +2706,6 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6" integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== -"@types/react-dom@^17.0.14": - version "17.0.25" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.25.tgz#e0e5b3571e1069625b3a3da2b279379aa33a0cb5" - integrity sha512-urx7A7UxkZQmThYA4So0NelOVjx3V4rNFVJwp0WZlbIK5eM4rNJDiN3R/E9ix0MBh6kAEojk/9YL+Te6D9zHNA== - dependencies: - "@types/react" "^17" - "@types/react-dom@^18.0.0": version "18.3.0" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.0.tgz#0cbc818755d87066ab6ca74fbedb2547d74a82b0" @@ -2720,6 +2713,11 @@ dependencies: "@types/react" "*" +"@types/react-dom@^18.3.0": + version "18.3.5" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.5.tgz#45f9f87398c5dcea085b715c58ddcf1faf65f716" + integrity sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q== + "@types/react@*": version "18.3.3" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.3.tgz#9679020895318b0915d7a3ab004d92d33375c45f" @@ -2728,13 +2726,12 @@ "@types/prop-types" "*" csstype "^3.0.2" -"@types/react@^17", "@types/react@^17.0.43": - version "17.0.80" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.80.tgz#a5dfc351d6a41257eb592d73d3a85d3b7dbcbb41" - integrity sha512-LrgHIu2lEtIo8M7d1FcI3BdwXWoRQwMoXOZ7+dPTW0lYREjmlHl3P0U1VD0i/9tppOuv8/sam7sOjx34TxSFbA== +"@types/react@^18.3.12": + version "18.3.17" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.17.tgz#d86ca0e081c7a5e979b7db175f9515a41038cea7" + integrity sha512-opAQ5no6LqJNo9TqnxBKsgnkIYHozW9KSTlFVoSUJYh1Fl/sswkEoqIugRSm7tbh6pABtYjGAjW+GOS23j8qbw== dependencies: "@types/prop-types" "*" - "@types/scheduler" "^0.16" csstype "^3.0.2" "@types/resolve@1.17.1": @@ -2744,11 +2741,6 @@ dependencies: "@types/node" "*" -"@types/scheduler@^0.16": - version "0.16.8" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" - integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== - "@types/semver@^6.0.1": version "6.2.7" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-6.2.7.tgz#473fb8d63ea04f7511c699fb9b96830c51e8a53d" @@ -2779,10 +2771,10 @@ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304" integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA== -"@types/use-sync-external-store@^0.0.3": - version "0.0.3" - resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43" - integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA== +"@types/use-sync-external-store@^0.0.6": + version "0.0.6" + resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz#60be8d21baab8c305132eb9cb912ed497852aadc" + integrity sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg== "@types/yargs-parser@*": version "21.0.3" @@ -11389,3 +11381,8 @@ zod@^3.21.4: version "3.23.8" resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g== + +zustand@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/zustand/-/zustand-5.0.2.tgz#f7595ada55a565f1fd6464f002a91e701ee0cfca" + integrity sha512-8qNdnJVJlHlrKXi50LDqqUNmUbuBjoKLrYQBnoChIbVph7vni+sY+YpvdjXG9YLd/Bxr6scMcR+rm5H3aSqPaw== From 51d4b94b13f52ddac58fd36e4658d1012e125f88 Mon Sep 17 00:00:00 2001 From: unadlib Date: Fri, 20 Dec 2024 01:20:25 +0800 Subject: [PATCH 13/20] docs(readme): update --- packages/coaction-zustand/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/coaction-zustand/README.md b/packages/coaction-zustand/README.md index 3af11d0..6349a5c 100644 --- a/packages/coaction-zustand/README.md +++ b/packages/coaction-zustand/README.md @@ -19,14 +19,14 @@ npm install coaction @coaction/zustand ```jsx import { create } from 'coaction'; import { bindZustand } from '@coaction/zustand'; -import { createWithZustand } from 'zustand'; +import { create as createWithZustand } from 'zustand'; const useStore = create(() => - createWithZustand((set) => - bindZustand({ + createWithZustand( + bindZustand((set) => ({ count: 1, inc: () => set((state) => ({ count: state.count + 1 })) - }) + })) ) ); ``` From f3e2834ca4c57a2004c3e1d2694162852047d69d Mon Sep 17 00:00:00 2001 From: unadlib Date: Fri, 20 Dec 2024 20:42:44 +0800 Subject: [PATCH 14/20] refactor(coaction): refactor toRaw --- packages/coaction-mobx/src/index.ts | 11 ++++++++--- packages/coaction-mobx/test/base.test.ts | 12 ++++++------ packages/coaction-pinia/src/index.ts | 13 +++++++++---- packages/core/src/binder.ts | 8 +++++++- packages/core/src/create.ts | 2 +- packages/core/src/getInitialState.ts | 12 +++++++++--- packages/core/src/getRawState.ts | 2 +- packages/core/src/interface.ts | 4 ---- packages/core/src/internal.ts | 4 ++++ 9 files changed, 45 insertions(+), 23 deletions(-) diff --git a/packages/coaction-mobx/src/index.ts b/packages/coaction-mobx/src/index.ts index 8437df2..53073d3 100644 --- a/packages/coaction-mobx/src/index.ts +++ b/packages/coaction-mobx/src/index.ts @@ -4,9 +4,14 @@ import { autorun, runInAction } from 'mobx'; const instancesMap = new WeakMap(); -const handleStore = (store: Store) => { - if (store.toRaw) return; - store.toRaw = (key: object) => instancesMap.get(key); +const handleStore = ( + store: Store, + rawState: object, + state: object, + internal: any +) => { + if (internal.toRaw) return; + internal.toRaw = (key: object) => instancesMap.get(key); Object.assign(store, { subscribe: autorun }); diff --git a/packages/coaction-mobx/test/base.test.ts b/packages/coaction-mobx/test/base.test.ts index f2b3641..8a2636d 100644 --- a/packages/coaction-mobx/test/base.test.ts +++ b/packages/coaction-mobx/test/base.test.ts @@ -125,12 +125,12 @@ test('base - error handling', () => { expect(() => useStore.getState().increment()).toThrow('test'); expect(fn).toHaveBeenCalledTimes(1); expect(useStore.getState()).toMatchInlineSnapshot(` - { - "count": 1, - "double": 2, - "increment": [Function], - } - `); +{ + "count": 1, + "double": 2, + "increment": [Function], +} +`); }); test('base enablePatches - error handling', () => { diff --git a/packages/coaction-pinia/src/index.ts b/packages/coaction-pinia/src/index.ts index 1c78618..e8a0464 100644 --- a/packages/coaction-pinia/src/index.ts +++ b/packages/coaction-pinia/src/index.ts @@ -47,9 +47,14 @@ export type IStore = [ Pick> ]; -const handleStore = (store: StoreWithSubscriptions, state: object) => { - if (!store.toRaw) { - store.toRaw = (key: any) => instancesMap.get(key); +const handleStore = ( + store: StoreWithSubscriptions, + state: object, + _: object, + internal: any +) => { + if (!internal.toRaw) { + internal.toRaw = (key: any) => instancesMap.get(key); Object.assign(store, { subscribe: (callback: any) => { store._subscriptions!.add(callback); @@ -87,7 +92,7 @@ const handleStore = (store: StoreWithSubscriptions, state: object) => { apply(state, patches); }; } - const stopWatch = store.toRaw(state).$subscribe((...args: unknown[]) => { + const stopWatch = internal.toRaw(state).$subscribe((...args: unknown[]) => { store._subscriptions!.forEach((callback) => callback(...args)); }); const destroy = () => { diff --git a/packages/core/src/binder.ts b/packages/core/src/binder.ts index 9e78586..2e10447 100644 --- a/packages/core/src/binder.ts +++ b/packages/core/src/binder.ts @@ -1,5 +1,6 @@ import type { Store } from './interface'; import { bindSymbol } from './constant'; +import { Internal } from './internal'; /** * createBinder is a function to create a binder for the 3rd party store. @@ -30,7 +31,12 @@ export function createBinder any>({ /** * handleStore is a function to handle the store object. */ - handleStore: (store: Store, rawState: object, state: object) => void; + handleStore: ( + store: Store, + rawState: object, + state: object, + internal: Internal + ) => void; }) { return ((state: S): S => { const { copyState, key, bind } = handleState(state); diff --git a/packages/core/src/create.ts b/packages/core/src/create.ts index a0dfb80..2567c8c 100644 --- a/packages/core/src/create.ts +++ b/packages/core/src/create.ts @@ -95,7 +95,7 @@ export const create: Creator = ( getPureState } as Store); applyMiddlewares(store, options.middlewares ?? []); - const initialState = getInitialState(store, createState); + const initialState = getInitialState(store, createState, internal); store.getInitialState = () => initialState; internal.rootState = getRawState( store, diff --git a/packages/core/src/getInitialState.ts b/packages/core/src/getInitialState.ts index e38faa7..073ebfb 100644 --- a/packages/core/src/getInitialState.ts +++ b/packages/core/src/getInitialState.ts @@ -1,9 +1,11 @@ import { bindSymbol } from './constant'; import type { CreateState, ISlices, Slice, Store } from './interface'; +import { Internal } from './internal'; export const getInitialState = ( store: Store, - createState: any + createState: any, + internal: Internal ) => { const makeState = (fn: (...args: any[]) => any) => { // make sure createState is a function @@ -11,12 +13,16 @@ export const getInitialState = ( throw new Error('createState should be a function'); } let state = fn(store.setState, store.getState, store); - if (typeof state === 'function') { + // support 3rd party library store like zustand, pinia + if (state.getState) { + state = state.getState(); + } else if (typeof state === 'function') { state = state(); } + // support bind store like mobx if (state[bindSymbol]) { const rawState = state[bindSymbol].bind(state); - state[bindSymbol].handleStore(store, rawState, state); + state[bindSymbol].handleStore(store, rawState, state, internal); return rawState; } return state; diff --git a/packages/core/src/getRawState.ts b/packages/core/src/getRawState.ts index 0008597..ff35e81 100644 --- a/packages/core/src/getRawState.ts +++ b/packages/core/src/getRawState.ts @@ -23,7 +23,7 @@ export const getRawState = ( ) => { const rawState = {} as Record; const handle = (_rawState: any, _initialState: any, sliceKey?: string) => { - internal.mutableInstance = store.toRaw?.(_initialState); + internal.mutableInstance = internal.toRaw?.(_initialState); const descriptors = Object.getOwnPropertyDescriptors(_initialState); Object.entries(descriptors).forEach(([key, descriptor]) => { if (Object.prototype.hasOwnProperty.call(descriptor, 'value')) { diff --git a/packages/core/src/interface.ts b/packages/core/src/interface.ts index 3a436cc..b816542 100644 --- a/packages/core/src/interface.ts +++ b/packages/core/src/interface.ts @@ -65,10 +65,6 @@ export interface Store { * Get the initial state. */ getInitialState: () => T; - /** - * Get the raw instance via the initial state. - */ - toRaw?: (key: any) => any; /** * The patch is used to update the state. */ diff --git a/packages/core/src/internal.ts b/packages/core/src/internal.ts index 44ef5e5..9180002 100644 --- a/packages/core/src/internal.ts +++ b/packages/core/src/internal.ts @@ -2,6 +2,10 @@ import type { Draft, Patches } from 'mutative'; import type { CreateState, Listener } from './interface'; export interface Internal { + /** + * Get the raw instance via the initial state. + */ + toRaw?: (key: any) => any; module: T; rootState: T | Draft; backupState: T | Draft; From ba6f4b822030a10477549832e002eafb2e9a071f Mon Sep 17 00:00:00 2001 From: unadlib Date: Fri, 20 Dec 2024 20:44:32 +0800 Subject: [PATCH 15/20] refactor(coaction): update --- packages/coaction-mobx/src/index.ts | 4 ++-- packages/coaction-pinia/src/index.ts | 12 +++++++----- packages/core/src/getRawState.ts | 2 +- packages/core/src/internal.ts | 28 ++++++++++++++++++++++++++-- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/packages/coaction-mobx/src/index.ts b/packages/coaction-mobx/src/index.ts index 53073d3..a5c2dd8 100644 --- a/packages/coaction-mobx/src/index.ts +++ b/packages/coaction-mobx/src/index.ts @@ -10,8 +10,8 @@ const handleStore = ( state: object, internal: any ) => { - if (internal.toRaw) return; - internal.toRaw = (key: object) => instancesMap.get(key); + if (internal.toMutableRaw) return; + internal.toMutableRaw = (key: object) => instancesMap.get(key); Object.assign(store, { subscribe: autorun }); diff --git a/packages/coaction-pinia/src/index.ts b/packages/coaction-pinia/src/index.ts index e8a0464..f88deb8 100644 --- a/packages/coaction-pinia/src/index.ts +++ b/packages/coaction-pinia/src/index.ts @@ -53,8 +53,8 @@ const handleStore = ( _: object, internal: any ) => { - if (!internal.toRaw) { - internal.toRaw = (key: any) => instancesMap.get(key); + if (!internal.toMutableRaw) { + internal.toMutableRaw = (key: any) => instancesMap.get(key); Object.assign(store, { subscribe: (callback: any) => { store._subscriptions!.add(callback); @@ -92,9 +92,11 @@ const handleStore = ( apply(state, patches); }; } - const stopWatch = internal.toRaw(state).$subscribe((...args: unknown[]) => { - store._subscriptions!.forEach((callback) => callback(...args)); - }); + const stopWatch = internal + .toMutableRaw(state) + .$subscribe((...args: unknown[]) => { + store._subscriptions!.forEach((callback) => callback(...args)); + }); const destroy = () => { instancesMap.delete(state); stopWatch(); diff --git a/packages/core/src/getRawState.ts b/packages/core/src/getRawState.ts index ff35e81..b5dd47a 100644 --- a/packages/core/src/getRawState.ts +++ b/packages/core/src/getRawState.ts @@ -23,7 +23,7 @@ export const getRawState = ( ) => { const rawState = {} as Record; const handle = (_rawState: any, _initialState: any, sliceKey?: string) => { - internal.mutableInstance = internal.toRaw?.(_initialState); + internal.mutableInstance = internal.toMutableRaw?.(_initialState); const descriptors = Object.getOwnPropertyDescriptors(_initialState); Object.entries(descriptors).forEach(([key, descriptor]) => { if (Object.prototype.hasOwnProperty.call(descriptor, 'value')) { diff --git a/packages/core/src/internal.ts b/packages/core/src/internal.ts index 9180002..413ceb9 100644 --- a/packages/core/src/internal.ts +++ b/packages/core/src/internal.ts @@ -3,15 +3,39 @@ import type { CreateState, Listener } from './interface'; export interface Internal { /** - * Get the raw instance via the initial state. + * Get the mutable raw instance via the initial state. + */ + toMutableRaw?: (key: any) => any; + /** + * The store module. */ - toRaw?: (key: any) => any; module: T; + /** + * The root state. + */ rootState: T | Draft; + /** + * The backup state. + */ backupState: T | Draft; + /** + * Finalize the draft. + */ finalizeDraft: () => [T, Patches, Patches]; + /** + * The mutable instance. + */ mutableInstance: any; + /** + * The sequence number. + */ sequence: number; + /** + * Whether the batch is running. + */ isBatching: boolean; + /** + * The listeners. + */ listeners: Set; } From d5d24f4d387b9fc52c95f1025f306a9180e883fc Mon Sep 17 00:00:00 2001 From: unadlib Date: Fri, 20 Dec 2024 20:52:33 +0800 Subject: [PATCH 16/20] refactor(coaction): refactor act() --- packages/coaction-mobx/src/index.ts | 2 +- packages/core/src/getRawState.ts | 4 ++-- packages/core/src/handleState.ts | 4 ++-- packages/core/src/interface.ts | 6 +----- packages/core/src/internal.ts | 12 ++++++++---- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/coaction-mobx/src/index.ts b/packages/coaction-mobx/src/index.ts index a5c2dd8..6bf5d87 100644 --- a/packages/coaction-mobx/src/index.ts +++ b/packages/coaction-mobx/src/index.ts @@ -15,7 +15,7 @@ const handleStore = ( Object.assign(store, { subscribe: autorun }); - store.act = runInAction; + internal.actMutable = runInAction; store.apply = (state = store.getState(), patches) => { if (!patches) { if (store.isSliceStore) { diff --git a/packages/core/src/getRawState.ts b/packages/core/src/getRawState.ts index b5dd47a..569a6d4 100644 --- a/packages/core/src/getRawState.ts +++ b/packages/core/src/getRawState.ts @@ -192,8 +192,8 @@ export const getRawState = ( done?.(result); return result; } - if (internal.mutableInstance && store.act) { - const result = store.act(() => { + if (internal.mutableInstance && internal.actMutable) { + const result = internal.actMutable(() => { return fn.apply( sliceKey ? store.getState()[sliceKey] : store.getState(), args diff --git a/packages/core/src/handleState.ts b/packages/core/src/handleState.ts index 10d0448..96cf9b0 100644 --- a/packages/core/src/handleState.ts +++ b/packages/core/src/handleState.ts @@ -47,8 +47,8 @@ export const handleState = ( store.transport ?? (options as StoreOptions).enablePatches; if (!enablePatches) { if (internal.mutableInstance) { - if (store.act) { - store.act(() => { + if (internal.actMutable) { + internal.actMutable(() => { fn.apply(null); }); return []; diff --git a/packages/core/src/interface.ts b/packages/core/src/interface.ts index b816542..4d08d19 100644 --- a/packages/core/src/interface.ts +++ b/packages/core/src/interface.ts @@ -34,7 +34,7 @@ export interface Store { */ getState: () => T; /** - * Subscribe to the state changes. + * Subscribe to the state changes, and return the unsubscribe function. */ subscribe: (listener: Listener) => () => void; /** @@ -72,10 +72,6 @@ export interface Store { patches: Patches; inversePatches: Patches; }; - /** - * The act is used to run the function in the action. - */ - act?: any>(fn: T) => ReturnType; /** * The trace is used to trace the action */ diff --git a/packages/core/src/internal.ts b/packages/core/src/internal.ts index 413ceb9..1095a62 100644 --- a/packages/core/src/internal.ts +++ b/packages/core/src/internal.ts @@ -2,10 +2,6 @@ import type { Draft, Patches } from 'mutative'; import type { CreateState, Listener } from './interface'; export interface Internal { - /** - * Get the mutable raw instance via the initial state. - */ - toMutableRaw?: (key: any) => any; /** * The store module. */ @@ -38,4 +34,12 @@ export interface Internal { * The listeners. */ listeners: Set; + /** + * The act is used to run the function in the action for mutable state. + */ + actMutable?: any>(fn: T) => ReturnType; + /** + * Get the mutable raw instance via the initial state. + */ + toMutableRaw?: (key: any) => any; } From 176109aec5264d51b714efd42e05a113e35f9fb2 Mon Sep 17 00:00:00 2001 From: unadlib Date: Sat, 21 Dec 2024 00:09:14 +0800 Subject: [PATCH 17/20] feat(zustand): implement @coaction/zustand --- examples/zustand-base/.gitignore | 24 + examples/zustand-base/README.md | 50 + examples/zustand-base/eslint.config.js | 28 + examples/zustand-base/index.html | 13 + examples/zustand-base/package.json | 29 + examples/zustand-base/public/vite.svg | 1 + examples/zustand-base/src/App.css | 42 + examples/zustand-base/src/App.tsx | 34 + examples/zustand-base/src/assets/react.svg | 1 + examples/zustand-base/src/counter.ts | 13 + examples/zustand-base/src/index.css | 68 + examples/zustand-base/src/main.tsx | 10 + examples/zustand-base/src/store.ts | 22 + examples/zustand-base/src/vite-env.d.ts | 1 + examples/zustand-base/src/worker.ts | 19 + examples/zustand-base/tsconfig.app.json | 26 + examples/zustand-base/tsconfig.json | 7 + examples/zustand-base/tsconfig.node.json | 24 + examples/zustand-base/vite.config.ts | 7 + examples/zustand-base/yarn.lock | 1505 ++++++++++++++++++ packages/coaction-zustand/src/index.ts | 61 +- packages/coaction-zustand/test/index.test.ts | 158 +- packages/core/src/create.ts | 6 +- packages/core/src/getInitialState.ts | 4 +- packages/core/src/handleState.ts | 12 +- packages/core/src/interface.ts | 2 + packages/core/src/internal.ts | 4 + 27 files changed, 2146 insertions(+), 25 deletions(-) create mode 100644 examples/zustand-base/.gitignore create mode 100644 examples/zustand-base/README.md create mode 100644 examples/zustand-base/eslint.config.js create mode 100644 examples/zustand-base/index.html create mode 100644 examples/zustand-base/package.json create mode 100644 examples/zustand-base/public/vite.svg create mode 100644 examples/zustand-base/src/App.css create mode 100644 examples/zustand-base/src/App.tsx create mode 100644 examples/zustand-base/src/assets/react.svg create mode 100644 examples/zustand-base/src/counter.ts create mode 100644 examples/zustand-base/src/index.css create mode 100644 examples/zustand-base/src/main.tsx create mode 100644 examples/zustand-base/src/store.ts create mode 100644 examples/zustand-base/src/vite-env.d.ts create mode 100644 examples/zustand-base/src/worker.ts create mode 100644 examples/zustand-base/tsconfig.app.json create mode 100644 examples/zustand-base/tsconfig.json create mode 100644 examples/zustand-base/tsconfig.node.json create mode 100644 examples/zustand-base/vite.config.ts create mode 100644 examples/zustand-base/yarn.lock diff --git a/examples/zustand-base/.gitignore b/examples/zustand-base/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/examples/zustand-base/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/examples/zustand-base/README.md b/examples/zustand-base/README.md new file mode 100644 index 0000000..fe47ff5 --- /dev/null +++ b/examples/zustand-base/README.md @@ -0,0 +1,50 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: + +- Configure the top-level `parserOptions` property like this: + +```js +export default tseslint.config({ + languageOptions: { + // other options... + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname + } + } +}); +``` + +- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` +- Optionally add `...tseslint.configs.stylisticTypeChecked` +- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: + +```js +// eslint.config.js +import react from 'eslint-plugin-react'; + +export default tseslint.config({ + // Set the react version + settings: { react: { version: '18.3' } }, + plugins: { + // Add the react plugin + react + }, + rules: { + // other rules... + // Enable its recommended rules + ...react.configs.recommended.rules, + ...react.configs['jsx-runtime'].rules + } +}); +``` diff --git a/examples/zustand-base/eslint.config.js b/examples/zustand-base/eslint.config.js new file mode 100644 index 0000000..61f2de9 --- /dev/null +++ b/examples/zustand-base/eslint.config.js @@ -0,0 +1,28 @@ +import js from '@eslint/js'; +import globals from 'globals'; +import reactHooks from 'eslint-plugin-react-hooks'; +import reactRefresh from 'eslint-plugin-react-refresh'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config( + { ignores: ['dist'] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ['**/*.{ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh + }, + rules: { + ...reactHooks.configs.recommended.rules, + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true } + ] + } + } +); diff --git a/examples/zustand-base/index.html b/examples/zustand-base/index.html new file mode 100644 index 0000000..e4b78ea --- /dev/null +++ b/examples/zustand-base/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + TS + + +
+ + + diff --git a/examples/zustand-base/package.json b/examples/zustand-base/package.json new file mode 100644 index 0000000..14ff34c --- /dev/null +++ b/examples/zustand-base/package.json @@ -0,0 +1,29 @@ +{ + "name": "zustand-base", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@eslint/js": "^9.17.0", + "@types/react": "^18.3.17", + "@types/react-dom": "^18.3.5", + "@vitejs/plugin-react": "^4.3.4", + "eslint": "^9.17.0", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.16", + "globals": "^15.13.0", + "typescript": "~5.6.2", + "typescript-eslint": "^8.18.1", + "vite": "^6.0.3" + } +} diff --git a/examples/zustand-base/public/vite.svg b/examples/zustand-base/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/examples/zustand-base/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/zustand-base/src/App.css b/examples/zustand-base/src/App.css new file mode 100644 index 0000000..b9d355d --- /dev/null +++ b/examples/zustand-base/src/App.css @@ -0,0 +1,42 @@ +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: no-preference) { + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} diff --git a/examples/zustand-base/src/App.tsx b/examples/zustand-base/src/App.tsx new file mode 100644 index 0000000..f336803 --- /dev/null +++ b/examples/zustand-base/src/App.tsx @@ -0,0 +1,34 @@ +import reactLogo from './assets/react.svg'; +import viteLogo from '/vite.svg'; +import './App.css'; + +import { useStore } from './store'; + +function App() { + const { count, increment } = useStore(); + + return ( + <> + +

Vite + React

+
+ +

+ Edit src/App.tsx and save to test HMR +

+
+

+ Click on the Vite and React logos to learn more +

+ + ); +} + +export default App; diff --git a/examples/zustand-base/src/assets/react.svg b/examples/zustand-base/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/examples/zustand-base/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/zustand-base/src/counter.ts b/examples/zustand-base/src/counter.ts new file mode 100644 index 0000000..4771871 --- /dev/null +++ b/examples/zustand-base/src/counter.ts @@ -0,0 +1,13 @@ +import type { Slice } from '@coaction/react'; + +export type Counter = { + count: number; + increment: () => void; +}; + +export const counter: Slice = (set) => ({ + count: 0, + increment() { + set((state) => ({ count: state.count + 1 })); + } +}); diff --git a/examples/zustand-base/src/index.css b/examples/zustand-base/src/index.css new file mode 100644 index 0000000..6119ad9 --- /dev/null +++ b/examples/zustand-base/src/index.css @@ -0,0 +1,68 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/examples/zustand-base/src/main.tsx b/examples/zustand-base/src/main.tsx new file mode 100644 index 0000000..df655ea --- /dev/null +++ b/examples/zustand-base/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react'; +import { createRoot } from 'react-dom/client'; +import './index.css'; +import App from './App.tsx'; + +createRoot(document.getElementById('root')!).render( + + + +); diff --git a/examples/zustand-base/src/store.ts b/examples/zustand-base/src/store.ts new file mode 100644 index 0000000..1f538e4 --- /dev/null +++ b/examples/zustand-base/src/store.ts @@ -0,0 +1,22 @@ +import { create } from '@coaction/react'; +import { logger } from '@coaction/logger'; +import { create as createWithZustand } from 'zustand'; +import { bindZustand } from '@coaction/zustand'; + +import { counter, type Counter } from './counter'; + +const worker = new SharedWorker(new URL('./worker.ts', import.meta.url), { + type: 'module' +}); + +export const useStore = create( + () => createWithZustand(bindZustand(counter)), + { + worker, + middlewares: [ + logger({ + collapsed: false + }) + ] + } +); diff --git a/examples/zustand-base/src/vite-env.d.ts b/examples/zustand-base/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/examples/zustand-base/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/examples/zustand-base/src/worker.ts b/examples/zustand-base/src/worker.ts new file mode 100644 index 0000000..8e05f16 --- /dev/null +++ b/examples/zustand-base/src/worker.ts @@ -0,0 +1,19 @@ +import { create } from '@coaction/react'; +import { logger } from '@coaction/logger'; +import { create as createWithZustand } from 'zustand'; +import { bindZustand } from '@coaction/zustand'; + +import { counter, type Counter } from './counter'; + +export const useStore = create( + () => createWithZustand(bindZustand(counter)), + { + middlewares: [ + logger({ + collapsed: false + }) + ] + } +); + +globalThis.useStore = useStore; diff --git a/examples/zustand-base/tsconfig.app.json b/examples/zustand-base/tsconfig.app.json new file mode 100644 index 0000000..358ca9b --- /dev/null +++ b/examples/zustand-base/tsconfig.app.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src"] +} diff --git a/examples/zustand-base/tsconfig.json b/examples/zustand-base/tsconfig.json new file mode 100644 index 0000000..1ffef60 --- /dev/null +++ b/examples/zustand-base/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/examples/zustand-base/tsconfig.node.json b/examples/zustand-base/tsconfig.node.json new file mode 100644 index 0000000..db0becc --- /dev/null +++ b/examples/zustand-base/tsconfig.node.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/examples/zustand-base/vite.config.ts b/examples/zustand-base/vite.config.ts new file mode 100644 index 0000000..4ae1e57 --- /dev/null +++ b/examples/zustand-base/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()] +}); diff --git a/examples/zustand-base/yarn.lock b/examples/zustand-base/yarn.lock new file mode 100644 index 0000000..676b97f --- /dev/null +++ b/examples/zustand-base/yarn.lock @@ -0,0 +1,1505 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@^2.2.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" + integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + +"@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0", "@babel/code-frame@^7.26.2": + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" + integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== + dependencies: + "@babel/helper-validator-identifier" "^7.25.9" + js-tokens "^4.0.0" + picocolors "^1.0.0" + +"@babel/compat-data@^7.25.9": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.3.tgz#99488264a56b2aded63983abd6a417f03b92ed02" + integrity sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g== + +"@babel/core@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.0.tgz#d78b6023cc8f3114ccf049eb219613f74a747b40" + integrity sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.26.0" + "@babel/generator" "^7.26.0" + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-module-transforms" "^7.26.0" + "@babel/helpers" "^7.26.0" + "@babel/parser" "^7.26.0" + "@babel/template" "^7.25.9" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.26.0" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.26.0", "@babel/generator@^7.26.3": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.3.tgz#ab8d4360544a425c90c248df7059881f4b2ce019" + integrity sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ== + dependencies: + "@babel/parser" "^7.26.3" + "@babel/types" "^7.26.3" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^3.0.2" + +"@babel/helper-compilation-targets@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz#55af025ce365be3cdc0c1c1e56c6af617ce88875" + integrity sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ== + dependencies: + "@babel/compat-data" "^7.25.9" + "@babel/helper-validator-option" "^7.25.9" + browserslist "^4.24.0" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-module-imports@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz#e7f8d20602ebdbf9ebbea0a0751fb0f2a4141715" + integrity sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw== + dependencies: + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" + +"@babel/helper-module-transforms@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz#8ce54ec9d592695e58d84cd884b7b5c6a2fdeeae" + integrity sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw== + dependencies: + "@babel/helper-module-imports" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + "@babel/traverse" "^7.25.9" + +"@babel/helper-plugin-utils@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz#9cbdd63a9443a2c92a725cca7ebca12cc8dd9f46" + integrity sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw== + +"@babel/helper-string-parser@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c" + integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== + +"@babel/helper-validator-identifier@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" + integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== + +"@babel/helper-validator-option@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz#86e45bd8a49ab7e03f276577f96179653d41da72" + integrity sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw== + +"@babel/helpers@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.0.tgz#30e621f1eba5aa45fe6f4868d2e9154d884119a4" + integrity sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw== + dependencies: + "@babel/template" "^7.25.9" + "@babel/types" "^7.26.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.25.9", "@babel/parser@^7.26.0", "@babel/parser@^7.26.3": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.3.tgz#8c51c5db6ddf08134af1ddbacf16aaab48bac234" + integrity sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA== + dependencies: + "@babel/types" "^7.26.3" + +"@babel/plugin-transform-react-jsx-self@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz#c0b6cae9c1b73967f7f9eb2fca9536ba2fad2858" + integrity sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-react-jsx-source@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz#4c6b8daa520b5f155b5fb55547d7c9fa91417503" + integrity sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/template@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.9.tgz#ecb62d81a8a6f5dc5fe8abfc3901fc52ddf15016" + integrity sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg== + dependencies: + "@babel/code-frame" "^7.25.9" + "@babel/parser" "^7.25.9" + "@babel/types" "^7.25.9" + +"@babel/traverse@^7.25.9": + version "7.26.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.26.4.tgz#ac3a2a84b908dde6d463c3bfa2c5fdc1653574bd" + integrity sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w== + dependencies: + "@babel/code-frame" "^7.26.2" + "@babel/generator" "^7.26.3" + "@babel/parser" "^7.26.3" + "@babel/template" "^7.25.9" + "@babel/types" "^7.26.3" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.25.9", "@babel/types@^7.26.0", "@babel/types@^7.26.3": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.3.tgz#37e79830f04c2b5687acc77db97fbc75fb81f3c0" + integrity sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA== + dependencies: + "@babel/helper-string-parser" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + +"@esbuild/aix-ppc64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz#b57697945b50e99007b4c2521507dc613d4a648c" + integrity sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw== + +"@esbuild/android-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz#1add7e0af67acefd556e407f8497e81fddad79c0" + integrity sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w== + +"@esbuild/android-arm@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.24.0.tgz#ab7263045fa8e090833a8e3c393b60d59a789810" + integrity sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew== + +"@esbuild/android-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.24.0.tgz#e8f8b196cfdfdd5aeaebbdb0110983460440e705" + integrity sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ== + +"@esbuild/darwin-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz#2d0d9414f2acbffd2d86e98253914fca603a53dd" + integrity sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw== + +"@esbuild/darwin-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz#33087aab31a1eb64c89daf3d2cf8ce1775656107" + integrity sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA== + +"@esbuild/freebsd-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz#bb76e5ea9e97fa3c753472f19421075d3a33e8a7" + integrity sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA== + +"@esbuild/freebsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz#e0e2ce9249fdf6ee29e5dc3d420c7007fa579b93" + integrity sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ== + +"@esbuild/linux-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz#d1b2aa58085f73ecf45533c07c82d81235388e75" + integrity sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g== + +"@esbuild/linux-arm@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz#8e4915df8ea3e12b690a057e77a47b1d5935ef6d" + integrity sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw== + +"@esbuild/linux-ia32@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz#8200b1110666c39ab316572324b7af63d82013fb" + integrity sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA== + +"@esbuild/linux-loong64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz#6ff0c99cf647504df321d0640f0d32e557da745c" + integrity sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g== + +"@esbuild/linux-mips64el@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz#3f720ccd4d59bfeb4c2ce276a46b77ad380fa1f3" + integrity sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA== + +"@esbuild/linux-ppc64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz#9d6b188b15c25afd2e213474bf5f31e42e3aa09e" + integrity sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ== + +"@esbuild/linux-riscv64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz#f989fdc9752dfda286c9cd87c46248e4dfecbc25" + integrity sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw== + +"@esbuild/linux-s390x@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz#29ebf87e4132ea659c1489fce63cd8509d1c7319" + integrity sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g== + +"@esbuild/linux-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz#4af48c5c0479569b1f359ffbce22d15f261c0cef" + integrity sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA== + +"@esbuild/netbsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz#1ae73d23cc044a0ebd4f198334416fb26c31366c" + integrity sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg== + +"@esbuild/openbsd-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz#5d904a4f5158c89859fd902c427f96d6a9e632e2" + integrity sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg== + +"@esbuild/openbsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz#4c8aa88c49187c601bae2971e71c6dc5e0ad1cdf" + integrity sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q== + +"@esbuild/sunos-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz#8ddc35a0ea38575fa44eda30a5ee01ae2fa54dd4" + integrity sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA== + +"@esbuild/win32-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz#6e79c8543f282c4539db684a207ae0e174a9007b" + integrity sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA== + +"@esbuild/win32-ia32@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz#057af345da256b7192d18b676a02e95d0fa39103" + integrity sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw== + +"@esbuild/win32-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz#168ab1c7e1c318b922637fad8f339d48b01e1244" + integrity sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA== + +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.4.1" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz#d1145bf2c20132d6400495d6df4bf59362fd9d56" + integrity sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA== + dependencies: + eslint-visitor-keys "^3.4.3" + +"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" + integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== + +"@eslint/config-array@^0.19.0": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.1.tgz#734aaea2c40be22bbb1f2a9dac687c57a6a4c984" + integrity sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA== + dependencies: + "@eslint/object-schema" "^2.1.5" + debug "^4.3.1" + minimatch "^3.1.2" + +"@eslint/core@^0.9.0": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.9.1.tgz#31763847308ef6b7084a4505573ac9402c51f9d1" + integrity sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q== + dependencies: + "@types/json-schema" "^7.0.15" + +"@eslint/eslintrc@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.2.0.tgz#57470ac4e2e283a6bf76044d63281196e370542c" + integrity sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^10.0.1" + globals "^14.0.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@9.17.0", "@eslint/js@^9.17.0": + version "9.17.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.17.0.tgz#1523e586791f80376a6f8398a3964455ecc651ec" + integrity sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w== + +"@eslint/object-schema@^2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.5.tgz#8670a8f6258a2be5b2c620ff314a1d984c23eb2e" + integrity sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ== + +"@eslint/plugin-kit@^0.2.3": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz#2b78e7bb3755784bb13faa8932a1d994d6537792" + integrity sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg== + dependencies: + levn "^0.4.1" + +"@humanfs/core@^0.19.1": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77" + integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== + +"@humanfs/node@^0.16.6": + version "0.16.6" + resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.6.tgz#ee2a10eaabd1131987bf0488fd9b820174cd765e" + integrity sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw== + dependencies: + "@humanfs/core" "^0.19.1" + "@humanwhocodes/retry" "^0.3.0" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/retry@^0.3.0": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a" + integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA== + +"@humanwhocodes/retry@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.1.tgz#9a96ce501bc62df46c4031fbd970e3cc6b10f07b" + integrity sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA== + +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz#4f0e06362e01362f823d348f1872b08f666d8142" + integrity sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@rollup/rollup-android-arm-eabi@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz#7f4c4d8cd5ccab6e95d6750dbe00321c1f30791e" + integrity sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ== + +"@rollup/rollup-android-arm64@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.1.tgz#17ea71695fb1518c2c324badbe431a0bd1879f2d" + integrity sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA== + +"@rollup/rollup-darwin-arm64@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.1.tgz#dac0f0d0cfa73e7d5225ae6d303c13c8979e7999" + integrity sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ== + +"@rollup/rollup-darwin-x64@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.1.tgz#8f63baa1d31784904a380d2e293fa1ddf53dd4a2" + integrity sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ== + +"@rollup/rollup-freebsd-arm64@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.1.tgz#30ed247e0df6e8858cdc6ae4090e12dbeb8ce946" + integrity sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA== + +"@rollup/rollup-freebsd-x64@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.1.tgz#57846f382fddbb508412ae07855b8a04c8f56282" + integrity sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ== + +"@rollup/rollup-linux-arm-gnueabihf@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.1.tgz#378ca666c9dae5e6f94d1d351e7497c176e9b6df" + integrity sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA== + +"@rollup/rollup-linux-arm-musleabihf@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.1.tgz#a692eff3bab330d5c33a5d5813a090c15374cddb" + integrity sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg== + +"@rollup/rollup-linux-arm64-gnu@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.1.tgz#6b1719b76088da5ac1ae1feccf48c5926b9e3db9" + integrity sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA== + +"@rollup/rollup-linux-arm64-musl@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.1.tgz#865baf5b6f5ff67acb32e5a359508828e8dc5788" + integrity sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A== + +"@rollup/rollup-linux-loongarch64-gnu@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.28.1.tgz#23c6609ba0f7fa7a7f2038b6b6a08555a5055a87" + integrity sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA== + +"@rollup/rollup-linux-powerpc64le-gnu@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.1.tgz#652ef0d9334a9f25b9daf85731242801cb0fc41c" + integrity sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A== + +"@rollup/rollup-linux-riscv64-gnu@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.1.tgz#1eb6651839ee6ebca64d6cc64febbd299e95e6bd" + integrity sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA== + +"@rollup/rollup-linux-s390x-gnu@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.1.tgz#015c52293afb3ff2a293cf0936b1d43975c1e9cd" + integrity sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg== + +"@rollup/rollup-linux-x64-gnu@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.1.tgz#b83001b5abed2bcb5e2dbeec6a7e69b194235c1e" + integrity sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw== + +"@rollup/rollup-linux-x64-musl@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.1.tgz#6cc7c84cd4563737f8593e66f33b57d8e228805b" + integrity sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g== + +"@rollup/rollup-win32-arm64-msvc@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.1.tgz#631ffeee094d71279fcd1fe8072bdcf25311bc11" + integrity sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A== + +"@rollup/rollup-win32-ia32-msvc@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.1.tgz#06d1d60d5b9f718e8a6c4a43f82e3f9e3254587f" + integrity sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA== + +"@rollup/rollup-win32-x64-msvc@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.1.tgz#4dff5c4259ebe6c5b4a8f2c5bc3829b7a8447ff0" + integrity sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA== + +"@types/babel__core@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.8" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*": + version "7.20.6" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.6.tgz#8dc9f0ae0f202c08d8d4dab648912c8d6038e3f7" + integrity sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg== + dependencies: + "@babel/types" "^7.20.7" + +"@types/estree@1.0.6", "@types/estree@^1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== + +"@types/json-schema@^7.0.15": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/prop-types@*": + version "15.7.14" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.14.tgz#1433419d73b2a7ebfc6918dcefd2ec0d5cd698f2" + integrity sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ== + +"@types/react-dom@^18.3.5": + version "18.3.5" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.5.tgz#45f9f87398c5dcea085b715c58ddcf1faf65f716" + integrity sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q== + +"@types/react@^18.3.17": + version "18.3.18" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.18.tgz#9b382c4cd32e13e463f97df07c2ee3bbcd26904b" + integrity sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ== + dependencies: + "@types/prop-types" "*" + csstype "^3.0.2" + +"@typescript-eslint/eslint-plugin@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.18.1.tgz#992e5ac1553ce20d0d46aa6eccd79dc36dedc805" + integrity sha512-Ncvsq5CT3Gvh+uJG0Lwlho6suwDfUXH0HztslDf5I+F2wAFAZMRwYLEorumpKLzmO2suAXZ/td1tBg4NZIi9CQ== + dependencies: + "@eslint-community/regexpp" "^4.10.0" + "@typescript-eslint/scope-manager" "8.18.1" + "@typescript-eslint/type-utils" "8.18.1" + "@typescript-eslint/utils" "8.18.1" + "@typescript-eslint/visitor-keys" "8.18.1" + graphemer "^1.4.0" + ignore "^5.3.1" + natural-compare "^1.4.0" + ts-api-utils "^1.3.0" + +"@typescript-eslint/parser@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.18.1.tgz#c258bae062778b7696793bc492249027a39dfb95" + integrity sha512-rBnTWHCdbYM2lh7hjyXqxk70wvon3p2FyaniZuey5TrcGBpfhVp0OxOa6gxr9Q9YhZFKyfbEnxc24ZnVbbUkCA== + dependencies: + "@typescript-eslint/scope-manager" "8.18.1" + "@typescript-eslint/types" "8.18.1" + "@typescript-eslint/typescript-estree" "8.18.1" + "@typescript-eslint/visitor-keys" "8.18.1" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.18.1.tgz#52cedc3a8178d7464a70beffed3203678648e55b" + integrity sha512-HxfHo2b090M5s2+/9Z3gkBhI6xBH8OJCFjH9MhQ+nnoZqxU3wNxkLT+VWXWSFWc3UF3Z+CfPAyqdCTdoXtDPCQ== + dependencies: + "@typescript-eslint/types" "8.18.1" + "@typescript-eslint/visitor-keys" "8.18.1" + +"@typescript-eslint/type-utils@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.18.1.tgz#10f41285475c0bdee452b79ff7223f0e43a7781e" + integrity sha512-jAhTdK/Qx2NJPNOTxXpMwlOiSymtR2j283TtPqXkKBdH8OAMmhiUfP0kJjc/qSE51Xrq02Gj9NY7MwK+UxVwHQ== + dependencies: + "@typescript-eslint/typescript-estree" "8.18.1" + "@typescript-eslint/utils" "8.18.1" + debug "^4.3.4" + ts-api-utils "^1.3.0" + +"@typescript-eslint/types@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.18.1.tgz#d7f4f94d0bba9ebd088de840266fcd45408a8fff" + integrity sha512-7uoAUsCj66qdNQNpH2G8MyTFlgerum8ubf21s3TSM3XmKXuIn+H2Sifh/ES2nPOPiYSRJWAk0fDkW0APBWcpfw== + +"@typescript-eslint/typescript-estree@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.18.1.tgz#2a86cd64b211a742f78dfa7e6f4860413475367e" + integrity sha512-z8U21WI5txzl2XYOW7i9hJhxoKKNG1kcU4RzyNvKrdZDmbjkmLBo8bgeiOJmA06kizLI76/CCBAAGlTlEeUfyg== + dependencies: + "@typescript-eslint/types" "8.18.1" + "@typescript-eslint/visitor-keys" "8.18.1" + debug "^4.3.4" + fast-glob "^3.3.2" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" + +"@typescript-eslint/utils@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.18.1.tgz#c4199ea23fc823c736e2c96fd07b1f7235fa92d5" + integrity sha512-8vikiIj2ebrC4WRdcAdDcmnu9Q/MXXwg+STf40BVfT8exDqBCUPdypvzcUPxEqRGKg9ALagZ0UWcYCtn+4W2iQ== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@typescript-eslint/scope-manager" "8.18.1" + "@typescript-eslint/types" "8.18.1" + "@typescript-eslint/typescript-estree" "8.18.1" + +"@typescript-eslint/visitor-keys@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.18.1.tgz#344b4f6bc83f104f514676facf3129260df7610a" + integrity sha512-Vj0WLm5/ZsD013YeUKn+K0y8p1M0jPpxOkKdbD1wB0ns53a5piVY02zjf072TblEweAbcYiFiPoSMF3kp+VhhQ== + dependencies: + "@typescript-eslint/types" "8.18.1" + eslint-visitor-keys "^4.2.0" + +"@vitejs/plugin-react@^4.3.4": + version "4.3.4" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz#c64be10b54c4640135a5b28a2432330e88ad7c20" + integrity sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug== + dependencies: + "@babel/core" "^7.26.0" + "@babel/plugin-transform-react-jsx-self" "^7.25.9" + "@babel/plugin-transform-react-jsx-source" "^7.25.9" + "@types/babel__core" "^7.20.5" + react-refresh "^0.14.2" + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn@^8.14.0: + version "8.14.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" + integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== + +ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + +browserslist@^4.24.0: + version "4.24.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.3.tgz#5fc2725ca8fb3c1432e13dac278c7cc103e026d2" + integrity sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA== + dependencies: + caniuse-lite "^1.0.30001688" + electron-to-chromium "^1.5.73" + node-releases "^2.0.19" + update-browserslist-db "^1.1.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +caniuse-lite@^1.0.30001688: + version "1.0.30001690" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz#f2d15e3aaf8e18f76b2b8c1481abde063b8104c8" + integrity sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w== + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +cross-spawn@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +csstype@^3.0.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + +debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: + version "4.4.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" + integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== + dependencies: + ms "^2.1.3" + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +electron-to-chromium@^1.5.73: + version "1.5.75" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.75.tgz#bba96eabf0e8ca36324679caa38b982800acc87d" + integrity sha512-Lf3++DumRE/QmweGjU+ZcKqQ+3bKkU/qjaKYhIJKEOhgIO9Xs6IiAQFkfFoj+RhgDk4LUeNsLo6plExHqSyu6Q== + +esbuild@0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.24.0.tgz#f2d470596885fcb2e91c21eb3da3b3c89c0b55e7" + integrity sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ== + optionalDependencies: + "@esbuild/aix-ppc64" "0.24.0" + "@esbuild/android-arm" "0.24.0" + "@esbuild/android-arm64" "0.24.0" + "@esbuild/android-x64" "0.24.0" + "@esbuild/darwin-arm64" "0.24.0" + "@esbuild/darwin-x64" "0.24.0" + "@esbuild/freebsd-arm64" "0.24.0" + "@esbuild/freebsd-x64" "0.24.0" + "@esbuild/linux-arm" "0.24.0" + "@esbuild/linux-arm64" "0.24.0" + "@esbuild/linux-ia32" "0.24.0" + "@esbuild/linux-loong64" "0.24.0" + "@esbuild/linux-mips64el" "0.24.0" + "@esbuild/linux-ppc64" "0.24.0" + "@esbuild/linux-riscv64" "0.24.0" + "@esbuild/linux-s390x" "0.24.0" + "@esbuild/linux-x64" "0.24.0" + "@esbuild/netbsd-x64" "0.24.0" + "@esbuild/openbsd-arm64" "0.24.0" + "@esbuild/openbsd-x64" "0.24.0" + "@esbuild/sunos-x64" "0.24.0" + "@esbuild/win32-arm64" "0.24.0" + "@esbuild/win32-ia32" "0.24.0" + "@esbuild/win32-x64" "0.24.0" + +escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-plugin-react-hooks@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0.tgz#3d34e37d5770866c34b87d5b499f5f0b53bf0854" + integrity sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw== + +eslint-plugin-react-refresh@^0.4.16: + version "0.4.16" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.16.tgz#149dbc9279bd16942409f1c1d2f0dce3299430ef" + integrity sha512-slterMlxAhov/DZO8NScf6mEeMBBXodFUolijDvrtTxyezyLoTQaa73FyYus/VbTdftd8wBgBxPMRk3poleXNQ== + +eslint-scope@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.2.0.tgz#377aa6f1cb5dc7592cfd0b7f892fd0cf352ce442" + integrity sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint-visitor-keys@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" + integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== + +eslint@^9.17.0: + version "9.17.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.17.0.tgz#faa1facb5dd042172fdc520106984b5c2421bb0c" + integrity sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.12.1" + "@eslint/config-array" "^0.19.0" + "@eslint/core" "^0.9.0" + "@eslint/eslintrc" "^3.2.0" + "@eslint/js" "9.17.0" + "@eslint/plugin-kit" "^0.2.3" + "@humanfs/node" "^0.16.6" + "@humanwhocodes/module-importer" "^1.0.1" + "@humanwhocodes/retry" "^0.4.1" + "@types/estree" "^1.0.6" + "@types/json-schema" "^7.0.15" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.6" + debug "^4.3.2" + escape-string-regexp "^4.0.0" + eslint-scope "^8.2.0" + eslint-visitor-keys "^4.2.0" + espree "^10.3.0" + esquery "^1.5.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^8.0.0" + find-up "^5.0.0" + glob-parent "^6.0.2" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + json-stable-stringify-without-jsonify "^1.0.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + +espree@^10.0.1, espree@^10.3.0: + version "10.3.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.3.0.tgz#29267cf5b0cb98735b65e64ba07e0ed49d1eed8a" + integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg== + dependencies: + acorn "^8.14.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^4.2.0" + +esquery@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" + integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastq@^1.6.0: + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== + dependencies: + reusify "^1.0.4" + +file-entry-cache@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f" + integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== + dependencies: + flat-cache "^4.0.0" + +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat-cache@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c" + integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== + dependencies: + flatted "^3.2.9" + keyv "^4.5.4" + +flatted@^3.2.9: + version "3.3.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.2.tgz#adba1448a9841bec72b42c532ea23dbbedef1a27" + integrity sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA== + +fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" + integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== + +globals@^15.13.0: + version "15.14.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-15.14.0.tgz#b8fd3a8941ff3b4d38f3319d433b61bbb482e73f" + integrity sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig== + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +ignore@^5.2.0, ignore@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" + integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsesc@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" + integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +keyv@^4.5.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +loose-envify@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4: + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + +minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + +ms@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +nanoid@^3.3.7: + version "3.3.8" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf" + integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +node-releases@^2.0.19: + version "2.0.19" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" + integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== + +optionator@^0.9.3: + version "0.9.4" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.5" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +picocolors@^1.0.0, picocolors@^1.1.0, picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +postcss@^8.4.49: + version "8.4.49" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.49.tgz#4ea479048ab059ab3ae61d082190fabfd994fe19" + integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA== + dependencies: + nanoid "^3.3.7" + picocolors "^1.1.1" + source-map-js "^1.2.1" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +react-dom@^18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" + integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.2" + +react-refresh@^0.14.2: + version "0.14.2" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9" + integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA== + +react@^18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" + integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== + dependencies: + loose-envify "^1.1.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rollup@^4.23.0: + version "4.28.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.28.1.tgz#7718ba34d62b449dfc49adbfd2f312b4fe0df4de" + integrity sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg== + dependencies: + "@types/estree" "1.0.6" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.28.1" + "@rollup/rollup-android-arm64" "4.28.1" + "@rollup/rollup-darwin-arm64" "4.28.1" + "@rollup/rollup-darwin-x64" "4.28.1" + "@rollup/rollup-freebsd-arm64" "4.28.1" + "@rollup/rollup-freebsd-x64" "4.28.1" + "@rollup/rollup-linux-arm-gnueabihf" "4.28.1" + "@rollup/rollup-linux-arm-musleabihf" "4.28.1" + "@rollup/rollup-linux-arm64-gnu" "4.28.1" + "@rollup/rollup-linux-arm64-musl" "4.28.1" + "@rollup/rollup-linux-loongarch64-gnu" "4.28.1" + "@rollup/rollup-linux-powerpc64le-gnu" "4.28.1" + "@rollup/rollup-linux-riscv64-gnu" "4.28.1" + "@rollup/rollup-linux-s390x-gnu" "4.28.1" + "@rollup/rollup-linux-x64-gnu" "4.28.1" + "@rollup/rollup-linux-x64-musl" "4.28.1" + "@rollup/rollup-win32-arm64-msvc" "4.28.1" + "@rollup/rollup-win32-ia32-msvc" "4.28.1" + "@rollup/rollup-win32-x64-msvc" "4.28.1" + fsevents "~2.3.2" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +scheduler@^0.23.2: + version "0.23.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== + dependencies: + loose-envify "^1.1.0" + +semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.6.0: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +ts-api-utils@^1.3.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz#bfc2215fe6528fecab2b0fba570a2e8a4263b064" + integrity sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +typescript-eslint@^8.18.1: + version "8.18.1" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.18.1.tgz#197b284b6769678ed77d9868df180eeaf61108eb" + integrity sha512-Mlaw6yxuaDEPQvb/2Qwu3/TfgeBHy9iTJ3mTwe7OvpPmF6KPQjVOfGyEJpPv6Ez2C34OODChhXrzYw/9phI0MQ== + dependencies: + "@typescript-eslint/eslint-plugin" "8.18.1" + "@typescript-eslint/parser" "8.18.1" + "@typescript-eslint/utils" "8.18.1" + +typescript@~5.6.2: + version "5.6.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b" + integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw== + +update-browserslist-db@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5" + integrity sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A== + dependencies: + escalade "^3.2.0" + picocolors "^1.1.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +vite@^6.0.3: + version "6.0.5" + resolved "https://registry.yarnpkg.com/vite/-/vite-6.0.5.tgz#1d0fbdb3ffe61e944089abeddb7d2c509420acfd" + integrity sha512-akD5IAH/ID5imgue2DYhzsEwCi0/4VKY31uhMLEYJwPP4TiUp8pL5PIK+Wo7H8qT8JY9i+pVfPydcFPYD1EL7g== + dependencies: + esbuild "0.24.0" + postcss "^8.4.49" + rollup "^4.23.0" + optionalDependencies: + fsevents "~2.3.3" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/packages/coaction-zustand/src/index.ts b/packages/coaction-zustand/src/index.ts index 9410d29..2bed6cf 100644 --- a/packages/coaction-zustand/src/index.ts +++ b/packages/coaction-zustand/src/index.ts @@ -1,22 +1,45 @@ -import { apply } from 'mutability'; import { type Store, createBinder } from 'coaction'; -const instancesMap = new WeakMap(); +interface BindZustand { + (target: T): T; +} -// const handleStore = (store: Store) => { -// // -// }; - -// interface BindMobx { -// (target: T): T; -// } - -// /** -// * Bind a store to Zustand -// */ -// export const bindZustand = createBinder({ -// handleStore, -// handleState: (options) => { -// // -// } -// }); +/** + * Bind a store to Zustand + */ +export const bindZustand = + (initializer: any) => (set: any, get: any, zustandStore: any) => { + let coactionStore: Store; + const internalBindZustand = createBinder({ + handleStore: ( + store: Store, + rawState: object, + state: object, + internal: any + ) => { + if (zustandStore.getState() === internal.rootState) return; + internal.rootState = zustandStore.getState(); + coactionStore = store; + zustandStore.subscribe(() => { + internal.listeners.forEach((listener: any) => listener()); + }); + internal.updateImmutable = (state: any) => { + zustandStore.setState(state, true); + }; + }, + handleState: (externalState) => { + return { + copyState: externalState, + bind: (state) => state + }; + } + }); + const state = initializer( + (state: any) => { + coactionStore.setState(state); + }, + () => coactionStore.getState(), + zustandStore + ); + return internalBindZustand(state); + }; diff --git a/packages/coaction-zustand/test/index.test.ts b/packages/coaction-zustand/test/index.test.ts index dce296a..7618293 100644 --- a/packages/coaction-zustand/test/index.test.ts +++ b/packages/coaction-zustand/test/index.test.ts @@ -1,5 +1,159 @@ -// import { add } from '../src/index.ts'; +import { create } from 'coaction'; +import { + createTransport, + mockPorts, + WorkerMainTransportOptions +} from 'data-transport'; +import { create as createWithZustand } from 'zustand'; +import { bindZustand } from '../src'; test('base', () => { - // expect(add(1, 2)).toBe(3); + const stateFn = jest.fn(); + const getterFn = jest.fn(); + const useStore = create<{ + count: number; + readonly double: number; + increment: () => void; + }>( + () => + createWithZustand( + bindZustand((set, get, store) => ({ + count: 0, + increment() { + set((state) => ({ count: state.count + 1 })); + // stateFn(get().count, this.count); + // getterFn(get().double, this.double); + } + })) + ), + { + name: 'test' + } + ); + const { count, increment } = useStore(); + expect(count).toBe(0); + expect(increment).toBeInstanceOf(Function); + expect(useStore.name).toBe('test'); + expect(useStore.getState()).toMatchInlineSnapshot(` +{ + "count": 0, + "increment": [Function], +} +`); + const fn = jest.fn(); + useStore.subscribe(fn); + useStore.getState().increment(); + expect(stateFn.mock.calls).toMatchInlineSnapshot(`[]`); + expect(getterFn.mock.calls).toMatchInlineSnapshot(`[]`); + expect(useStore.getState()).toMatchInlineSnapshot(` +{ + "count": 1, + "increment": [Function], +} +`); + increment(); + expect(stateFn.mock.calls).toMatchInlineSnapshot(`[]`); + expect(getterFn.mock.calls).toMatchInlineSnapshot(`[]`); + expect(useStore.getState()).toMatchInlineSnapshot(` +{ + "count": 2, + "increment": [Function], +} +`); +}); + +test('worker', async () => { + const ports = mockPorts(); + const serverTransport = createTransport('WebWorkerInternal', ports.main); + const clientTransport = createTransport( + 'WebWorkerClient', + ports.create() as WorkerMainTransportOptions + ); + + const counter: Slice<{ + count: number; + increment: () => void; + }> = (set) => ({ + count: 0, + increment() { + set((state) => ({ count: state.count + 1 })); + } + }); + const useServerStore = create(() => createWithZustand(bindZustand(counter)), { + transport: serverTransport, + workerType: 'WebWorkerInternal', + name: 'test' + }); + const { count, increment } = useServerStore(); + expect(count).toBe(0); + expect(increment).toBeInstanceOf(Function); + expect(useServerStore.name).toBe('test'); + expect(useServerStore.getState()).toMatchInlineSnapshot(` +{ + "count": 0, + "increment": [Function], +} +`); + const fn = jest.fn(); + useServerStore.subscribe(fn); + useServerStore.getState().increment(); + expect(useServerStore.getState()).toMatchInlineSnapshot(` +{ + "count": 1, + "increment": [Function], +} +`); + increment(); + expect(useServerStore.getState()).toMatchInlineSnapshot(` +{ + "count": 2, + "increment": [Function], +} +`); + { + const useClientStore = create( + () => createWithZustand(bindZustand(counter)), + { + name: 'test', + clientTransport, + workerType: 'WebWorkerClient' + } + ); + + await new Promise((resolve) => { + clientTransport.onConnect(() => { + setTimeout(resolve); + }); + }); + + const { count, increment } = useClientStore(); + expect(count).toBe(2); + expect(increment).toBeInstanceOf(Function); + expect(useClientStore.name).toBe('test'); + expect(useClientStore.getState()).toMatchInlineSnapshot(` +{ + "count": 2, + "increment": [Function], +} +`); + const fn = jest.fn(); + useClientStore.subscribe(fn); + const returnValue0 = useClientStore.getState().increment(); + expect(returnValue0 instanceof Promise).toBeTruthy(); + await returnValue0; + expect(useClientStore.getState()).toMatchInlineSnapshot(` +{ + "count": 3, + "increment": [Function], +} +`); + const returnValue1 = increment(); + expect(returnValue1 instanceof Promise).toBeTruthy(); + expect(useClientStore.getState()).toMatchInlineSnapshot(` +{ + "count": 4, + "increment": [Function], +} +`); + } }); diff --git a/packages/core/src/create.ts b/packages/core/src/create.ts index 2567c8c..5dafc19 100644 --- a/packages/core/src/create.ts +++ b/packages/core/src/create.ts @@ -78,7 +78,11 @@ export const create: Creator = ( internal.rootState = patches ? (applyWithMutative(state, patches) as T) : state; - internal.listeners.forEach((listener) => listener()); + if (internal.updateImmutable) { + internal.updateImmutable(internal.rootState as T); + } else { + internal.listeners.forEach((listener) => listener()); + } }; const getPureState: Store['getPureState'] = () => internal.rootState as T; diff --git a/packages/core/src/getInitialState.ts b/packages/core/src/getInitialState.ts index 073ebfb..ef35e44 100644 --- a/packages/core/src/getInitialState.ts +++ b/packages/core/src/getInitialState.ts @@ -13,9 +13,10 @@ export const getInitialState = ( throw new Error('createState should be a function'); } let state = fn(store.setState, store.getState, store); - // support 3rd party library store like zustand, pinia + // support 3rd party library store like zustand, redux if (state.getState) { state = state.getState(); + // support 3rd party library store like pinia } else if (typeof state === 'function') { state = state(); } @@ -23,6 +24,7 @@ export const getInitialState = ( if (state[bindSymbol]) { const rawState = state[bindSymbol].bind(state); state[bindSymbol].handleStore(store, rawState, state, internal); + delete state[bindSymbol]; return rawState; } return state; diff --git a/packages/core/src/handleState.ts b/packages/core/src/handleState.ts index 96cf9b0..8d89485 100644 --- a/packages/core/src/handleState.ts +++ b/packages/core/src/handleState.ts @@ -71,7 +71,11 @@ export const handleState = ( internal.rootState = internal.backupState; throw error; } - internal.listeners.forEach((listener) => listener()); + if (internal.updateImmutable) { + internal.updateImmutable(internal.rootState as T); + } else { + internal.listeners.forEach((listener) => listener()); + } return []; } internal.backupState = internal.rootState; @@ -99,7 +103,11 @@ export const handleState = ( if (finalPatches.patches.length) { store.apply(internal.rootState as T, finalPatches.patches); if (!internal.mutableInstance) { - internal.listeners.forEach((listener) => listener()); + if (internal.updateImmutable) { + internal.updateImmutable(internal.rootState as T); + } else { + internal.listeners.forEach((listener) => listener()); + } } } return [internal.rootState as any, patches, inversePatches]; diff --git a/packages/core/src/interface.ts b/packages/core/src/interface.ts index 4d08d19..81bfaac 100644 --- a/packages/core/src/interface.ts +++ b/packages/core/src/interface.ts @@ -65,6 +65,7 @@ export interface Store { * Get the initial state. */ getInitialState: () => T; + // TODO: remove this /** * The patch is used to update the state. */ @@ -72,6 +73,7 @@ export interface Store { patches: Patches; inversePatches: Patches; }; + // TODO: remove this /** * The trace is used to trace the action */ diff --git a/packages/core/src/internal.ts b/packages/core/src/internal.ts index 1095a62..60a8f82 100644 --- a/packages/core/src/internal.ts +++ b/packages/core/src/internal.ts @@ -42,4 +42,8 @@ export interface Internal { * Get the mutable raw instance via the initial state. */ toMutableRaw?: (key: any) => any; + /** + * The update immutable function. + */ + updateImmutable?: (state: T) => void; } From 72087b3350901444ce8833e6d96a5bf7b4560654 Mon Sep 17 00:00:00 2001 From: unadlib Date: Sat, 21 Dec 2024 00:47:57 +0800 Subject: [PATCH 18/20] fix(zustand): fix @coaction/zustand type --- examples/zustand-base/src/counter.ts | 11 +++- examples/zustand-base/src/store.ts | 4 +- examples/zustand-base/src/worker.ts | 4 +- packages/coaction-zustand/src/index.ts | 32 +++++----- packages/coaction-zustand/test/index.test.ts | 62 +++++++++++--------- 5 files changed, 64 insertions(+), 49 deletions(-) diff --git a/examples/zustand-base/src/counter.ts b/examples/zustand-base/src/counter.ts index 4771871..6b231ef 100644 --- a/examples/zustand-base/src/counter.ts +++ b/examples/zustand-base/src/counter.ts @@ -1,11 +1,18 @@ -import type { Slice } from '@coaction/react'; +import type { StateCreator } from 'zustand'; export type Counter = { count: number; increment: () => void; }; -export const counter: Slice = (set) => ({ +export const counter: StateCreator< + { + count: number; + increment: () => void; + }, + [], + [] +> = (set) => ({ count: 0, increment() { set((state) => ({ count: state.count + 1 })); diff --git a/examples/zustand-base/src/store.ts b/examples/zustand-base/src/store.ts index 1f538e4..b770964 100644 --- a/examples/zustand-base/src/store.ts +++ b/examples/zustand-base/src/store.ts @@ -1,7 +1,7 @@ import { create } from '@coaction/react'; import { logger } from '@coaction/logger'; import { create as createWithZustand } from 'zustand'; -import { bindZustand } from '@coaction/zustand'; +import { bindZustand, adapt } from '@coaction/zustand'; import { counter, type Counter } from './counter'; @@ -10,7 +10,7 @@ const worker = new SharedWorker(new URL('./worker.ts', import.meta.url), { }); export const useStore = create( - () => createWithZustand(bindZustand(counter)), + () => adapt(createWithZustand(bindZustand(counter))), { worker, middlewares: [ diff --git a/examples/zustand-base/src/worker.ts b/examples/zustand-base/src/worker.ts index 8e05f16..70fc864 100644 --- a/examples/zustand-base/src/worker.ts +++ b/examples/zustand-base/src/worker.ts @@ -1,12 +1,12 @@ import { create } from '@coaction/react'; import { logger } from '@coaction/logger'; import { create as createWithZustand } from 'zustand'; -import { bindZustand } from '@coaction/zustand'; +import { bindZustand, adapt } from '@coaction/zustand'; import { counter, type Counter } from './counter'; export const useStore = create( - () => createWithZustand(bindZustand(counter)), + () => adapt(createWithZustand(bindZustand(counter))), { middlewares: [ logger({ diff --git a/packages/coaction-zustand/src/index.ts b/packages/coaction-zustand/src/index.ts index 2bed6cf..9c9d339 100644 --- a/packages/coaction-zustand/src/index.ts +++ b/packages/coaction-zustand/src/index.ts @@ -1,27 +1,23 @@ import { type Store, createBinder } from 'coaction'; +import type { StateCreator, StoreApi } from 'zustand'; -interface BindZustand { - (target: T): T; -} +type BindZustand = ( + initializer: StateCreator +) => StateCreator; /** * Bind a store to Zustand */ -export const bindZustand = - (initializer: any) => (set: any, get: any, zustandStore: any) => { +export const bindZustand = ((initializer: StateCreator) => + (set, get, zustandStore) => { let coactionStore: Store; const internalBindZustand = createBinder({ - handleStore: ( - store: Store, - rawState: object, - state: object, - internal: any - ) => { + handleStore: (store, rawState, state, internal) => { if (zustandStore.getState() === internal.rootState) return; - internal.rootState = zustandStore.getState(); + internal.rootState = zustandStore.getState() as object; coactionStore = store; zustandStore.subscribe(() => { - internal.listeners.forEach((listener: any) => listener()); + internal.listeners.forEach((listener) => listener()); }); internal.updateImmutable = (state: any) => { zustandStore.setState(state, true); @@ -35,11 +31,17 @@ export const bindZustand = } }); const state = initializer( - (state: any) => { + (state) => { coactionStore.setState(state); }, () => coactionStore.getState(), zustandStore ); return internalBindZustand(state); - }; + }) as BindZustand; + +/** + * Adapt a store type to Pinia + */ +export const adapt = (store: StoreApi) => + store as unknown as T; diff --git a/packages/coaction-zustand/test/index.test.ts b/packages/coaction-zustand/test/index.test.ts index 7618293..cf00e11 100644 --- a/packages/coaction-zustand/test/index.test.ts +++ b/packages/coaction-zustand/test/index.test.ts @@ -4,28 +4,27 @@ import { mockPorts, WorkerMainTransportOptions } from 'data-transport'; -import { create as createWithZustand } from 'zustand'; -import { bindZustand } from '../src'; +import { create as createWithZustand, StateCreator } from 'zustand'; +import { bindZustand, adapt } from '../src'; test('base', () => { const stateFn = jest.fn(); const getterFn = jest.fn(); - const useStore = create<{ - count: number; - readonly double: number; - increment: () => void; - }>( - () => - createWithZustand( - bindZustand((set, get, store) => ({ - count: 0, - increment() { - set((state) => ({ count: state.count + 1 })); - // stateFn(get().count, this.count); - // getterFn(get().double, this.double); - } - })) - ), + const counter: StateCreator< + { + count: number; + increment: () => void; + }, + [], + [] + > = (set) => ({ + count: 0, + increment() { + set((state) => ({ count: state.count + 1 })); + } + }); + const useStore = create( + () => adapt(createWithZustand(bindZustand(counter))), { name: 'test' } @@ -70,20 +69,27 @@ test('worker', async () => { ports.create() as WorkerMainTransportOptions ); - const counter: Slice<{ - count: number; - increment: () => void; - }> = (set) => ({ + const counter: StateCreator< + { + count: number; + increment: () => void; + }, + [], + [] + > = (set) => ({ count: 0, increment() { set((state) => ({ count: state.count + 1 })); } }); - const useServerStore = create(() => createWithZustand(bindZustand(counter)), { - transport: serverTransport, - workerType: 'WebWorkerInternal', - name: 'test' - }); + const useServerStore = create( + () => adapt(createWithZustand(bindZustand(counter))), + { + transport: serverTransport, + workerType: 'WebWorkerInternal', + name: 'test' + } + ); const { count, increment } = useServerStore(); expect(count).toBe(0); expect(increment).toBeInstanceOf(Function); @@ -112,7 +118,7 @@ test('worker', async () => { `); { const useClientStore = create( - () => createWithZustand(bindZustand(counter)), + () => adapt(createWithZustand(bindZustand(counter))), { name: 'test', clientTransport, From a476392c92b541c4d6da4c72d4235ce37e5b741c Mon Sep 17 00:00:00 2001 From: unadlib Date: Sat, 21 Dec 2024 00:51:51 +0800 Subject: [PATCH 19/20] chore(version): update version to 0.1.5 --- lerna.json | 2 +- package.json | 2 +- packages/coaction-mobx/package.json | 6 +++--- packages/coaction-pinia/package.json | 6 +++--- packages/coaction-react/package.json | 6 +++--- packages/coaction-zustand/package.json | 6 +++--- packages/core/package.json | 2 +- packages/logger/package.json | 6 +++--- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/lerna.json b/lerna.json index 9d3da41..780b24e 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "0.1.4", + "version": "0.1.5", "packages": ["packages/*"], "npmClient": "yarn" } diff --git a/package.json b/package.json index 581918a..6448465 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "commit": "cz", "changeset": "changeset", "version": "changeset version && node ./scripts/bump-peer-dep-ranges.js", - "publish": "lerna exec --no-private --no-bail -- npm publish", + "publish": "lerna exec --no-private --no-bail -- npm publish --access=public", "update:version": "lerna version --amend --no-git-tag-version", "benchmark": "tsx ./packages/coaction-mobx/test/benchmark/index.ts" }, diff --git a/packages/coaction-mobx/package.json b/packages/coaction-mobx/package.json index 69cc98c..32887c2 100644 --- a/packages/coaction-mobx/package.json +++ b/packages/coaction-mobx/package.json @@ -1,6 +1,6 @@ { "name": "@coaction/mobx", - "version": "0.1.4", + "version": "0.1.5", "description": "A Coaction integration tool for MobX", "keywords": [ "state", @@ -47,7 +47,7 @@ ] }, "peerDependencies": { - "coaction": "^0.1.4", + "coaction": "^0.1.5", "mobx": "^6.13.2", "mutative": "^1.1.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -72,7 +72,7 @@ "@types/react": "^18.3.12", "@types/react-dom": "^18.3.0", "@types/use-sync-external-store": "^0.0.6", - "coaction": "^0.1.4", + "coaction": "^0.1.5", "jsdom": "^25.0.1", "jsdom-global": "^3.0.2", "mobx": "^6.13.2", diff --git a/packages/coaction-pinia/package.json b/packages/coaction-pinia/package.json index e8f3928..e088f53 100644 --- a/packages/coaction-pinia/package.json +++ b/packages/coaction-pinia/package.json @@ -1,6 +1,6 @@ { "name": "@coaction/pinia", - "version": "0.1.4", + "version": "0.1.5", "description": "A Coaction integration tool for Pinia", "keywords": [ "state", @@ -47,7 +47,7 @@ ] }, "peerDependencies": { - "coaction": "^0.1.4", + "coaction": "^0.1.5", "mutative": "^1.1.0", "pinia": "^2.0" }, @@ -63,7 +63,7 @@ } }, "devDependencies": { - "coaction": "^0.1.4", + "coaction": "^0.1.5", "mutative": "^1.1.0", "pinia": "^2.2.4" }, diff --git a/packages/coaction-react/package.json b/packages/coaction-react/package.json index 0153bd7..188d596 100644 --- a/packages/coaction-react/package.json +++ b/packages/coaction-react/package.json @@ -1,6 +1,6 @@ { "name": "@coaction/react", - "version": "0.1.4", + "version": "0.1.5", "description": "A Coaction integration tool for React", "keywords": [ "state", @@ -48,7 +48,7 @@ }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "coaction": "^0.1.4", + "coaction": "^0.1.5", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { @@ -65,7 +65,7 @@ "@types/react": "^18.3.12", "@types/react-dom": "^18.3.0", "@types/use-sync-external-store": "^0.0.6", - "coaction": "^0.1.4", + "coaction": "^0.1.5", "jsdom": "^25.0.1", "jsdom-global": "^3.0.2", "react": "^18.0.0", diff --git a/packages/coaction-zustand/package.json b/packages/coaction-zustand/package.json index 726b55d..8d3f954 100644 --- a/packages/coaction-zustand/package.json +++ b/packages/coaction-zustand/package.json @@ -1,6 +1,6 @@ { "name": "@coaction/zustand", - "version": "0.1.4", + "version": "0.1.5", "description": "A Coaction integration tool for Zustand", "keywords": [ "state", @@ -48,7 +48,7 @@ }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "coaction": "^0.1.4", + "coaction": "^0.1.5", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "use-sync-external-store": ">=1.2.0", "zustand": "^4.0.0 || ^5.0.0" @@ -76,7 +76,7 @@ "@types/react": "^18.3.12", "@types/react-dom": "^18.3.0", "@types/use-sync-external-store": "^0.0.6", - "coaction": "^0.1.4", + "coaction": "^0.1.5", "jsdom": "^25.0.1", "jsdom-global": "^3.0.2", "react": "^18.0.0", diff --git a/packages/core/package.json b/packages/core/package.json index 4ba75d7..d006ab4 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "coaction", - "version": "0.1.4", + "version": "0.1.5", "description": "A sleek JavaScript library designed for high-performance and multithreading web apps.", "keywords": [ "coaction" diff --git a/packages/logger/package.json b/packages/logger/package.json index 55e667b..04809f6 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -1,6 +1,6 @@ { "name": "@coaction/logger", - "version": "0.1.4", + "version": "0.1.5", "description": "A logger middleware for Coaction.", "keywords": [ "coaction" @@ -38,7 +38,7 @@ "url": "https://github.com/unadlib/coaction/issues" }, "devDependencies": { - "coaction": "^0.1.4", + "coaction": "^0.1.5", "mutative": "^1.1.0" }, "preconstruct": { @@ -48,7 +48,7 @@ ] }, "peerDependencies": { - "coaction": "^0.1.4", + "coaction": "^0.1.5", "mutative": "^1.1.0" }, "peerDependenciesMeta": { From f272a3bc507cfe4b89b673a2950c444d1a36048f Mon Sep 17 00:00:00 2001 From: unadlib Date: Sat, 21 Dec 2024 00:53:58 +0800 Subject: [PATCH 20/20] docs(readme): readme update --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7be5324..f0fc446 100644 --- a/README.md +++ b/README.md @@ -246,8 +246,8 @@ Coaction is designed to be compatible with a wide range of libraries and framewo | ------------- | ----------------- | ------- | | MobX | @coaction/mobx | ✅ Done | | Pinia | @coaction/pinia | ✅ Done | -| Zustand | @coaction/zustand | Ongoing | -| Redux Toolkit | @coaction/redux | | +| Zustand | @coaction/zustand | ✅ Done | +| Redux Toolkit | @coaction/redux | Ongoing | | Jotai | @coaction/jotai | | | XState | @coaction/xstate | | | Valtio | @coaction/valtio | |