This commit is contained in:
azizziy
2025-05-20 17:02:10 +05:00
commit c01e852a59
257 changed files with 27766 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
'use client';
import { type PropsWithChildren, useRef } from 'react';
import type { StoreInterface, StoreType } from './store';
import { initializeStore, Provider } from './store';
// export interface PreloadedStoreInterface extends Pick<StoreInterface, 'lastUpdate'> {}
export interface PreloadedStoreInterface {}
export default function StoreProvider({ children, ...props }: PropsWithChildren<PreloadedStoreInterface>) {
const storeRef = useRef<StoreType>();
if (!storeRef.current) {
storeRef.current = initializeStore(props);
}
return <Provider value={storeRef.current}>{children}</Provider>;
}

59
src/clientStore/store.ts Normal file
View File

@@ -0,0 +1,59 @@
import { createContext, useContext } from 'react';
import { createStore, useStore as useZustandStore } from 'zustand';
import { PreloadedStoreInterface } from './StoreProvider';
export interface StoreInterface {
lastUpdate: number;
light: boolean;
count: number;
tick: (lastUpdate: number) => void;
increment: () => void;
decrement: () => void;
reset: () => void;
}
function getDefaultInitialState() {
return {
lastUpdate: new Date(1970, 1, 1).getTime(),
light: false,
count: 0,
} as const;
}
export type StoreType = ReturnType<typeof initializeStore>;
const storeContext = createContext<StoreType | null>(null);
export const Provider = storeContext.Provider;
export function useStore<T>(selector: (state: StoreInterface) => T) {
const store = useContext(storeContext);
if (!store) throw new Error('Store is missing the provider');
return useZustandStore(store, selector);
}
export function initializeStore(preloadedState: PreloadedStoreInterface) {
return createStore<StoreInterface>((set, get) => ({
...getDefaultInitialState(),
...preloadedState,
tick: lastUpdate =>
set({
lastUpdate,
light: !get().light,
}),
increment: () =>
set({
count: get().count + 1,
}),
decrement: () =>
set({
count: get().count - 1,
}),
reset: () =>
set({
count: getDefaultInitialState().count,
}),
}));
}

View File

@@ -0,0 +1,20 @@
'use client';
import { useEffect, useRef } from 'react';
// https://overreacted.io/making-setinterval-declarative-with-react-hooks/
export default function useInterval(callback: () => void, delay: number | undefined) {
const savedCallback = useRef<typeof callback>();
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
useEffect(() => {
const handler = () => savedCallback.current?.();
if (delay !== null) {
const id = setInterval(handler, delay);
return () => clearInterval(id);
}
}, [delay]);
}