feat: add ConfigContext with Zustand store for instance-scoped configuration#3973
feat: add ConfigContext with Zustand store for instance-scoped configuration#3973DBosley wants to merge 2 commits into
Conversation
✅ Deploy Preview for wormhole-connect-mainnet ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for wormhole-connect ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
24af433 to
f6cbde0
Compare
f6cbde0 to
652291d
Compare
652291d to
e071690
Compare
e071690 to
d2c1f94
Compare
d2c1f94 to
160afc1
Compare
f74902e to
539d6c1
Compare
Introduces React Context pattern for config access, enabling future support for multiple WormholeConnect instances on the same page. Changes: - Add ConfigContext with ConfigProvider and useConfig() hook - Wrap WormholeConnect with ConfigProvider - Update AppRouter to use useConfig() (example migration) - Add TestConfigContext pattern in testHelpers for test isolation - Mark singleton export with @deprecated JSDoc - Fix TypeScript dev server errors (@types/color, env.d.ts) The singleton remains functional for backwards compatibility. Migration can proceed incrementally file-by-file.
Adds Zustand-based config store to enable granular re-renders when config values change. Components can now use useConfigSelector() to subscribe to specific config properties instead of re-rendering on any config change. - Add zustand as dev and peer dependency - Create configStore.ts with useConfigSelector/useConfigValue hooks - Integrate Zustand store into ConfigProvider - Add legacy bridge (updateLegacyStore) for setConfig() compatibility - Support multiple WormholeConnect instances with isolated state - Add comprehensive tests for store and context integration
539d6c1 to
7876801
Compare
| * Context for providing the store instance to the component tree. | ||
| * Components use this to access the correct store for their WormholeConnect instance. | ||
| */ | ||
| export const ConfigStoreContext = React.createContext<ConfigStore | null>(null); |
| * Hook to access the config store from Context. | ||
| * @throws Error if used outside ConfigProvider | ||
| */ | ||
| function useConfigStore(): ConfigStore { |
| * })); | ||
| * ``` | ||
| */ | ||
| export function useConfigSelector<T>( |
There was a problem hiding this comment.
Can just be useConfig() inside useConfig.ts.
Consumers will just do const config = useConfig();
| * Hook to get the store's setState function for updating config. | ||
| * Used internally by ConfigProvider. | ||
| */ | ||
| export function useConfigStoreApi(): ConfigStore { |
There was a problem hiding this comment.
Not sure what is this doing
| initialConfig: InternalConfig<Network>, | ||
| ): ConfigStore { | ||
| return createStore<ConfigState>()(() => ({ | ||
| config: initialConfig, |
There was a problem hiding this comment.
Should break this down to different configs, so that consumers can react to specific changes on sub configs.
There was a problem hiding this comment.
Probably should also have setters for the config, so that the place where we build the config calls this.
| * Prefer useConfigSelector() for better performance - this hook will | ||
| * re-render on ANY config change. | ||
| */ | ||
| export function useConfigValue(): InternalConfig<Network> { |
There was a problem hiding this comment.
duplicate, but instead might make sense to have useUIConfig() in useUIConfig.ts, useTokensConfig() in useTokensConfig.ts etc, each returns that slice of the state.
| } | ||
| } | ||
|
|
||
| /** |
There was a problem hiding this comment.
I think both the register and unregister can likely move inside the main store's methods? When you call the main store's setXXX method, it should set itself and additionally set legacy stuff.
Summary
ConfigContext,useConfig()hook) for config accessuseConfigSelector()) to enable granular re-rendersChanges
src/contexts/ConfigContext.tsxsrc/store/configStore.tssrc/config/index.tssrc/WormholeConnect.tsxsrc/AppRouter.tsxpackage.jsonTest plan
npm run build:libnpm run test:unitKey Features
Selector-based subscriptions
Multi-instance support
Each
<WormholeConnect>widget gets its own isolated Zustand store.Legacy compatibility
setConfig()calls sync to the active Zustand store viaupdateLegacyStore().Migration path
This PR establishes the foundation. Subsequent PRs will:
useConfigSelector()for optimized re-renders