From 2b548aba1231272af4c6c6b44ade6add6948f967 Mon Sep 17 00:00:00 2001 From: Davide Segullo Date: Tue, 30 Jan 2024 03:16:55 +0100 Subject: [PATCH] fix(vue): :bug: fix reactivity --- package.json | 4 +- packages/vue/package.json | 14 ++--- packages/vue/src/hooks/chain.ts | 14 +++-- packages/vue/src/hooks/config.ts | 8 ++- packages/vue/src/hooks/connect.ts | 28 ++++----- packages/vue/src/hooks/quirks.ts | 12 ++-- packages/vue/src/hooks/wallet-connect.ts | 8 ++- packages/vue/src/plugin.ts | 19 ++---- packages/vue/vite.config.ts | 2 +- pnpm-lock.yaml | 73 +++++++++++++++++++----- 10 files changed, 110 insertions(+), 72 deletions(-) diff --git a/package.json b/package.json index a8cb2321..25a75cbb 100644 --- a/package.json +++ b/package.json @@ -121,7 +121,7 @@ "vue": "^3.3.4", "vue-qrcode": "^2.2.2", "vue-router": "^4.2.4", - "zustand": "^4.5.0", - "zustand-vue": "1.0.0-beta.20" + "vue-zustand": "^0.6.0", + "zustand": "^4.5.0" } } diff --git a/packages/vue/package.json b/packages/vue/package.json index 5cf4940e..dbb59c0b 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -16,15 +16,15 @@ "type": "module", "dependencies": { "@quirks/store": "*", - "@quirks/core": "*" - }, - "peerDependencies": { - "vue": "^3.3.4", - "cosmjs-types": "^0.8.0", - "@cosmjs/amino": "^0.31.3", + "@quirks/core": "*", + "vue-zustand": "^0.6.0", "eventemitter3": "^5.0.1", "zustand": "^4.5.0", - "zustand-vue": "1.0.0-beta.20" + "cosmjs-types": "^0.8.0", + "@cosmjs/amino": "^0.31.3" + }, + "peerDependencies": { + "vue": "^3.3.4" }, "main": "./index.js", "module": "./index.js", diff --git a/packages/vue/src/hooks/chain.ts b/packages/vue/src/hooks/chain.ts index 138ccc5f..b1bc00fa 100644 --- a/packages/vue/src/hooks/chain.ts +++ b/packages/vue/src/hooks/chain.ts @@ -4,8 +4,9 @@ import type { StdSignDoc } from '@cosmjs/amino'; import { computed } from 'vue'; export const useChains = () => { - const accounts = useQuirks()((state) => state.accounts); - const accountName = useQuirks()((state) => state.accountName); + const state = useQuirks()((state) => state); + const accounts = computed(() => state.accounts.value); + const accountName = computed(() => state.accountName); const getAddresses = useQuirks()((state) => state.getAddresses); const getAddress = useQuirks()((state) => state.getAddress); const getChain = useQuirks()((state) => state.getChain); @@ -20,9 +21,10 @@ export const useChains = () => { }; export const useChain = (chainName: string) => { - const chains = useQuirks()((state) => state.chains); - const accounts = useQuirks()((state) => state.accounts); - const accountName = useQuirks()((state) => state.accountName); + const state = useQuirks()((state) => state); + const chains = computed(() => state.chains.value); + const accounts = computed(() => state.accounts.value); + const accountName = computed(() => state.accountName); const getOfflineSigner = useQuirks()((state) => state.getOfflineSigner); const getOfflineSignerOnlyAmino = useQuirks()( (state) => state.getOfflineSignerOnlyAmino, @@ -38,7 +40,7 @@ export const useChain = (chainName: string) => { ); const account = computed(() => - accounts.value.find((account) => account.chainId === chain.value!.chain_id), + accounts.value.find((account) => account.chainId === chain.value?.chain_id), ); const address = computed(() => account.value?.bech32Address); diff --git a/packages/vue/src/hooks/config.ts b/packages/vue/src/hooks/config.ts index 24f5fa88..6a5a9e60 100644 --- a/packages/vue/src/hooks/config.ts +++ b/packages/vue/src/hooks/config.ts @@ -1,9 +1,11 @@ +import { computed } from 'vue'; import { useQuirks } from './quirks'; export const useConfig = () => { - const wallets = useQuirks()((state) => state.wallets); - const chains = useQuirks()((state) => state.chains); - const assetsLists = useQuirks()((state) => state.assetsLists); + const state = useQuirks()((state) => state); + const wallets = computed(() => state.wallets.value); + const chains = computed(() => state.chains.value); + const assetsLists = computed(() => state.assetsLists.value); return { wallets, diff --git a/packages/vue/src/hooks/connect.ts b/packages/vue/src/hooks/connect.ts index ceeee937..a775f59a 100644 --- a/packages/vue/src/hooks/connect.ts +++ b/packages/vue/src/hooks/connect.ts @@ -1,26 +1,22 @@ import { ConnectionStates } from '@quirks/store'; import { useQuirks } from './quirks'; +import { computed } from 'vue'; export const useConnect = () => { + const state = useQuirks()((state) => state); const connect = useQuirks()((state) => state.connect); const disconnect = useQuirks()((state) => state.disconnect); - const status = useQuirks()((state) => state.status); - const setupStatus = useQuirks()((state) => state.setupStatus); - const reconnectionStatus = useQuirks()((state) => state.reconnectionStatus); - const wallet = useQuirks()((state) => state.wallet); - const walletName = useQuirks()((state) => state.walletName); - const connected = useQuirks()( - (state) => state.status === ConnectionStates.CONNECTED, - ); - const waiting = useQuirks()( - (state) => state.status === ConnectionStates.WAITING, - ); - const disconnected = useQuirks()( - (state) => state.status === ConnectionStates.DISCONNECTED, - ); - const rejected = useQuirks()( - (state) => state.status === ConnectionStates.REJECTED, + const status = computed(() => state.status.value); + const setupStatus = computed(() => state.setupStatus.value); + const reconnectionStatus = computed(() => state.reconnectionStatus.value); + const wallet = computed(() => state.wallet?.value); + const walletName = computed(() => state.walletName?.value); + const connected = computed(() => status.value === ConnectionStates.CONNECTED); + const waiting = computed(() => status.value === ConnectionStates.WAITING); + const disconnected = computed( + () => status.value === ConnectionStates.DISCONNECTED, ); + const rejected = computed(() => status.value === ConnectionStates.REJECTED); return { connect, diff --git a/packages/vue/src/hooks/quirks.ts b/packages/vue/src/hooks/quirks.ts index 08636bb9..55eab0fe 100644 --- a/packages/vue/src/hooks/quirks.ts +++ b/packages/vue/src/hooks/quirks.ts @@ -1,15 +1,15 @@ import { createConfig } from '@quirks/store'; -import { type Ref, inject } from 'vue'; -import create from 'zustand-vue'; +import { inject } from 'vue'; +import create from 'vue-zustand'; import { USE_QUIRKS_KEY } from '../plugin'; export function useQuirks() { - const store = inject>>(USE_QUIRKS_KEY); + const store = inject>(USE_QUIRKS_KEY); - if (!store?.value) + if (!store) throw new Error( - ['[Quirks]: `useConfig` must be used within `quirksPlugin`'].join('\n'), + ['[Quirks]: `useQuirks` must be used within `quirksPlugin`'].join('\n'), ); - return create(store.value); + return create(store); } diff --git a/packages/vue/src/hooks/wallet-connect.ts b/packages/vue/src/hooks/wallet-connect.ts index 9a5659e3..a8e16149 100644 --- a/packages/vue/src/hooks/wallet-connect.ts +++ b/packages/vue/src/hooks/wallet-connect.ts @@ -1,9 +1,11 @@ +import { computed } from 'vue'; import { useQuirks } from './quirks'; export const useWalletConnect = () => { - const pairingURI = useQuirks()((state) => state.pairingURI); - const namespaces = useQuirks()((state) => state.namespaces); - const providerOpts = useQuirks()((state) => state.providerOpts); + const state = useQuirks()((state) => state); + const pairingURI = computed(() => state.pairingURI?.value); + const namespaces = computed(() => state.namespaces.value); + const providerOpts = computed(() => state.providerOpts?.value); return { pairingURI, diff --git a/packages/vue/src/plugin.ts b/packages/vue/src/plugin.ts index f9785cec..e55e9e35 100644 --- a/packages/vue/src/plugin.ts +++ b/packages/vue/src/plugin.ts @@ -1,29 +1,18 @@ import { type Config, createConfig } from '@quirks/store'; -import { markRaw, shallowRef, triggerRef, type Plugin } from 'vue'; +import { type Plugin } from 'vue'; export const USE_QUIRKS_KEY = 'USE_QUIRKS' as const; export const quirksPlugin: Plugin = { install: (app, config: Config) => { - const store = shallowRef(markRaw(createConfig(config))); - - const unsubscribe = store.value.subscribe(() => { - triggerRef(markRaw(store)); - }); - - const originalUnmount = app.unmount; - - app.unmount = function vueQueryUnmount() { - unsubscribe(); - originalUnmount(); - }; + const store = createConfig(config); app.provide(USE_QUIRKS_KEY, store); const mount = { mounted() { - if (!store.value.persist.hasHydrated()) { - setTimeout(() => store.value.persist.rehydrate(), 0); + if (!store.persist.hasHydrated()) { + setTimeout(() => store.persist.rehydrate(), 0); } }, }; diff --git a/packages/vue/vite.config.ts b/packages/vue/vite.config.ts index 737fc9c1..d1ce67c3 100644 --- a/packages/vue/vite.config.ts +++ b/packages/vue/vite.config.ts @@ -45,7 +45,7 @@ export default defineConfig({ 'zustand', 'zustand/vanilla', 'zustand/middleware', - 'zustand-vue', + 'vue-zustand', '@quirks/store', '@quirks/core', 'cosmjs-types', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9ad14a0e..55476acf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -122,12 +122,12 @@ dependencies: vue-router: specifier: ^4.2.4 version: 4.2.5(vue@3.3.8) + vue-zustand: + specifier: ^0.6.0 + version: 0.6.0(vue@3.3.8)(zustand@4.5.0) zustand: specifier: ^4.5.0 version: 4.5.0(@types/react@18.2.31)(react@18.2.0) - zustand-vue: - specifier: 1.0.0-beta.20 - version: 1.0.0-beta.20(vue@3.3.8)(zustand@4.5.0) devDependencies: '@babel/core': @@ -6239,6 +6239,10 @@ packages: resolution: {integrity: sha512-95Sfz4nvMAb0Nl9DTxN3j64adfwfbBPEYq14VN7zT5J5O2M9V6iZMIIQU1U+pJyl9agHYHNCqhCXgyEtIRRa5A==} dev: true + /@types/web-bluetooth@0.0.20: + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + dev: false + /@types/yargs-parser@21.0.2: resolution: {integrity: sha512-5qcvofLPbfjmBfKaLfj/+f+Sbd6pN4zl7w7VSVI5uz7m9QZTuB2aZAa2uo1wHFBNN2x6g/SoTkXmd8mQnQF2Cw==} @@ -7098,6 +7102,31 @@ packages: transitivePeerDependencies: - typescript + /@vueuse/core@10.7.2(vue@3.3.8): + resolution: {integrity: sha512-AOyAL2rK0By62Hm+iqQn6Rbu8bfmbgaIMXcE3TSr7BdQ42wnSFlwIdPjInO62onYsEMK/yDMU8C6oGfDAtZ2qQ==} + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 10.7.2 + '@vueuse/shared': 10.7.2(vue@3.3.8) + vue-demi: 0.14.6(vue@3.3.8) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: false + + /@vueuse/metadata@10.7.2: + resolution: {integrity: sha512-kCWPb4J2KGrwLtn1eJwaJD742u1k5h6v/St5wFe8Quih90+k2a0JP8BS4Zp34XUuJqS2AxFYMb1wjUL8HfhWsQ==} + dev: false + + /@vueuse/shared@10.7.2(vue@3.3.8): + resolution: {integrity: sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA==} + dependencies: + vue-demi: 0.14.6(vue@3.3.8) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: false + /@walletconnect/core@2.10.5(@react-native-async-storage/async-storage@1.21.0)(bufferutil@4.0.8)(utf-8-validate@6.0.3): resolution: {integrity: sha512-QnGHkA05KzJrtqExPqXm/TsstM1uTDI8tQT0x86/DuR6LdiYEntzSpVjnv7kKK6Mo9UxlXfud431dNRfOW5uJg==} dependencies: @@ -18965,6 +18994,21 @@ packages: resolution: {integrity: sha512-6bnLkn8O0JJyiFSIF0EfCogzeqNXpnjJ0vW/SZzNHfe6sPx30lTtTXlE5TFs2qhJlAtDFybStVNpL73cPe3OMQ==} dev: true + /vue-demi@0.14.6(vue@3.3.8): + resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + dependencies: + vue: 3.3.8(typescript@5.2.2) + dev: false + /vue-devtools-stub@0.1.0: resolution: {integrity: sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==} dev: false @@ -19024,6 +19068,19 @@ packages: semver: 7.5.4 typescript: 5.2.2 + /vue-zustand@0.6.0(vue@3.3.8)(zustand@4.5.0): + resolution: {integrity: sha512-injGg2Nxcq7RBXe4n92LmIOcAP3DxqHr3w5uVhkV1BnCIChjztXfsWEX9k8IP3zb7EmHnDV5SW0XtxY6TQct2Q==} + peerDependencies: + vue: '>=3.2.0' + zustand: '>=4.3.0' + dependencies: + '@vueuse/core': 10.7.2(vue@3.3.8) + vue: 3.3.8(typescript@5.2.2) + zustand: 4.5.0(@types/react@18.2.31)(react@18.2.0) + transitivePeerDependencies: + - '@vue/composition-api' + dev: false + /vue@3.3.8(typescript@5.2.2): resolution: {integrity: sha512-5VSX/3DabBikOXMsxzlW8JyfeLKlG9mzqnWgLQLty88vdZL7ZJgrdgBOmrArwxiLtmS+lNNpPcBYqrhE6TQW5w==} peerDependencies: @@ -19529,16 +19586,6 @@ packages: readable-stream: 3.6.2 dev: false - /zustand-vue@1.0.0-beta.20(vue@3.3.8)(zustand@4.5.0): - resolution: {integrity: sha512-4lKOGVxFNnSpisO9czhv+RHGTIsVKSLh/Ub63i7A2jaebDQ5MrmBcXrHG094SiIsw4PGF2AEfI9LG9tpVxqj4A==} - peerDependencies: - vue: '>=2.6.0' - zustand: '>=4.1.4' - dependencies: - vue: 3.3.8(typescript@5.2.2) - zustand: 4.5.0(@types/react@18.2.31)(react@18.2.0) - dev: false - /zustand@4.5.0(@types/react@18.2.31)(react@18.2.0): resolution: {integrity: sha512-zlVFqS5TQ21nwijjhJlx4f9iGrXSL0o/+Dpy4txAP22miJ8Ti6c1Ol1RLNN98BMib83lmDH/2KmLwaNXpjrO1A==} engines: {node: '>=12.7.0'}