import React, { use, useEffect, useState, type ComponentType, type ReactNode } from 'react'; import { createReactContext } from '@wener/reaction'; import { getGlobalStates } from '@wener/utils'; import { createStore } from 'zustand'; import { mutative } from 'zustand-mutative'; type ComponentProvide = { provide: string | ComponentType; use: ComponentType; }; type ComponentContextValue = { find: (provide: string | ComponentType) => ComponentType | undefined; }; const ComponentContext = createReactContext('ComponentContext', undefined); type ComponentProviderProps = { provides: ComponentProvide[]; children?: ReactNode; }; type ComponentStoreState = { provides: ComponentProvide[]; actions: {}; }; type ComponentStore = ReturnType; function createComponentStore(init: { provides?: ComponentProvide[] } = {}) { return createStore( mutative((setState, getState, store) => { return { provides: [], ...init, actions: { find(provide: string | ComponentType) { const { provides } = getState(); const p = provides.find((p) => p.provide === provide); if (p) { return p.use; } return undefined; }, }, }; }), ); } export function useComponentStore(): ComponentStore { const value = use(ComponentContext); return value || getGlobalStates('ComponentStore', () => createComponentStore()); } export const ComponentProvider = ({ children, provides }: ComponentProviderProps) => { let parent = useComponentStore(); const [store] = useState(() => createComponentStore({ provides })); useEffect(() => {}, provides); return {children}; };