vorma 0.0.0-pre.0 → 0.83.0
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 +28 -0
- package/README.md +48 -0
- package/internal/framework/_typescript/client/index.ts +64 -0
- package/internal/framework/_typescript/client/src/asset_manager.ts +67 -0
- package/internal/framework/_typescript/client/src/client.ts +1201 -0
- package/internal/framework/_typescript/client/src/client_loaders.ts +249 -0
- package/internal/framework/_typescript/client/src/component_loader.ts +105 -0
- package/internal/framework/_typescript/client/src/error_boundary.ts +7 -0
- package/internal/framework/_typescript/client/src/events.ts +54 -0
- package/internal/framework/_typescript/client/src/global_loading_indicator/global_loading_indicator.ts +125 -0
- package/internal/framework/_typescript/client/src/hard_reload.ts +1 -0
- package/internal/framework/_typescript/client/src/head_elements/head_elements.ts +193 -0
- package/internal/framework/_typescript/client/src/history/history.ts +118 -0
- package/internal/framework/_typescript/client/src/history/npm_history_types.ts +83 -0
- package/internal/framework/_typescript/client/src/hmr/hmr.ts +71 -0
- package/internal/framework/_typescript/client/src/init_client.ts +134 -0
- package/internal/framework/_typescript/client/src/links.ts +218 -0
- package/internal/framework/_typescript/client/src/redirects/redirects.ts +203 -0
- package/internal/framework/_typescript/client/src/rendering.ts +135 -0
- package/internal/framework/_typescript/client/src/resolve_public_href.ts +15 -0
- package/internal/framework/_typescript/client/src/scroll_state_manager.ts +100 -0
- package/internal/framework/_typescript/client/src/static_route_defs/route_def_helpers.ts +22 -0
- package/internal/framework/_typescript/client/src/ui_lib_impl_helpers/link_components.ts +131 -0
- package/internal/framework/_typescript/client/src/ui_lib_impl_helpers/route_components.ts +56 -0
- package/internal/framework/_typescript/client/src/ui_lib_impl_helpers/typed_navigate.ts +58 -0
- package/internal/framework/_typescript/client/src/utils/errors.ts +10 -0
- package/internal/framework/_typescript/client/src/utils/logging.ts +7 -0
- package/internal/framework/_typescript/client/src/vorma_app_helpers/vorma_app_helpers.ts +290 -0
- package/internal/framework/_typescript/client/src/vorma_ctx/vorma_ctx.ts +128 -0
- package/internal/framework/_typescript/client/src/window_focus_revalidation/window_focus_revalidation.ts +32 -0
- package/internal/framework/_typescript/client/tsconfig.json +3 -0
- package/internal/framework/_typescript/create/main.ts +378 -0
- package/internal/framework/_typescript/create/package.json +33 -0
- package/internal/framework/_typescript/create/pnpm-lock.yaml +70 -0
- package/internal/framework/_typescript/create/tsconfig.json +3 -0
- package/internal/framework/_typescript/preact/index.tsx +10 -0
- package/internal/framework/_typescript/preact/src/helpers.ts +113 -0
- package/internal/framework/_typescript/preact/src/link.tsx +107 -0
- package/internal/framework/_typescript/preact/src/preact.tsx +191 -0
- package/internal/framework/_typescript/preact/tsconfig.json +7 -0
- package/internal/framework/_typescript/react/index.tsx +10 -0
- package/internal/framework/_typescript/react/src/helpers.ts +118 -0
- package/internal/framework/_typescript/react/src/link.tsx +115 -0
- package/internal/framework/_typescript/react/src/react.tsx +299 -0
- package/internal/framework/_typescript/react/tsconfig.json +6 -0
- package/internal/framework/_typescript/solid/index.tsx +10 -0
- package/internal/framework/_typescript/solid/src/helpers.ts +114 -0
- package/internal/framework/_typescript/solid/src/link.tsx +104 -0
- package/internal/framework/_typescript/solid/src/solid.tsx +204 -0
- package/internal/framework/_typescript/solid/tsconfig.json +7 -0
- package/internal/framework/_typescript/vite/tsconfig.json +3 -0
- package/internal/framework/_typescript/vite/vite.ts +93 -0
- package/internal/site/frontend/assets/vorma-banner.webp +0 -0
- package/kit/_typescript/converters/converters.ts +152 -0
- package/kit/_typescript/cookies/cookies.ts +18 -0
- package/kit/_typescript/csrf/csrf.ts +10 -0
- package/kit/_typescript/debounce/debounce.ts +17 -0
- package/kit/_typescript/fmt/fmt.ts +3 -0
- package/kit/_typescript/json/deep_equals.ts +54 -0
- package/kit/_typescript/json/json.ts +3 -0
- package/kit/_typescript/json/search_param_serializer.ts +49 -0
- package/kit/_typescript/json/stringify_stable.ts +43 -0
- package/kit/_typescript/listeners/listeners.ts +16 -0
- package/kit/_typescript/matcher/find_best_match.ts +205 -0
- package/kit/_typescript/matcher/find_nested_matches.ts +357 -0
- package/kit/_typescript/matcher/parse_segments.ts +30 -0
- package/kit/_typescript/matcher/register.ts +271 -0
- package/kit/_typescript/theme/theme.ts +177 -0
- package/kit/_typescript/tsconfig.json +3 -0
- package/kit/_typescript/url/url.ts +132 -0
- package/npm_dist/internal/framework/_typescript/client/index.d.ts +17 -0
- package/npm_dist/internal/framework/_typescript/client/index.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/index.js +2489 -0
- package/npm_dist/internal/framework/_typescript/client/index.js.map +7 -0
- package/npm_dist/internal/framework/_typescript/client/src/asset_manager.d.ts +6 -0
- package/npm_dist/internal/framework/_typescript/client/src/asset_manager.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/client.d.ts +119 -0
- package/npm_dist/internal/framework/_typescript/client/src/client.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/client_loaders.d.ts +18 -0
- package/npm_dist/internal/framework/_typescript/client/src/client_loaders.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/component_loader.d.ts +10 -0
- package/npm_dist/internal/framework/_typescript/client/src/component_loader.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/error_boundary.d.ts +3 -0
- package/npm_dist/internal/framework/_typescript/client/src/error_boundary.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/events.d.ts +26 -0
- package/npm_dist/internal/framework/_typescript/client/src/events.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/global_loading_indicator/global_loading_indicator.d.ts +12 -0
- package/npm_dist/internal/framework/_typescript/client/src/global_loading_indicator/global_loading_indicator.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/hard_reload.d.ts +2 -0
- package/npm_dist/internal/framework/_typescript/client/src/hard_reload.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/head_elements/head_elements.d.ts +7 -0
- package/npm_dist/internal/framework/_typescript/client/src/head_elements/head_elements.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/history/history.d.ts +14 -0
- package/npm_dist/internal/framework/_typescript/client/src/history/history.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/history/npm_history_types.d.ts +84 -0
- package/npm_dist/internal/framework/_typescript/client/src/history/npm_history_types.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/hmr/hmr.d.ts +3 -0
- package/npm_dist/internal/framework/_typescript/client/src/hmr/hmr.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/init_client.d.ts +9 -0
- package/npm_dist/internal/framework/_typescript/client/src/init_client.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/links.d.ts +33 -0
- package/npm_dist/internal/framework/_typescript/client/src/links.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/redirects/redirects.d.ts +26 -0
- package/npm_dist/internal/framework/_typescript/client/src/redirects/redirects.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/rendering.d.ts +18 -0
- package/npm_dist/internal/framework/_typescript/client/src/rendering.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/resolve_public_href.d.ts +2 -0
- package/npm_dist/internal/framework/_typescript/client/src/resolve_public_href.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/scroll_state_manager.d.ts +22 -0
- package/npm_dist/internal/framework/_typescript/client/src/scroll_state_manager.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/static_route_defs/route_def_helpers.d.ts +12 -0
- package/npm_dist/internal/framework/_typescript/client/src/static_route_defs/route_def_helpers.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/link_components.d.ts +28 -0
- package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/link_components.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/route_components.d.ts +18 -0
- package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/route_components.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/typed_navigate.d.ts +11 -0
- package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/typed_navigate.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/utils/errors.d.ts +3 -0
- package/npm_dist/internal/framework/_typescript/client/src/utils/errors.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/utils/logging.d.ts +3 -0
- package/npm_dist/internal/framework/_typescript/client/src/utils/logging.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/vorma_app_helpers/vorma_app_helpers.d.ts +119 -0
- package/npm_dist/internal/framework/_typescript/client/src/vorma_app_helpers/vorma_app_helpers.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/vorma_ctx/vorma_ctx.d.ts +88 -0
- package/npm_dist/internal/framework/_typescript/client/src/vorma_ctx/vorma_ctx.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/window_focus_revalidation/window_focus_revalidation.d.ts +10 -0
- package/npm_dist/internal/framework/_typescript/client/src/window_focus_revalidation/window_focus_revalidation.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/create/main.d.ts +3 -0
- package/npm_dist/internal/framework/_typescript/create/main.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/preact/index.d.ts +4 -0
- package/npm_dist/internal/framework/_typescript/preact/index.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/preact/index.js +283 -0
- package/npm_dist/internal/framework/_typescript/preact/index.js.map +7 -0
- package/npm_dist/internal/framework/_typescript/preact/src/helpers.d.ts +21 -0
- package/npm_dist/internal/framework/_typescript/preact/src/helpers.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/preact/src/link.d.ts +11 -0
- package/npm_dist/internal/framework/_typescript/preact/src/link.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/preact/src/preact.d.ts +21 -0
- package/npm_dist/internal/framework/_typescript/preact/src/preact.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/react/index.d.ts +4 -0
- package/npm_dist/internal/framework/_typescript/react/index.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/react/index.js +370 -0
- package/npm_dist/internal/framework/_typescript/react/index.js.map +7 -0
- package/npm_dist/internal/framework/_typescript/react/src/helpers.d.ts +21 -0
- package/npm_dist/internal/framework/_typescript/react/src/helpers.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/react/src/link.d.ts +11 -0
- package/npm_dist/internal/framework/_typescript/react/src/link.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/react/src/react.d.ts +20 -0
- package/npm_dist/internal/framework/_typescript/react/src/react.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/solid/index.d.ts +4 -0
- package/npm_dist/internal/framework/_typescript/solid/index.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/solid/index.js +314 -0
- package/npm_dist/internal/framework/_typescript/solid/index.js.map +7 -0
- package/npm_dist/internal/framework/_typescript/solid/src/helpers.d.ts +22 -0
- package/npm_dist/internal/framework/_typescript/solid/src/helpers.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/solid/src/link.d.ts +11 -0
- package/npm_dist/internal/framework/_typescript/solid/src/link.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/solid/src/solid.d.ts +22 -0
- package/npm_dist/internal/framework/_typescript/solid/src/solid.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/vite/vite.d.ts +11 -0
- package/npm_dist/internal/framework/_typescript/vite/vite.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/vite/vite.js +82 -0
- package/npm_dist/internal/framework/_typescript/vite/vite.js.map +7 -0
- package/npm_dist/kit/_typescript/chunk-YBAPNBS2.js +202 -0
- package/npm_dist/kit/_typescript/chunk-YBAPNBS2.js.map +7 -0
- package/npm_dist/kit/_typescript/converters/converters.d.ts +26 -0
- package/npm_dist/kit/_typescript/converters/converters.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/converters/converters.js +99 -0
- package/npm_dist/kit/_typescript/converters/converters.js.map +7 -0
- package/npm_dist/kit/_typescript/cookies/cookies.d.ts +13 -0
- package/npm_dist/kit/_typescript/cookies/cookies.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/cookies/cookies.js +13 -0
- package/npm_dist/kit/_typescript/cookies/cookies.js.map +7 -0
- package/npm_dist/kit/_typescript/csrf/csrf.d.ts +5 -0
- package/npm_dist/kit/_typescript/csrf/csrf.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/csrf/csrf.js +11 -0
- package/npm_dist/kit/_typescript/csrf/csrf.js.map +7 -0
- package/npm_dist/kit/_typescript/debounce/debounce.d.ts +4 -0
- package/npm_dist/kit/_typescript/debounce/debounce.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/debounce/debounce.js +16 -0
- package/npm_dist/kit/_typescript/debounce/debounce.js.map +7 -0
- package/npm_dist/kit/_typescript/fmt/fmt.d.ts +2 -0
- package/npm_dist/kit/_typescript/fmt/fmt.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/fmt/fmt.js +8 -0
- package/npm_dist/kit/_typescript/fmt/fmt.js.map +7 -0
- package/npm_dist/kit/_typescript/json/deep_equals.d.ts +7 -0
- package/npm_dist/kit/_typescript/json/deep_equals.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/json/json.d.ts +4 -0
- package/npm_dist/kit/_typescript/json/json.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/json/json.js +110 -0
- package/npm_dist/kit/_typescript/json/json.js.map +7 -0
- package/npm_dist/kit/_typescript/json/search_param_serializer.d.ts +2 -0
- package/npm_dist/kit/_typescript/json/search_param_serializer.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/json/stringify_stable.d.ts +7 -0
- package/npm_dist/kit/_typescript/json/stringify_stable.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/listeners/listeners.d.ts +2 -0
- package/npm_dist/kit/_typescript/listeners/listeners.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/listeners/listeners.js +20 -0
- package/npm_dist/kit/_typescript/listeners/listeners.js.map +7 -0
- package/npm_dist/kit/_typescript/matcher/find_best_match.d.ts +10 -0
- package/npm_dist/kit/_typescript/matcher/find_best_match.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/matcher/find_best_match.js +146 -0
- package/npm_dist/kit/_typescript/matcher/find_best_match.js.map +7 -0
- package/npm_dist/kit/_typescript/matcher/find_nested_matches.d.ts +14 -0
- package/npm_dist/kit/_typescript/matcher/find_nested_matches.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/matcher/find_nested_matches.js +248 -0
- package/npm_dist/kit/_typescript/matcher/find_nested_matches.js.map +7 -0
- package/npm_dist/kit/_typescript/matcher/parse_segments.d.ts +2 -0
- package/npm_dist/kit/_typescript/matcher/parse_segments.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/matcher/register.d.ts +54 -0
- package/npm_dist/kit/_typescript/matcher/register.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/matcher/register.js +21 -0
- package/npm_dist/kit/_typescript/matcher/register.js.map +7 -0
- package/npm_dist/kit/_typescript/theme/theme.d.ts +24 -0
- package/npm_dist/kit/_typescript/theme/theme.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/theme/theme.js +133 -0
- package/npm_dist/kit/_typescript/theme/theme.js.map +7 -0
- package/npm_dist/kit/_typescript/url/url.d.ts +30 -0
- package/npm_dist/kit/_typescript/url/url.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/url/url.js +100 -0
- package/npm_dist/kit/_typescript/url/url.js.map +7 -0
- package/package.json +135 -3
- package/tsconfig.base.json +17 -0
- package/index.js +0 -1
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { h, type JSX } from "preact";
|
|
2
|
+
import { memo } from "preact/compat";
|
|
3
|
+
import type {
|
|
4
|
+
ExtractApp,
|
|
5
|
+
PermissivePatternBasedProps,
|
|
6
|
+
VormaAppBase,
|
|
7
|
+
VormaLoaderPattern,
|
|
8
|
+
} from "vorma/client";
|
|
9
|
+
import {
|
|
10
|
+
__makeFinalLinkProps,
|
|
11
|
+
__resolvePath,
|
|
12
|
+
type VormaAppConfig,
|
|
13
|
+
type VormaLinkPropsBase,
|
|
14
|
+
} from "vorma/client";
|
|
15
|
+
|
|
16
|
+
export const VormaLink = memo(function VormaLink(
|
|
17
|
+
props: JSX.HTMLAttributes<HTMLAnchorElement> &
|
|
18
|
+
VormaLinkPropsBase<
|
|
19
|
+
(
|
|
20
|
+
e: JSX.TargetedMouseEvent<HTMLAnchorElement>,
|
|
21
|
+
) => void | Promise<void>
|
|
22
|
+
>,
|
|
23
|
+
) {
|
|
24
|
+
const finalLinkProps = __makeFinalLinkProps(props);
|
|
25
|
+
// oxlint-disable-next-line no-unused-vars
|
|
26
|
+
const { prefetch, scrollToTop, replace, state, ...rest } = props;
|
|
27
|
+
|
|
28
|
+
return h(
|
|
29
|
+
"a",
|
|
30
|
+
{
|
|
31
|
+
"data-external": finalLinkProps.dataExternal,
|
|
32
|
+
...(rest as any),
|
|
33
|
+
onPointerEnter: finalLinkProps.onPointerEnter,
|
|
34
|
+
onFocus: finalLinkProps.onFocus,
|
|
35
|
+
onPointerLeave: finalLinkProps.onPointerLeave,
|
|
36
|
+
onBlur: finalLinkProps.onBlur,
|
|
37
|
+
onTouchCancel: finalLinkProps.onTouchCancel,
|
|
38
|
+
onClick: finalLinkProps.onClick,
|
|
39
|
+
},
|
|
40
|
+
props.children,
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
type TypedVormaLinkProps<
|
|
45
|
+
App extends VormaAppBase,
|
|
46
|
+
Pattern extends VormaLoaderPattern<App> = VormaLoaderPattern<App>,
|
|
47
|
+
> = Omit<JSX.HTMLAttributes<HTMLAnchorElement>, "href" | "pattern"> &
|
|
48
|
+
VormaLinkPropsBase<
|
|
49
|
+
(e: JSX.TargetedMouseEvent<HTMLAnchorElement>) => void | Promise<void>
|
|
50
|
+
> &
|
|
51
|
+
PermissivePatternBasedProps<App, Pattern> & {
|
|
52
|
+
search?: string;
|
|
53
|
+
hash?: string;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export function makeTypedLink<C extends VormaAppConfig>(
|
|
57
|
+
vormaAppConfig: C,
|
|
58
|
+
defaultProps?: Partial<
|
|
59
|
+
Omit<
|
|
60
|
+
TypedVormaLinkProps<ExtractApp<C>>,
|
|
61
|
+
"pattern" | "params" | "splatValues"
|
|
62
|
+
>
|
|
63
|
+
>,
|
|
64
|
+
) {
|
|
65
|
+
type App = ExtractApp<C>;
|
|
66
|
+
|
|
67
|
+
const TypedLink = memo(function TypedLink<
|
|
68
|
+
Pattern extends VormaLoaderPattern<App>,
|
|
69
|
+
>(props: TypedVormaLinkProps<App, Pattern>) {
|
|
70
|
+
const {
|
|
71
|
+
pattern,
|
|
72
|
+
params,
|
|
73
|
+
splatValues,
|
|
74
|
+
search,
|
|
75
|
+
hash,
|
|
76
|
+
state,
|
|
77
|
+
...linkProps
|
|
78
|
+
} = props as any;
|
|
79
|
+
|
|
80
|
+
const href = __resolvePath({
|
|
81
|
+
vormaAppConfig,
|
|
82
|
+
type: "loader",
|
|
83
|
+
props: {
|
|
84
|
+
pattern,
|
|
85
|
+
...(params && { params }),
|
|
86
|
+
...(splatValues && { splatValues }),
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const url = new URL(href, window.location.origin);
|
|
91
|
+
if (search !== undefined) url.search = search;
|
|
92
|
+
if (hash !== undefined) url.hash = hash;
|
|
93
|
+
|
|
94
|
+
const finalProps = {
|
|
95
|
+
...defaultProps,
|
|
96
|
+
...linkProps,
|
|
97
|
+
href: url.href,
|
|
98
|
+
state,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
return h(VormaLink, finalProps);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
(TypedLink as any).displayName =
|
|
105
|
+
`TypedLink(${Object.keys(defaultProps || {}).join(", ")})`;
|
|
106
|
+
return TypedLink;
|
|
107
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { batch, computed, effect, signal } from "@preact/signals";
|
|
2
|
+
import { h } from "preact";
|
|
3
|
+
import { useEffect, useLayoutEffect, useMemo, useRef } from "preact/hooks";
|
|
4
|
+
import {
|
|
5
|
+
__applyScrollState,
|
|
6
|
+
addLocationListener,
|
|
7
|
+
addRouteChangeListener,
|
|
8
|
+
__vormaClientGlobal as ctx,
|
|
9
|
+
getLocation,
|
|
10
|
+
getRouterData,
|
|
11
|
+
type RouteChangeEvent,
|
|
12
|
+
} from "vorma/client";
|
|
13
|
+
|
|
14
|
+
/////////////////////////////////////////////////////////////////////
|
|
15
|
+
/////// CORE SETUP
|
|
16
|
+
/////////////////////////////////////////////////////////////////////
|
|
17
|
+
|
|
18
|
+
const latestEvent = signal<RouteChangeEvent | null>(null);
|
|
19
|
+
const loadersData = signal(ctx.get("loadersData"));
|
|
20
|
+
const clientLoadersData = signal(ctx.get("clientLoadersData"));
|
|
21
|
+
const routerData = signal(getRouterData());
|
|
22
|
+
const outermostErrorIdx = signal(ctx.get("outermostErrorIdx"));
|
|
23
|
+
const outermostError = signal(ctx.get("outermostError"));
|
|
24
|
+
const activeComponents = signal(ctx.get("activeComponents"));
|
|
25
|
+
const activeErrorBoundary = signal(ctx.get("activeErrorBoundary"));
|
|
26
|
+
const importURLs = signal(ctx.get("importURLs"));
|
|
27
|
+
const exportKeys = signal(ctx.get("exportKeys"));
|
|
28
|
+
|
|
29
|
+
export { clientLoadersData, loadersData, routerData };
|
|
30
|
+
|
|
31
|
+
let isInited = false;
|
|
32
|
+
|
|
33
|
+
function initUIListeners() {
|
|
34
|
+
if (isInited) return;
|
|
35
|
+
isInited = true;
|
|
36
|
+
|
|
37
|
+
addRouteChangeListener((e) => {
|
|
38
|
+
batch(() => {
|
|
39
|
+
latestEvent.value = e;
|
|
40
|
+
loadersData.value = ctx.get("loadersData");
|
|
41
|
+
clientLoadersData.value = ctx.get("clientLoadersData");
|
|
42
|
+
routerData.value = getRouterData();
|
|
43
|
+
outermostErrorIdx.value = ctx.get("outermostErrorIdx");
|
|
44
|
+
outermostError.value = ctx.get("outermostError");
|
|
45
|
+
activeComponents.value = ctx.get("activeComponents");
|
|
46
|
+
activeErrorBoundary.value = ctx.get("activeErrorBoundary");
|
|
47
|
+
importURLs.value = ctx.get("importURLs");
|
|
48
|
+
exportKeys.value = ctx.get("exportKeys");
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
addLocationListener(() => {
|
|
53
|
+
location.value = getLocation();
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const location = signal(getLocation());
|
|
58
|
+
|
|
59
|
+
/////////////////////////////////////////////////////////////////////
|
|
60
|
+
/////// COMPONENT
|
|
61
|
+
/////////////////////////////////////////////////////////////////////
|
|
62
|
+
|
|
63
|
+
export function VormaRootOutlet(props: { idx?: number }): h.JSX.Element {
|
|
64
|
+
const idx = props.idx ?? 0;
|
|
65
|
+
|
|
66
|
+
const initialRenderRef = useRef(true);
|
|
67
|
+
|
|
68
|
+
if (idx === 0 && initialRenderRef.current) {
|
|
69
|
+
initUIListeners();
|
|
70
|
+
|
|
71
|
+
initialRenderRef.current = false;
|
|
72
|
+
batch(() => {
|
|
73
|
+
loadersData.value = ctx.get("loadersData");
|
|
74
|
+
clientLoadersData.value = ctx.get("clientLoadersData");
|
|
75
|
+
routerData.value = getRouterData();
|
|
76
|
+
outermostError.value = ctx.get("outermostError");
|
|
77
|
+
outermostErrorIdx.value = ctx.get("outermostErrorIdx");
|
|
78
|
+
activeComponents.value = ctx.get("activeComponents");
|
|
79
|
+
activeErrorBoundary.value = ctx.get("activeErrorBoundary");
|
|
80
|
+
importURLs.value = ctx.get("importURLs");
|
|
81
|
+
exportKeys.value = ctx.get("exportKeys");
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const currentImportURL = signal(importURLs.value[idx]);
|
|
86
|
+
const currentExportKey = signal(exportKeys.value[idx]);
|
|
87
|
+
const nextImportURL = signal(importURLs.value[idx + 1]);
|
|
88
|
+
const nextExportKey = signal(exportKeys.value[idx + 1]);
|
|
89
|
+
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
const dispose = effect(() => {
|
|
92
|
+
if (!currentImportURL.value || !latestEvent.value) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
batch(() => {
|
|
97
|
+
const newCurrentImportURL = importURLs.value[idx];
|
|
98
|
+
const newCurrentExportKey = exportKeys.value[idx];
|
|
99
|
+
|
|
100
|
+
if (currentImportURL.value !== newCurrentImportURL) {
|
|
101
|
+
currentImportURL.value = newCurrentImportURL;
|
|
102
|
+
}
|
|
103
|
+
if (currentExportKey.value !== newCurrentExportKey) {
|
|
104
|
+
currentExportKey.value = newCurrentExportKey;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// these are also needed for Outlets to render correctly
|
|
108
|
+
const newNextImportURL = importURLs.value[idx + 1];
|
|
109
|
+
const newNextExportKey = exportKeys.value[idx + 1];
|
|
110
|
+
|
|
111
|
+
if (nextImportURL.value !== newNextImportURL) {
|
|
112
|
+
nextImportURL.value = newNextImportURL;
|
|
113
|
+
}
|
|
114
|
+
if (nextExportKey.value !== newNextExportKey) {
|
|
115
|
+
nextExportKey.value = newNextExportKey;
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
return dispose;
|
|
121
|
+
}, [idx]);
|
|
122
|
+
|
|
123
|
+
useLayoutEffect(() => {
|
|
124
|
+
const dispose = effect(() => {
|
|
125
|
+
const event = latestEvent.value;
|
|
126
|
+
if (!event || idx !== 0) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
window.requestAnimationFrame(() => {
|
|
130
|
+
__applyScrollState(event.detail.__scrollState);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
return dispose;
|
|
135
|
+
}, [idx]);
|
|
136
|
+
|
|
137
|
+
const isErrorIdx = computed(() => idx === outermostErrorIdx.value);
|
|
138
|
+
|
|
139
|
+
const CurrentComp = computed(() => {
|
|
140
|
+
if (isErrorIdx.value) {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
currentImportURL.value;
|
|
144
|
+
currentExportKey.value;
|
|
145
|
+
return activeComponents.value?.[idx];
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const Outlet = useMemo(
|
|
149
|
+
() => (localProps: Record<string, any> | undefined) => {
|
|
150
|
+
return h(VormaRootOutlet, {
|
|
151
|
+
...localProps,
|
|
152
|
+
...props,
|
|
153
|
+
idx: idx + 1,
|
|
154
|
+
});
|
|
155
|
+
},
|
|
156
|
+
[nextImportURL.value, nextExportKey.value],
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
const shouldFallbackOutlet = computed(() => {
|
|
160
|
+
if (isErrorIdx.value) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
if (CurrentComp.value) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
return idx + 1 < loadersData.value.length;
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
const ErrorComp = computed(() => {
|
|
170
|
+
if (!isErrorIdx.value) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
return activeErrorBoundary.value;
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
if (isErrorIdx.value) {
|
|
177
|
+
if (ErrorComp.value) {
|
|
178
|
+
return h(ErrorComp.value, { error: outermostError.value });
|
|
179
|
+
}
|
|
180
|
+
return h("div", {}, `Error: ${outermostError.value || "unknown"}`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (!CurrentComp.value) {
|
|
184
|
+
if (shouldFallbackOutlet.value) {
|
|
185
|
+
return h(Outlet, {});
|
|
186
|
+
}
|
|
187
|
+
return h("div", {});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return h(CurrentComp.value, { idx, Outlet });
|
|
191
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export {
|
|
2
|
+
makeTypedAddClientLoader,
|
|
3
|
+
makeTypedUseLoaderData,
|
|
4
|
+
makeTypedUsePatternLoaderData,
|
|
5
|
+
makeTypedUseRouterData,
|
|
6
|
+
type VormaRoute,
|
|
7
|
+
type VormaRouteProps,
|
|
8
|
+
} from "./src/helpers.ts";
|
|
9
|
+
export { VormaLink, makeTypedLink } from "./src/link.tsx";
|
|
10
|
+
export { VormaRootOutlet, useLocation } from "./src/react.tsx";
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
2
|
+
|
|
3
|
+
import { useMemo, type JSX } from "react";
|
|
4
|
+
import {
|
|
5
|
+
__registerClientLoaderPattern,
|
|
6
|
+
__runClientLoadersAfterHMRUpdate,
|
|
7
|
+
__vormaClientGlobal,
|
|
8
|
+
type ClientLoaderAwaitedServerData,
|
|
9
|
+
type ParamsForPattern,
|
|
10
|
+
type UseRouterDataFunction,
|
|
11
|
+
type VormaAppBase,
|
|
12
|
+
type VormaLoaderOutput,
|
|
13
|
+
type VormaLoaderPattern,
|
|
14
|
+
type VormaRouteGeneric,
|
|
15
|
+
type VormaRoutePropsGeneric,
|
|
16
|
+
} from "vorma/client";
|
|
17
|
+
import {
|
|
18
|
+
useClientLoadersData,
|
|
19
|
+
useLoadersData,
|
|
20
|
+
useRouterData,
|
|
21
|
+
} from "./react.tsx";
|
|
22
|
+
|
|
23
|
+
export type VormaRouteProps<
|
|
24
|
+
App extends VormaAppBase = any,
|
|
25
|
+
Pattern extends VormaLoaderPattern<App> = string,
|
|
26
|
+
> = VormaRoutePropsGeneric<JSX.Element, App, Pattern>;
|
|
27
|
+
|
|
28
|
+
export type VormaRoute<
|
|
29
|
+
App extends VormaAppBase = any,
|
|
30
|
+
Pattern extends VormaLoaderPattern<App> = string,
|
|
31
|
+
> = VormaRouteGeneric<JSX.Element, App, Pattern>;
|
|
32
|
+
|
|
33
|
+
export function makeTypedUseRouterData<App extends VormaAppBase>() {
|
|
34
|
+
return useRouterData as UseRouterDataFunction<App, false>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function makeTypedUseLoaderData<App extends VormaAppBase>() {
|
|
38
|
+
return function useLoaderData<Pattern extends VormaLoaderPattern<App>>(
|
|
39
|
+
props: VormaRouteProps<App, Pattern>,
|
|
40
|
+
): VormaLoaderOutput<App, Pattern> {
|
|
41
|
+
const loadersData = useLoadersData();
|
|
42
|
+
return loadersData[props.idx];
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function makeTypedUsePatternLoaderData<App extends VormaAppBase>() {
|
|
47
|
+
return function usePatternLoaderData<
|
|
48
|
+
Pattern extends VormaLoaderPattern<App>,
|
|
49
|
+
>(pattern: Pattern): VormaLoaderOutput<App, Pattern> | undefined {
|
|
50
|
+
const routerData = useRouterData();
|
|
51
|
+
const loadersData = useLoadersData();
|
|
52
|
+
const idx = useMemo(() => {
|
|
53
|
+
return routerData.matchedPatterns.findIndex((p) => p === pattern);
|
|
54
|
+
}, [routerData.matchedPatterns, pattern]);
|
|
55
|
+
|
|
56
|
+
if (idx === -1) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
return loadersData[idx];
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function makeTypedAddClientLoader<App extends VormaAppBase>() {
|
|
64
|
+
const m = __vormaClientGlobal.get("patternToWaitFnMap");
|
|
65
|
+
return function addClientLoader<
|
|
66
|
+
Pattern extends VormaLoaderPattern<App>,
|
|
67
|
+
LoaderData extends VormaLoaderOutput<App, Pattern>,
|
|
68
|
+
T = any,
|
|
69
|
+
>(props: {
|
|
70
|
+
pattern: Pattern;
|
|
71
|
+
clientLoader: (props: {
|
|
72
|
+
params: Record<ParamsForPattern<App, Pattern>, string>;
|
|
73
|
+
splatValues: string[];
|
|
74
|
+
serverDataPromise: Promise<
|
|
75
|
+
ClientLoaderAwaitedServerData<App["rootData"], LoaderData>
|
|
76
|
+
>;
|
|
77
|
+
signal: AbortSignal;
|
|
78
|
+
}) => Promise<T>;
|
|
79
|
+
reRunOnModuleChange?: ImportMeta;
|
|
80
|
+
}) {
|
|
81
|
+
const p = props.pattern;
|
|
82
|
+
const fn = props.clientLoader;
|
|
83
|
+
|
|
84
|
+
__registerClientLoaderPattern(p as string).catch((error) => {
|
|
85
|
+
console.error("Failed to register client loader pattern:", error);
|
|
86
|
+
});
|
|
87
|
+
(m as any)[p] = fn;
|
|
88
|
+
|
|
89
|
+
if (import.meta.env.DEV && props.reRunOnModuleChange) {
|
|
90
|
+
__runClientLoadersAfterHMRUpdate(props.reRunOnModuleChange, p);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
type Res = Awaited<ReturnType<typeof fn>>;
|
|
94
|
+
|
|
95
|
+
const useClientLoaderData = (
|
|
96
|
+
props?: VormaRouteProps<App, Pattern>,
|
|
97
|
+
): Res | undefined => {
|
|
98
|
+
const clientLoadersData = useClientLoadersData();
|
|
99
|
+
const routerData = useRouterData();
|
|
100
|
+
|
|
101
|
+
const idx = useMemo(() => {
|
|
102
|
+
if (props) {
|
|
103
|
+
return props.idx;
|
|
104
|
+
}
|
|
105
|
+
const matched = routerData.matchedPatterns;
|
|
106
|
+
return matched.findIndex((pattern) => pattern === p);
|
|
107
|
+
}, [props, routerData.matchedPatterns]);
|
|
108
|
+
|
|
109
|
+
if (idx === -1) return undefined;
|
|
110
|
+
return clientLoadersData[idx];
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
return useClientLoaderData as {
|
|
114
|
+
(props: VormaRouteProps<App, Pattern>): Res;
|
|
115
|
+
(): Res | undefined;
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { memo, type ComponentProps, type JSX } from "react";
|
|
2
|
+
import type {
|
|
3
|
+
ExtractApp,
|
|
4
|
+
PermissivePatternBasedProps,
|
|
5
|
+
VormaAppBase,
|
|
6
|
+
VormaLoaderPattern,
|
|
7
|
+
} from "vorma/client";
|
|
8
|
+
import {
|
|
9
|
+
__makeFinalLinkProps,
|
|
10
|
+
__resolvePath,
|
|
11
|
+
type VormaAppConfig,
|
|
12
|
+
type VormaLinkPropsBase,
|
|
13
|
+
} from "vorma/client";
|
|
14
|
+
|
|
15
|
+
export const VormaLink = memo(function VormaLink(
|
|
16
|
+
props: ComponentProps<"a"> &
|
|
17
|
+
VormaLinkPropsBase<
|
|
18
|
+
(
|
|
19
|
+
e: React.MouseEvent<HTMLAnchorElement, MouseEvent>,
|
|
20
|
+
) => void | Promise<void>
|
|
21
|
+
>,
|
|
22
|
+
) {
|
|
23
|
+
const finalLinkProps = __makeFinalLinkProps(props);
|
|
24
|
+
// oxlint-disable-next-line no-unused-vars
|
|
25
|
+
const { prefetch, scrollToTop, replace, state, ...rest } = props;
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<a
|
|
29
|
+
data-external={finalLinkProps.dataExternal}
|
|
30
|
+
{...(rest as any)}
|
|
31
|
+
onPointerEnter={finalLinkProps.onPointerEnter}
|
|
32
|
+
onFocus={finalLinkProps.onFocus}
|
|
33
|
+
onPointerLeave={finalLinkProps.onPointerLeave}
|
|
34
|
+
onBlur={finalLinkProps.onBlur}
|
|
35
|
+
onTouchCancel={finalLinkProps.onTouchCancel}
|
|
36
|
+
onClick={finalLinkProps.onClick}
|
|
37
|
+
>
|
|
38
|
+
{props.children}
|
|
39
|
+
</a>
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
type TypedVormaLinkProps<
|
|
44
|
+
App extends VormaAppBase,
|
|
45
|
+
Pattern extends VormaLoaderPattern<App> = VormaLoaderPattern<App>,
|
|
46
|
+
> = Omit<ComponentProps<"a">, "href" | "pattern"> &
|
|
47
|
+
VormaLinkPropsBase<
|
|
48
|
+
(
|
|
49
|
+
e: React.MouseEvent<HTMLAnchorElement, MouseEvent>,
|
|
50
|
+
) => void | Promise<void>
|
|
51
|
+
> &
|
|
52
|
+
PermissivePatternBasedProps<App, Pattern> & {
|
|
53
|
+
search?: string;
|
|
54
|
+
hash?: string;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export function makeTypedLink<C extends VormaAppConfig>(
|
|
58
|
+
vormaAppConfig: C,
|
|
59
|
+
defaultProps?: Partial<
|
|
60
|
+
Omit<
|
|
61
|
+
TypedVormaLinkProps<ExtractApp<C>>,
|
|
62
|
+
"pattern" | "params" | "splatValues"
|
|
63
|
+
>
|
|
64
|
+
>,
|
|
65
|
+
) {
|
|
66
|
+
type App = ExtractApp<C>;
|
|
67
|
+
|
|
68
|
+
const TypedLink = <Pattern extends VormaLoaderPattern<App>>(
|
|
69
|
+
props: TypedVormaLinkProps<App, Pattern>,
|
|
70
|
+
) => {
|
|
71
|
+
const {
|
|
72
|
+
pattern,
|
|
73
|
+
params,
|
|
74
|
+
splatValues,
|
|
75
|
+
search,
|
|
76
|
+
hash,
|
|
77
|
+
state,
|
|
78
|
+
...linkProps
|
|
79
|
+
} = props as any;
|
|
80
|
+
|
|
81
|
+
const href = __resolvePath({
|
|
82
|
+
vormaAppConfig,
|
|
83
|
+
type: "loader",
|
|
84
|
+
props: {
|
|
85
|
+
pattern,
|
|
86
|
+
...(params && { params }),
|
|
87
|
+
...(splatValues && { splatValues }),
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const url = new URL(href, window.location.origin);
|
|
92
|
+
if (search !== undefined) url.search = search;
|
|
93
|
+
if (hash !== undefined) url.hash = hash;
|
|
94
|
+
|
|
95
|
+
const finalProps = {
|
|
96
|
+
...defaultProps,
|
|
97
|
+
...linkProps,
|
|
98
|
+
href: url.href,
|
|
99
|
+
state,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
return <VormaLink {...finalProps} />;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const MemoizedTypedLink = memo(TypedLink) as <
|
|
106
|
+
Pattern extends VormaLoaderPattern<App>,
|
|
107
|
+
>(
|
|
108
|
+
props: TypedVormaLinkProps<App, Pattern>,
|
|
109
|
+
) => JSX.Element;
|
|
110
|
+
|
|
111
|
+
(MemoizedTypedLink as any).displayName =
|
|
112
|
+
`TypedLink(${Object.keys(defaultProps || {}).join(", ")})`;
|
|
113
|
+
|
|
114
|
+
return MemoizedTypedLink;
|
|
115
|
+
}
|