@cedarjs/router 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +36 -0
- package/dist/ActivePageContext.d.ts +15 -0
- package/dist/ActivePageContext.d.ts.map +1 -0
- package/dist/ActivePageContext.js +17 -0
- package/dist/AuthenticatedRoute.d.ts +11 -0
- package/dist/AuthenticatedRoute.d.ts.map +1 -0
- package/dist/AuthenticatedRoute.js +49 -0
- package/dist/PageLoadingContext.d.ts +14 -0
- package/dist/PageLoadingContext.d.ts.map +1 -0
- package/dist/PageLoadingContext.js +29 -0
- package/dist/Route.d.ts +32 -0
- package/dist/Route.d.ts.map +1 -0
- package/dist/Route.js +7 -0
- package/dist/Set.d.ts +58 -0
- package/dist/Set.d.ts.map +1 -0
- package/dist/Set.js +28 -0
- package/dist/a11yUtils.d.ts +14 -0
- package/dist/a11yUtils.d.ts.map +1 -0
- package/dist/a11yUtils.js +35 -0
- package/dist/active-route-loader.d.ts +12 -0
- package/dist/active-route-loader.d.ts.map +1 -0
- package/dist/active-route-loader.js +82 -0
- package/dist/analyzeRoutes.d.ts +44 -0
- package/dist/analyzeRoutes.d.ts.map +1 -0
- package/dist/analyzeRoutes.js +128 -0
- package/dist/cjs/ActivePageContext.d.ts +15 -0
- package/dist/cjs/ActivePageContext.d.ts.map +1 -0
- package/dist/cjs/ActivePageContext.js +42 -0
- package/dist/cjs/AuthenticatedRoute.d.ts +11 -0
- package/dist/cjs/AuthenticatedRoute.d.ts.map +1 -0
- package/dist/cjs/AuthenticatedRoute.js +83 -0
- package/dist/cjs/PageLoadingContext.d.ts +14 -0
- package/dist/cjs/PageLoadingContext.d.ts.map +1 -0
- package/dist/cjs/PageLoadingContext.js +64 -0
- package/dist/cjs/Route.d.ts +32 -0
- package/dist/cjs/Route.d.ts.map +1 -0
- package/dist/cjs/Route.js +41 -0
- package/dist/cjs/Set.d.ts +58 -0
- package/dist/cjs/Set.d.ts.map +1 -0
- package/dist/cjs/Set.js +67 -0
- package/dist/cjs/a11yUtils.d.ts +14 -0
- package/dist/cjs/a11yUtils.d.ts.map +1 -0
- package/dist/cjs/a11yUtils.js +61 -0
- package/dist/cjs/active-route-loader.d.ts +12 -0
- package/dist/cjs/active-route-loader.d.ts.map +1 -0
- package/dist/cjs/active-route-loader.js +116 -0
- package/dist/cjs/analyzeRoutes.d.ts +44 -0
- package/dist/cjs/analyzeRoutes.d.ts.map +1 -0
- package/dist/cjs/analyzeRoutes.js +143 -0
- package/dist/cjs/createNamedContext.d.ts +3 -0
- package/dist/cjs/createNamedContext.d.ts.map +1 -0
- package/dist/cjs/createNamedContext.js +33 -0
- package/dist/cjs/dummyComponent.d.ts +3 -0
- package/dist/cjs/dummyComponent.d.ts.map +1 -0
- package/dist/cjs/dummyComponent.js +24 -0
- package/dist/cjs/history.d.ts +24 -0
- package/dist/cjs/history.d.ts.map +1 -0
- package/dist/cjs/history.js +146 -0
- package/dist/cjs/index.d.ts +35 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +110 -0
- package/dist/cjs/link.d.ts +9 -0
- package/dist/cjs/link.d.ts.map +1 -0
- package/dist/cjs/link.js +62 -0
- package/dist/cjs/location.d.ts +28 -0
- package/dist/cjs/location.d.ts.map +1 -0
- package/dist/cjs/location.js +110 -0
- package/dist/cjs/namedRoutes.d.ts +3 -0
- package/dist/cjs/namedRoutes.d.ts.map +1 -0
- package/dist/cjs/namedRoutes.js +28 -0
- package/dist/cjs/navLink.d.ts +11 -0
- package/dist/cjs/navLink.d.ts.map +1 -0
- package/dist/cjs/navLink.js +70 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/page.d.ts +28 -0
- package/dist/cjs/page.d.ts.map +1 -0
- package/dist/cjs/page.js +42 -0
- package/dist/cjs/params.d.ts +13 -0
- package/dist/cjs/params.d.ts.map +1 -0
- package/dist/cjs/params.js +64 -0
- package/dist/cjs/react-util.d.ts +3 -0
- package/dist/cjs/react-util.d.ts.map +1 -0
- package/dist/cjs/react-util.js +37 -0
- package/dist/cjs/redirect.d.ts +12 -0
- package/dist/cjs/redirect.d.ts.map +1 -0
- package/dist/cjs/redirect.js +35 -0
- package/dist/cjs/route-announcement.d.ts +13 -0
- package/dist/cjs/route-announcement.d.ts.map +1 -0
- package/dist/cjs/route-announcement.js +61 -0
- package/dist/cjs/route-focus.d.ts +12 -0
- package/dist/cjs/route-focus.d.ts.map +1 -0
- package/dist/cjs/route-focus.js +36 -0
- package/dist/cjs/route-validators.d.ts +21 -0
- package/dist/cjs/route-validators.d.ts.map +1 -0
- package/dist/cjs/route-validators.js +71 -0
- package/dist/cjs/routeParamsTypes.d.ts +49 -0
- package/dist/cjs/routeParamsTypes.d.ts.map +1 -0
- package/dist/cjs/routeParamsTypes.js +16 -0
- package/dist/cjs/router-context.d.ts +21 -0
- package/dist/cjs/router-context.d.ts.map +1 -0
- package/dist/cjs/router-context.js +69 -0
- package/dist/cjs/router.d.ts +11 -0
- package/dist/cjs/router.d.ts.map +1 -0
- package/dist/cjs/router.js +207 -0
- package/dist/cjs/rsc/ClientRouter.d.ts +4 -0
- package/dist/cjs/rsc/ClientRouter.d.ts.map +1 -0
- package/dist/cjs/rsc/ClientRouter.js +90 -0
- package/dist/cjs/rsc/RscCache.d.ts +23 -0
- package/dist/cjs/rsc/RscCache.d.ts.map +1 -0
- package/dist/cjs/rsc/RscCache.js +110 -0
- package/dist/cjs/rsc/RscRoutes.d.ts +7 -0
- package/dist/cjs/rsc/RscRoutes.d.ts.map +1 -0
- package/dist/cjs/rsc/RscRoutes.js +124 -0
- package/dist/cjs/rsc/ServerRouteLoader.d.ts +12 -0
- package/dist/cjs/rsc/ServerRouteLoader.d.ts.map +1 -0
- package/dist/cjs/rsc/ServerRouteLoader.js +65 -0
- package/dist/cjs/rsc/ServerRouter.d.ts +11 -0
- package/dist/cjs/rsc/ServerRouter.d.ts.map +1 -0
- package/dist/cjs/rsc/ServerRouter.js +170 -0
- package/dist/cjs/rsc/SsrRouter.d.ts +4 -0
- package/dist/cjs/rsc/SsrRouter.d.ts.map +1 -0
- package/dist/cjs/rsc/SsrRouter.js +56 -0
- package/dist/cjs/rsc/clientSsr.d.ts +2 -0
- package/dist/cjs/rsc/clientSsr.d.ts.map +1 -0
- package/dist/cjs/rsc/clientSsr.js +114 -0
- package/dist/cjs/rsc/rscCss.d.ts +2 -0
- package/dist/cjs/rsc/rscCss.d.ts.map +1 -0
- package/dist/cjs/rsc/rscCss.js +94 -0
- package/dist/cjs/rsc/ssrModuleMap.d.ts +14 -0
- package/dist/cjs/rsc/ssrModuleMap.d.ts.map +1 -0
- package/dist/cjs/rsc/ssrModuleMap.js +49 -0
- package/dist/cjs/rsc/utils.d.ts +20 -0
- package/dist/cjs/rsc/utils.d.ts.map +1 -0
- package/dist/cjs/rsc/utils.js +68 -0
- package/dist/cjs/rsc-link.d.ts +6 -0
- package/dist/cjs/rsc-link.d.ts.map +1 -0
- package/dist/cjs/rsc-link.js +41 -0
- package/dist/cjs/skipNav.d.ts +81 -0
- package/dist/cjs/skipNav.d.ts.map +1 -0
- package/dist/cjs/skipNav.js +69 -0
- package/dist/cjs/splash-page.d.ts +12 -0
- package/dist/cjs/splash-page.d.ts.map +1 -0
- package/dist/cjs/splash-page.js +515 -0
- package/dist/cjs/useBlocker.d.ts +11 -0
- package/dist/cjs/useBlocker.d.ts.map +1 -0
- package/dist/cjs/useBlocker.js +65 -0
- package/dist/cjs/useIsMounted.d.ts +2 -0
- package/dist/cjs/useIsMounted.d.ts.map +1 -0
- package/dist/cjs/useIsMounted.js +37 -0
- package/dist/cjs/useMatch.d.ts +43 -0
- package/dist/cjs/useMatch.d.ts.map +1 -0
- package/dist/cjs/useMatch.js +72 -0
- package/dist/cjs/useRouteName.d.ts +3 -0
- package/dist/cjs/useRouteName.d.ts.map +1 -0
- package/dist/cjs/useRouteName.js +40 -0
- package/dist/cjs/useRoutePaths.d.ts +4 -0
- package/dist/cjs/useRoutePaths.d.ts.map +1 -0
- package/dist/cjs/useRoutePaths.js +50 -0
- package/dist/cjs/util.d.ts +121 -0
- package/dist/cjs/util.d.ts.map +1 -0
- package/dist/cjs/util.js +214 -0
- package/dist/createNamedContext.d.ts +3 -0
- package/dist/createNamedContext.d.ts.map +1 -0
- package/dist/createNamedContext.js +9 -0
- package/dist/dummyComponent.d.ts +3 -0
- package/dist/dummyComponent.d.ts.map +1 -0
- package/dist/dummyComponent.js +4 -0
- package/dist/history.d.ts +24 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +118 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/link.d.ts +9 -0
- package/dist/link.d.ts.map +1 -0
- package/dist/link.js +28 -0
- package/dist/location.d.ts +28 -0
- package/dist/location.d.ts.map +1 -0
- package/dist/location.js +74 -0
- package/dist/namedRoutes.d.ts +3 -0
- package/dist/namedRoutes.d.ts.map +1 -0
- package/dist/namedRoutes.js +4 -0
- package/dist/navLink.d.ts +11 -0
- package/dist/navLink.d.ts.map +1 -0
- package/dist/navLink.js +36 -0
- package/dist/page.d.ts +28 -0
- package/dist/page.d.ts.map +1 -0
- package/dist/page.js +17 -0
- package/dist/params.d.ts +13 -0
- package/dist/params.d.ts.map +1 -0
- package/dist/params.js +28 -0
- package/dist/react-util.d.ts +3 -0
- package/dist/react-util.d.ts.map +1 -0
- package/dist/react-util.js +13 -0
- package/dist/redirect.d.ts +12 -0
- package/dist/redirect.d.ts.map +1 -0
- package/dist/redirect.js +11 -0
- package/dist/route-announcement.d.ts +13 -0
- package/dist/route-announcement.d.ts.map +1 -0
- package/dist/route-announcement.js +31 -0
- package/dist/route-focus.d.ts +12 -0
- package/dist/route-focus.d.ts.map +1 -0
- package/dist/route-focus.js +6 -0
- package/dist/route-validators.d.ts +21 -0
- package/dist/route-validators.d.ts.map +1 -0
- package/dist/route-validators.js +44 -0
- package/dist/routeParamsTypes.d.ts +49 -0
- package/dist/routeParamsTypes.d.ts.map +1 -0
- package/dist/routeParamsTypes.js +0 -0
- package/dist/router-context.d.ts +21 -0
- package/dist/router-context.d.ts.map +1 -0
- package/dist/router-context.js +34 -0
- package/dist/router.d.ts +11 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +173 -0
- package/dist/rsc/ClientRouter.d.ts +4 -0
- package/dist/rsc/ClientRouter.d.ts.map +1 -0
- package/dist/rsc/ClientRouter.js +56 -0
- package/dist/rsc/RscCache.d.ts +23 -0
- package/dist/rsc/RscCache.d.ts.map +1 -0
- package/dist/rsc/RscCache.js +86 -0
- package/dist/rsc/RscRoutes.d.ts +7 -0
- package/dist/rsc/RscRoutes.d.ts.map +1 -0
- package/dist/rsc/RscRoutes.js +100 -0
- package/dist/rsc/ServerRouteLoader.d.ts +12 -0
- package/dist/rsc/ServerRouteLoader.d.ts.map +1 -0
- package/dist/rsc/ServerRouteLoader.js +31 -0
- package/dist/rsc/ServerRouter.d.ts +11 -0
- package/dist/rsc/ServerRouter.d.ts.map +1 -0
- package/dist/rsc/ServerRouter.js +136 -0
- package/dist/rsc/SsrRouter.d.ts +4 -0
- package/dist/rsc/SsrRouter.d.ts.map +1 -0
- package/dist/rsc/SsrRouter.js +22 -0
- package/dist/rsc/clientSsr.d.ts +2 -0
- package/dist/rsc/clientSsr.d.ts.map +1 -0
- package/dist/rsc/clientSsr.js +80 -0
- package/dist/rsc/rscCss.d.ts +2 -0
- package/dist/rsc/rscCss.d.ts.map +1 -0
- package/dist/rsc/rscCss.js +60 -0
- package/dist/rsc/ssrModuleMap.d.ts +14 -0
- package/dist/rsc/ssrModuleMap.d.ts.map +1 -0
- package/dist/rsc/ssrModuleMap.js +25 -0
- package/dist/rsc/utils.d.ts +20 -0
- package/dist/rsc/utils.d.ts.map +1 -0
- package/dist/rsc/utils.js +31 -0
- package/dist/rsc-link.d.ts +6 -0
- package/dist/rsc-link.d.ts.map +1 -0
- package/dist/rsc-link.js +7 -0
- package/dist/skipNav.d.ts +81 -0
- package/dist/skipNav.d.ts.map +1 -0
- package/dist/skipNav.js +34 -0
- package/dist/splash-page.d.ts +12 -0
- package/dist/splash-page.d.ts.map +1 -0
- package/dist/splash-page.js +481 -0
- package/dist/useBlocker.d.ts +11 -0
- package/dist/useBlocker.d.ts.map +1 -0
- package/dist/useBlocker.js +41 -0
- package/dist/useIsMounted.d.ts +2 -0
- package/dist/useIsMounted.d.ts.map +1 -0
- package/dist/useIsMounted.js +13 -0
- package/dist/useMatch.d.ts +43 -0
- package/dist/useMatch.d.ts.map +1 -0
- package/dist/useMatch.js +48 -0
- package/dist/useRouteName.d.ts +3 -0
- package/dist/useRouteName.d.ts.map +1 -0
- package/dist/useRouteName.js +16 -0
- package/dist/useRoutePaths.d.ts +4 -0
- package/dist/useRoutePaths.d.ts.map +1 -0
- package/dist/useRoutePaths.js +25 -0
- package/dist/util.d.ts +121 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +183 -0
- package/package.json +127 -0
- package/skip-nav.css +31 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ReactNode, ReactElement } from 'react';
|
|
2
|
+
import type { InternalRouteProps, NotFoundRouteProps, RedirectRouteProps, RouteProps } from './Route.js';
|
|
3
|
+
/**
|
|
4
|
+
* Narrows down the type of the Route element to RouteProps
|
|
5
|
+
*
|
|
6
|
+
* It means that it is not a notfound page or a redirected route
|
|
7
|
+
*/
|
|
8
|
+
export declare function isStandardRoute(node: ReactElement<InternalRouteProps>): node is ReactElement<RouteProps>;
|
|
9
|
+
/** Checks if a Route element is a Redirect Route */
|
|
10
|
+
export declare function isRedirectRoute(node: ReactElement<InternalRouteProps>): node is ReactElement<RedirectRouteProps>;
|
|
11
|
+
/** Checks if a Route element is a NotFound Route */
|
|
12
|
+
export declare function isNotFoundRoute(node: ReactElement<InternalRouteProps>): node is ReactElement<NotFoundRouteProps>;
|
|
13
|
+
/**
|
|
14
|
+
* Check that the Route element is ok
|
|
15
|
+
* and that it could be one of the following:
|
|
16
|
+
* <Route redirect .../> (redirect Route)
|
|
17
|
+
* <Route notfound .../> (notfound Route)
|
|
18
|
+
* <Route .../> (standard Route)
|
|
19
|
+
*/
|
|
20
|
+
export declare function isValidRoute(node: ReactNode): node is ReactElement<InternalRouteProps>;
|
|
21
|
+
//# sourceMappingURL=route-validators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-validators.d.ts","sourceRoot":"","sources":["../src/route-validators.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAGpD,OAAO,KAAK,EACV,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,EACX,MAAM,YAAY,CAAA;AAanB;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,YAAY,CAAC,kBAAkB,CAAC,GACrC,IAAI,IAAI,YAAY,CAAC,UAAU,CAAC,CAElC;AAED,oDAAoD;AACpD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,YAAY,CAAC,kBAAkB,CAAC,GACrC,IAAI,IAAI,YAAY,CAAC,kBAAkB,CAAC,CAE1C;AAED,oDAAoD;AACpD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,YAAY,CAAC,kBAAkB,CAAC,GACrC,IAAI,IAAI,YAAY,CAAC,kBAAkB,CAAC,CAE1C;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,SAAS,GACd,IAAI,IAAI,YAAY,CAAC,kBAAkB,CAAC,CA8B1C"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { isValidElement } from "react";
|
|
2
|
+
import { Route } from "./Route.js";
|
|
3
|
+
function isNodeTypeRoute(node) {
|
|
4
|
+
return isValidElement(node) && node.type === Route;
|
|
5
|
+
}
|
|
6
|
+
function isString(value) {
|
|
7
|
+
return typeof value === "string";
|
|
8
|
+
}
|
|
9
|
+
function isStandardRoute(node) {
|
|
10
|
+
return !node.props.notfound && !node.props.redirect;
|
|
11
|
+
}
|
|
12
|
+
function isRedirectRoute(node) {
|
|
13
|
+
return !!node.props.redirect;
|
|
14
|
+
}
|
|
15
|
+
function isNotFoundRoute(node) {
|
|
16
|
+
return !!node.props.notfound;
|
|
17
|
+
}
|
|
18
|
+
function isValidRoute(node) {
|
|
19
|
+
const isValidRouteElement = isNodeTypeRoute(node);
|
|
20
|
+
if (isValidRouteElement) {
|
|
21
|
+
const notFoundOrRedirect = node.props.notfound || node.props.redirect;
|
|
22
|
+
const requiredKeys = [
|
|
23
|
+
!node.props.notfound && "path",
|
|
24
|
+
// redirects don't need an actual page, but notfound and standard do
|
|
25
|
+
!node.props.redirect && "page",
|
|
26
|
+
// Redirects can have names, but aren't required to
|
|
27
|
+
!notFoundOrRedirect && "name"
|
|
28
|
+
].filter(isString);
|
|
29
|
+
const missingKeys = requiredKeys.filter((key) => !(key in node.props));
|
|
30
|
+
if (missingKeys.length > 0) {
|
|
31
|
+
const stringToHelpIdentify = node.props.name || node.props.path ? `for "${node.props.name || node.props.path}" ` : "";
|
|
32
|
+
throw new Error(
|
|
33
|
+
`Route element ${stringToHelpIdentify}is missing required props: ` + missingKeys.join(", ")
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return isValidRouteElement;
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
isNotFoundRoute,
|
|
41
|
+
isRedirectRoute,
|
|
42
|
+
isStandardRoute,
|
|
43
|
+
isValidRoute
|
|
44
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { A } from 'ts-toolbelt';
|
|
2
|
+
export type GenericParams = Record<string | number, string | number | boolean>;
|
|
3
|
+
export type QueryParams = GenericParams;
|
|
4
|
+
export type RouteParams<Route> = Route extends `${string}/${infer Rest}` ? A.Compute<ParsedParams<Rest>> : GenericParams;
|
|
5
|
+
export type ParamType<match> = match extends 'Int' ? number : match extends 'Boolean' ? boolean : match extends 'Float' ? number : string;
|
|
6
|
+
type ParamsFromGreedyMatch<TParam extends string, TMatch extends string, TRest extends string> = {
|
|
7
|
+
[ParamName in TParam as RemoveGlobDots<ParamName>]: string;
|
|
8
|
+
} & ParsedParams<`${TRest}:${TMatch}}`> & ParsedParams<`${TRest}`>;
|
|
9
|
+
type TypedParamInFront<TParam extends string, TMatch extends string, TRest extends string> = TParam extends `${infer Param2}}/${infer Rest2}` ? ParamsFromGreedyMatch<Param2, TMatch, Rest2> : // Otherwise its a regular match
|
|
10
|
+
{
|
|
11
|
+
[ParamName in TParam]: ParamType<TMatch>;
|
|
12
|
+
} & ParsedParams<`${TRest}`>;
|
|
13
|
+
type TypedParamAtEnd<TParam extends string, TMatch extends string> = TParam extends `${infer Param2}}/${infer Rest2}` ? {
|
|
14
|
+
[ParamName in Param2]: string;
|
|
15
|
+
} & ParsedParams<`${Rest2}:${TMatch}}`> : {
|
|
16
|
+
[ParamName in TParam]: ParamType<TMatch>;
|
|
17
|
+
};
|
|
18
|
+
type RemoveGlobDots<Param> = Param extends `${infer GlobParamName}...` ? GlobParamName : Param;
|
|
19
|
+
type MultiParamsWithoutType<TParam extends string, TRest extends string> = {
|
|
20
|
+
[ParamName in TParam as RemoveGlobDots<ParamName>]: string;
|
|
21
|
+
} & ParsedParams<`${TRest}`>;
|
|
22
|
+
type JustParamNoType<TParam extends string> = {
|
|
23
|
+
[ParamName in TParam as RemoveGlobDots<ParamName>]: string;
|
|
24
|
+
};
|
|
25
|
+
type ParsedParams<PartialRoute> = PartialRoute extends `${string}{${infer Param}:${infer Match}}${string}/${infer Rest}` ? TypedParamInFront<Param, Match, Rest> : PartialRoute extends `${string}{${infer Param}:${infer Match}}${string}` ? TypedParamAtEnd<Param, Match> : PartialRoute extends `${string}{${infer Param}}${string}/${infer Rest}` ? MultiParamsWithoutType<Param, Rest> : PartialRoute extends `${string}{${infer Param}}${string}` ? JustParamNoType<Param> : PartialRoute extends `${string}/${infer Rest}` ? ParsedParams<`${Rest}`> : GenericParams;
|
|
26
|
+
export {};
|
|
27
|
+
/**
|
|
28
|
+
* Translation in pseudocode without ternaries
|
|
29
|
+
*
|
|
30
|
+
if ('he{c:Int}lo/...rest') {
|
|
31
|
+
checkForGreedyMatch()
|
|
32
|
+
} else if ('he{c:Int}lo') {
|
|
33
|
+
typedParamAtEnd()
|
|
34
|
+
} else if ('he{c}yo/...rest') {
|
|
35
|
+
multipleParamsNoTypes()
|
|
36
|
+
} else if('he{d}yo') {
|
|
37
|
+
justParamNoType()
|
|
38
|
+
} else if ('bazinga/..rest') {
|
|
39
|
+
// Call itself
|
|
40
|
+
parseParamsRecursiveCall(rest)
|
|
41
|
+
} else{
|
|
42
|
+
// fallback, because it doesn't match any of the above
|
|
43
|
+
GenericParams
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
Its a bit odd, but the he{d}llo is a form we support in the router
|
|
47
|
+
// e.g. /signedUp/e{status:Boolean}y
|
|
48
|
+
**/
|
|
49
|
+
//# sourceMappingURL=routeParamsTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routeParamsTypes.d.ts","sourceRoot":"","sources":["../src/routeParamsTypes.ts"],"names":[],"mappings":"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"}
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { AuthContextInterface } from '@cedarjs/auth' with { 'resolution-mode': 'import' };
|
|
3
|
+
import type { analyzeRoutes } from './analyzeRoutes.js';
|
|
4
|
+
import type { ParamType } from './util.js';
|
|
5
|
+
type UseAuth = () => AuthContextInterface<unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown>;
|
|
6
|
+
export interface RouterState {
|
|
7
|
+
paramTypes?: Record<string, ParamType>;
|
|
8
|
+
useAuth: UseAuth;
|
|
9
|
+
routes: ReturnType<typeof analyzeRoutes>;
|
|
10
|
+
activeRouteName?: string | undefined | null;
|
|
11
|
+
}
|
|
12
|
+
export interface RouterContextProviderProps extends Omit<RouterState, 'useAuth'> {
|
|
13
|
+
useAuth?: UseAuth;
|
|
14
|
+
routes: ReturnType<typeof analyzeRoutes>;
|
|
15
|
+
activeRouteName?: string | undefined | null;
|
|
16
|
+
children: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
export declare const RouterContextProvider: React.FC<RouterContextProviderProps>;
|
|
19
|
+
export declare const useRouterState: () => RouterState;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=router-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router-context.d.ts","sourceRoot":"","sources":["../src/router-context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAA;AAEjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC,OAAO,iBAAiB,EAAE,QAAQ,EAAE,CAAA;AAG9F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1C,KAAK,OAAO,GAAG,MAAM,oBAAoB,CACvC,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,CACR,CAAA;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACtC,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA;IACxC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAA;CAC5C;AAID,MAAM,WAAW,0BACf,SAAQ,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA;IACxC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAA;IAC3C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CAsBtE,CAAA;AAED,eAAO,MAAM,cAAc,mBAU1B,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React, { createContext, useContext, useMemo } from "react";
|
|
2
|
+
import { useNoAuth } from "@cedarjs/auth";
|
|
3
|
+
const RouterStateContext = createContext(void 0);
|
|
4
|
+
const RouterContextProvider = ({
|
|
5
|
+
useAuth,
|
|
6
|
+
paramTypes,
|
|
7
|
+
routes,
|
|
8
|
+
activeRouteName,
|
|
9
|
+
children
|
|
10
|
+
}) => {
|
|
11
|
+
const state = useMemo(
|
|
12
|
+
() => ({
|
|
13
|
+
useAuth: useAuth || useNoAuth,
|
|
14
|
+
paramTypes,
|
|
15
|
+
routes,
|
|
16
|
+
activeRouteName
|
|
17
|
+
}),
|
|
18
|
+
[useAuth, paramTypes, routes, activeRouteName]
|
|
19
|
+
);
|
|
20
|
+
return /* @__PURE__ */ React.createElement(RouterStateContext.Provider, { value: state }, children);
|
|
21
|
+
};
|
|
22
|
+
const useRouterState = () => {
|
|
23
|
+
const context = useContext(RouterStateContext);
|
|
24
|
+
if (context === void 0) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
"useRouterState must be used within a RouterContextProvider"
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return context;
|
|
30
|
+
};
|
|
31
|
+
export {
|
|
32
|
+
RouterContextProvider,
|
|
33
|
+
useRouterState
|
|
34
|
+
};
|
package/dist/router.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import type { RouterContextProviderProps } from './router-context.js';
|
|
4
|
+
import type { TrailingSlashesTypes } from './util.js';
|
|
5
|
+
export interface RouterProps extends Omit<RouterContextProviderProps, 'routes' | 'activeRouteName'> {
|
|
6
|
+
trailingSlashes?: TrailingSlashesTypes;
|
|
7
|
+
pageLoadingDelay?: number;
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
export declare const Router: React.FC<RouterProps>;
|
|
11
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAwB,MAAM,OAAO,CAAA;AAY5C,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAA;AAIrE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAErD,MAAM,WAAW,WACf,SAAQ,IAAI,CAAC,0BAA0B,EAAE,QAAQ,GAAG,iBAAiB,CAAC;IACtE,eAAe,CAAC,EAAE,oBAAoB,CAAA;IACtC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAoBxC,CAAA"}
|
package/dist/router.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import React, { useMemo, memo } from "react";
|
|
2
|
+
import { ActiveRouteLoader } from "./active-route-loader.js";
|
|
3
|
+
import { analyzeRoutes } from "./analyzeRoutes.js";
|
|
4
|
+
import { AuthenticatedRoute } from "./AuthenticatedRoute.js";
|
|
5
|
+
import { LocationProvider, useLocation } from "./location.js";
|
|
6
|
+
import { namedRoutes } from "./namedRoutes.js";
|
|
7
|
+
import { normalizePage } from "./page.js";
|
|
8
|
+
import { PageLoadingContextProvider } from "./PageLoadingContext.js";
|
|
9
|
+
import { ParamsProvider } from "./params.js";
|
|
10
|
+
import { Redirect } from "./redirect.js";
|
|
11
|
+
import { RouterContextProvider } from "./router-context.js";
|
|
12
|
+
import { SplashPage } from "./splash-page.js";
|
|
13
|
+
import { matchPath, parseSearch, replaceParams, validatePath } from "./util.js";
|
|
14
|
+
const Router = ({
|
|
15
|
+
useAuth,
|
|
16
|
+
paramTypes,
|
|
17
|
+
pageLoadingDelay,
|
|
18
|
+
trailingSlashes = "never",
|
|
19
|
+
children
|
|
20
|
+
}) => {
|
|
21
|
+
return (
|
|
22
|
+
// Level 1/3 (outer-most)
|
|
23
|
+
// Wrap it in the provider so that useLocation can be used
|
|
24
|
+
/* @__PURE__ */ React.createElement(LocationProvider, { trailingSlashes }, /* @__PURE__ */ React.createElement(
|
|
25
|
+
LocationAwareRouter,
|
|
26
|
+
{
|
|
27
|
+
useAuth,
|
|
28
|
+
paramTypes,
|
|
29
|
+
pageLoadingDelay
|
|
30
|
+
},
|
|
31
|
+
children
|
|
32
|
+
))
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
const LocationAwareRouter = ({
|
|
36
|
+
useAuth,
|
|
37
|
+
paramTypes,
|
|
38
|
+
pageLoadingDelay,
|
|
39
|
+
children
|
|
40
|
+
}) => {
|
|
41
|
+
const location = useLocation();
|
|
42
|
+
const analyzeRoutesResult = useMemo(() => {
|
|
43
|
+
return analyzeRoutes(children, {
|
|
44
|
+
currentPathName: location.pathname,
|
|
45
|
+
// @TODO We haven't handled this with SSR/Streaming yet.
|
|
46
|
+
// May need a babel plugin to extract userParamTypes from Routes.tsx
|
|
47
|
+
userParamTypes: paramTypes
|
|
48
|
+
});
|
|
49
|
+
}, [location.pathname, children, paramTypes]);
|
|
50
|
+
const {
|
|
51
|
+
pathRouteMap,
|
|
52
|
+
hasRootRoute,
|
|
53
|
+
namedRoutesMap,
|
|
54
|
+
NotFoundPage,
|
|
55
|
+
activeRoutePath
|
|
56
|
+
} = analyzeRoutesResult;
|
|
57
|
+
const hasGeneratedRoutes = hasCustomRoutes(namedRoutesMap);
|
|
58
|
+
const splashPageExists = typeof SplashPage !== "undefined";
|
|
59
|
+
const isOnNonExistentRootRoute = !hasRootRoute && location.pathname === "/";
|
|
60
|
+
if (!hasRootRoute && splashPageExists) {
|
|
61
|
+
namedRoutesMap["home"] = () => "/";
|
|
62
|
+
}
|
|
63
|
+
Object.assign(namedRoutes, namedRoutesMap);
|
|
64
|
+
const shouldShowSplash = (isOnNonExistentRootRoute || !hasGeneratedRoutes) && splashPageExists;
|
|
65
|
+
if (shouldShowSplash) {
|
|
66
|
+
return /* @__PURE__ */ React.createElement(
|
|
67
|
+
SplashPage,
|
|
68
|
+
{
|
|
69
|
+
hasGeneratedRoutes,
|
|
70
|
+
allStandardRoutes: pathRouteMap
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
if (!activeRoutePath) {
|
|
75
|
+
if (NotFoundPage) {
|
|
76
|
+
return /* @__PURE__ */ React.createElement(
|
|
77
|
+
RouterContextProvider,
|
|
78
|
+
{
|
|
79
|
+
useAuth,
|
|
80
|
+
paramTypes,
|
|
81
|
+
routes: analyzeRoutesResult
|
|
82
|
+
},
|
|
83
|
+
/* @__PURE__ */ React.createElement(ParamsProvider, null, /* @__PURE__ */ React.createElement(PageLoadingContextProvider, { delay: pageLoadingDelay }, /* @__PURE__ */ React.createElement(
|
|
84
|
+
ActiveRouteLoader,
|
|
85
|
+
{
|
|
86
|
+
spec: normalizePage(NotFoundPage),
|
|
87
|
+
path: location.pathname
|
|
88
|
+
}
|
|
89
|
+
)))
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
const { path, page, name, redirect, whileLoadingPage, sets } = pathRouteMap[activeRoutePath];
|
|
95
|
+
if (!path) {
|
|
96
|
+
throw new Error(`Route "${name}" needs to specify a path`);
|
|
97
|
+
}
|
|
98
|
+
validatePath(path, name || path);
|
|
99
|
+
const { params: pathParams } = matchPath(path, location.pathname, {
|
|
100
|
+
userParamTypes: paramTypes
|
|
101
|
+
});
|
|
102
|
+
const searchParams = parseSearch(location.search);
|
|
103
|
+
const allParams = { ...searchParams, ...pathParams };
|
|
104
|
+
let redirectPath = void 0;
|
|
105
|
+
if (redirect) {
|
|
106
|
+
if (redirect.startsWith("/")) {
|
|
107
|
+
redirectPath = replaceParams(redirect, allParams);
|
|
108
|
+
} else {
|
|
109
|
+
const redirectRouteObject = Object.values(pathRouteMap).find(
|
|
110
|
+
(route) => route.name === redirect
|
|
111
|
+
);
|
|
112
|
+
if (!redirectRouteObject) {
|
|
113
|
+
throw new Error(
|
|
114
|
+
`Redirect target route "${redirect}" does not exist for route "${name}"`
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
redirectPath = replaceParams(redirectRouteObject.path, allParams);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return /* @__PURE__ */ React.createElement(
|
|
121
|
+
RouterContextProvider,
|
|
122
|
+
{
|
|
123
|
+
useAuth,
|
|
124
|
+
paramTypes,
|
|
125
|
+
routes: analyzeRoutesResult,
|
|
126
|
+
activeRouteName: name
|
|
127
|
+
},
|
|
128
|
+
/* @__PURE__ */ React.createElement(ParamsProvider, { allParams }, /* @__PURE__ */ React.createElement(PageLoadingContextProvider, { delay: pageLoadingDelay }, redirectPath && /* @__PURE__ */ React.createElement(Redirect, { to: redirectPath }), !redirectPath && page && /* @__PURE__ */ React.createElement(WrappedPage, { sets }, /* @__PURE__ */ React.createElement(
|
|
129
|
+
ActiveRouteLoader,
|
|
130
|
+
{
|
|
131
|
+
path,
|
|
132
|
+
spec: normalizePage(page),
|
|
133
|
+
params: allParams,
|
|
134
|
+
whileLoadingPage
|
|
135
|
+
}
|
|
136
|
+
))))
|
|
137
|
+
);
|
|
138
|
+
};
|
|
139
|
+
const WrappedPage = memo(({ sets, children }) => {
|
|
140
|
+
if (!sets || sets.length === 0) {
|
|
141
|
+
return children;
|
|
142
|
+
}
|
|
143
|
+
return sets.reduceRight((acc, set) => {
|
|
144
|
+
let wrapped = set.wrappers.reduceRight((acc2, Wrapper, index) => {
|
|
145
|
+
return React.createElement(
|
|
146
|
+
Wrapper,
|
|
147
|
+
{ ...set.props, key: set.id + "-" + index },
|
|
148
|
+
acc2
|
|
149
|
+
);
|
|
150
|
+
}, acc);
|
|
151
|
+
if (set.isPrivate) {
|
|
152
|
+
const unauthenticated = set.props.unauthenticated;
|
|
153
|
+
if (!unauthenticated || typeof unauthenticated !== "string") {
|
|
154
|
+
throw new Error(
|
|
155
|
+
"You must specify an `unauthenticated` route when using PrivateSet"
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
wrapped = /* @__PURE__ */ React.createElement(AuthenticatedRoute, { ...set.props, unauthenticated }, wrapped);
|
|
159
|
+
}
|
|
160
|
+
return wrapped;
|
|
161
|
+
}, children);
|
|
162
|
+
});
|
|
163
|
+
function hasCustomRoutes(obj) {
|
|
164
|
+
for (const prop in obj) {
|
|
165
|
+
if (Object.hasOwn(obj, prop)) {
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
export {
|
|
172
|
+
Router
|
|
173
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClientRouter.d.ts","sourceRoot":"","sources":["../../src/rsc/ClientRouter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAA;AAOtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAI/C,eAAO,MAAM,MAAM,sCAAuC,WAAW,sBASpE,CAAA"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React, { useMemo } from "react";
|
|
2
|
+
import { analyzeRoutes } from "../analyzeRoutes.js";
|
|
3
|
+
import { AuthenticatedRoute } from "../AuthenticatedRoute.js";
|
|
4
|
+
import { LocationProvider, useLocation } from "../location.js";
|
|
5
|
+
import { namedRoutes } from "../namedRoutes.js";
|
|
6
|
+
import { RouterContextProvider } from "../router-context.js";
|
|
7
|
+
import { RscRoutes } from "./RscRoutes.js";
|
|
8
|
+
const Router = ({ useAuth, paramTypes, children }) => {
|
|
9
|
+
return (
|
|
10
|
+
// Wrap it in the provider so that useLocation can be used
|
|
11
|
+
/* @__PURE__ */ React.createElement(LocationProvider, null, /* @__PURE__ */ React.createElement(LocationAwareRouter, { paramTypes, useAuth }, children))
|
|
12
|
+
);
|
|
13
|
+
};
|
|
14
|
+
const LocationAwareRouter = ({
|
|
15
|
+
useAuth,
|
|
16
|
+
paramTypes,
|
|
17
|
+
children
|
|
18
|
+
}) => {
|
|
19
|
+
const { pathname, search } = useLocation();
|
|
20
|
+
const analyzeRoutesResult = useMemo(() => {
|
|
21
|
+
return analyzeRoutes(children, {
|
|
22
|
+
currentPathName: pathname,
|
|
23
|
+
userParamTypes: paramTypes
|
|
24
|
+
});
|
|
25
|
+
}, [pathname, children, paramTypes]);
|
|
26
|
+
const { namedRoutesMap, pathRouteMap, activeRoutePath } = analyzeRoutesResult;
|
|
27
|
+
Object.assign(namedRoutes, namedRoutesMap);
|
|
28
|
+
if (!activeRoutePath) {
|
|
29
|
+
return /* @__PURE__ */ React.createElement(RscRoutes, { pathname, search });
|
|
30
|
+
}
|
|
31
|
+
const requestedRoute = pathRouteMap[activeRoutePath];
|
|
32
|
+
const reversedSets = requestedRoute.sets.toReversed();
|
|
33
|
+
const privateSet = reversedSets.find((set) => set.isPrivate);
|
|
34
|
+
if (privateSet) {
|
|
35
|
+
const unauthenticated = privateSet.props.unauthenticated;
|
|
36
|
+
if (!unauthenticated || typeof unauthenticated !== "string") {
|
|
37
|
+
throw new Error(
|
|
38
|
+
"You must specify an `unauthenticated` route when using PrivateSet"
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
return /* @__PURE__ */ React.createElement(
|
|
42
|
+
RouterContextProvider,
|
|
43
|
+
{
|
|
44
|
+
useAuth,
|
|
45
|
+
paramTypes,
|
|
46
|
+
routes: analyzeRoutesResult,
|
|
47
|
+
activeRouteName: requestedRoute.name
|
|
48
|
+
},
|
|
49
|
+
/* @__PURE__ */ React.createElement(AuthenticatedRoute, { unauthenticated }, /* @__PURE__ */ React.createElement(RscRoutes, { pathname, search }))
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
return /* @__PURE__ */ React.createElement(RscRoutes, { pathname, search });
|
|
53
|
+
};
|
|
54
|
+
export {
|
|
55
|
+
Router
|
|
56
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface RscModel {
|
|
2
|
+
__rwjs__Routes: [React.ReactElement];
|
|
3
|
+
__rwjs__rsa_data?: unknown;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* This cache is used for RSC fetches, so that we don't re-fetch the same
|
|
7
|
+
* component (i.e. page) multiple times and get stuck in a loop.
|
|
8
|
+
*
|
|
9
|
+
* `key`: A stringified location-like object.
|
|
10
|
+
* `value`: A Promise that resolves to a React element.
|
|
11
|
+
*/
|
|
12
|
+
export declare class RscCache {
|
|
13
|
+
private cache;
|
|
14
|
+
private socket;
|
|
15
|
+
private sendRetries;
|
|
16
|
+
private isEnabled;
|
|
17
|
+
constructor();
|
|
18
|
+
get(key: string): Thenable<RscModel> | undefined;
|
|
19
|
+
set(key: string, value: Thenable<RscModel>): void;
|
|
20
|
+
private sendToWebSocket;
|
|
21
|
+
private sendUpdateToWebSocket;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=RscCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RscCache.d.ts","sourceRoot":"","sources":["../../src/rsc/RscCache.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,cAAc,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IACpC,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B;AAED;;;;;;GAMG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,KAAK,CAAwC;IACrD,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,WAAW,CAAI;IAEvB,OAAO,CAAC,SAAS,CAAQ;;IAgDzB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,SAAS;IAMhD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC;IA2B1C,OAAO,CAAC,eAAe;IAsBvB,OAAO,CAAC,qBAAqB;CAW9B"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
class RscCache {
|
|
2
|
+
cache = /* @__PURE__ */ new Map();
|
|
3
|
+
socket;
|
|
4
|
+
sendRetries = 0;
|
|
5
|
+
// Turn the cache off for now. We can turn it on later if we decide we need it
|
|
6
|
+
isEnabled = false;
|
|
7
|
+
constructor() {
|
|
8
|
+
this.socket = new WebSocket("ws://localhost:18998");
|
|
9
|
+
this.socket.addEventListener("open", () => {
|
|
10
|
+
});
|
|
11
|
+
this.socket.addEventListener("message", (event) => {
|
|
12
|
+
if (event.data.startsWith("{")) {
|
|
13
|
+
const data = JSON.parse(event.data);
|
|
14
|
+
if (data.id === "rsc-cache-delete") {
|
|
15
|
+
if (!this.cache.has(data.key)) {
|
|
16
|
+
}
|
|
17
|
+
this.cache.delete(data.key);
|
|
18
|
+
this.sendUpdateToWebSocket();
|
|
19
|
+
} else if (data.id === "rsc-cache-clear") {
|
|
20
|
+
this.cache.clear();
|
|
21
|
+
this.sendToWebSocket("update", { fullCache: {} });
|
|
22
|
+
} else if (data.id === "rsc-cache-enable") {
|
|
23
|
+
this.isEnabled = true;
|
|
24
|
+
this.sendUpdateToWebSocket();
|
|
25
|
+
} else if (data.id === "rsc-cache-disable") {
|
|
26
|
+
this.isEnabled = false;
|
|
27
|
+
} else if (data.id === "rsc-cache-read") {
|
|
28
|
+
this.sendUpdateToWebSocket();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
get(key) {
|
|
34
|
+
const value = this.cache.get(key);
|
|
35
|
+
console.log("RscCache.get", key, value);
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
set(key, value) {
|
|
39
|
+
console.log("RscCache.set", key, value);
|
|
40
|
+
if (!this.isEnabled) {
|
|
41
|
+
this.cache.clear();
|
|
42
|
+
}
|
|
43
|
+
this.cache.set(key, value);
|
|
44
|
+
value.then((_resolvedValue) => {
|
|
45
|
+
this.sendToWebSocket("set", {
|
|
46
|
+
updatedKey: key,
|
|
47
|
+
fullCache: Object.fromEntries(
|
|
48
|
+
Array.from(this.cache.entries()).map(
|
|
49
|
+
// @ts-expect-error hack to get the value of a Thenable
|
|
50
|
+
([location, elementThenable]) => [location, elementThenable.value]
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
sendToWebSocket(action, payload) {
|
|
57
|
+
if (this.socket.readyState === WebSocket?.OPEN) {
|
|
58
|
+
this.sendRetries = 0;
|
|
59
|
+
this.socket.send(JSON.stringify({ id: "rsc-cache-" + action, payload }));
|
|
60
|
+
} else if (this.socket.readyState === WebSocket?.CONNECTING && this.sendRetries < 10) {
|
|
61
|
+
const backoff = 300 + this.sendRetries * 100;
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
this.sendRetries++;
|
|
64
|
+
this.sendToWebSocket(action, payload);
|
|
65
|
+
}, backoff);
|
|
66
|
+
} else if (this.sendRetries >= 10) {
|
|
67
|
+
console.error("Exhausted retries to send message to WebSocket server.");
|
|
68
|
+
} else {
|
|
69
|
+
console.error("WebSocket connection is closed.");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
sendUpdateToWebSocket() {
|
|
73
|
+
this.sendToWebSocket("update", {
|
|
74
|
+
fullCache: Object.fromEntries(
|
|
75
|
+
Array.from(this.cache.entries()).map(([location, elementThenable]) => [
|
|
76
|
+
location,
|
|
77
|
+
// @ts-expect-error hack to get the value of a Thenable
|
|
78
|
+
elementThenable.value
|
|
79
|
+
])
|
|
80
|
+
)
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export {
|
|
85
|
+
RscCache
|
|
86
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
pathname: string;
|
|
3
|
+
search: string;
|
|
4
|
+
}
|
|
5
|
+
export declare const RscRoutes: ({ pathname, search }: Props) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=RscRoutes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RscRoutes.d.ts","sourceRoot":"","sources":["../../src/rsc/RscRoutes.tsx"],"names":[],"mappings":"AAiIA,UAAU,KAAK;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,eAAO,MAAM,SAAS,yBAA0B,KAAK,2FAkCpD,CAAA"}
|