Move route utils to packages/routes
Signed-off-by: Émile Ré <nemile.re@gmail.com>
This commit is contained in:
27
packages/routes/package.json
Normal file
27
packages/routes/package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "@probo/routes",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "./src/index.ts",
|
||||
"scripts": {
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest",
|
||||
"format": "prettier --write ./src"
|
||||
},
|
||||
"prettier": "@probo/prettier",
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@probo/prettier": "1.0.0",
|
||||
"prettier": "^3.5.3",
|
||||
"typescript": "^5.8.3",
|
||||
"vitest": "^3.1.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^19.2.1",
|
||||
"react-relay": "^19.0.0",
|
||||
"react-router": "^7.10.0",
|
||||
"relay-runtime": "^19.0.0"
|
||||
}
|
||||
}
|
||||
30
packages/routes/src/appRoute.tsx
Normal file
30
packages/routes/src/appRoute.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import { ComponentType, Suspense } from "react";
|
||||
import { RouteObject } from "react-router";
|
||||
|
||||
export type AppRoute = Omit<RouteObject, "children"> & {
|
||||
children?: AppRoute[];
|
||||
Fallback?: ComponentType;
|
||||
}
|
||||
|
||||
export function routeFromAppRoute(appRoute: AppRoute): RouteObject {
|
||||
const { Component, Fallback, children, ...rest } = appRoute;
|
||||
let route = { ...rest } as RouteObject;
|
||||
|
||||
if (Component && Fallback) {
|
||||
const OriginalComponent = Component as ComponentType;
|
||||
|
||||
route = {
|
||||
...route,
|
||||
Component: () => (
|
||||
<Suspense fallback={<Fallback />}>
|
||||
<OriginalComponent />
|
||||
</Suspense>
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...route,
|
||||
children: children?.map(routeFromAppRoute),
|
||||
} as RouteObject;
|
||||
}
|
||||
2
packages/routes/src/index.ts
Normal file
2
packages/routes/src/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { routeFromAppRoute, type AppRoute } from "./appRoute";
|
||||
export { withQueryRef, loaderFromQueryLoader } from "./relay";
|
||||
35
packages/routes/src/relay.tsx
Normal file
35
packages/routes/src/relay.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import { ComponentType } from "react";
|
||||
import { EnvironmentProviderOptions, PreloadedQuery } from "react-relay";
|
||||
import { LoaderFunction, LoaderFunctionArgs, useLoaderData } from "react-router";
|
||||
import { OperationType } from "relay-runtime";
|
||||
import { useCleanup } from "@probo/hooks";
|
||||
|
||||
export function withQueryRef<
|
||||
TQuery extends OperationType,
|
||||
TEnvironmentProviderOptions = EnvironmentProviderOptions
|
||||
>(
|
||||
Component: ComponentType<{ queryRef: PreloadedQuery<TQuery, TEnvironmentProviderOptions> }>,
|
||||
) {
|
||||
return () => {
|
||||
const { queryRef, dispose } = useLoaderData();
|
||||
|
||||
useCleanup(dispose, 1000);
|
||||
|
||||
return <Component queryRef={queryRef} />
|
||||
}
|
||||
}
|
||||
|
||||
export function loaderFromQueryLoader<
|
||||
TQuery extends OperationType,
|
||||
TEnvironmentProviderOptions = EnvironmentProviderOptions
|
||||
>(
|
||||
queryLoader: (params: Record<string, string>) => PreloadedQuery<TQuery, TEnvironmentProviderOptions>
|
||||
): LoaderFunction {
|
||||
return ({ params }: LoaderFunctionArgs) => {
|
||||
const query = queryLoader(params as Record<string, string>);
|
||||
return {
|
||||
queryRef: query,
|
||||
dispose: query.dispose,
|
||||
};
|
||||
}
|
||||
}
|
||||
6
packages/routes/tsconfig.json
Normal file
6
packages/routes/tsconfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["ES2021", "dom"],
|
||||
"jsx": "react-jsx",
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user