mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 18:57:03 +02:00
feat: next safe generalization
This commit is contained in:
1 parent
eb87463f08
commit
dae902fe03
19 files changed
+163
-155
No files matched your search
@@ -1,4 +1,3 @@
|
||||
import { TankFilters } from '../../stores/tankFilters';
|
||||
import { TankDefinition } from './tankDefinitions';
|
||||
|
||||
export function filterTank(filters: TankFilters, tank: TankDefinition) {
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import { Draft, produce } from 'immer';
|
||||
import { Context, createContext, ReactNode, useContext, useRef } from 'react';
|
||||
import { createStore, StoreApi, useStore as useStoreZustand } from 'zustand';
|
||||
|
||||
interface StoreProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export function createStoreContext<Type>() {
|
||||
return createContext<StoreApi<Type> | undefined>(undefined);
|
||||
}
|
||||
|
||||
export function createStoreProvider<Type>(
|
||||
initialState: Type,
|
||||
Context: Context<StoreApi<Type> | undefined>,
|
||||
) {
|
||||
return function Provider({ children }: StoreProviderProps) {
|
||||
const storeRef = useRef<StoreApi<Type>>();
|
||||
if (!storeRef.current) {
|
||||
storeRef.current = createStore<Type>()(() => ({ ...initialState }));
|
||||
}
|
||||
|
||||
return (
|
||||
<Context.Provider value={storeRef.current}>{children}</Context.Provider>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export function createNextSafeStore<Type>(initialState: Type) {
|
||||
const Context = createContext<StoreApi<Type> | undefined>(undefined);
|
||||
|
||||
function Provider({ children }: StoreProviderProps) {
|
||||
const storeRef = useRef<StoreApi<Type>>();
|
||||
if (!storeRef.current) {
|
||||
storeRef.current = createStore<Type>()(() => ({ ...initialState }));
|
||||
}
|
||||
|
||||
return (
|
||||
<Context.Provider value={storeRef.current}>{children}</Context.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
function useStore() {
|
||||
const store = useContext(Context);
|
||||
if (!store) {
|
||||
throw new Error('useStoreContext must be used within Provider');
|
||||
}
|
||||
return store;
|
||||
}
|
||||
|
||||
function use<Slice = Type>(
|
||||
selector: (store: Type) => Slice = (state) => state as unknown as Slice,
|
||||
): Slice {
|
||||
const store = useStore();
|
||||
return useStoreZustand(store, selector);
|
||||
}
|
||||
|
||||
function useMutation() {
|
||||
const counterStoreContext = useStore();
|
||||
|
||||
return function (recipe: (draft: Draft<Type>) => void) {
|
||||
counterStoreContext.setState(
|
||||
produce<Type>((draft) => {
|
||||
recipe(draft);
|
||||
}),
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
return { Provider, use, useMutation, useStore };
|
||||
}
|
||||
Reference in new issue
Block a user