@alphanova/builder
Version:
A fully fledged facade that facilitates object manipulation
330 lines (329 loc) • 16.2 kB
JavaScript
/* eslint-disable @typescript-eslint/no-explicit-any */
import { useDispatch, useSelector } from 'react-redux';
import { actionBuilder, getConfig, stateSorter } from './Redux';
import { useMutation, useQuery } from '@tanstack/react-query';
import { useMemo } from 'react';
/**
*
* @param _typer This is the raw getConfig() file you used to setup the package. You do not have to provide this parameter. It is only used for type checking but it is recommended to provide it. Not providing it would require you to type-cast the return value of the hook.
* @param key This is the list of the models that will be provided by using the useStorage hook. It is pulled from the action name property in the configs. Do not provide actions that will not be used as it will slow down the hook.
* @returns A Record holding the functions that will be used to interact with the Redux store. The functions are named after the actions provided in the configs. Do not use functions that you did not provide.
* @deprecated
*/
export function useStorage(_typer, key) {
const conf = stateSorter(key);
const data = useSelector(data => data[key.toLowerCase()]);
return conf.builder.list(data ?? {});
}
export function useFetchMany(_typer, key, params, override_url) {
const dispatch = useDispatch();
const conf = stateSorter(key);
const action_builder = actionBuilder(conf.action, conf.api_route || conf.action.toLowerCase() + 's', dispatch, override_url);
if (conf.providers?.FETCH_MANY === false)
throw new Error(`Not provided. Make sure to provide FETCH_MANY in the configs related to ${conf.action}`);
const query = useQuery({
...params,
queryKey: [key],
queryFn: () => action_builder.FETCH_MANY(),
});
const data = useMemo(() => {
return [...query.data ?? []];
}, [query]);
const map = useMemo(() => {
return data?.reduce((result, current) => {
result.set(current.id, current);
return result;
}, new Map()) ?? new Map();
}, [data]);
return {
...query,
data: data ?? [],
dataMap: map
};
}
export function useFetchAny(_typer, key, route, params, override_url) {
const dispatch = useDispatch();
const conf = stateSorter(key);
const action_builder = actionBuilder(conf.action, conf.api_route || conf.action.toLowerCase() + 's', dispatch, override_url);
if (conf.providers?.FETCH_ANY === false)
throw new Error(`Not provided. Make sure to provide FETCH_ANY in the configs related to ${conf.action}`);
const query = useQuery({
...params,
queryKey: [key],
queryFn: () => action_builder.FETCH_ANY({ route }),
});
const data = useMemo(() => {
return [...query.data ?? []];
}, [query]);
const map = useMemo(() => {
return data?.reduce((result, current) => {
result.set(current.id, current);
return result;
}, new Map()) ?? new Map();
}, [data]);
return {
...query,
data: data ?? [],
dataMap: map
};
}
export function useFetchOne(_typer, key, id, params, override_url) {
const dispatch = useDispatch();
const conf = stateSorter(key);
const action_builder = actionBuilder(conf.action, conf.api_route || conf.action.toLowerCase() + 's', dispatch, override_url);
if (conf.providers?.FETCH_MANY === false)
throw new Error(`Not provided. Make sure to provide FETCH_MANY in the configs related to ${conf.action}`);
const query = useQuery({
...params,
queryKey: [key],
queryFn: () => action_builder.FETCH_ONE({ id }),
});
const data = useMemo(() => {
return [...query.data ?? []];
}, [query]);
const map = useMemo(() => {
return data?.reduce((result, current) => {
result.set(current.id, current);
return result;
}, new Map()) ?? new Map();
}, [data]);
return {
...query,
data: data ?? [],
dataMap: map
};
}
export function useFetchManyArray(_typer, key, params, override_url) {
const dispatch = useDispatch();
const conf = stateSorter(key);
const action_builder = actionBuilder(conf.action, conf.api_route || conf.action.toLowerCase() + 's', dispatch, override_url);
if (conf.providers?.FETCH_MANY === false)
throw new Error(`Not provided. Make sure to provide FETCH_MANY in the configs related to ${conf.action}`);
const query = useQuery({
...params,
queryKey: [key],
queryFn: () => action_builder.FETCH_MANY(),
});
const data = useMemo(() => {
return [...query.data ?? []];
}, [query]);
return {
...query,
data: data ?? []
};
}
export function useFetchAnyArray(_typer, key, route, params, override_url) {
const dispatch = useDispatch();
const conf = stateSorter(key);
const action_builder = actionBuilder(conf.action, conf.api_route || conf.action.toLowerCase() + 's', dispatch, override_url);
if (conf.providers?.FETCH_ANY === false)
throw new Error(`Not provided. Make sure to provide FETCH_ANY in the configs related to ${conf.action}`);
const query = useQuery({
...params,
queryKey: [key],
queryFn: () => action_builder.FETCH_ANY({ route }),
});
const data = useMemo(() => {
return [...query.data ?? []];
}, [query]);
return {
...query,
data: data ?? []
};
}
export function useFetchOneArray(_typer, key, id, params, override_url) {
const dispatch = useDispatch();
const conf = stateSorter(key);
const action_builder = actionBuilder(conf.action, conf.api_route || conf.action.toLowerCase() + 's', dispatch, override_url);
if (conf.providers?.FETCH_MANY === false)
throw new Error(`Not provided. Make sure to provide FETCH_MANY in the configs related to ${conf.action}`);
const query = useQuery({
...params,
queryKey: [key],
queryFn: () => action_builder.FETCH_ONE({ id }),
});
const data = useMemo(() => {
return [...query.data ?? []];
}, [query]);
return {
...query,
data: data ?? []
};
}
export function useFetchManyMap(_typer, key, params, override_url) {
const dispatch = useDispatch();
const conf = stateSorter(key);
const action_builder = actionBuilder(conf.action, conf.api_route || conf.action.toLowerCase() + 's', dispatch, override_url);
if (conf.providers?.FETCH_MANY === false)
throw new Error(`Not provided. Make sure to provide FETCH_MANY in the configs related to ${conf.action}`);
const query = useQuery({
...params,
queryKey: [key],
queryFn: () => action_builder.FETCH_MANY(),
});
const map = useMemo(() => {
return query.data?.reduce((result, current) => {
result.set(current.id, current);
return result;
}, new Map()) ?? new Map();
}, [query]);
return {
...query,
data: map
};
}
export function useFetchAnyMap(_typer, key, route, params, override_url) {
const dispatch = useDispatch();
const conf = stateSorter(key);
const action_builder = actionBuilder(conf.action, conf.api_route || conf.action.toLowerCase() + 's', dispatch, override_url);
if (conf.providers?.FETCH_ANY === false)
throw new Error(`Not provided. Make sure to provide FETCH_ANY in the configs related to ${conf.action}`);
const query = useQuery({
...params,
queryKey: [key],
queryFn: () => action_builder.FETCH_ANY({ route }),
});
const map = useMemo(() => {
return query.data?.reduce((result, current) => {
result.set(current.id, current);
return result;
}, new Map()) ?? new Map();
}, [query]);
return {
...query,
data: map
};
}
export function useFetchOneMap(_typer, key, id, params, override_url) {
const dispatch = useDispatch();
const conf = stateSorter(key);
const action_builder = actionBuilder(conf.action, conf.api_route || conf.action.toLowerCase() + 's', dispatch, override_url);
if (conf.providers?.FETCH_MANY === false)
throw new Error(`Not provided. Make sure to provide FETCH_MANY in the configs related to ${conf.action}`);
const query = useQuery({
...params,
queryKey: [key],
queryFn: () => action_builder.FETCH_ONE({ id }),
});
const map = useMemo(() => {
return query.data?.reduce((result, current) => {
result.set(current.id, current);
return result;
}, new Map()) ?? new Map();
}, [query.data]);
return {
...query,
data: map
};
}
function useBuildMutation(modelKey, functionKey, override_url) {
const conf = stateSorter(modelKey);
if (conf.providers?.[functionKey] === false)
throw new Error(`Not provided. Make sure to provide ${functionKey} in the configs related to ${conf.action}`);
const dispatch = useDispatch();
return actionBuilder(conf.action, conf.api_route || conf.action.toLowerCase() + 's', dispatch, override_url);
}
function handleErrors(key) {
const data = getConfig().queryClient.getQueryData([key]);
return {
onMutate: () => getConfig().queryClient.getQueryData([key]),
onError: (_1, _2, context) => getConfig().queryClient.setQueryData([key], context),
onSuccess: (result) => getConfig().queryClient.setQueryData([key], data.map(c => (c.id === result.id ? result : c))),
};
}
export function useAddLocal(_typer, key, override_url) {
const action_builder = useBuildMutation(key, 'LOCAL_ADD', override_url);
return action_builder.LOCAL_ADD;
}
export function useUpdateLocal(_typer, key, override_url) {
const action_builder = useBuildMutation(key, 'LOCAL_UPDATE', override_url);
return action_builder.LOCAL_UPDATE;
}
export function useDeleteLocal(_typer, key, override_url) {
const action_builder = useBuildMutation(key, 'LOCAL_DELETE', override_url);
return action_builder.LOCAL_DELETE;
}
export function useAdd(_typer, key, override_url) {
const action_builder = useBuildMutation(key, 'ADD', override_url);
return useMutation({ mutationFn: action_builder.ADD, ...handleErrors(key) });
}
export function useDelete(_typer, key, override_url) {
const action_builder = useBuildMutation(key, 'DELETE', override_url);
return useMutation({ mutationFn: action_builder.DELETE, ...handleErrors(key) });
}
export function useUpdate(_typer, key, override_url) {
const action_builder = useBuildMutation(key, 'UPDATE', override_url);
return useMutation({ mutationFn: action_builder.UPDATE, ...handleErrors(key) });
}
export function useServerAdd(_typer, key, override_url) {
const action_builder = useBuildMutation(key, 'SERVER_ADD', override_url);
return useMutation({ mutationFn: action_builder.SERVER_ADD, ...handleErrors(key) });
}
export function useServerDelete(_typer, key, override_url) {
const action_builder = useBuildMutation(key, 'SERVER_DELETE', override_url);
return useMutation({ mutationFn: action_builder.SERVER_DELETE, ...handleErrors(key) });
}
export function useServerUpdate(_typer, key, override_url) {
const action_builder = useBuildMutation(key, 'SERVER_UPDATE', override_url);
return useMutation({ mutationFn: action_builder.SERVER_UPDATE, ...handleErrors(key) });
}
// export function useStorage<T extends C[number]['action'] | 'ERRONEOUS', C extends Rule<any, Structure, any>[]>(_typer: C, yields: T, params?: Options<useContainerType<C, T>[], unknown, useContainerType<C, T>[], QueryKey>,override_url?: string): returnType<C, T> {
// if (yields.length === 0) throw new Error('Make sure to provide at least one yield')
// const dispatch = useDispatch()
// const conf = stateSorter(yields)
// // const getData = (state: Record<string, GeneralState<Structure>>) => {
// // const states = _.reduce(
// // Object.entries(state),
// // (result, current) => {
// // const [key, value] = current
// // if (conf.find(c => c.action.toLowerCase().includes(key))) {
// // result[key] = value
// // }
// // return result
// // },.
// // {} as Record<string, GeneralState<Structure>>
// // )
// // states['erroneous'] = state['ERRONEOUS']
// // return states
// // }
// // const dataSelector = createSelector(
// // getData,
// // data => data
// // )
// const data = useSelector(data => (data as Record<string, Record<string, Structure>>)[(yields as string).toLowerCase()])
// const action_builder = actionBuilder(conf.action, conf.api_route || conf.action.toLowerCase() + 's', dispatch, override_url)
// const result: returnType<C, T> = {
// ADD: () => { throw new Error(`Not provided. Make sure to provide add in the configs related to ${conf.action}`) },
// ASYNC_ADD: () => { throw new Error(`Not provided. Make sure to provide asyncAdd in the configs related to ${conf.action}`) },
// LOCAL_ADD: () => { throw new Error(`Not provided. Make sure to provide local add in the configs related to ${conf.action}`) },
// SERVER_ADD: () => { throw new Error(`Not provided. Make sure to provide server add in the configs related to ${conf.action}`) },
// DELETE: () => { throw new Error(`Not provided. Make sure to provide delete in the configs related to ${conf.action}`) },
// LOCAL_DELETE: () => { throw new Error(`Not provided. Make sure to provide local delete in the configs related to ${conf.action}`) },
// SERVER_DELETE: () => { throw new Error(`Not provided. Make sure to provide server delete in the configs related to ${conf.action}`) },
// UPDATE: () => { throw new Error(`Not provided. Make sure to provide update in the configs related to ${conf.action}`) },
// LOCAL_UPDATE: () => { throw new Error(`Not provided. Make sure to provide local update in the configs related to ${conf.action}`) },
// SERVER_UPDATE: () => { throw new Error(`Not provided. Make sure to provide server update in the configs related to ${conf.action}`) },
// FETCH_MANY: () => { throw new Error(`Not provided. Make sure to provide fetchAll in the configs related to ${conf.action}`) },
// FETCH_ONE: () => { throw new Error(`Not provided. Make sure to provide fetchOne in the configs related to ${conf.action}`) },
// FETCH_ANY: () => { throw new Error(`Not provided. Make sure to provide fetchAny in the configs related to ${conf.action}`) },
// GET: () => { throw new Error(`Not provided. Make sure to provide get in the configs related to ${conf.action}`) },
// }
// console.log(data)
// if (conf.providers?.get === undefined || conf.providers?.get)
// result.GET = () =>
// conf.builder.list(data ?? {})
// if (conf.providers?.add) result.ADD = action_builder.ADD
// if (conf.providers?.asyncAdd) result.ASYNC_ADD = action_builder.ASYNC_ADD
// if (conf.providers?.localAdd) result.LOCAL_ADD = action_builder.LOCAL_ADD
// if (conf.providers?.remove) result.DELETE = action_builder.DELETE
// if (conf.providers?.localRemove) result.LOCAL_DELETE = action_builder.LOCAL_DELETE
// if (conf.providers?.update) result.UPDATE = action_builder.UPDATE
// if (conf.providers?.localUpdate) result.LOCAL_UPDATE = action_builder.LOCAL_UPDATE
// if (conf.providers?.fetchMany) result.FETCH_MANY = action_builder.FETCH_MANY
// if (conf.providers?.fetchOne) result.FETCH_ONE = action_builder.FETCH_ONE
// if (conf.providers?.fetchAny) result.FETCH_ANY = action_builder.FETCH_ANY
// if (conf.providers?.serverAdd) result.SERVER_ADD = action_builder.SERVER_ADD
// if (conf.providers?.serverRemove) result.SERVER_DELETE = action_builder.SERVER_DELETE
// if (conf.providers?.serverUpdate) result.SERVER_UPDATE = action_builder.SERVER_UPDATE
// return { ...result } as returnType<C, T>
// }