From fed8ec051a541b8ddc331d9dc3e9ef62eed96c65 Mon Sep 17 00:00:00 2001 From: unadlib Date: Sat, 21 Dec 2024 01:34:16 +0800 Subject: [PATCH 01/33] fix(zustand): fix update state issue --- packages/coaction-zustand/src/index.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/coaction-zustand/src/index.ts b/packages/coaction-zustand/src/index.ts index 9c9d339..cf8c495 100644 --- a/packages/coaction-zustand/src/index.ts +++ b/packages/coaction-zustand/src/index.ts @@ -14,13 +14,27 @@ export const bindZustand = ((initializer: StateCreator) => const internalBindZustand = createBinder({ handleStore: (store, rawState, state, internal) => { if (zustandStore.getState() === internal.rootState) return; + let isCoactionUpdated = false; internal.rootState = zustandStore.getState() as object; coactionStore = store; zustandStore.subscribe(() => { + if (!isCoactionUpdated) { + internal.rootState = zustandStore.getState() as object; + if (coactionStore.share === 'client') { + throw new Error('client zustand store cannot be updated'); + } else if (coactionStore.share === 'main') { + // TODO: emit to all clients + } + } internal.listeners.forEach((listener) => listener()); }); internal.updateImmutable = (state: any) => { - zustandStore.setState(state, true); + isCoactionUpdated = true; + try { + zustandStore.setState(state, true); + } finally { + isCoactionUpdated = false; + } }; }, handleState: (externalState) => { From 59cdbd2189b454a83f09017387aa7be8d241b60f Mon Sep 17 00:00:00 2001 From: unadlib Date: Sat, 21 Dec 2024 19:18:08 +0800 Subject: [PATCH 02/33] fix(coaction): fix @coaction/zustand sync issue --- examples/zustand-base/package.json | 1 + examples/zustand-base/src/worker.ts | 12 +++++++++++- examples/zustand-base/yarn.lock | 19 +++++++++++++++++++ packages/coaction-zustand/src/index.ts | 3 ++- 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/examples/zustand-base/package.json b/examples/zustand-base/package.json index 14ff34c..0a3e4fc 100644 --- a/examples/zustand-base/package.json +++ b/examples/zustand-base/package.json @@ -10,6 +10,7 @@ "preview": "vite preview" }, "dependencies": { + "localforage": "^1.10.0", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/zustand-base/src/worker.ts b/examples/zustand-base/src/worker.ts index 70fc864..b6bae7e 100644 --- a/examples/zustand-base/src/worker.ts +++ b/examples/zustand-base/src/worker.ts @@ -2,11 +2,21 @@ import { create } from '@coaction/react'; import { logger } from '@coaction/logger'; import { create as createWithZustand } from 'zustand'; import { bindZustand, adapt } from '@coaction/zustand'; +import { persist, createJSONStorage } from 'zustand/middleware'; +import localforage from 'localforage'; import { counter, type Counter } from './counter'; export const useStore = create( - () => adapt(createWithZustand(bindZustand(counter))), + () => + adapt( + createWithZustand( + persist(bindZustand(counter), { + name: 'counter', + storage: createJSONStorage(() => localforage) + }) + ) + ), { middlewares: [ logger({ diff --git a/examples/zustand-base/yarn.lock b/examples/zustand-base/yarn.lock index 676b97f..c784e02 100644 --- a/examples/zustand-base/yarn.lock +++ b/examples/zustand-base/yarn.lock @@ -1075,6 +1075,11 @@ ignore@^5.2.0, ignore@^5.3.1: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -1162,6 +1167,20 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +lie@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" + integrity sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw== + dependencies: + immediate "~3.0.5" + +localforage@^1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4" + integrity sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg== + dependencies: + lie "3.1.1" + locate-path@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" diff --git a/packages/coaction-zustand/src/index.ts b/packages/coaction-zustand/src/index.ts index cf8c495..fee37f2 100644 --- a/packages/coaction-zustand/src/index.ts +++ b/packages/coaction-zustand/src/index.ts @@ -23,7 +23,8 @@ export const bindZustand = ((initializer: StateCreator) => if (coactionStore.share === 'client') { throw new Error('client zustand store cannot be updated'); } else if (coactionStore.share === 'main') { - // TODO: emit to all clients + // emit to all clients + coactionStore.setState(zustandStore.getState()!); } } internal.listeners.forEach((listener) => listener()); From cb9b893f35a28e689c0e28ef159d2cc7e3538589 Mon Sep 17 00:00:00 2001 From: unadlib Date: Sat, 21 Dec 2024 20:41:46 +0800 Subject: [PATCH 03/33] docs(readme): update --- examples/zustand-base/global.d.ts | 9 +++++++++ examples/zustand-base/tsconfig.app.json | 2 +- packages/coaction-mobx/README.md | 16 +++++++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 examples/zustand-base/global.d.ts diff --git a/examples/zustand-base/global.d.ts b/examples/zustand-base/global.d.ts new file mode 100644 index 0000000..8a1f60f --- /dev/null +++ b/examples/zustand-base/global.d.ts @@ -0,0 +1,9 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable no-var */ +export {}; + +declare global { + var useWorkerStore: any; + var WorkerGlobalScope: any; + var useStore: any; +} diff --git a/examples/zustand-base/tsconfig.app.json b/examples/zustand-base/tsconfig.app.json index 358ca9b..d1b7c1e 100644 --- a/examples/zustand-base/tsconfig.app.json +++ b/examples/zustand-base/tsconfig.app.json @@ -22,5 +22,5 @@ "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, - "include": ["src"] + "include": ["src", "./global.d.ts"] } diff --git a/packages/coaction-mobx/README.md b/packages/coaction-mobx/README.md index 961fcfb..7573d1e 100644 --- a/packages/coaction-mobx/README.md +++ b/packages/coaction-mobx/README.md @@ -24,7 +24,6 @@ import { makeAutoObservable } from 'mobx'; const useStore = create(() => makeAutoObservable( bindMobx({ - name: 'test', count: 0, get double() { return this.count * 2; @@ -37,6 +36,21 @@ const useStore = create(() => ); ``` +### setState() + +- It is recommended to update state through store methods, instead of directly updating the state. +- Any direct mutations to the state outside of methods should be wrapped in setState() + +```js +// ❌ it will not be triggered state update +store.getState().counter.count += 1; + +// ✅ it will be triggered state update +store.setState(() => { + store.getState().counter.count += 1; +}); +``` + ## Documentation You can find the documentation [here](https://github.com/unadlib/coaction). From cd44adf360832e4234004127d67b244121eb54f1 Mon Sep 17 00:00:00 2001 From: unadlib Date: Sat, 21 Dec 2024 20:44:02 +0800 Subject: [PATCH 04/33] chore(example): update --- examples/mobx-base/src/worker.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/mobx-base/src/worker.ts b/examples/mobx-base/src/worker.ts index 0b86827..24322d5 100644 --- a/examples/mobx-base/src/worker.ts +++ b/examples/mobx-base/src/worker.ts @@ -15,3 +15,5 @@ export const useStore = create( ] } ); + +globalThis.useStore = useStore; From 3a94de4f7f53954e54d9906b91a329fae5a3663b Mon Sep 17 00:00:00 2001 From: unadlib Date: Sat, 21 Dec 2024 22:36:09 +0800 Subject: [PATCH 05/33] docs(readme): update --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index f0fc446..0dfcddf 100644 --- a/README.md +++ b/README.md @@ -278,6 +278,9 @@ Coaction is designed to be compatible with a wide range of libraries and framewo - Coaction's concept is inspired by [Partytown](https://partytown.qwik.dev/). - Coaction's API is inspired by [Zustand](https://zustand.docs.pmnd.rs/). +- Inspiring Technical Article + - [React + Redux + Comlink = Off-main-thread](https://dassur.ma/things/react-redux-comlink/) + - [Is postMessage slow?](https://dassur.ma/things/is-postmessage-slow/) ## License From 6384324c201a83e1998adec10c190d1041b3845e Mon Sep 17 00:00:00 2001 From: unadlib Date: Sun, 22 Dec 2024 02:14:30 +0800 Subject: [PATCH 06/33] docs(readme): update benchmark --- README.md | 37 +-- benchmark.jpg | Bin 55830 -> 43371 bytes package.json | 7 +- packages/coaction-mobx/README.md | 33 +++ packages/coaction-mobx/benchmark.jpg | Bin 0 -> 55830 bytes .../coaction-mobx/test/benchmark/index.ts | 5 +- packages/core/src/handleState.ts | 74 +++-- packages/core/test/middleware.test.ts | 172 ++++++------ packages/logger/test/middleware.test.ts | 172 ++++++------ scripts/benchmark.ts | 261 ++++++++++++++++++ yarn.lock | 10 + 11 files changed, 541 insertions(+), 230 deletions(-) create mode 100644 packages/coaction-mobx/benchmark.jpg create mode 100644 scripts/benchmark.ts diff --git a/README.md b/README.md index 0dfcddf..50f2988 100644 --- a/README.md +++ b/README.md @@ -88,34 +88,19 @@ sequenceDiagram ## Performance +Measure(ops/sec) to update 50K arrays and 1K objects, bigger is better([view source](./scripts/benchmark.ts)). [Coaction v0.1.5 vs Zustand v5.0.2] + ![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 Case | Ops/sec | -| -------------- | ------------------------------- | ------- | -| @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.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 | 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 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. +``` +Coaction x 4,837 ops/sec ±3.79% (65 runs sampled) +Coaction with Mutative x 4,276 ops/sec ±3.04% (85 runs sampled) +Zustand x 4,753 ops/sec ±3.52% (75 runs sampled) +Zustand with Immer x 251 ops/sec ±0.26% (93 runs sampled) +Zustand with Mutative x 4,292 ops/sec ±3.30% (72 runs sampled) + +The fastest method is Coaction,Zustand +``` > We will also provide more complete benchmarking. diff --git a/benchmark.jpg b/benchmark.jpg index af5d4c0ad492deaf698fd7b1eec27ed526e7f0a8..b7b72fac0532f39f95c867ee3ab657946b2803c5 100644 GIT binary patch literal 43371 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 literal 55830 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 OU)EOBEF&knZuuAeV}8Z} diff --git a/package.json b/package.json index 6448465..38258b2 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,8 @@ "version": "changeset version && node ./scripts/bump-peer-dep-ranges.js", "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" + "benchmark:mobx": "tsx ./packages/coaction-mobx/test/benchmark/index.ts", + "benchmark": "NODE_ENV='production' tsx ./scripts/benchmark.ts" }, "authors": [ "Michael Lin (https://github.com/unadlib)" @@ -80,6 +81,7 @@ "commitizen": "^4.3.0", "cz-conventional-changelog": "^3.3.0", "husky": "^3.1.0", + "immer": "^10.1.1", "jest": "^29.7.0", "jest-config": "^29.7.0", "jest-environment-jsdom": "^29.7.0", @@ -95,7 +97,8 @@ "tsx": "^4.19.2", "typescript": "^5.6.3", "vue": "^3.0.11", - "webpack-dev-middleware": "^3.6.0" + "webpack-dev-middleware": "^3.6.0", + "zustand-mutative": "^1.2.0" }, "config": { "commitizen": { diff --git a/packages/coaction-mobx/README.md b/packages/coaction-mobx/README.md index 7573d1e..2ed4532 100644 --- a/packages/coaction-mobx/README.md +++ b/packages/coaction-mobx/README.md @@ -51,6 +51,39 @@ store.setState(() => { }); ``` +## Performance + +![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 Case | Ops/sec | +| -------------- | ------------------------------- | ------- | +| @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.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 | 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 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. + ## Documentation You can find the documentation [here](https://github.com/unadlib/coaction). diff --git a/packages/coaction-mobx/benchmark.jpg b/packages/coaction-mobx/benchmark.jpg new file mode 100644 index 0000000000000000000000000000000000000000..af5d4c0ad492deaf698fd7b1eec27ed526e7f0a8 GIT binary patch literal 55830 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 OU)EOBEF&knZuuAeV}8Z} literal 0 HcmV?d00001 diff --git a/packages/coaction-mobx/test/benchmark/index.ts b/packages/coaction-mobx/test/benchmark/index.ts index 3cb0aaf..10b9ccb 100644 --- a/packages/coaction-mobx/test/benchmark/index.ts +++ b/packages/coaction-mobx/test/benchmark/index.ts @@ -1,5 +1,6 @@ import fs from 'fs'; import https from 'https'; +import path from 'path'; import { Suite } from 'benchmark'; import QuickChart from 'quickchart-js'; import { createCoactionMobxStore } from './coaction-mobx'; @@ -316,7 +317,9 @@ try { const chart = new QuickChart(); chart.setConfig(config); console.log('config:', JSON.stringify(config)); - const file = fs.createWriteStream('benchmark.jpg'); + const file = fs.createWriteStream( + path.resolve(__dirname, '../../benchmark.jpg') + ); https.get(chart.getUrl(), (response) => { response.pipe(file); file.on('finish', () => { diff --git a/packages/core/src/handleState.ts b/packages/core/src/handleState.ts index 8d89485..6541851 100644 --- a/packages/core/src/handleState.ts +++ b/packages/core/src/handleState.ts @@ -45,37 +45,14 @@ export const handleState = ( : merge; const enablePatches = store.transport ?? (options as StoreOptions).enablePatches; - if (!enablePatches) { - if (internal.mutableInstance) { - if (internal.actMutable) { - internal.actMutable(() => { - fn.apply(null); - }); - return []; - } - fn.apply(null); + if (!enablePatches && internal.mutableInstance) { + if (internal.actMutable) { + internal.actMutable(() => { + fn.apply(null); + }); return []; } - // best performance by default for immutable state - // TODO: supporting nested set functions? - try { - internal.backupState = internal.rootState; - internal.rootState = createWithMutative( - internal.rootState, - (draft) => { - internal.rootState = draft as Draft; - return fn.apply(null); - } - ); - } catch (error) { - internal.rootState = internal.backupState; - throw error; - } - if (internal.updateImmutable) { - internal.updateImmutable(internal.rootState as T); - } else { - internal.listeners.forEach((listener) => listener()); - } + fn.apply(null); return []; } internal.backupState = internal.rootState; @@ -122,6 +99,45 @@ export const handleState = ( throw new Error('setState cannot be called within the updater'); } internal.isBatching = true; + if ( + !store.share && + !(options as StoreOptions).enablePatches && + !internal.mutableInstance + ) { + if (typeof next === 'function') { + try { + internal.backupState = internal.rootState; + internal.rootState = createWithMutative( + internal.rootState, + (draft) => { + internal.rootState = draft as Draft; + return next(internal.module); + } + ); + } catch (error) { + internal.rootState = internal.backupState; + internal.isBatching = false; + throw error; + } + } else { + const copy = {} as T; + const rootState = internal.rootState as T; + for (const key of Object.keys(rootState)) { + copy[key] = rootState[key]; + } + for (const key of Object.keys(next!)) { + copy[key] = next![key]; + } + internal.rootState = copy; + } + if (internal.updateImmutable) { + internal.updateImmutable(internal.rootState as T); + } else { + internal.listeners.forEach((listener) => listener()); + } + internal.isBatching = false; + return []; + } let result: void | [] | [any, Patches, Patches]; try { const isDrafted = internal.mutableInstance && isDraft(internal.rootState); diff --git a/packages/core/test/middleware.test.ts b/packages/core/test/middleware.test.ts index dd476f2..abe5de3 100644 --- a/packages/core/test/middleware.test.ts +++ b/packages/core/test/middleware.test.ts @@ -78,42 +78,42 @@ test('base', () => { ] `); expect(stateFn.mock.calls).toMatchInlineSnapshot(` +[ [ - [ - 1, - 1, - 1, - 1, - ], - [ - 1, - 1, - 1, - ], - ] - `); + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + ], +] +`); expect(getterFn.mock.calls).toMatchInlineSnapshot(` +[ [ - [ - 2, - 2, - 2, - 2, - ], - [ - 2, - 2, - 2, - ], - ] - `); + 2, + 2, + 2, + 2, + ], + [ + 2, + 2, + 2, + ], +] +`); expect(useStore.getState()).toMatchInlineSnapshot(` - { - "count": 1, - "double": 2, - "increment": [Function], - } - `); +{ + "count": 1, + "double": 2, + "increment": [Function], +} +`); increment(); expect(logFn.mock.calls).toMatchInlineSnapshot(` [ @@ -136,62 +136,62 @@ test('base', () => { ] `); expect(stateFn.mock.calls).toMatchInlineSnapshot(` +[ [ - [ - 1, - 1, - 1, - 1, - ], - [ - 1, - 1, - 1, - ], - [ - 2, - 2, - 2, - 2, - ], - [ - 2, - 2, - 2, - ], - ] - `); + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + ], + [ + 2, + 2, + 2, + 2, + ], + [ + 2, + 2, + 2, + ], +] +`); expect(getterFn.mock.calls).toMatchInlineSnapshot(` +[ [ - [ - 2, - 2, - 2, - 2, - ], - [ - 2, - 2, - 2, - ], - [ - 4, - 4, - 4, - 4, - ], - [ - 4, - 4, - 4, - ], - ] - `); + 2, + 2, + 2, + 2, + ], + [ + 2, + 2, + 2, + ], + [ + 4, + 4, + 4, + 4, + ], + [ + 4, + 4, + 4, + ], +] +`); expect(useStore.getState()).toMatchInlineSnapshot(` - { - "count": 2, - "double": 4, - "increment": [Function], - } - `); +{ + "count": 2, + "double": 4, + "increment": [Function], +} +`); }); diff --git a/packages/logger/test/middleware.test.ts b/packages/logger/test/middleware.test.ts index 49bb343..38fc056 100644 --- a/packages/logger/test/middleware.test.ts +++ b/packages/logger/test/middleware.test.ts @@ -51,101 +51,101 @@ test('base', () => { useStore.getState().increment(); expect(logFn.mock.calls).toMatchInlineSnapshot(`[]`); expect(stateFn.mock.calls).toMatchInlineSnapshot(` +[ [ - [ - 1, - 1, - 1, - 1, - ], - [ - 1, - 1, - 1, - ], - ] - `); + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + ], +] +`); expect(getterFn.mock.calls).toMatchInlineSnapshot(` +[ [ - [ - 2, - 2, - 2, - 2, - ], - [ - 2, - 2, - 2, - ], - ] - `); + 2, + 2, + 2, + 2, + ], + [ + 2, + 2, + 2, + ], +] +`); expect(useStore.getState()).toMatchInlineSnapshot(` - { - "count": 1, - "double": 2, - "increment": [Function], - } - `); +{ + "count": 1, + "double": 2, + "increment": [Function], +} +`); increment(); expect(logFn.mock.calls).toMatchInlineSnapshot(`[]`); expect(stateFn.mock.calls).toMatchInlineSnapshot(` +[ [ - [ - 1, - 1, - 1, - 1, - ], - [ - 1, - 1, - 1, - ], - [ - 2, - 2, - 2, - 2, - ], - [ - 2, - 2, - 2, - ], - ] - `); + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + ], + [ + 2, + 2, + 2, + 2, + ], + [ + 2, + 2, + 2, + ], +] +`); expect(getterFn.mock.calls).toMatchInlineSnapshot(` +[ [ - [ - 2, - 2, - 2, - 2, - ], - [ - 2, - 2, - 2, - ], - [ - 4, - 4, - 4, - 4, - ], - [ - 4, - 4, - 4, - ], - ] - `); + 2, + 2, + 2, + 2, + ], + [ + 2, + 2, + 2, + ], + [ + 4, + 4, + 4, + 4, + ], + [ + 4, + 4, + 4, + ], +] +`); expect(useStore.getState()).toMatchInlineSnapshot(` - { - "count": 2, - "double": 4, - "increment": [Function], - } - `); +{ + "count": 2, + "double": 4, + "increment": [Function], +} +`); }); diff --git a/scripts/benchmark.ts b/scripts/benchmark.ts new file mode 100644 index 0000000..b9ac151 --- /dev/null +++ b/scripts/benchmark.ts @@ -0,0 +1,261 @@ +import fs from 'fs'; +import https from 'https'; +import { Suite } from 'benchmark'; +import QuickChart from 'quickchart-js'; +import { create as createWithCoaction } from 'coaction'; +import { create as createWithZustand } from 'zustand'; +import { immer } from 'zustand/middleware/immer'; +import { mutative } from 'zustand-mutative'; + +const labels: string[] = []; +const result = [ + { + label: 'Coaction', + backgroundColor: 'rgba(54, 162, 235, 0.5)', + data: [] + }, + { + label: 'Zustand', + backgroundColor: 'rgba(0, 255, 0, 0.5)', + data: [] + }, + { + label: 'Zustand with Immer', + backgroundColor: 'rgba(255, 0, 0, 0.5)', + data: [] + }, + { + label: 'Zustand with Mutative', + backgroundColor: 'rgba(255, 0, 217, 0.5)', + data: [] + }, + { + label: 'Coaction with Mutative', + backgroundColor: 'rgba(255, 120, 120, 0.5)', + data: [] + } +]; + +interface Data { + arr: Record[]; + map: Record>; +} + +type Store = Data & { + update: () => void; +}; + +const getData = () => { + const baseState: Data = { + arr: [], + map: {} + }; + + const createTestObject = () => + Array(10 * 5) + .fill(1) + .reduce((i, _, k) => Object.assign(i, { [k]: k }), {}); + + baseState.arr = Array(10 ** 4 * 5) + .fill('') + .map(() => createTestObject()); + + Array(10 ** 3) + .fill(1) + .forEach((_, i) => { + baseState.map[i] = { i }; + }); + return baseState; + // return deepFreeze(baseState); +}; + +let baseState: any; +let i: any; +let store: any; + +const suite = new Suite(); + +suite + .add( + 'Coaction', + () => { + store.getState().update(); + }, + { + onStart: () => { + i = Math.random(); + baseState = getData(); + store = createWithCoaction((set, get) => ({ + arr: baseState.arr, + map: baseState.map, + update: () => { + set({ + arr: [...get().arr, i], + map: { ...get().map, [i]: { i } } + }); + } + })); + } + } + ) + .add( + 'Coaction with Mutative', + () => { + store.getState().update(); + }, + { + onStart: () => { + i = Math.random(); + baseState = getData(); + store = createWithCoaction((set, get) => ({ + arr: baseState.arr, + map: baseState.map, + update: () => { + set((state) => { + state.arr.push(i); + state.map[i] = { i }; + }); + } + })); + } + } + ) + .add( + 'Zustand', + () => { + store.getState().update(); + }, + { + onStart: () => { + i = Math.random(); + baseState = getData(); + store = createWithZustand((set, get) => ({ + arr: baseState.arr, + map: baseState.map, + update: () => + set({ + arr: [...get().arr, i], + map: { ...get().map, [i]: { i } } + }) + })); + } + } + ) + .add( + 'Zustand with Immer', + () => { + store.getState().update(); + }, + { + onStart: () => { + i = Math.random(); + baseState = getData(); + store = createWithZustand( + immer((set) => ({ + arr: baseState.arr, + map: baseState.map, + update: () => { + set((state) => { + state.arr.push(i); + state.map[i] = { i }; + }); + } + })) + ); + } + } + ) + .add( + 'Zustand with Mutative', + () => { + store.getState().update(); + }, + { + onStart: () => { + i = Math.random(); + baseState = getData(); + store = createWithZustand( + mutative((set) => ({ + arr: baseState.arr, + map: baseState.map, + update: () => { + set((state) => { + state.arr.push(i); + state.map[i] = { i }; + }); + } + })) + ); + } + } + ) + .on('cycle', (event: any) => { + console.log(String(event.target)); + const [name, field = 'Update'] = event.target.name.split(' - '); + if (!labels.includes(field)) labels.push(field); + const item = result.find(({ label }) => label === name); + // @ts-ignore + item.data[labels.indexOf(field)] = Math.round(event.target.hz); + }) + .on('complete', function (this: any) { + 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: 'Coaction vs Zustand vs Zustand with Immer Performance' + }, + legend: { + position: 'bottom' + }, + elements: { + rectangle: { + borderWidth: 1 + } + }, + scales: { + xAxes: [ + { + display: true, + scaleLabel: { + display: true, + fontSize: 10, + labelString: + 'Measure(ops/sec) to update 50K arrays and 1K objects, bigger is better.' + } + } + ] + }, + plugins: { + datalabels: { + anchor: 'center', + align: 'center', + font: { + size: 8 + } + } + } + } + }; + const chart = new QuickChart(); + chart.setConfig(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/yarn.lock b/yarn.lock index 2c721b7..0203b08 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6014,6 +6014,11 @@ ignore@^5.0.4, ignore@^5.2.0: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== +immer@^10.1.1: + version "10.1.1" + resolved "https://registry.yarnpkg.com/immer/-/immer-10.1.1.tgz#206f344ea372d8ea176891545ee53ccc062db7bc" + integrity sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw== + import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" @@ -11382,6 +11387,11 @@ zod@^3.21.4: resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g== +zustand-mutative@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/zustand-mutative/-/zustand-mutative-1.2.0.tgz#550c917c0e10cf02f83b0ef561908aba40457245" + integrity sha512-6TIfG4iXlrftnrmfpuxpPyqoybyTIuZRG9aKO+h+mTiNiZ55rxIoHoQe7v4eDe+lAd0enFNWer9ZvKQhOb25HQ== + zustand@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/zustand/-/zustand-5.0.2.tgz#f7595ada55a565f1fd6464f002a91e701ee0cfca" From 05123d5dc4b73bda11a27936978823dff661768c Mon Sep 17 00:00:00 2001 From: unadlib Date: Sun, 22 Dec 2024 02:43:52 +0800 Subject: [PATCH 07/33] docs(readme): update --- README.md | 13 +++++++---- benchmark.jpg | Bin 43371 -> 39194 bytes packages/core/src/handleState.ts | 2 +- scripts/benchmark.ts | 38 ++++--------------------------- 4 files changed, 13 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 50f2988..7101435 100644 --- a/README.md +++ b/README.md @@ -93,15 +93,18 @@ Measure(ops/sec) to update 50K arrays and 1K objects, bigger is better([view sou ![Benchmark](benchmark.jpg) ``` -Coaction x 4,837 ops/sec ±3.79% (65 runs sampled) -Coaction with Mutative x 4,276 ops/sec ±3.04% (85 runs sampled) -Zustand x 4,753 ops/sec ±3.52% (75 runs sampled) -Zustand with Immer x 251 ops/sec ±0.26% (93 runs sampled) -Zustand with Mutative x 4,292 ops/sec ±3.30% (72 runs sampled) +Coaction x 5,272 ops/sec ±3.08% (63 runs sampled) +Coaction with Mutative x 4,626 ops/sec ±2.26% (83 runs sampled) +Zustand x 5,233 ops/sec ±2.68% (79 runs sampled) +Zustand with Immer x 253 ops/sec ±0.26% (93 runs sampled) The fastest method is Coaction,Zustand ``` +According to the provided performance data, Coaction's performance is comparable to Zustand's performance. However, Coaction with Mutative demonstrates a significant performance advantage compared to Zustand with Immer. + +While standard Coaction achieves approximately 5,272 operations per second (ops/sec) and standard Zustand reaches around 5,233 ops/sec, the most striking difference is observed with Zustand with Immer, which drastically drops to a mere 253 ops/sec. Furthermore, Coaction with Mutative achieves around 4,626 ops/sec. This means Coaction with Mutative is approximately 18.3 times faster than Zustand with Immer (4626 / 253 ≈ 18.3). The data clearly indicates that Coaction offers superior performance characteristics compared to Zustand, and this advantage is especially pronounced when contrasted with Zustand's Immer implementation. + > We will also provide more complete benchmarking. ## Installation diff --git a/benchmark.jpg b/benchmark.jpg index b7b72fac0532f39f95c867ee3ab657946b2803c5..1a3bf1195f92f71722cea7bc5f87a856b1909192 100644 GIT binary patch literal 39194 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 diff --git a/packages/core/src/handleState.ts b/packages/core/src/handleState.ts index 6541851..7c828ba 100644 --- a/packages/core/src/handleState.ts +++ b/packages/core/src/handleState.ts @@ -110,7 +110,7 @@ export const handleState = ( internal.rootState = createWithMutative( internal.rootState, (draft) => { - internal.rootState = draft as Draft; + internal.rootState = draft as Draft; return next(internal.module); } ); diff --git a/scripts/benchmark.ts b/scripts/benchmark.ts index b9ac151..bf0d6bd 100644 --- a/scripts/benchmark.ts +++ b/scripts/benchmark.ts @@ -5,7 +5,6 @@ import QuickChart from 'quickchart-js'; import { create as createWithCoaction } from 'coaction'; import { create as createWithZustand } from 'zustand'; import { immer } from 'zustand/middleware/immer'; -import { mutative } from 'zustand-mutative'; const labels: string[] = []; const result = [ @@ -20,18 +19,13 @@ const result = [ data: [] }, { - label: 'Zustand with Immer', - backgroundColor: 'rgba(255, 0, 0, 0.5)', - data: [] - }, - { - label: 'Zustand with Mutative', + label: 'Coaction with Mutative', backgroundColor: 'rgba(255, 0, 217, 0.5)', data: [] }, { - label: 'Coaction with Mutative', - backgroundColor: 'rgba(255, 120, 120, 0.5)', + label: 'Zustand with Immer', + backgroundColor: 'rgba(255, 0, 0, 0.5)', data: [] } ]; @@ -165,30 +159,6 @@ suite } } ) - .add( - 'Zustand with Mutative', - () => { - store.getState().update(); - }, - { - onStart: () => { - i = Math.random(); - baseState = getData(); - store = createWithZustand( - mutative((set) => ({ - arr: baseState.arr, - map: baseState.map, - update: () => { - set((state) => { - state.arr.push(i); - state.map[i] = { i }; - }); - } - })) - ); - } - } - ) .on('cycle', (event: any) => { console.log(String(event.target)); const [name, field = 'Update'] = event.target.name.split(' - '); @@ -212,7 +182,7 @@ try { options: { title: { display: true, - text: 'Coaction vs Zustand vs Zustand with Immer Performance' + text: 'Coaction vs Zustand Performance' }, legend: { position: 'bottom' From 6a57f5f30e892d7088e28074d68c216d7ee32891 Mon Sep 17 00:00:00 2001 From: unadlib Date: Sun, 22 Dec 2024 03:30:39 +0800 Subject: [PATCH 08/33] docs(readme): update --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 7101435..d8bd626 100644 --- a/README.md +++ b/README.md @@ -103,10 +103,23 @@ The fastest method is Coaction,Zustand According to the provided performance data, Coaction's performance is comparable to Zustand's performance. However, Coaction with Mutative demonstrates a significant performance advantage compared to Zustand with Immer. -While standard Coaction achieves approximately 5,272 operations per second (ops/sec) and standard Zustand reaches around 5,233 ops/sec, the most striking difference is observed with Zustand with Immer, which drastically drops to a mere 253 ops/sec. Furthermore, Coaction with Mutative achieves around 4,626 ops/sec. This means Coaction with Mutative is approximately 18.3 times faster than Zustand with Immer (4626 / 253 ≈ 18.3). The data clearly indicates that Coaction offers superior performance characteristics compared to Zustand, and this advantage is especially pronounced when contrasted with Zustand's Immer implementation. +While standard Coaction achieves approximately 5,272 (ops/sec) and standard Zustand reaches around 5,233 (ops/sec), the most striking difference is observed with Zustand with Immer, which drastically drops to a mere 253 ops/sec. Furthermore, Coaction with Mutative achieves around 4,626 ops/sec. This means Coaction with Mutative is approximately 18.3 faster than Zustand with Immer (4626 / 253 ≈ 18.3). The data clearly indicates that Coaction offers superior performance characteristics compared to Zustand, and this advantage is especially pronounced when contrasted with Zustand's Immer implementation. > We will also provide more complete benchmarking. +## Difference between Coaction and Zustand + +| | `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 | ✅ | ❌ | + ## Installation You can install `@coaction/react` for React application via npm, yarn, or pnpm. @@ -249,19 +262,6 @@ Coaction is designed to be compatible with a wide range of libraries and framewo | Persist | @coaction/persist | Ongoing | | Undo/Redo | @coaction/history | Ongoing | -## Difference between Coaction and Zustand - -| | `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 - Coaction's concept is inspired by [Partytown](https://partytown.qwik.dev/). From caf7f41db1e7b32a1337da3077b6a5812a2087aa Mon Sep 17 00:00:00 2001 From: unadlib Date: Sun, 22 Dec 2024 03:35:23 +0800 Subject: [PATCH 09/33] docs(readme): update --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d8bd626..945e9e8 100644 --- a/README.md +++ b/README.md @@ -103,12 +103,14 @@ The fastest method is Coaction,Zustand According to the provided performance data, Coaction's performance is comparable to Zustand's performance. However, Coaction with Mutative demonstrates a significant performance advantage compared to Zustand with Immer. -While standard Coaction achieves approximately 5,272 (ops/sec) and standard Zustand reaches around 5,233 (ops/sec), the most striking difference is observed with Zustand with Immer, which drastically drops to a mere 253 ops/sec. Furthermore, Coaction with Mutative achieves around 4,626 ops/sec. This means Coaction with Mutative is approximately 18.3 faster than Zustand with Immer (4626 / 253 ≈ 18.3). The data clearly indicates that Coaction offers superior performance characteristics compared to Zustand, and this advantage is especially pronounced when contrasted with Zustand's Immer implementation. +While standard Coaction achieves approximately 5,272 (ops/sec) and standard Zustand reaches around 5,233 (ops/sec), the most striking difference is observed with Zustand with Immer, which drastically drops to a mere 253 (ops/sec). Furthermore, Coaction with Mutative achieves around 4,626 (ops/sec). This means Coaction with Mutative is approximately 18.3X faster than Zustand with Immer (4626 / 253 ≈ 18.3). The data clearly indicates that Coaction offers superior performance characteristics compared to Zustand, and this advantage is especially pronounced when contrasted with Zustand's Immer implementation. > We will also provide more complete benchmarking. ## Difference between Coaction and Zustand +Coaction's design philosophy is to provide a necessary and sufficiently simple API, making it easy for developers to use. Therefore, Coaction inherits the advantages of Zustand's API design and includes built-in support for features that Zustand does not offer. + | | `coaction` | Zustand | | --------------------------------- | ---------- | ------- | | Built-in multithreading | ✅ | ❌ | From 5524f1f49e15b79c8832cfac226d57f85e4fc594 Mon Sep 17 00:00:00 2001 From: unadlib Date: Mon, 23 Dec 2024 00:14:56 +0800 Subject: [PATCH 10/33] docs(readme): update --- README.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 945e9e8..9be2b49 100644 --- a/README.md +++ b/README.md @@ -111,16 +111,18 @@ While standard Coaction achieves approximately 5,272 (ops/sec) and standard Zust Coaction's design philosophy is to provide a necessary and sufficiently simple API, making it easy for developers to use. Therefore, Coaction inherits the advantages of Zustand's API design and includes built-in support for features that Zustand does not offer. -| | `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 | ✅ | ❌ | + +> Some of these features may already have corresponding solutions in the Zustand community; however, Coaction opts for a more unified and streamlined API, better suited to the development needs of modern web applications. ## Installation From 60226b2c02561099b22e89f0695a9f565af53c82 Mon Sep 17 00:00:00 2001 From: unadlib Date: Wed, 25 Dec 2024 23:26:47 +0800 Subject: [PATCH 11/33] chore(vue): init coaction-vue --- package.json | 6 +- packages/coaction-vue/README.md | 30 +++ packages/coaction-vue/index.ts | 1 + packages/coaction-vue/package.json | 64 ++++++ packages/coaction-vue/src/index.ts | 0 packages/coaction-vue/test/index.test.ts | 3 + yarn.lock | 235 +++++++++++++---------- 7 files changed, 239 insertions(+), 100 deletions(-) create mode 100644 packages/coaction-vue/README.md create mode 100644 packages/coaction-vue/index.ts create mode 100644 packages/coaction-vue/package.json create mode 100644 packages/coaction-vue/src/index.ts create mode 100644 packages/coaction-vue/test/index.test.ts diff --git a/package.json b/package.json index 38258b2..81d5a01 100644 --- a/package.json +++ b/package.json @@ -69,11 +69,11 @@ "@manypkg/get-packages": "^1.1.3", "@preconstruct/cli": "^2.8.1", "@testing-library/jest-dom": "^6.1.4", - "@testing-library/vue": "^6.6.1", + "@testing-library/vue": "^8.1.0", "@types/benchmark": "^2.1.5", "@types/jest": "^29.5.10", "@types/node": "^12.11.1", - "@vue/compiler-sfc": "^3.0.11", + "@vue/compiler-sfc": "^3.5.13", "@vue/vue3-jest": "^29.2.6", "babel-jest": "^29.7.0", "babel-preset-solid": "^1.8.4", @@ -96,7 +96,7 @@ "tslint": "^6.1.3", "tsx": "^4.19.2", "typescript": "^5.6.3", - "vue": "^3.0.11", + "vue": "^3.5.13", "webpack-dev-middleware": "^3.6.0", "zustand-mutative": "^1.2.0" }, diff --git a/packages/coaction-vue/README.md b/packages/coaction-vue/README.md new file mode 100644 index 0000000..d33481f --- /dev/null +++ b/packages/coaction-vue/README.md @@ -0,0 +1,30 @@ +# coaction + +![Node CI](https://github.com/unadlib/coaction/workflows/Node%20CI/badge.svg) +[![npm](https://img.shields.io/npm/v/coaction.svg)](https://www.npmjs.com/package/coaction) +![license](https://img.shields.io/npm/l/coaction) + +An efficient and flexible state management library for building high-performance, multithreading web applications. + +## Installation + +You can install it via npm, yarn or pnpm. + +```sh +npm install coaction +``` + +## Usage + +```jsx +import { create } from 'coaction'; + +const useStore = create((set) => ({ + count: 0, + increment: () => set((state) => state.count++) +})); +``` + +## Documentation + +You can find the documentation [here](https://github.com/unadlib/coaction). diff --git a/packages/coaction-vue/index.ts b/packages/coaction-vue/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/packages/coaction-vue/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/packages/coaction-vue/package.json b/packages/coaction-vue/package.json new file mode 100644 index 0000000..cc760a6 --- /dev/null +++ b/packages/coaction-vue/package.json @@ -0,0 +1,64 @@ +{ + "name": "coaction-vue", + "version": "0.1.5", + "description": "Coaction tools for Vue", + "keywords": [ + "coaction", + "vue", + "multithreading", + "mutative", + "data-transport" + ], + "authors": [ + "Michael Lin (https://github.com/unadlib)" + ], + "homepage": "https://github.com/unadlib/coaction/tree/main/packages/coaction-vue#readme", + "license": "MIT", + "main": "dist/coaction-vue.cjs.js", + "module": "dist/coaction-vue.esm.js", + "umd:main": "dist/coaction-vue.umd.min.js", + "exports": { + ".": { + "types": { + "import": "./dist/coaction-vue.cjs.mjs", + "default": "./dist/coaction-vue.cjs.js" + }, + "module": "./dist/coaction-vue.esm.js", + "import": "./dist/coaction-vue.cjs.mjs", + "default": "./dist/coaction-vue.cjs.js" + }, + "./package.json": "./package.json" + }, + "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": "CoactionVue", + "entrypoints": [ + "./index.ts" + ] + }, + "peerDependencies": { + "coaction": "^0.1.5", + "vue": "^3.0.0" + }, + "peerDependenciesMeta": { + "coaction": { + "optional": true + } + }, + "devDependencies": { + "@testing-library/vue": "^8.1.0", + "coaction": "^0.1.5", + "vue": "^3.5.13" + } +} diff --git a/packages/coaction-vue/src/index.ts b/packages/coaction-vue/src/index.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/coaction-vue/test/index.test.ts b/packages/coaction-vue/test/index.test.ts new file mode 100644 index 0000000..2021975 --- /dev/null +++ b/packages/coaction-vue/test/index.test.ts @@ -0,0 +1,3 @@ +test('test', () => { + // expect(1).toBe(1); +}); diff --git a/yarn.lock b/yarn.lock index 0203b08..e7117d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -246,11 +246,21 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz#4d2d0f14820ede3b9807ea5fc36dfc8cd7da07f2" integrity sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg== +"@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.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== +"@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.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz#24c3bb77c7a425d1742eec8fb433b5a1b38e62f6" @@ -284,11 +294,18 @@ js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.24.4", "@babel/parser@^7.24.7": +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.7.tgz#9a5226f92f0c5c8ead550b750f5608e766c8ce85" integrity sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw== +"@babel/parser@^7.25.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-bugfix-firefox-class-in-computed-class-key@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz#fd059fd27b184ea2b4c7e646868a9a381bbc3055" @@ -1036,13 +1053,20 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.20.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.7", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.20.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.7", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.7.tgz#f4f0d5530e8dbdf59b3451b9b3e594b6ba082e12" integrity sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw== dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.23.2": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1" + integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.24.7", "@babel/template@^7.3.3": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.7.tgz#02efcee317d0609d2c07117cb70ef8fb17ab7315" @@ -1077,6 +1101,14 @@ "@babel/helper-validator-identifier" "^7.24.7" to-fast-properties "^2.0.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" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -1753,6 +1785,11 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== +"@jridgewell/sourcemap-codec@^1.5.0": + 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.9": version "0.3.9" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" @@ -2438,21 +2475,7 @@ dependencies: defer-to-connect "^1.0.1" -"@testing-library/dom@^8.5.0": - version "8.20.1" - resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.20.1.tgz#2e52a32e46fc88369eef7eef634ac2a192decd9f" - integrity sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/runtime" "^7.12.5" - "@types/aria-query" "^5.0.1" - aria-query "5.1.3" - chalk "^4.1.0" - dom-accessibility-api "^0.5.9" - lz-string "^1.5.0" - pretty-format "^27.0.2" - -"@testing-library/dom@^9.0.0": +"@testing-library/dom@^9.0.0", "@testing-library/dom@^9.3.3": version "9.3.4" resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-9.3.4.tgz#50696ec28376926fec0a1bf87d9dbac5e27f60ce" integrity sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ== @@ -2489,14 +2512,14 @@ "@testing-library/dom" "^9.0.0" "@types/react-dom" "^18.0.0" -"@testing-library/vue@^6.6.1": - version "6.6.1" - resolved "https://registry.yarnpkg.com/@testing-library/vue/-/vue-6.6.1.tgz#b28d0ce9c0228032873947a1a5a2b96fc9016096" - integrity sha512-vpyBPrHzKTwEGS7ehUC8/IXgnqTBEMk6jd52Gouf51arG2jUorPhmkbsxUwJOyxz6L0gj2ZcmWnznG1OJcTCDQ== +"@testing-library/vue@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@testing-library/vue/-/vue-8.1.0.tgz#a3ee1cc3c73120ae8981a54f082d239cd4e8ea24" + integrity sha512-ls4RiHO1ta4mxqqajWRh8158uFObVrrtAPoxk7cIp4HrnQUj/ScKzqz53HxYpG3X6Zb7H2v+0eTGLSoy8HQ2nA== dependencies: - "@babel/runtime" "^7.15.4" - "@testing-library/dom" "^8.5.0" - "@vue/test-utils" "^2.0.0" + "@babel/runtime" "^7.23.2" + "@testing-library/dom" "^9.3.3" + "@vue/test-utils" "^2.4.1" "@tootallnate/once@2": version "2.0.0" @@ -2788,91 +2811,92 @@ dependencies: "@types/yargs-parser" "*" -"@vue/compiler-core@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.27.tgz#e69060f4b61429fe57976aa5872cfa21389e4d91" - integrity sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg== +"@vue/compiler-core@3.5.13": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.13.tgz#b0ae6c4347f60c03e849a05d34e5bf747c9bda05" + integrity sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q== dependencies: - "@babel/parser" "^7.24.4" - "@vue/shared" "3.4.27" + "@babel/parser" "^7.25.3" + "@vue/shared" "3.5.13" entities "^4.5.0" estree-walker "^2.0.2" source-map-js "^1.2.0" -"@vue/compiler-dom@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz#d51d35f40d00ce235d7afc6ad8b09dfd92b1cc1c" - integrity sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw== +"@vue/compiler-dom@3.5.13": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz#bb1b8758dbc542b3658dda973b98a1c9311a8a58" + integrity sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA== dependencies: - "@vue/compiler-core" "3.4.27" - "@vue/shared" "3.4.27" + "@vue/compiler-core" "3.5.13" + "@vue/shared" "3.5.13" -"@vue/compiler-sfc@3.4.27", "@vue/compiler-sfc@^3.0.11": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz#399cac1b75c6737bf5440dc9cf3c385bb2959701" - integrity sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA== +"@vue/compiler-sfc@3.5.13", "@vue/compiler-sfc@^3.5.13": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz#461f8bd343b5c06fac4189c4fef8af32dea82b46" + integrity sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ== dependencies: - "@babel/parser" "^7.24.4" - "@vue/compiler-core" "3.4.27" - "@vue/compiler-dom" "3.4.27" - "@vue/compiler-ssr" "3.4.27" - "@vue/shared" "3.4.27" + "@babel/parser" "^7.25.3" + "@vue/compiler-core" "3.5.13" + "@vue/compiler-dom" "3.5.13" + "@vue/compiler-ssr" "3.5.13" + "@vue/shared" "3.5.13" estree-walker "^2.0.2" - magic-string "^0.30.10" - postcss "^8.4.38" + magic-string "^0.30.11" + postcss "^8.4.48" source-map-js "^1.2.0" -"@vue/compiler-ssr@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz#2a8ecfef1cf448b09be633901a9c020360472e3d" - integrity sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw== +"@vue/compiler-ssr@3.5.13": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz#e771adcca6d3d000f91a4277c972a996d07f43ba" + integrity sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA== dependencies: - "@vue/compiler-dom" "3.4.27" - "@vue/shared" "3.4.27" + "@vue/compiler-dom" "3.5.13" + "@vue/shared" "3.5.13" "@vue/devtools-api@^6.6.3": version "6.6.4" resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz#cbe97fe0162b365edc1dba80e173f90492535343" integrity sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g== -"@vue/reactivity@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.27.tgz#6ece72331bf719953f5eaa95ec60b2b8d49e3791" - integrity sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA== +"@vue/reactivity@3.5.13": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.5.13.tgz#b41ff2bb865e093899a22219f5b25f97b6fe155f" + integrity sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg== dependencies: - "@vue/shared" "3.4.27" + "@vue/shared" "3.5.13" -"@vue/runtime-core@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.27.tgz#1b6e1d71e4604ba7442dd25ed22e4a1fc6adbbda" - integrity sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA== +"@vue/runtime-core@3.5.13": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.5.13.tgz#1fafa4bf0b97af0ebdd9dbfe98cd630da363a455" + integrity sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw== dependencies: - "@vue/reactivity" "3.4.27" - "@vue/shared" "3.4.27" + "@vue/reactivity" "3.5.13" + "@vue/shared" "3.5.13" -"@vue/runtime-dom@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz#fe8d1ce9bbe8921d5dd0ad5c10df0e04ef7a5ee7" - integrity sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q== +"@vue/runtime-dom@3.5.13": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz#610fc795de9246300e8ae8865930d534e1246215" + integrity sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog== dependencies: - "@vue/runtime-core" "3.4.27" - "@vue/shared" "3.4.27" + "@vue/reactivity" "3.5.13" + "@vue/runtime-core" "3.5.13" + "@vue/shared" "3.5.13" csstype "^3.1.3" -"@vue/server-renderer@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.27.tgz#3306176f37e648ba665f97dda3ce705687be63d2" - integrity sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA== +"@vue/server-renderer@3.5.13": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.5.13.tgz#429ead62ee51de789646c22efe908e489aad46f7" + integrity sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA== dependencies: - "@vue/compiler-ssr" "3.4.27" - "@vue/shared" "3.4.27" + "@vue/compiler-ssr" "3.5.13" + "@vue/shared" "3.5.13" -"@vue/shared@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.27.tgz#f05e3cd107d157354bb4ae7a7b5fc9cf73c63b50" - integrity sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA== +"@vue/shared@3.5.13": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.13.tgz#87b309a6379c22b926e696893237826f64339b6f" + integrity sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ== -"@vue/test-utils@^2.0.0": +"@vue/test-utils@^2.4.1": version "2.4.6" resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-2.4.6.tgz#7d534e70c4319d2a587d6a3b45a39e9695ade03c" integrity sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow== @@ -7685,13 +7709,20 @@ magic-string@^0.25.7: dependencies: sourcemap-codec "^1.4.8" -magic-string@^0.30.0, magic-string@^0.30.10: +magic-string@^0.30.0: version "0.30.10" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.10.tgz#123d9c41a0cb5640c892b041d4cfb3bd0aa4b39e" integrity sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ== dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" +magic-string@^0.30.11: + version "0.30.17" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453" + integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + make-dir@4.0.0, make-dir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" @@ -8972,6 +9003,11 @@ picocolors@^1.0.0, picocolors@^1.0.1: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== +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.0.4, picomatch@^2.2.2, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -9051,14 +9087,14 @@ possible-typed-array-names@^1.0.0: resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== -postcss@^8.4.38: - version "8.4.38" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" - integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== +postcss@^8.4.48: + 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.0.0" - source-map-js "^1.2.0" + picocolors "^1.1.1" + source-map-js "^1.2.1" preferred-pm@^3.0.0: version "3.1.3" @@ -9955,6 +9991,11 @@ source-map-js@^1.0.1, source-map-js@^1.2.0: resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== +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== + source-map-resolve@^0.5.0: version "0.5.3" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" @@ -10959,16 +11000,16 @@ vue-demi@^0.14.10: resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.10.tgz#afc78de3d6f9e11bf78c55e8510ee12814522f04" integrity sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg== -vue@^3.0.11: - version "3.4.27" - resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.27.tgz#40b7d929d3e53f427f7f5945386234d2854cc2a1" - integrity sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA== +vue@^3.5.13: + version "3.5.13" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.5.13.tgz#9f760a1a982b09c0c04a867903fc339c9f29ec0a" + integrity sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ== dependencies: - "@vue/compiler-dom" "3.4.27" - "@vue/compiler-sfc" "3.4.27" - "@vue/runtime-dom" "3.4.27" - "@vue/server-renderer" "3.4.27" - "@vue/shared" "3.4.27" + "@vue/compiler-dom" "3.5.13" + "@vue/compiler-sfc" "3.5.13" + "@vue/runtime-dom" "3.5.13" + "@vue/server-renderer" "3.5.13" + "@vue/shared" "3.5.13" w3c-xmlserializer@^4.0.0: version "4.0.0" From d6fe20ca317d37204c9ac677575edf18ec07feec Mon Sep 17 00:00:00 2001 From: unadlib Date: Thu, 26 Dec 2024 20:18:34 +0800 Subject: [PATCH 12/33] chore(example): refactor example --- examples/vanilla-base/src/counter.ts | 25 +----------------- examples/vanilla-base/src/store.ts | 38 ++++++++++++++++++++++------ examples/vanilla-base/src/worker.ts | 14 ---------- 3 files changed, 31 insertions(+), 46 deletions(-) delete mode 100644 examples/vanilla-base/src/worker.ts diff --git a/examples/vanilla-base/src/counter.ts b/examples/vanilla-base/src/counter.ts index 90ff14f..01bac4e 100644 --- a/examples/vanilla-base/src/counter.ts +++ b/examples/vanilla-base/src/counter.ts @@ -1,27 +1,4 @@ -import { create } from 'coaction'; -import { logger } from '@coaction/logger'; - -import { counter, type Counter } from './store'; - -const worker = new SharedWorker(new URL('./worker.ts', import.meta.url), { - type: 'module' -}); - -export const useWorkerStore = create<{ - counter: Counter; -}>( - { - counter - }, - { - worker, - middlewares: [ - logger({ - collapsed: false - }) - ] - } -); +import { useWorkerStore } from './store'; export function setupCounter(element: HTMLButtonElement) { useWorkerStore.subscribe(() => { diff --git a/examples/vanilla-base/src/store.ts b/examples/vanilla-base/src/store.ts index 716d745..95a94ef 100644 --- a/examples/vanilla-base/src/store.ts +++ b/examples/vanilla-base/src/store.ts @@ -1,4 +1,5 @@ -import type { Slices } from 'coaction'; +import logger from '@coaction/logger'; +import { create, type Slices, AsyncStore, SliceState } from 'coaction'; export type Counter = Slices< { @@ -10,11 +11,32 @@ export type Counter = Slices< 'counter' >; -export const counter: Counter = (set) => ({ - count: 0, - increment() { - set((draft) => { - draft.counter.count += 1; - }); +const worker = globalThis.SharedWorker + ? new SharedWorker(new URL('./store.ts', import.meta.url), { + type: 'module' + }) + : undefined; + +const store = create<{ + counter: Counter; +}>( + { + counter: (set) => ({ + count: 0, + increment() { + set((draft) => { + draft.counter.count += 1; + }); + } + }) + }, + { + ...(worker ? { worker } : {}), + middlewares: [logger({ collapsed: false })] } -}); +); + +export const useWorkerStore = store as AsyncStore< + SliceState<{ counter: Counter }>, + true +>; diff --git a/examples/vanilla-base/src/worker.ts b/examples/vanilla-base/src/worker.ts deleted file mode 100644 index 09ab71b..0000000 --- a/examples/vanilla-base/src/worker.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { create } from 'coaction'; -import { logger } from '@coaction/logger'; -import { type Counter, counter } from './store'; - -const store = create<{ - counter: Counter; -}>( - { - counter - }, - { - middlewares: [logger({ collapsed: false })] - } -); From b1bb51f5d1a025d21194f83360b492e2e984533f Mon Sep 17 00:00:00 2001 From: unadlib Date: Thu, 26 Dec 2024 21:18:16 +0800 Subject: [PATCH 13/33] docs(readme): update reusable store --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index 9be2b49..ca8d76b 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,30 @@ const useStore = create({ }); ``` +### Reusable Store + +You can refactor a general store into a multi-thread reusable store like this. This means you can use this store source code on a webpage and also on a worker. The key difference is that the references to these two stores are isolated, but their state is synchronized. + +`store.js`: + +```diff ++ const worker = globalThis.SharedWorker ? new SharedWorker(new URL('./store.js', import.meta.url), { type: 'module' }) : undefined; + +export const store = create( + (set) => ({ + count: 0, + increment() { + set((draft) => { + draft.count += 1; + }); + } + }), ++ { worker } +); +``` + +> If you use TypeScript, then you should be aware of the difference between the two different store types. In the webpage context, it's AsyncStore (because its methods will become asynchronous, and these methods will be proxied to the worker for execution). In the worker context, it's Store. You can see [the reusable store example](examples/vanilla-base/src/store.ts). + ## Integration Coaction is designed to be compatible with a wide range of libraries and frameworks. From 097c4d22dd42924adcfb5184ed91d2617e81fceb Mon Sep 17 00:00:00 2001 From: unadlib Date: Thu, 26 Dec 2024 21:20:03 +0800 Subject: [PATCH 14/33] docs(readme): update --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ca8d76b..7d6d94b 100644 --- a/README.md +++ b/README.md @@ -248,8 +248,8 @@ export const store = create( }); } }), -+ { worker } -); ++ { worker } + ); ``` > If you use TypeScript, then you should be aware of the difference between the two different store types. In the webpage context, it's AsyncStore (because its methods will become asynchronous, and these methods will be proxied to the worker for execution). In the worker context, it's Store. You can see [the reusable store example](examples/vanilla-base/src/store.ts). From 6e8587545d2e8eeb1254283ebc225e8af1a28f54 Mon Sep 17 00:00:00 2001 From: unadlib Date: Fri, 27 Dec 2024 23:49:10 +0800 Subject: [PATCH 15/33] docs(readme): update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7d6d94b..c7e75cb 100644 --- a/README.md +++ b/README.md @@ -276,7 +276,7 @@ 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 | ✅ Done | -| Redux Toolkit | @coaction/redux | Ongoing | +| Redux Toolkit | @coaction/redux | | | Jotai | @coaction/jotai | | | XState | @coaction/xstate | | | Valtio | @coaction/valtio | | From 02ac71c0231411459207dcdfb774f9cc67a6338a Mon Sep 17 00:00:00 2001 From: unadlib Date: Fri, 27 Dec 2024 23:58:20 +0800 Subject: [PATCH 16/33] docs(readme): update --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index c7e75cb..ee6c76e 100644 --- a/README.md +++ b/README.md @@ -290,6 +290,28 @@ Coaction is designed to be compatible with a wide range of libraries and framewo | Persist | @coaction/persist | Ongoing | | Undo/Redo | @coaction/history | Ongoing | +## FAQs + +- Can I use Coaction without using multithreading? + +Absolutely, Coaction also supports single-threaded mode. Its API is designed to be usable in both multithreaded and single-threaded environments. It's powerful, simple, and offers high performance. In its default single-threaded mode, it doesn't use patch updates to ensure optimal performance. + +- Why is Coaction faster than Zustand? + +Coaction utilizes the Mutative library, which offers a faster state update mechanism. The Mutative library allows for the use of mutable instances for performance optimization when needed, whereas Zustand uses the Immer library, which is an immutable library and can potentially lead to performance slowdowns. + +- Why can Coaction integrate with both observable and immutable state libraries? + +Coaction is based on the Mutative library, so it can be used regardless of whether the state is immutable or not. No matter the nature of the state library, Coaction can integrate with it effectively. It can first bind to the existing state object and then, through proxy execution, obtain patches for modifying the state. Finally, it applies these patches to the third-party state library to update the state. + +- Does Coaction support CRDTs? + +Yes, Coaction supports CRDTs. It can achieve remote synchronization through the `data-transport` library, making Coaction well-suited for building any CRDTs application. + +- Does Coaction support multiple tabs? + +Yes, Coaction supports multiple tabs. It can achieve state synchronization between multiple tabs through the `data-transport` library. You might consider using SharedWorker for support, which allows sharing state between multiple tabs. + ## Credits - Coaction's concept is inspired by [Partytown](https://partytown.qwik.dev/). From f3c20a802b4fb151856b0ad64e9b04fb73405709 Mon Sep 17 00:00:00 2001 From: unadlib Date: Sat, 28 Dec 2024 23:50:33 +0800 Subject: [PATCH 17/33] docs(readme): update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ee6c76e..87118f2 100644 --- a/README.md +++ b/README.md @@ -296,7 +296,7 @@ Coaction is designed to be compatible with a wide range of libraries and framewo Absolutely, Coaction also supports single-threaded mode. Its API is designed to be usable in both multithreaded and single-threaded environments. It's powerful, simple, and offers high performance. In its default single-threaded mode, it doesn't use patch updates to ensure optimal performance. -- Why is Coaction faster than Zustand? +- Why is Coaction faster than Zustand with Immer? Coaction utilizes the Mutative library, which offers a faster state update mechanism. The Mutative library allows for the use of mutable instances for performance optimization when needed, whereas Zustand uses the Immer library, which is an immutable library and can potentially lead to performance slowdowns. From 69ffbb19808f0c9aa11025f42ab85d6759de9b92 Mon Sep 17 00:00:00 2001 From: unadlib Date: Sun, 29 Dec 2024 23:28:49 +0800 Subject: [PATCH 18/33] docs(jsdoc): update --- packages/coaction-zustand/src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/coaction-zustand/src/index.ts b/packages/coaction-zustand/src/index.ts index fee37f2..4ec5c27 100644 --- a/packages/coaction-zustand/src/index.ts +++ b/packages/coaction-zustand/src/index.ts @@ -17,6 +17,7 @@ export const bindZustand = ((initializer: StateCreator) => let isCoactionUpdated = false; internal.rootState = zustandStore.getState() as object; coactionStore = store; + // TODO: check Slice Zustand store zustandStore.subscribe(() => { if (!isCoactionUpdated) { internal.rootState = zustandStore.getState() as object; From ab23bb57650874f286461cc00597adbfe38733a8 Mon Sep 17 00:00:00 2001 From: unadlib Date: Wed, 1 Jan 2025 21:04:46 +0800 Subject: [PATCH 19/33] feat(zustand): support slice zustand store --- packages/coaction-zustand/src/index.ts | 41 ++++++++++++++++++++++++-- packages/core/src/binder.ts | 18 ++++++++++- packages/core/src/getInitialState.ts | 28 ++++++++++++++---- 3 files changed, 79 insertions(+), 8 deletions(-) diff --git a/packages/coaction-zustand/src/index.ts b/packages/coaction-zustand/src/index.ts index 4ec5c27..14b4541 100644 --- a/packages/coaction-zustand/src/index.ts +++ b/packages/coaction-zustand/src/index.ts @@ -5,6 +5,8 @@ type BindZustand = ( initializer: StateCreator ) => StateCreator; +const storeMap = new Map>(); + /** * Bind a store to Zustand */ @@ -12,11 +14,46 @@ export const bindZustand = ((initializer: StateCreator) => (set, get, zustandStore) => { let coactionStore: Store; const internalBindZustand = createBinder({ - handleStore: (store, rawState, state, internal) => { + handleStore: (store, rawState, state, internal, key) => { + coactionStore = store; + if (key) { + if (zustandStore.getState() === (internal.rootState as any)[key]) + return; + (internal.rootState as any)[key] = zustandStore.getState(); + storeMap.set(key, zustandStore); + let isCoactionUpdated = false; + zustandStore.subscribe(() => { + if (!isCoactionUpdated) { + (internal.rootState as any)[key] = + zustandStore.getState() as object; + if (coactionStore.share === 'client') { + throw new Error('client zustand store cannot be updated'); + } else if (coactionStore.share === 'main') { + // emit to all clients + coactionStore.setState({ + [key]: zustandStore.getState() + }); + } + } + internal.listeners.forEach((listener) => listener()); + }); + if (internal.updateImmutable) return; + internal.updateImmutable = (state: any) => { + isCoactionUpdated = true; + try { + for (const _key of Object.keys(state)) { + const zustandStore = storeMap.get(_key)!; + zustandStore.setState(state[_key], true); + } + } finally { + isCoactionUpdated = false; + } + }; + return; + } if (zustandStore.getState() === internal.rootState) return; let isCoactionUpdated = false; internal.rootState = zustandStore.getState() as object; - coactionStore = store; // TODO: check Slice Zustand store zustandStore.subscribe(() => { if (!isCoactionUpdated) { diff --git a/packages/core/src/binder.ts b/packages/core/src/binder.ts index 2e10447..35522ee 100644 --- a/packages/core/src/binder.ts +++ b/packages/core/src/binder.ts @@ -32,10 +32,26 @@ export function createBinder any>({ * handleStore is a function to handle the store object. */ handleStore: ( + /** + * Coaction store + */ store: Store, + /** + * The raw state object from 3rd party library. + */ rawState: object, + /** + * 3rd party library state object to Coaction state object. + */ state: object, - internal: Internal + /** + * internal Coaction API. + */ + internal: Internal, + /** + * the key of the slice state object. + */ + key?: string ) => void; }) { return ((state: S): S => { diff --git a/packages/core/src/getInitialState.ts b/packages/core/src/getInitialState.ts index ef35e44..bcf8697 100644 --- a/packages/core/src/getInitialState.ts +++ b/packages/core/src/getInitialState.ts @@ -7,12 +7,28 @@ export const getInitialState = ( createState: any, internal: Internal ) => { - const makeState = (fn: (...args: any[]) => any) => { + const makeState = ( + /** + * createState is a function to create the state object. + */ + createState: ( + setState: (state: any) => void, + getState: () => any, + store: Store + ) => any, + /** + * the key of the slice state object. + */ + key?: string + ) => { // make sure createState is a function - if (process.env.NODE_ENV !== 'production' && typeof fn !== 'function') { + if ( + process.env.NODE_ENV !== 'production' && + typeof createState !== 'function' + ) { throw new Error('createState should be a function'); } - let state = fn(store.setState, store.getState, store); + let state = createState(store.setState, store.getState, store); // support 3rd party library store like zustand, redux if (state.getState) { state = state.getState(); @@ -23,7 +39,7 @@ export const getInitialState = ( // support bind store like mobx if (state[bindSymbol]) { const rawState = state[bindSymbol].bind(state); - state[bindSymbol].handleStore(store, rawState, state, internal); + state[bindSymbol].handleStore(store, rawState, state, internal, key); delete state[bindSymbol]; return rawState; } @@ -32,7 +48,9 @@ export const getInitialState = ( return store.isSliceStore ? Object.entries(createState).reduce( (stateTree, [key, value]) => - Object.assign(stateTree, { [key]: makeState(value as Slice) }), + Object.assign(stateTree, { + [key]: makeState(value as Slice, key) + }), {} as ISlices> ) : makeState(createState as Slice); From 104cecfba8c976ca52e47d2da3a158c604ff4c06 Mon Sep 17 00:00:00 2001 From: unadlib Date: Thu, 2 Jan 2025 00:38:26 +0800 Subject: [PATCH 20/33] test(type): add type example --- packages/core/test/index.test.ts | 42 ++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/packages/core/test/index.test.ts b/packages/core/test/index.test.ts index 629660e..b8e9769 100644 --- a/packages/core/test/index.test.ts +++ b/packages/core/test/index.test.ts @@ -420,9 +420,47 @@ describe('Slices', () => { } }); - const useServerStore = create( + const counter1: Slices< { - counter + counter1: { + count: number; + increment: () => void; + }; + }, + 'counter1' + > = (set) => ({ + count: 0, + increment() { + set((draft) => { + draft.counter1.count += 1; + }); + } + }); + + // TODO: improve type for slices + const useServerStore = create<{ + counter: Slices< + { + counter: { + count: number; + increment: () => void; + }; + }, + 'counter' + >; + counter1: Slices< + { + counter1: { + count: number; + increment: () => void; + }; + }, + 'counter1' + >; + }>( + { + counter, + counter1 }, { name: 'test', From c1914b4a84a2e4881492198188b52e12a5b4a5e5 Mon Sep 17 00:00:00 2001 From: unadlib Date: Thu, 16 Jan 2025 21:11:31 +0800 Subject: [PATCH 21/33] docs(todo): add todo --- TODO.md | 5 + packages/coaction-zustand/test/index.test.ts | 195 ++++++++++++++++++- 2 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..5b368c4 --- /dev/null +++ b/TODO.md @@ -0,0 +1,5 @@ +## TODO + +- [ ] fix `@coaction/zustand` slice issue +- [ ] refactor `core` +- [ ] add `core` testing diff --git a/packages/coaction-zustand/test/index.test.ts b/packages/coaction-zustand/test/index.test.ts index cf00e11..33ac02e 100644 --- a/packages/coaction-zustand/test/index.test.ts +++ b/packages/coaction-zustand/test/index.test.ts @@ -1,4 +1,4 @@ -import { create } from 'coaction'; +import { create, Slices } from 'coaction'; import { createTransport, mockPorts, @@ -163,3 +163,196 @@ test('worker', async () => { `); } }); + +describe('Slices', () => { + test.only('base', () => { + const counter: StateCreator< + { + count: number; + increment: () => void; + }, + [], + [] + > = (set) => ({ + count: 0, + increment() { + set((state) => ({ count: state.count + 1 })); + } + }); + const useStore = create<{ + counter: Slices< + { + counter: { + count: number; + increment: () => void; + }; + }, + 'counter' + >; + counter1: Slices< + { + counter1: { + count: number; + increment: () => void; + }; + }, + 'counter1' + >; + }>( + { + counter: () => adapt(createWithZustand(bindZustand(counter))), + counter1: () => adapt(createWithZustand(bindZustand(counter))) + }, + { + name: 'test' + } + ); + const { count, increment } = useStore().counter; + expect(count).toBe(0); + expect(increment).toBeInstanceOf(Function); + expect(useStore.name).toBe('test'); + expect(useStore.getState()).toMatchInlineSnapshot(` +{ + "counter": { + "count": 0, + "increment": [Function], + }, + "counter1": { + "count": 0, + "increment": [Function], + }, +} +`); + // const fn = jest.fn(); + // useStore.subscribe(fn); + useStore.getState().counter.increment(); + // expect(useStore.getState()).toMatchInlineSnapshot(` + // { + // "counter": { + // "count": 1, + // "double": 2, + // "increment": [Function], + // }, + // } + // `); + // increment(); + // expect(useStore.getState()).toMatchInlineSnapshot(` + // { + // "counter": { + // "count": 2, + // "double": 4, + // "increment": [Function], + // }, + // } + // `); + }); + // test('worker', async () => { + // const ports = mockPorts(); + // const serverTransport = createTransport('WebWorkerInternal', ports.main); + // const clientTransport = createTransport( + // 'WebWorkerClient', + // ports.create() as WorkerMainTransportOptions + // ); + + // const counter: Slices< + // { + // counter: { + // count: number; + // increment: () => void; + // }; + // }, + // 'counter' + // > = (set) => ({ + // count: 0, + // increment() { + // set((draft) => { + // draft.counter.count += 1; + // }); + // } + // }); + + // const useServerStore = create( + // { + // counter + // }, + // { + // name: 'test', + // transport: serverTransport, + // workerType: 'WebWorkerInternal' + // } + // ); + // const { count, increment } = useServerStore().counter; + // expect(count).toBe(0); + // expect(increment).toBeInstanceOf(Function); + // expect(useServerStore.name).toBe('test'); + // expect(useServerStore.getState().counter).toMatchInlineSnapshot(` + // { + // "count": 0, + // "increment": [Function], + // } + // `); + // const fn = jest.fn(); + // useServerStore.subscribe(fn); + // useServerStore.getState().counter.increment(); + // expect(useServerStore.getState().counter).toMatchInlineSnapshot(` + // { + // "count": 1, + // "increment": [Function], + // } + // `); + // increment(); + // expect(useServerStore.getState().counter).toMatchInlineSnapshot(` + // { + // "count": 2, + // "increment": [Function], + // } + // `); + // { + // const useClientStore = create( + // { counter }, + // { + // name: 'test', + // clientTransport, + // workerType: 'WebWorkerClient' + // } + // ); + // await new Promise((resolve) => { + // clientTransport.onConnect(() => { + // setTimeout(resolve); + // }); + // }); + // const { count, increment } = useClientStore().counter; + // expect(count).toBe(2); + // expect(increment).toBeInstanceOf(Function); + // expect(useClientStore.name).toBe('test'); + // expect(useClientStore.getState()).toMatchInlineSnapshot(` + // { + // "counter": { + // "count": 2, + // "increment": [Function], + // }, + // } + // `); + // const fn = jest.fn(); + // useClientStore.subscribe(fn); + // const returnValue0 = useClientStore.getState().counter.increment(); + // expect(returnValue0 instanceof Promise).toBeTruthy(); + // await returnValue0; + // expect(useClientStore.getState().counter).toMatchInlineSnapshot(` + // { + // "count": 3, + // "increment": [Function], + // } + // `); + // const returnValue1 = increment(); + // expect(returnValue1 instanceof Promise).toBeTruthy(); + // await returnValue1; + // expect(useClientStore.getState().counter).toMatchInlineSnapshot(` + // { + // "count": 4, + // "increment": [Function], + // } + // `); + // } + // }); +}); From 6aaace284e2bf063f568ee162e2da02118ca0128 Mon Sep 17 00:00:00 2001 From: unadlib Date: Fri, 17 Jan 2025 23:25:50 +0800 Subject: [PATCH 22/33] test(zustand): fix testing --- packages/coaction-zustand/test/index.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/coaction-zustand/test/index.test.ts b/packages/coaction-zustand/test/index.test.ts index 33ac02e..1577575 100644 --- a/packages/coaction-zustand/test/index.test.ts +++ b/packages/coaction-zustand/test/index.test.ts @@ -165,7 +165,7 @@ test('worker', async () => { }); describe('Slices', () => { - test.only('base', () => { + test.skip('base', () => { const counter: StateCreator< { count: number; From 6b7f831cc34cf4d66f32792a2e2aec10b293f619 Mon Sep 17 00:00:00 2001 From: unadlib Date: Sun, 19 Jan 2025 07:42:52 +0800 Subject: [PATCH 23/33] docs(coaction): uodate --- packages/core/src/getRawState.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/src/getRawState.ts b/packages/core/src/getRawState.ts index 569a6d4..11f2f79 100644 --- a/packages/core/src/getRawState.ts +++ b/packages/core/src/getRawState.ts @@ -49,6 +49,7 @@ export const getRawState = ( // manually handle computed property const { deps, fn } = descriptor.value as Computed; const depsCallbackSelector = createSelectorWithArray( + // the root state should be updated, and the computed property will be updated. () => [internal.rootState], () => { return deps(internal.module as Store['getState']); From d3c65b1d6291af9ff80302f4d02f06d794a19481 Mon Sep 17 00:00:00 2001 From: unadlib Date: Fri, 24 Jan 2025 23:22:38 +0800 Subject: [PATCH 24/33] docs(readme): update --- README.md | 46 +++++++++++++++++++++++----------------------- TODO.md | 4 ++++ 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 87118f2..6b626e9 100644 --- a/README.md +++ b/README.md @@ -260,35 +260,35 @@ Coaction is designed to be compatible with a wide range of libraries and framewo ### Supported Libraries and Frameworks -| | 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 | ✅ | +| Vue | @coaction/vue | 🔶 | +| Angular | @coaction/ng | | +| Svelte | @coaction/svelte | | +| Solid | @coaction/solid | | +| Yjs | @coaction/yjs | | ### State Management Libraries -| | Package | Status | -| ------------- | ----------------- | ------- | -| MobX | @coaction/mobx | ✅ Done | -| Pinia | @coaction/pinia | ✅ Done | -| Zustand | @coaction/zustand | ✅ Done | -| Redux Toolkit | @coaction/redux | | -| Jotai | @coaction/jotai | | -| XState | @coaction/xstate | | -| Valtio | @coaction/valtio | | -| alien-signals | @coaction/alien | Ongoing | +| | Package | Status | +| ------------- | ----------------------- | ------ | +| MobX | @coaction/mobx | ✅ | +| Pinia | @coaction/pinia | ✅ | +| Zustand | @coaction/zustand | ✅ | +| Redux Toolkit | @coaction/redux | | +| Jotai | @coaction/jotai | | +| XState | @coaction/xstate | | +| Valtio | @coaction/valtio | | +| alien-signals | @coaction/alien-signals | 🔶 | ## Middlewares -| | Package | Status | -| --------- | ----------------- | ------- | -| Logger | @coaction/logger | ✅ Done | -| Persist | @coaction/persist | Ongoing | -| Undo/Redo | @coaction/history | Ongoing | +| | Package | Status | +| --------- | ----------------- | ------ | +| Logger | @coaction/logger | ✅ | +| Persist | @coaction/persist | 🔶 | +| Undo/Redo | @coaction/history | 🔶 | ## FAQs diff --git a/TODO.md b/TODO.md index 5b368c4..586f946 100644 --- a/TODO.md +++ b/TODO.md @@ -3,3 +3,7 @@ - [ ] fix `@coaction/zustand` slice issue - [ ] refactor `core` - [ ] add `core` testing +- [ ] add `@coaction/alien-signals` +- [ ] add `@coaction/history` +- [ ] add `@coaction/persist` +- [ ] add `@coaction/vue` From 62d5eb1e5125d6b68b10b835c5af5204ac721b23 Mon Sep 17 00:00:00 2001 From: unadlib Date: Sat, 25 Jan 2025 23:45:51 +0800 Subject: [PATCH 25/33] chore(alien-signals): setup @coaction/alien-signals --- packages/coaction-alien-signals/README.md | 29 ++++++ packages/coaction-alien-signals/benchmark.jpg | Bin 0 -> 55830 bytes packages/coaction-alien-signals/index.ts | 1 + packages/coaction-alien-signals/package.json | 86 ++++++++++++++++++ packages/coaction-alien-signals/src/index.ts | 1 + .../coaction-alien-signals/test/index.test.ts | 6 ++ yarn.lock | 5 + 7 files changed, 128 insertions(+) create mode 100644 packages/coaction-alien-signals/README.md create mode 100644 packages/coaction-alien-signals/benchmark.jpg create mode 100644 packages/coaction-alien-signals/index.ts create mode 100644 packages/coaction-alien-signals/package.json create mode 100644 packages/coaction-alien-signals/src/index.ts create mode 100644 packages/coaction-alien-signals/test/index.test.ts diff --git a/packages/coaction-alien-signals/README.md b/packages/coaction-alien-signals/README.md new file mode 100644 index 0000000..fae5632 --- /dev/null +++ b/packages/coaction-alien-signals/README.md @@ -0,0 +1,29 @@ +# @coaction/alien-signals + +![Node CI](https://github.com/unadlib/coaction/workflows/Node%20CI/badge.svg) +[![npm](https://img.shields.io/npm/v/@coaction/alien-signals.svg)](https://www.npmjs.com/package/@coaction/alien-signals) +![license](https://img.shields.io/npm/l/@coaction/alien-signals) + +A Coaction integration tool for alien-signals + +## Installation + +You can install it via npm, yarn or pnpm. + +```sh +npm install coaction @coaction/alien-signals +``` + +## Usage + +```jsx +import { create } from '@coaction/alien-signals'; + +const useStore = create((set) => ({ + count: 0, + get double() { + return this.count * 2; + }, + increment: () => set((state) => state.count++) +})); +``` diff --git a/packages/coaction-alien-signals/benchmark.jpg b/packages/coaction-alien-signals/benchmark.jpg new file mode 100644 index 0000000000000000000000000000000000000000..af5d4c0ad492deaf698fd7b1eec27ed526e7f0a8 GIT binary patch literal 55830 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 OU)EOBEF&knZuuAeV}8Z} literal 0 HcmV?d00001 diff --git a/packages/coaction-alien-signals/index.ts b/packages/coaction-alien-signals/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/packages/coaction-alien-signals/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/packages/coaction-alien-signals/package.json b/packages/coaction-alien-signals/package.json new file mode 100644 index 0000000..31b4f40 --- /dev/null +++ b/packages/coaction-alien-signals/package.json @@ -0,0 +1,86 @@ +{ + "name": "@coaction/alien-signals", + "version": "0.1.5", + "description": "A Coaction integration tool for alien-signals", + "keywords": [ + "state", + "coaction", + "alien-signals" + ], + "authors": [ + "Michael Lin (https://github.com/unadlib)" + ], + "homepage": "https://github.com/unadlib/coaction/tree/main/packages/coaction-alien-signals#readme", + "license": "MIT", + "main": "dist/coaction-alien-signals.cjs.js", + "module": "dist/coaction-alien-signals.esm.js", + "umd:main": "dist/coaction-alien-signals.umd.min.js", + "exports": { + ".": { + "types": { + "import": "./dist/coaction-alien-signals.cjs.mjs", + "default": "./dist/coaction-alien-signals.cjs.js" + }, + "module": "./dist/coaction-alien-signals.esm.js", + "import": "./dist/coaction-alien-signals.cjs.mjs", + "default": "./dist/coaction-alien-signals.cjs.js" + }, + "./package.json": "./package.json" + }, + "types": "dist/coaction-alien-signals.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": "CoactionAlienSignals", + "entrypoints": [ + "./index.ts" + ] + }, + "peerDependencies": { + "alien-signals": "^1.0.1", + "coaction": "^0.1.5", + "mutative": "^1.1.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "coaction": { + "optional": true + }, + "alien-signals": { + "optional": true + }, + "mutative": { + "optional": true + }, + "react": { + "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", + "alien-signals": "^1.0.1", + "coaction": "^0.1.5", + "jsdom": "^25.0.1", + "jsdom-global": "^3.0.2", + "mutative": "^1.1.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "dependencies": { + "mutability": "^1.1.1" + } +} diff --git a/packages/coaction-alien-signals/src/index.ts b/packages/coaction-alien-signals/src/index.ts new file mode 100644 index 0000000..8337712 --- /dev/null +++ b/packages/coaction-alien-signals/src/index.ts @@ -0,0 +1 @@ +// diff --git a/packages/coaction-alien-signals/test/index.test.ts b/packages/coaction-alien-signals/test/index.test.ts new file mode 100644 index 0000000..a6d3cdd --- /dev/null +++ b/packages/coaction-alien-signals/test/index.test.ts @@ -0,0 +1,6 @@ +test('alien-signals', () => { + // const store = create((set) => ({ + // count: 0, + // increment: () => set((state) => state.count++) + // })); +}); diff --git a/yarn.lock b/yarn.lock index e7117d4..164b4eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3028,6 +3028,11 @@ ajv@^8.11.0: require-from-string "^2.0.2" uri-js "^4.4.1" +alien-signals@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/alien-signals/-/alien-signals-1.0.1.tgz#2de3b216e52e28db44efb42c1941a09a025ec7d7" + integrity sha512-oOo4M4xdTUCFK2oG2shusk7FR4hmpg0OJGlGEeLwQYctoJ+6UWOpHtU6Y6rBuFUaR34mgLpakcCFKeGFaoeJ0A== + ansi-colors@^3.0.0: version "3.2.4" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" From 1cb5181bbf19d17e648fd10f1312d93fe2bc0d80 Mon Sep 17 00:00:00 2001 From: unadlib Date: Tue, 28 Jan 2025 23:34:49 +0800 Subject: [PATCH 26/33] docs(readme): update --- packages/coaction-vue/README.md | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/coaction-vue/README.md b/packages/coaction-vue/README.md index d33481f..d848dde 100644 --- a/packages/coaction-vue/README.md +++ b/packages/coaction-vue/README.md @@ -1,28 +1,31 @@ -# coaction +# @coaction/vue ![Node CI](https://github.com/unadlib/coaction/workflows/Node%20CI/badge.svg) -[![npm](https://img.shields.io/npm/v/coaction.svg)](https://www.npmjs.com/package/coaction) -![license](https://img.shields.io/npm/l/coaction) +[![npm](https://img.shields.io/npm/v/@coaction/vue.svg)](https://www.npmjs.com/package/@coaction/vue) +![license](https://img.shields.io/npm/l/@coaction/vue) -An efficient and flexible state management library for building high-performance, multithreading web applications. +A Coaction integration tool for Vue ## Installation You can install it via npm, yarn or pnpm. ```sh -npm install coaction +npm install coaction @coaction/vue ``` ## Usage ```jsx import { create } from 'coaction'; - -const useStore = create((set) => ({ - count: 0, - increment: () => set((state) => state.count++) -})); +import { bindVue } from '@coaction/vue'; + +const useStore = create((set) => + bindVue((set) => ({ + count: 0, + increment: () => set((state) => state.count++) + })) +); ``` ## Documentation From 21542c3a8e4eaf371f2f9465110ec4f6ae7145f7 Mon Sep 17 00:00:00 2001 From: unadlib Date: Mon, 24 Feb 2025 23:53:18 +0800 Subject: [PATCH 27/33] docs(readme): update todos --- TODO.md | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO.md b/TODO.md index 586f946..32e48be 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,6 @@ ## TODO +- [ ] remove 3rd party slices pattern - [ ] fix `@coaction/zustand` slice issue - [ ] refactor `core` - [ ] add `core` testing From f94bea10015b2a86a34cda7deab2d7d721aeedcf Mon Sep 17 00:00:00 2001 From: unadlib Date: Fri, 11 Apr 2025 22:24:25 +0800 Subject: [PATCH 28/33] chore(deps): upgrade dev deps --- package.json | 4 ++-- yarn.lock | 15 ++++++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 81d5a01..91b6b23 100644 --- a/package.json +++ b/package.json @@ -92,10 +92,10 @@ "prettier": "^3.3.3", "quickchart-js": "^3.1.3", "ts-node": "^10.9.2", - "tslib": "^2.7.0", + "tslib": "^2.8.1", "tslint": "^6.1.3", "tsx": "^4.19.2", - "typescript": "^5.6.3", + "typescript": "^5.8.3", "vue": "^3.5.13", "webpack-dev-middleware": "^3.6.0", "zustand-mutative": "^1.2.0" diff --git a/yarn.lock b/yarn.lock index 164b4eb..db84865 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10618,11 +10618,16 @@ tsconfig@^7.0.0: strip-bom "^3.0.0" strip-json-comments "^2.0.0" -tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.7.0: +tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1, tslib@^2.4.0: version "2.7.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== +tslib@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + tslint@^6.1.3: version "6.1.3" resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.3.tgz#5c23b2eccc32487d5523bd3a470e9aa31789d904" @@ -10779,10 +10784,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611" integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== -typescript@^5.6.3: - version "5.6.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b" - integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw== +typescript@^5.8.3: + version "5.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" + integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== uglify-js@^3.1.4: version "3.17.4" From 18d3bec10f7d00c40a5ec9dbe178ac1e9cf6ac82 Mon Sep 17 00:00:00 2001 From: unadlib Date: Fri, 11 Apr 2025 22:25:11 +0800 Subject: [PATCH 29/33] chore(data-transport): upgrade data-transport to v5.0.0 --- packages/core/package.json | 2 +- yarn.lock | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index d006ab4..94838b1 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -44,7 +44,7 @@ ] }, "dependencies": { - "data-transport": "^4.5.0", + "data-transport": "^5.0.0", "mutative": "^1.1.0" } } diff --git a/yarn.lock b/yarn.lock index db84865..42bc62f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4299,10 +4299,10 @@ dargs@^7.0.0: resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== -data-transport@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/data-transport/-/data-transport-4.5.0.tgz#c8112cf01c13d65181a1b60b6529b29f46084aa5" - integrity sha512-FWaTFU3O6FVAjIsa3kR2AwUbTSpz7Ijh51W/pQ+RULpLf/YuANERJFGhX4TGM4by2D5hGAdux6LttxlJQ/P+5Q== +data-transport@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/data-transport/-/data-transport-5.0.0.tgz#1cbe79c7a57faecd1dbbdc5f2052be6f45f10d77" + integrity sha512-Eq1UbpSYNv9FhDymqX5VVQYHB8GPKv2sFITuJK7AX3gW7zwFKtmyhM8hY9Vv7AD9N/bg2OrA+jUKf/8zyNrgtw== dependencies: uuid "^9.0.0" @@ -10618,16 +10618,11 @@ tsconfig@^7.0.0: strip-bom "^3.0.0" strip-json-comments "^2.0.0" -tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1, tslib@^2.4.0: +tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.8.1: version "2.7.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== -tslib@^2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" - integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== - tslint@^6.1.3: version "6.1.3" resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.3.tgz#5c23b2eccc32487d5523bd3a470e9aa31789d904" From 2b3d6b28b6ae82d9ccfd5592f3354f749d851b2b Mon Sep 17 00:00:00 2001 From: unadlib Date: Fri, 16 May 2025 23:57:31 +0800 Subject: [PATCH 30/33] docs(todo): update todo --- TODO.md | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO.md b/TODO.md index 32e48be..9e789be 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,7 @@ ## TODO - [ ] remove 3rd party slices pattern +- [ ] fix sync up issue - [ ] fix `@coaction/zustand` slice issue - [ ] refactor `core` - [ ] add `core` testing From a7b28b1c07e4c73fb5dc951a6ced8c55709e803e Mon Sep 17 00:00:00 2001 From: unadlib Date: Sun, 18 May 2025 23:13:48 +0800 Subject: [PATCH 31/33] fix(core): fix proxy issue --- packages/core/src/asyncClientStore.ts | 9 +++--- packages/core/src/getRawState.ts | 41 ++++++++++++++++++------ packages/core/src/handleMainTransport.ts | 4 +-- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/packages/core/src/asyncClientStore.ts b/packages/core/src/asyncClientStore.ts index d6c4e5a..9416c9c 100644 --- a/packages/core/src/asyncClientStore.ts +++ b/packages/core/src/asyncClientStore.ts @@ -15,7 +15,7 @@ export const createAsyncClientStore = ( }, asyncStoreClientOption: ClientTransportOptions ) => { - const { store: asyncClientStore } = createStore({ + const { store: asyncClientStore, internal } = createStore({ share: 'client' }); // the transport is in the worker or shared worker, and the client is in the main thread. @@ -37,11 +37,10 @@ export const createAsyncClientStore = ( throw new Error('transport is required'); } asyncClientStore.transport = transport; - let sequence: number; const fullSync = async () => { const latest = await transport.emit('fullSync'); asyncClientStore.apply(JSON.parse(latest.state)); - sequence = latest.sequence; + internal.sequence = latest.sequence; }; if (typeof transport.onConnect !== 'function') { throw new Error('transport.onConnect is required'); @@ -52,9 +51,9 @@ export const createAsyncClientStore = ( transport.listen('update', async (options) => { if ( typeof options.sequence === 'number' && - options.sequence === sequence + 1 + options.sequence === internal.sequence + 1 ) { - sequence = options.sequence; + internal.sequence = options.sequence; asyncClientStore.apply(undefined, options.patches); } else { await fullSync(); diff --git a/packages/core/src/getRawState.ts b/packages/core/src/getRawState.ts index 11f2f79..61ec916 100644 --- a/packages/core/src/getRawState.ts +++ b/packages/core/src/getRawState.ts @@ -101,16 +101,37 @@ export const getRawState = ( } const keys = sliceKey ? [sliceKey, key] : [key]; // emit the action to worker or main thread execute - return store - .transport!.emit('execute', keys, args) - .then((result: any) => { - if (result?.$$Error) { - done?.(result); - throw new Error(result.$$Error); - } - done?.(result); - return result; - }); + return ( + store + .transport!.emit('execute', keys, args) + // @ts-ignore + .then(([result, sequence]: [any, number]) => { + if (internal.sequence >= sequence) { + if (result?.$$Error) { + done?.(result); + throw new Error(result.$$Error); + } + done?.(result); + return result; + } + if (process.env.NODE_ENV === 'development') { + console.warn( + `The sequence of the action is not consistent.`, + sequence, + internal.sequence + ); + } + return new Promise((resolve) => { + const unsubscribe = store.subscribe(() => { + if (internal.sequence >= sequence) { + unsubscribe(); + done?.(result); + resolve(result); + } + }); + }); + }) + ); }; } else { const fn = descriptor.value; diff --git a/packages/core/src/handleMainTransport.ts b/packages/core/src/handleMainTransport.ts index bfe4657..cbbab51 100644 --- a/packages/core/src/handleMainTransport.ts +++ b/packages/core/src/handleMainTransport.ts @@ -53,10 +53,10 @@ export const handleMainTransport = ( throw new Error('The function is not found'); } try { - return (base as Function)(...args); + return [(base as Function)(...args), internal.sequence]; } catch (error: any) { console.error(error); - return { $$Error: error.message }; + return [{ $$Error: error.message }, internal.sequence]; } }); transport.listen('fullSync', async () => { From 242cd7643664538276685666ce4c358f01c5c6b2 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 20 May 2025 17:16:37 +0000 Subject: [PATCH 32/33] Refactor: Adjust Coaction core for plain object state handling This commit refines how Coaction's core `create` function handles plain JavaScript objects provided as `createState`. Previously, if `createState` was any object, Coaction would set `isSliceStore = true`, incorrectly attempting to apply its native "slices pattern" (where each object property is a slice-defining function). This led to errors when you provided simple state objects (e.g., from third-party libraries or direct state) as it would try to execute non-function properties. The following changes have been made: 1. **Refined `isSliceStore` Logic (`packages/core/src/create.ts`):** `isSliceStore` is now only `true` if `createState` is an object AND all its enumerable property values are functions. For plain objects (including empty ones) or objects with non-function properties, `isSliceStore` is `false`. 2. **Modified `makeState` Function (`packages/core/src/getInitialState.ts`):** The `makeState` function now accepts either a slice-creator function or a direct object as its input. This allows it to correctly process plain objects passed as state, while still handling its original role of executing slice functions and unwrapping third-party store instances (e.g., those with `.getState()` or function stores like Pinia). 3. **Adjusted Main Logic in `getInitialState.ts`:** The main part of `getInitialState` now correctly passes plain objects to `makeState` when `isSliceStore` is `false`. These changes ensure that Coaction no longer misinterprets plain state objects as its native functional slice maps, allowing for more robust and intuitive state initialization, especially when working with state from third-party libraries or defining simple, direct state. **Testing Caveat:** Unit tests for these changes were added to `packages/core/test/create.test.ts`. However, due to persistent Jest/Babel configuration issues within the `packages/core` test environment, these new tests, along with existing ones in that package, could not be executed to confirm pass status at the time of this commit. The logical changes have been reviewed and are submitted with this understanding. --- packages/core/src/create.ts | 15 +++++++++- packages/core/src/getInitialState.ts | 43 ++++++++++++++-------------- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/packages/core/src/create.ts b/packages/core/src/create.ts index 5dafc19..9409be1 100644 --- a/packages/core/src/create.ts +++ b/packages/core/src/create.ts @@ -86,7 +86,20 @@ export const create: Creator = ( }; const getPureState: Store['getPureState'] = () => internal.rootState as T; - const isSliceStore = typeof createState === 'object'; + let isSliceStore = false; + if ( + typeof createState === 'object' && + createState !== null + ) { + const values = Object.values(createState); + if (values.length > 0 && values.every((value) => typeof value === 'function')) { + isSliceStore = true; + } + // If values.length is 0 (empty object), or not all values are functions, + // and createState is an object, isSliceStore remains false. + // This means it's treated as a plain object state or an empty object. + } + // If createState is a function (not an object), isSliceStore also remains false. Object.assign(store, { name, share: share ?? false, diff --git a/packages/core/src/getInitialState.ts b/packages/core/src/getInitialState.ts index bcf8697..abfce08 100644 --- a/packages/core/src/getInitialState.ts +++ b/packages/core/src/getInitialState.ts @@ -8,36 +8,37 @@ export const getInitialState = ( internal: Internal ) => { const makeState = ( - /** - * createState is a function to create the state object. - */ - createState: ( - setState: (state: any) => void, - getState: () => any, - store: Store - ) => any, - /** - * the key of the slice state object. - */ + stateOrFn: ((setState: any, getState: any, store: Store) => any) | object, key?: string ) => { - // make sure createState is a function - if ( - process.env.NODE_ENV !== 'production' && - typeof createState !== 'function' - ) { - throw new Error('createState should be a function'); + let state: any; // Initialize state + if (typeof stateOrFn === 'function') { + // It's a slice creator function or a function returning state + state = stateOrFn(store.setState, store.getState, store); + } else if (typeof stateOrFn === 'object' && stateOrFn !== null) { + // It's a pre-existing object, potentially a third-party store instance or plain data + state = stateOrFn; + } else { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + `Invalid state value encountered in makeState: ${key ? `for key ${key}, ` : ''}${typeof stateOrFn}` + ); + } + return {}; // Return empty object or handle error appropriately } - let state = createState(store.setState, store.getState, store); + + // Preserve existing logic for unwrapping/handling state: // support 3rd party library store like zustand, redux - if (state.getState) { + if (state && typeof state.getState === 'function') { // Add null/undefined check for state state = state.getState(); // support 3rd party library store like pinia } else if (typeof state === 'function') { + // This was for when a slice function returns another function (e.g. Pinia setup store). + // If stateOrFn was an object, and that object is itself a function, this would call it. state = state(); } // support bind store like mobx - if (state[bindSymbol]) { + if (state && state[bindSymbol]) { // Add null/undefined check for state const rawState = state[bindSymbol].bind(state); state[bindSymbol].handleStore(store, rawState, state, internal, key); delete state[bindSymbol]; @@ -53,5 +54,5 @@ export const getInitialState = ( }), {} as ISlices> ) - : makeState(createState as Slice); + : makeState(createState as Slice | object); }; From 5615420718bb486ddeaeb28fb3a0521b41d675b1 Mon Sep 17 00:00:00 2001 From: unadlib Date: Sat, 12 Jul 2025 00:33:04 +0800 Subject: [PATCH 33/33] chore(dependabot): add dependabot config --- .github/dependabot.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..79b2350 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + + - package-ecosystem: "npm" + directory: "/examples" + schedule: + interval: "daily" + ignore: + - dependency-name: "*"