Skip to content

Instantly share code, notes, and snippets.

@jacob-ebey
Created July 16, 2021 16:47
Show Gist options
  • Save jacob-ebey/6b443d08ef9ec5d6a3e6e24742ce6b68 to your computer and use it in GitHub Desktop.
Save jacob-ebey/6b443d08ef9ec5d6a3e6e24742ce6b68 to your computer and use it in GitHub Desktop.
Compose Remix routes
import type { LinksFunction, LoaderFunction, MetaFunction } from "remix";
export let composeMeta =
(
...metas: (MetaFunction | { data: string; meta: MetaFunction })[]
): MetaFunction =>
(args) =>
metas.reduce<ReturnType<MetaFunction>>((res, meta) => {
if (typeof meta === "function") {
return { ...res, ...meta(args) };
}
let newArgs = { ...args, data: args.data[meta.data] };
return { ...res, ...meta.meta(newArgs) };
}, {});
export let composeLinks =
(
...links: (LinksFunction | { data: string; links: LinksFunction })[]
): LinksFunction =>
(args) =>
links.reduce<ReturnType<LinksFunction>>((res, link) => {
if (typeof link === "function") {
return [...res, ...link(args)];
}
let newArgs = { ...args, data: args.data[link.data] };
return [...res, ...link.links(newArgs)];
}, []);
export let composeLoaders =
(
...loaders: (LoaderFunction | { as: string; loader: LoaderFunction })[]
): LoaderFunction =>
async (args) => {
let loaderResults = await Promise.all(
loaders.map(async (loader) => {
if (typeof loader === "function") {
return loader(args);
}
// TODO: handle Response return type
return { [loader.as]: await loader.loader(args) };
})
);
// TODO: handle Response return type
return loaderResults.reduce(
(res, loaderRes) => ({ ...res, ...loaderRes }),
{}
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment