Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | 332x 10504x 332x 7904x 7904x 7904x 326x 6898x 1313x 7904x 1313x 7904x 10504x 993x 12803x 12803x 12803x 7904x 10504x 2x 2x 2x 7904x 7904x 10504x 7904x 7904x 10504x 7904x 7904x 60472x 60472x 7904x 7904x | import React from "react";
import { fromEntries, keys } from "remeda";
import { StoreContext } from "~app/contexts/store-context";
import { StoreDataContext } from "~app/contexts/store-data-context";
import type { StoreStates, StoreValues } from "~app/utils/store-data";
import { getStoreStatesFromValues, schemas } from "~app/utils/store-data";
import { updateSetStateAction } from "~utils/react";
const resolveState = (values: StoreValues) =>
fromEntries(keys(schemas).map((key) => [key, values[key]])) as StoreValues;
type SetValues = {
[K in keyof StoreStates]: StoreStates[K][1];
};
type DeleteValues = {
[K in keyof StoreStates]: StoreStates[K][2];
};
type StoreKey = keyof StoreStates;
export const StoredDataProvider: React.FC<React.PropsWithChildren> = ({
children,
}) => {
const { setItem, deleteItem, getInitialItems } = React.use(StoreContext);
const initialItems = getInitialItems();
const mounted = React.useSyncExternalStore(
() => () => {
/* empty */
},
() => true,
() => false,
);
const [ssrState, setSsrState] = React.useState<StoreValues>(() =>
resolveState(initialItems),
);
const updateValue = React.useCallback(
<K extends StoreKey>(key: K) =>
(setStateAction: React.SetStateAction<(typeof ssrState)[K]>) => {
setSsrState((prevState) => {
const nextState = updateSetStateAction(
setStateAction,
prevState[key],
);
// Updating a store value and updating local state in the same time
setItem(key, nextState);
return { ...prevState, [key]: nextState };
});
},
[setItem],
);
const deleteValue = React.useCallback(
<K extends StoreKey>(key: K) =>
() => {
setSsrState((prevState) => {
// Removing a store value and updating local state in the same time
deleteItem(key);
return { ...prevState, [key]: schemas[key].parse(undefined) };
});
},
[deleteItem],
);
const ssrSetValues = React.useMemo<SetValues>(
() =>
fromEntries(
keys(schemas).map((key) => [key, updateValue(key)]),
) as SetValues,
[updateValue],
);
const ssrDeleteValues = React.useMemo<DeleteValues>(
() =>
fromEntries(
keys(schemas).map((key) => [key, deleteValue(key)]),
) as DeleteValues,
[deleteValue],
);
const ssrStates = React.useMemo(
() =>
getStoreStatesFromValues(
ssrState,
(key) => ssrSetValues[key],
(key) => ssrDeleteValues[key],
),
[ssrState, ssrSetValues, ssrDeleteValues],
);
return (
<StoreDataContext
value={React.useMemo(
() => ({
isFirstRender: !mounted,
nowTimestamp: initialItems.nowTimestamp,
...ssrStates,
}),
[ssrStates, initialItems.nowTimestamp, mounted],
)}
>
{children}
</StoreDataContext>
);
};
|