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.
Files changed (225) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +48 -0
  3. package/internal/framework/_typescript/client/index.ts +64 -0
  4. package/internal/framework/_typescript/client/src/asset_manager.ts +67 -0
  5. package/internal/framework/_typescript/client/src/client.ts +1201 -0
  6. package/internal/framework/_typescript/client/src/client_loaders.ts +249 -0
  7. package/internal/framework/_typescript/client/src/component_loader.ts +105 -0
  8. package/internal/framework/_typescript/client/src/error_boundary.ts +7 -0
  9. package/internal/framework/_typescript/client/src/events.ts +54 -0
  10. package/internal/framework/_typescript/client/src/global_loading_indicator/global_loading_indicator.ts +125 -0
  11. package/internal/framework/_typescript/client/src/hard_reload.ts +1 -0
  12. package/internal/framework/_typescript/client/src/head_elements/head_elements.ts +193 -0
  13. package/internal/framework/_typescript/client/src/history/history.ts +118 -0
  14. package/internal/framework/_typescript/client/src/history/npm_history_types.ts +83 -0
  15. package/internal/framework/_typescript/client/src/hmr/hmr.ts +71 -0
  16. package/internal/framework/_typescript/client/src/init_client.ts +134 -0
  17. package/internal/framework/_typescript/client/src/links.ts +218 -0
  18. package/internal/framework/_typescript/client/src/redirects/redirects.ts +203 -0
  19. package/internal/framework/_typescript/client/src/rendering.ts +135 -0
  20. package/internal/framework/_typescript/client/src/resolve_public_href.ts +15 -0
  21. package/internal/framework/_typescript/client/src/scroll_state_manager.ts +100 -0
  22. package/internal/framework/_typescript/client/src/static_route_defs/route_def_helpers.ts +22 -0
  23. package/internal/framework/_typescript/client/src/ui_lib_impl_helpers/link_components.ts +131 -0
  24. package/internal/framework/_typescript/client/src/ui_lib_impl_helpers/route_components.ts +56 -0
  25. package/internal/framework/_typescript/client/src/ui_lib_impl_helpers/typed_navigate.ts +58 -0
  26. package/internal/framework/_typescript/client/src/utils/errors.ts +10 -0
  27. package/internal/framework/_typescript/client/src/utils/logging.ts +7 -0
  28. package/internal/framework/_typescript/client/src/vorma_app_helpers/vorma_app_helpers.ts +290 -0
  29. package/internal/framework/_typescript/client/src/vorma_ctx/vorma_ctx.ts +128 -0
  30. package/internal/framework/_typescript/client/src/window_focus_revalidation/window_focus_revalidation.ts +32 -0
  31. package/internal/framework/_typescript/client/tsconfig.json +3 -0
  32. package/internal/framework/_typescript/create/main.ts +378 -0
  33. package/internal/framework/_typescript/create/package.json +33 -0
  34. package/internal/framework/_typescript/create/pnpm-lock.yaml +70 -0
  35. package/internal/framework/_typescript/create/tsconfig.json +3 -0
  36. package/internal/framework/_typescript/preact/index.tsx +10 -0
  37. package/internal/framework/_typescript/preact/src/helpers.ts +113 -0
  38. package/internal/framework/_typescript/preact/src/link.tsx +107 -0
  39. package/internal/framework/_typescript/preact/src/preact.tsx +191 -0
  40. package/internal/framework/_typescript/preact/tsconfig.json +7 -0
  41. package/internal/framework/_typescript/react/index.tsx +10 -0
  42. package/internal/framework/_typescript/react/src/helpers.ts +118 -0
  43. package/internal/framework/_typescript/react/src/link.tsx +115 -0
  44. package/internal/framework/_typescript/react/src/react.tsx +299 -0
  45. package/internal/framework/_typescript/react/tsconfig.json +6 -0
  46. package/internal/framework/_typescript/solid/index.tsx +10 -0
  47. package/internal/framework/_typescript/solid/src/helpers.ts +114 -0
  48. package/internal/framework/_typescript/solid/src/link.tsx +104 -0
  49. package/internal/framework/_typescript/solid/src/solid.tsx +204 -0
  50. package/internal/framework/_typescript/solid/tsconfig.json +7 -0
  51. package/internal/framework/_typescript/vite/tsconfig.json +3 -0
  52. package/internal/framework/_typescript/vite/vite.ts +93 -0
  53. package/internal/site/frontend/assets/vorma-banner.webp +0 -0
  54. package/kit/_typescript/converters/converters.ts +152 -0
  55. package/kit/_typescript/cookies/cookies.ts +18 -0
  56. package/kit/_typescript/csrf/csrf.ts +10 -0
  57. package/kit/_typescript/debounce/debounce.ts +17 -0
  58. package/kit/_typescript/fmt/fmt.ts +3 -0
  59. package/kit/_typescript/json/deep_equals.ts +54 -0
  60. package/kit/_typescript/json/json.ts +3 -0
  61. package/kit/_typescript/json/search_param_serializer.ts +49 -0
  62. package/kit/_typescript/json/stringify_stable.ts +43 -0
  63. package/kit/_typescript/listeners/listeners.ts +16 -0
  64. package/kit/_typescript/matcher/find_best_match.ts +205 -0
  65. package/kit/_typescript/matcher/find_nested_matches.ts +357 -0
  66. package/kit/_typescript/matcher/parse_segments.ts +30 -0
  67. package/kit/_typescript/matcher/register.ts +271 -0
  68. package/kit/_typescript/theme/theme.ts +177 -0
  69. package/kit/_typescript/tsconfig.json +3 -0
  70. package/kit/_typescript/url/url.ts +132 -0
  71. package/npm_dist/internal/framework/_typescript/client/index.d.ts +17 -0
  72. package/npm_dist/internal/framework/_typescript/client/index.d.ts.map +1 -0
  73. package/npm_dist/internal/framework/_typescript/client/index.js +2489 -0
  74. package/npm_dist/internal/framework/_typescript/client/index.js.map +7 -0
  75. package/npm_dist/internal/framework/_typescript/client/src/asset_manager.d.ts +6 -0
  76. package/npm_dist/internal/framework/_typescript/client/src/asset_manager.d.ts.map +1 -0
  77. package/npm_dist/internal/framework/_typescript/client/src/client.d.ts +119 -0
  78. package/npm_dist/internal/framework/_typescript/client/src/client.d.ts.map +1 -0
  79. package/npm_dist/internal/framework/_typescript/client/src/client_loaders.d.ts +18 -0
  80. package/npm_dist/internal/framework/_typescript/client/src/client_loaders.d.ts.map +1 -0
  81. package/npm_dist/internal/framework/_typescript/client/src/component_loader.d.ts +10 -0
  82. package/npm_dist/internal/framework/_typescript/client/src/component_loader.d.ts.map +1 -0
  83. package/npm_dist/internal/framework/_typescript/client/src/error_boundary.d.ts +3 -0
  84. package/npm_dist/internal/framework/_typescript/client/src/error_boundary.d.ts.map +1 -0
  85. package/npm_dist/internal/framework/_typescript/client/src/events.d.ts +26 -0
  86. package/npm_dist/internal/framework/_typescript/client/src/events.d.ts.map +1 -0
  87. package/npm_dist/internal/framework/_typescript/client/src/global_loading_indicator/global_loading_indicator.d.ts +12 -0
  88. package/npm_dist/internal/framework/_typescript/client/src/global_loading_indicator/global_loading_indicator.d.ts.map +1 -0
  89. package/npm_dist/internal/framework/_typescript/client/src/hard_reload.d.ts +2 -0
  90. package/npm_dist/internal/framework/_typescript/client/src/hard_reload.d.ts.map +1 -0
  91. package/npm_dist/internal/framework/_typescript/client/src/head_elements/head_elements.d.ts +7 -0
  92. package/npm_dist/internal/framework/_typescript/client/src/head_elements/head_elements.d.ts.map +1 -0
  93. package/npm_dist/internal/framework/_typescript/client/src/history/history.d.ts +14 -0
  94. package/npm_dist/internal/framework/_typescript/client/src/history/history.d.ts.map +1 -0
  95. package/npm_dist/internal/framework/_typescript/client/src/history/npm_history_types.d.ts +84 -0
  96. package/npm_dist/internal/framework/_typescript/client/src/history/npm_history_types.d.ts.map +1 -0
  97. package/npm_dist/internal/framework/_typescript/client/src/hmr/hmr.d.ts +3 -0
  98. package/npm_dist/internal/framework/_typescript/client/src/hmr/hmr.d.ts.map +1 -0
  99. package/npm_dist/internal/framework/_typescript/client/src/init_client.d.ts +9 -0
  100. package/npm_dist/internal/framework/_typescript/client/src/init_client.d.ts.map +1 -0
  101. package/npm_dist/internal/framework/_typescript/client/src/links.d.ts +33 -0
  102. package/npm_dist/internal/framework/_typescript/client/src/links.d.ts.map +1 -0
  103. package/npm_dist/internal/framework/_typescript/client/src/redirects/redirects.d.ts +26 -0
  104. package/npm_dist/internal/framework/_typescript/client/src/redirects/redirects.d.ts.map +1 -0
  105. package/npm_dist/internal/framework/_typescript/client/src/rendering.d.ts +18 -0
  106. package/npm_dist/internal/framework/_typescript/client/src/rendering.d.ts.map +1 -0
  107. package/npm_dist/internal/framework/_typescript/client/src/resolve_public_href.d.ts +2 -0
  108. package/npm_dist/internal/framework/_typescript/client/src/resolve_public_href.d.ts.map +1 -0
  109. package/npm_dist/internal/framework/_typescript/client/src/scroll_state_manager.d.ts +22 -0
  110. package/npm_dist/internal/framework/_typescript/client/src/scroll_state_manager.d.ts.map +1 -0
  111. package/npm_dist/internal/framework/_typescript/client/src/static_route_defs/route_def_helpers.d.ts +12 -0
  112. package/npm_dist/internal/framework/_typescript/client/src/static_route_defs/route_def_helpers.d.ts.map +1 -0
  113. package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/link_components.d.ts +28 -0
  114. package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/link_components.d.ts.map +1 -0
  115. package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/route_components.d.ts +18 -0
  116. package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/route_components.d.ts.map +1 -0
  117. package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/typed_navigate.d.ts +11 -0
  118. package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/typed_navigate.d.ts.map +1 -0
  119. package/npm_dist/internal/framework/_typescript/client/src/utils/errors.d.ts +3 -0
  120. package/npm_dist/internal/framework/_typescript/client/src/utils/errors.d.ts.map +1 -0
  121. package/npm_dist/internal/framework/_typescript/client/src/utils/logging.d.ts +3 -0
  122. package/npm_dist/internal/framework/_typescript/client/src/utils/logging.d.ts.map +1 -0
  123. package/npm_dist/internal/framework/_typescript/client/src/vorma_app_helpers/vorma_app_helpers.d.ts +119 -0
  124. package/npm_dist/internal/framework/_typescript/client/src/vorma_app_helpers/vorma_app_helpers.d.ts.map +1 -0
  125. package/npm_dist/internal/framework/_typescript/client/src/vorma_ctx/vorma_ctx.d.ts +88 -0
  126. package/npm_dist/internal/framework/_typescript/client/src/vorma_ctx/vorma_ctx.d.ts.map +1 -0
  127. package/npm_dist/internal/framework/_typescript/client/src/window_focus_revalidation/window_focus_revalidation.d.ts +10 -0
  128. package/npm_dist/internal/framework/_typescript/client/src/window_focus_revalidation/window_focus_revalidation.d.ts.map +1 -0
  129. package/npm_dist/internal/framework/_typescript/create/main.d.ts +3 -0
  130. package/npm_dist/internal/framework/_typescript/create/main.d.ts.map +1 -0
  131. package/npm_dist/internal/framework/_typescript/preact/index.d.ts +4 -0
  132. package/npm_dist/internal/framework/_typescript/preact/index.d.ts.map +1 -0
  133. package/npm_dist/internal/framework/_typescript/preact/index.js +283 -0
  134. package/npm_dist/internal/framework/_typescript/preact/index.js.map +7 -0
  135. package/npm_dist/internal/framework/_typescript/preact/src/helpers.d.ts +21 -0
  136. package/npm_dist/internal/framework/_typescript/preact/src/helpers.d.ts.map +1 -0
  137. package/npm_dist/internal/framework/_typescript/preact/src/link.d.ts +11 -0
  138. package/npm_dist/internal/framework/_typescript/preact/src/link.d.ts.map +1 -0
  139. package/npm_dist/internal/framework/_typescript/preact/src/preact.d.ts +21 -0
  140. package/npm_dist/internal/framework/_typescript/preact/src/preact.d.ts.map +1 -0
  141. package/npm_dist/internal/framework/_typescript/react/index.d.ts +4 -0
  142. package/npm_dist/internal/framework/_typescript/react/index.d.ts.map +1 -0
  143. package/npm_dist/internal/framework/_typescript/react/index.js +370 -0
  144. package/npm_dist/internal/framework/_typescript/react/index.js.map +7 -0
  145. package/npm_dist/internal/framework/_typescript/react/src/helpers.d.ts +21 -0
  146. package/npm_dist/internal/framework/_typescript/react/src/helpers.d.ts.map +1 -0
  147. package/npm_dist/internal/framework/_typescript/react/src/link.d.ts +11 -0
  148. package/npm_dist/internal/framework/_typescript/react/src/link.d.ts.map +1 -0
  149. package/npm_dist/internal/framework/_typescript/react/src/react.d.ts +20 -0
  150. package/npm_dist/internal/framework/_typescript/react/src/react.d.ts.map +1 -0
  151. package/npm_dist/internal/framework/_typescript/solid/index.d.ts +4 -0
  152. package/npm_dist/internal/framework/_typescript/solid/index.d.ts.map +1 -0
  153. package/npm_dist/internal/framework/_typescript/solid/index.js +314 -0
  154. package/npm_dist/internal/framework/_typescript/solid/index.js.map +7 -0
  155. package/npm_dist/internal/framework/_typescript/solid/src/helpers.d.ts +22 -0
  156. package/npm_dist/internal/framework/_typescript/solid/src/helpers.d.ts.map +1 -0
  157. package/npm_dist/internal/framework/_typescript/solid/src/link.d.ts +11 -0
  158. package/npm_dist/internal/framework/_typescript/solid/src/link.d.ts.map +1 -0
  159. package/npm_dist/internal/framework/_typescript/solid/src/solid.d.ts +22 -0
  160. package/npm_dist/internal/framework/_typescript/solid/src/solid.d.ts.map +1 -0
  161. package/npm_dist/internal/framework/_typescript/vite/vite.d.ts +11 -0
  162. package/npm_dist/internal/framework/_typescript/vite/vite.d.ts.map +1 -0
  163. package/npm_dist/internal/framework/_typescript/vite/vite.js +82 -0
  164. package/npm_dist/internal/framework/_typescript/vite/vite.js.map +7 -0
  165. package/npm_dist/kit/_typescript/chunk-YBAPNBS2.js +202 -0
  166. package/npm_dist/kit/_typescript/chunk-YBAPNBS2.js.map +7 -0
  167. package/npm_dist/kit/_typescript/converters/converters.d.ts +26 -0
  168. package/npm_dist/kit/_typescript/converters/converters.d.ts.map +1 -0
  169. package/npm_dist/kit/_typescript/converters/converters.js +99 -0
  170. package/npm_dist/kit/_typescript/converters/converters.js.map +7 -0
  171. package/npm_dist/kit/_typescript/cookies/cookies.d.ts +13 -0
  172. package/npm_dist/kit/_typescript/cookies/cookies.d.ts.map +1 -0
  173. package/npm_dist/kit/_typescript/cookies/cookies.js +13 -0
  174. package/npm_dist/kit/_typescript/cookies/cookies.js.map +7 -0
  175. package/npm_dist/kit/_typescript/csrf/csrf.d.ts +5 -0
  176. package/npm_dist/kit/_typescript/csrf/csrf.d.ts.map +1 -0
  177. package/npm_dist/kit/_typescript/csrf/csrf.js +11 -0
  178. package/npm_dist/kit/_typescript/csrf/csrf.js.map +7 -0
  179. package/npm_dist/kit/_typescript/debounce/debounce.d.ts +4 -0
  180. package/npm_dist/kit/_typescript/debounce/debounce.d.ts.map +1 -0
  181. package/npm_dist/kit/_typescript/debounce/debounce.js +16 -0
  182. package/npm_dist/kit/_typescript/debounce/debounce.js.map +7 -0
  183. package/npm_dist/kit/_typescript/fmt/fmt.d.ts +2 -0
  184. package/npm_dist/kit/_typescript/fmt/fmt.d.ts.map +1 -0
  185. package/npm_dist/kit/_typescript/fmt/fmt.js +8 -0
  186. package/npm_dist/kit/_typescript/fmt/fmt.js.map +7 -0
  187. package/npm_dist/kit/_typescript/json/deep_equals.d.ts +7 -0
  188. package/npm_dist/kit/_typescript/json/deep_equals.d.ts.map +1 -0
  189. package/npm_dist/kit/_typescript/json/json.d.ts +4 -0
  190. package/npm_dist/kit/_typescript/json/json.d.ts.map +1 -0
  191. package/npm_dist/kit/_typescript/json/json.js +110 -0
  192. package/npm_dist/kit/_typescript/json/json.js.map +7 -0
  193. package/npm_dist/kit/_typescript/json/search_param_serializer.d.ts +2 -0
  194. package/npm_dist/kit/_typescript/json/search_param_serializer.d.ts.map +1 -0
  195. package/npm_dist/kit/_typescript/json/stringify_stable.d.ts +7 -0
  196. package/npm_dist/kit/_typescript/json/stringify_stable.d.ts.map +1 -0
  197. package/npm_dist/kit/_typescript/listeners/listeners.d.ts +2 -0
  198. package/npm_dist/kit/_typescript/listeners/listeners.d.ts.map +1 -0
  199. package/npm_dist/kit/_typescript/listeners/listeners.js +20 -0
  200. package/npm_dist/kit/_typescript/listeners/listeners.js.map +7 -0
  201. package/npm_dist/kit/_typescript/matcher/find_best_match.d.ts +10 -0
  202. package/npm_dist/kit/_typescript/matcher/find_best_match.d.ts.map +1 -0
  203. package/npm_dist/kit/_typescript/matcher/find_best_match.js +146 -0
  204. package/npm_dist/kit/_typescript/matcher/find_best_match.js.map +7 -0
  205. package/npm_dist/kit/_typescript/matcher/find_nested_matches.d.ts +14 -0
  206. package/npm_dist/kit/_typescript/matcher/find_nested_matches.d.ts.map +1 -0
  207. package/npm_dist/kit/_typescript/matcher/find_nested_matches.js +248 -0
  208. package/npm_dist/kit/_typescript/matcher/find_nested_matches.js.map +7 -0
  209. package/npm_dist/kit/_typescript/matcher/parse_segments.d.ts +2 -0
  210. package/npm_dist/kit/_typescript/matcher/parse_segments.d.ts.map +1 -0
  211. package/npm_dist/kit/_typescript/matcher/register.d.ts +54 -0
  212. package/npm_dist/kit/_typescript/matcher/register.d.ts.map +1 -0
  213. package/npm_dist/kit/_typescript/matcher/register.js +21 -0
  214. package/npm_dist/kit/_typescript/matcher/register.js.map +7 -0
  215. package/npm_dist/kit/_typescript/theme/theme.d.ts +24 -0
  216. package/npm_dist/kit/_typescript/theme/theme.d.ts.map +1 -0
  217. package/npm_dist/kit/_typescript/theme/theme.js +133 -0
  218. package/npm_dist/kit/_typescript/theme/theme.js.map +7 -0
  219. package/npm_dist/kit/_typescript/url/url.d.ts +30 -0
  220. package/npm_dist/kit/_typescript/url/url.d.ts.map +1 -0
  221. package/npm_dist/kit/_typescript/url/url.js +100 -0
  222. package/npm_dist/kit/_typescript/url/url.js.map +7 -0
  223. package/package.json +135 -3
  224. package/tsconfig.base.json +17 -0
  225. package/index.js +0 -1
@@ -0,0 +1,299 @@
1
+ import {
2
+ type JSX,
3
+ useEffect,
4
+ useLayoutEffect,
5
+ useMemo,
6
+ useRef,
7
+ useState,
8
+ useSyncExternalStore,
9
+ } from "react";
10
+ import {
11
+ __applyScrollState,
12
+ addLocationListener,
13
+ addRouteChangeListener,
14
+ __vormaClientGlobal as ctx,
15
+ getLocation,
16
+ getRouterData,
17
+ type RouteChangeEvent,
18
+ } from "vorma/client";
19
+
20
+ /////////////////////////////////////////////////////////////////////
21
+ /////// STORE
22
+ /////////////////////////////////////////////////////////////////////
23
+
24
+ type NavigationState = {
25
+ latestEvent: RouteChangeEvent | null;
26
+ loadersData: any;
27
+ clientLoadersData: any;
28
+ routerData: ReturnType<typeof getRouterData>;
29
+ outermostError: any;
30
+ outermostErrorIdx: number | undefined;
31
+ activeComponents: any[] | null;
32
+ activeErrorBoundary: any;
33
+ importURLs: string[];
34
+ exportKeys: string[];
35
+ };
36
+
37
+ type StoreState = {
38
+ navigation: NavigationState;
39
+ location: ReturnType<typeof getLocation>;
40
+ };
41
+
42
+ function getInitialState(): StoreState {
43
+ return {
44
+ navigation: {
45
+ latestEvent: null,
46
+ loadersData: ctx.get("loadersData"),
47
+ clientLoadersData: ctx.get("clientLoadersData"),
48
+ routerData: getRouterData(),
49
+ outermostError: ctx.get("outermostError"),
50
+ outermostErrorIdx: ctx.get("outermostErrorIdx"),
51
+ activeComponents: ctx.get("activeComponents"),
52
+ activeErrorBoundary: ctx.get("activeErrorBoundary"),
53
+ importURLs: ctx.get("importURLs"),
54
+ exportKeys: ctx.get("exportKeys"),
55
+ },
56
+ location: getLocation(),
57
+ };
58
+ }
59
+
60
+ let state = getInitialState();
61
+ const listeners = new Set<() => void>();
62
+
63
+ const store = {
64
+ getSnapshot: () => state,
65
+ subscribe: (listener: () => void) => {
66
+ listeners.add(listener);
67
+ return () => listeners.delete(listener);
68
+ },
69
+ setState: (updater: (prevState: StoreState) => StoreState) => {
70
+ const nextState = updater(state);
71
+ if (nextState !== state) {
72
+ state = nextState;
73
+ listeners.forEach((listener) => listener());
74
+ }
75
+ },
76
+ };
77
+
78
+ function useStoreSelector<T>(selector: (state: StoreState) => T): T {
79
+ const getSelectedSnapshot = useMemo(() => {
80
+ let selectedSnapshot: T;
81
+ return () => {
82
+ const nextSnapshot = selector(store.getSnapshot());
83
+ if (
84
+ selectedSnapshot === undefined ||
85
+ !Object.is(selectedSnapshot, nextSnapshot)
86
+ ) {
87
+ selectedSnapshot = nextSnapshot;
88
+ }
89
+ return selectedSnapshot;
90
+ };
91
+ }, [selector]);
92
+
93
+ return useSyncExternalStore(store.subscribe, getSelectedSnapshot);
94
+ }
95
+
96
+ export function useLoadersData() {
97
+ return useStoreSelector((s) => s.navigation.loadersData);
98
+ }
99
+ export function useClientLoadersData() {
100
+ return useStoreSelector((s) => s.navigation.clientLoadersData);
101
+ }
102
+ export function useRouterData() {
103
+ return useStoreSelector((s) => s.navigation.routerData);
104
+ }
105
+ function useLatestEvent() {
106
+ return useStoreSelector((s) => s.navigation.latestEvent);
107
+ }
108
+ function useOutermostError() {
109
+ return useStoreSelector((s) => s.navigation.outermostError);
110
+ }
111
+ function useOutermostErrorIdx() {
112
+ return useStoreSelector((s) => s.navigation.outermostErrorIdx);
113
+ }
114
+ function useActiveComponents() {
115
+ return useStoreSelector((s) => s.navigation.activeComponents);
116
+ }
117
+ function useActiveErrorBoundary() {
118
+ return useStoreSelector((s) => s.navigation.activeErrorBoundary);
119
+ }
120
+ function useImportURLs() {
121
+ return useStoreSelector((s) => s.navigation.importURLs);
122
+ }
123
+ function useExportKeys() {
124
+ return useStoreSelector((s) => s.navigation.exportKeys);
125
+ }
126
+
127
+ let isInited = false;
128
+
129
+ function initUIListeners() {
130
+ if (isInited) return;
131
+ isInited = true;
132
+
133
+ addRouteChangeListener((e) => {
134
+ store.setState((prev) => {
135
+ return {
136
+ ...prev,
137
+ navigation: {
138
+ latestEvent: e,
139
+ loadersData: ctx.get("loadersData"),
140
+ clientLoadersData: ctx.get("clientLoadersData"),
141
+ routerData: getRouterData(),
142
+ outermostError: ctx.get("outermostError"),
143
+ outermostErrorIdx: ctx.get("outermostErrorIdx"),
144
+ activeComponents: ctx.get("activeComponents"),
145
+ activeErrorBoundary: ctx.get("activeErrorBoundary"),
146
+ importURLs: ctx.get("importURLs"),
147
+ exportKeys: ctx.get("exportKeys"),
148
+ },
149
+ };
150
+ });
151
+ });
152
+
153
+ addLocationListener(() => {
154
+ store.setState((prev) => {
155
+ return {
156
+ ...prev,
157
+ location: getLocation(),
158
+ };
159
+ });
160
+ });
161
+ }
162
+
163
+ export function useLocation() {
164
+ return useStoreSelector((s) => s.location);
165
+ }
166
+
167
+ /////////////////////////////////////////////////////////////////////
168
+ /////// COMPONENT
169
+ /////////////////////////////////////////////////////////////////////
170
+
171
+ export function VormaRootOutlet(props: { idx?: number }): JSX.Element {
172
+ const idx = props.idx ?? 0;
173
+
174
+ const initialRenderRef = useRef(true);
175
+
176
+ if (idx === 0 && initialRenderRef.current) {
177
+ initUIListeners();
178
+
179
+ initialRenderRef.current = false;
180
+ store.setState((prev) => {
181
+ return {
182
+ ...prev,
183
+ navigation: {
184
+ latestEvent: null,
185
+ loadersData: ctx.get("loadersData"),
186
+ clientLoadersData: ctx.get("clientLoadersData"),
187
+ routerData: getRouterData(),
188
+ outermostError: ctx.get("outermostError"),
189
+ outermostErrorIdx: ctx.get("outermostErrorIdx"),
190
+ activeComponents: ctx.get("activeComponents"),
191
+ activeErrorBoundary: ctx.get("activeErrorBoundary"),
192
+ importURLs: ctx.get("importURLs"),
193
+ exportKeys: ctx.get("exportKeys"),
194
+ },
195
+ };
196
+ });
197
+ }
198
+
199
+ const latestEvent = useLatestEvent();
200
+ const loadersData = useLoadersData();
201
+ const outermostError = useOutermostError();
202
+ const outermostErrorIdx = useOutermostErrorIdx();
203
+ const activeComponents = useActiveComponents();
204
+ const activeErrorBoundary = useActiveErrorBoundary();
205
+ const importURLs = useImportURLs();
206
+ const exportKeys = useExportKeys();
207
+
208
+ const [currentImportURL, setCurrentImportURL] = useState(importURLs[idx]);
209
+ const [currentExportKey, setCurrentExportKey] = useState(exportKeys[idx]);
210
+ const [nextImportURL, setNextImportURL] = useState(importURLs[idx + 1]);
211
+ const [nextExportKey, setNextExportKey] = useState(exportKeys[idx + 1]);
212
+
213
+ useEffect(() => {
214
+ if (!currentImportURL || !latestEvent) {
215
+ return;
216
+ }
217
+
218
+ const newCurrentImportURL = importURLs[idx];
219
+ const newCurrentExportKey = exportKeys[idx];
220
+
221
+ if (currentImportURL !== newCurrentImportURL) {
222
+ setCurrentImportURL(newCurrentImportURL);
223
+ }
224
+ if (currentExportKey !== newCurrentExportKey) {
225
+ setCurrentExportKey(newCurrentExportKey);
226
+ }
227
+
228
+ // these are also needed for Outlets to render correctly
229
+ const newNextImportURL = importURLs[idx + 1];
230
+ const newNextExportKey = exportKeys[idx + 1];
231
+
232
+ if (nextImportURL !== newNextImportURL) {
233
+ setNextImportURL(newNextImportURL);
234
+ }
235
+ if (nextExportKey !== newNextExportKey) {
236
+ setNextExportKey(newNextExportKey);
237
+ }
238
+ }, [latestEvent, importURLs, exportKeys]);
239
+
240
+ useLayoutEffect(() => {
241
+ if (!latestEvent || idx !== 0) {
242
+ return;
243
+ }
244
+ window.requestAnimationFrame(() => {
245
+ __applyScrollState(latestEvent.detail.__scrollState);
246
+ });
247
+ }, [latestEvent, idx]);
248
+
249
+ const isErrorIdxMemo = useMemo(() => {
250
+ return idx === outermostErrorIdx;
251
+ }, [idx, outermostErrorIdx]);
252
+
253
+ const CurrentCompMemo = useMemo(() => {
254
+ if (isErrorIdxMemo) {
255
+ return null;
256
+ }
257
+ return activeComponents?.[idx];
258
+ }, [isErrorIdxMemo, currentImportURL, currentExportKey, activeComponents]);
259
+
260
+ const Outlet = useMemo(
261
+ () => (localProps: Record<string, any> | undefined) => {
262
+ return <VormaRootOutlet {...localProps} {...props} idx={idx + 1} />;
263
+ },
264
+ [nextImportURL, nextExportKey],
265
+ );
266
+
267
+ const shouldFallbackOutletMemo = useMemo(() => {
268
+ if (isErrorIdxMemo) {
269
+ return false;
270
+ }
271
+ if (CurrentCompMemo) {
272
+ return false;
273
+ }
274
+ return idx + 1 < loadersData.length;
275
+ }, [isErrorIdxMemo, CurrentCompMemo, idx, loadersData]);
276
+
277
+ const ErrorCompMemo = useMemo(() => {
278
+ if (!isErrorIdxMemo) {
279
+ return null;
280
+ }
281
+ return activeErrorBoundary;
282
+ }, [isErrorIdxMemo, activeErrorBoundary]);
283
+
284
+ if (isErrorIdxMemo) {
285
+ if (ErrorCompMemo) {
286
+ return <ErrorCompMemo error={outermostError} />;
287
+ }
288
+ return <>{`Error: ${outermostError || "unknown"}`}</>;
289
+ }
290
+
291
+ if (!CurrentCompMemo) {
292
+ if (shouldFallbackOutletMemo) {
293
+ return <Outlet />;
294
+ }
295
+ return <></>;
296
+ }
297
+
298
+ return <CurrentCompMemo idx={idx} Outlet={Outlet} />;
299
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "../../../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "jsx": "react-jsx"
5
+ }
6
+ }
@@ -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, location } from "./src/solid.tsx";
@@ -0,0 +1,114 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ import { createMemo, type Accessor } from "solid-js";
4
+ import type { JSX } from "solid-js/jsx-runtime";
5
+ import {
6
+ __registerClientLoaderPattern,
7
+ __runClientLoadersAfterHMRUpdate,
8
+ __vormaClientGlobal,
9
+ type ClientLoaderAwaitedServerData,
10
+ type ParamsForPattern,
11
+ type UseRouterDataFunction,
12
+ type VormaAppBase,
13
+ type VormaLoaderOutput,
14
+ type VormaLoaderPattern,
15
+ type VormaRouteGeneric,
16
+ type VormaRoutePropsGeneric,
17
+ } from "vorma/client";
18
+ import { clientLoadersData, loadersData, routerData } from "./solid.tsx";
19
+
20
+ export type VormaRouteProps<
21
+ App extends VormaAppBase = any,
22
+ Pattern extends VormaLoaderPattern<App> = string,
23
+ > = VormaRoutePropsGeneric<JSX.Element, App, Pattern>;
24
+
25
+ export type VormaRoute<
26
+ App extends VormaAppBase = any,
27
+ Pattern extends VormaLoaderPattern<App> = string,
28
+ > = VormaRouteGeneric<JSX.Element, App, Pattern>;
29
+
30
+ export function makeTypedUseRouterData<App extends VormaAppBase>() {
31
+ return (() => routerData) as UseRouterDataFunction<App, true>;
32
+ }
33
+
34
+ export function makeTypedUseLoaderData<App extends VormaAppBase>() {
35
+ return function useLoaderData<Pattern extends VormaLoaderPattern<App>>(
36
+ props: VormaRouteProps<App, Pattern>,
37
+ ): Accessor<VormaLoaderOutput<App, Pattern>> {
38
+ return createMemo(() => {
39
+ return loadersData()[props.idx];
40
+ });
41
+ };
42
+ }
43
+
44
+ export function makeTypedUsePatternLoaderData<App extends VormaAppBase>() {
45
+ return function usePatternLoaderData<
46
+ Pattern extends VormaLoaderPattern<App>,
47
+ >(pattern: Pattern): Accessor<VormaLoaderOutput<App, Pattern> | undefined> {
48
+ const idx = createMemo(() => {
49
+ const matchedPatterns = routerData().matchedPatterns;
50
+ return matchedPatterns.findIndex((p) => p === pattern);
51
+ });
52
+ const loaderData = createMemo(() => {
53
+ const index = idx();
54
+ if (index === -1) {
55
+ return undefined;
56
+ }
57
+ return loadersData()[index];
58
+ });
59
+ return loaderData;
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
+ ): Accessor<Res | undefined> => {
98
+ return createMemo(() => {
99
+ if (props) {
100
+ return clientLoadersData()[props.idx];
101
+ }
102
+ const matched = routerData().matchedPatterns;
103
+ const idx = matched.findIndex((pattern) => pattern === p);
104
+ if (idx === -1) return undefined;
105
+ return clientLoadersData()[idx];
106
+ });
107
+ };
108
+
109
+ return useClientLoaderData as {
110
+ (props: VormaRouteProps<App, Pattern>): Accessor<Res>;
111
+ (): Accessor<Res | undefined>;
112
+ };
113
+ };
114
+ }
@@ -0,0 +1,104 @@
1
+ import { createMemo, mergeProps, splitProps, type JSX } from "solid-js";
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 function VormaLink(
16
+ props: JSX.AnchorHTMLAttributes<HTMLAnchorElement> &
17
+ VormaLinkPropsBase<
18
+ JSX.CustomEventHandlersCamelCase<HTMLAnchorElement>["onClick"]
19
+ >,
20
+ ) {
21
+ const finalLinkProps = createMemo(() => __makeFinalLinkProps(props));
22
+ const [, rest] = splitProps(props, [
23
+ "prefetch",
24
+ "scrollToTop",
25
+ "replace",
26
+ "state",
27
+ ]);
28
+
29
+ return (
30
+ <a
31
+ data-external={finalLinkProps().dataExternal}
32
+ {...rest}
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
+ </a>
42
+ );
43
+ }
44
+
45
+ type TypedVormaLinkProps<
46
+ App extends VormaAppBase,
47
+ Pattern extends VormaLoaderPattern<App> = VormaLoaderPattern<App>,
48
+ > = Omit<JSX.AnchorHTMLAttributes<HTMLAnchorElement>, "href" | "pattern"> &
49
+ VormaLinkPropsBase<
50
+ JSX.CustomEventHandlersCamelCase<HTMLAnchorElement>["onClick"]
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 merged = mergeProps(defaultProps || {}, props);
72
+
73
+ const [local, linkProps] = splitProps(merged as any, [
74
+ "pattern",
75
+ "params",
76
+ "splatValues",
77
+ "search",
78
+ "hash",
79
+ "state",
80
+ ]);
81
+
82
+ const href = createMemo(() => {
83
+ const basePath = __resolvePath({
84
+ vormaAppConfig,
85
+ type: "loader",
86
+ props: {
87
+ pattern: local.pattern,
88
+ ...(local.params && { params: local.params }),
89
+ ...(local.splatValues && {
90
+ splatValues: local.splatValues,
91
+ }),
92
+ },
93
+ });
94
+ const url = new URL(basePath, window.location.origin);
95
+ if (local.search !== undefined) url.search = local.search;
96
+ if (local.hash !== undefined) url.hash = local.hash;
97
+ return url.href;
98
+ });
99
+
100
+ return <VormaLink {...linkProps} href={href()} state={local.state} />;
101
+ };
102
+
103
+ return TypedLink;
104
+ }