eddev 2.0.0-beta.6 → 2.0.0-beta.61

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 (257) hide show
  1. package/dist/app/entry/MetaTags.d.ts +7 -0
  2. package/dist/app/entry/MetaTags.js +17 -0
  3. package/dist/app/entry/boot-admin.d.ts +1 -0
  4. package/dist/app/entry/boot-admin.js +14 -0
  5. package/dist/app/entry/spa-root.d.ts +1 -0
  6. package/dist/app/entry/spa-root.js +8 -0
  7. package/dist/app/entry/ssr-root-client.d.ts +6 -0
  8. package/dist/app/entry/ssr-root-client.js +26 -0
  9. package/dist/app/entry/ssr-root.d.ts +10 -0
  10. package/dist/app/entry/ssr-root.js +23 -0
  11. package/dist/app/lib/admin/index.d.ts +2 -2
  12. package/dist/app/lib/admin/index.js +2 -2
  13. package/dist/app/lib/admin/installFieldTypes.js +1 -1
  14. package/dist/app/lib/admin/runWidgets.js +1 -1
  15. package/dist/app/lib/blocks/ContentBlocks.d.ts +1 -1
  16. package/dist/app/lib/blocks/ContentBlocks.js +5 -5
  17. package/dist/app/lib/blocks/EditableText.d.ts +1 -1
  18. package/dist/app/lib/blocks/EditableText.js +3 -3
  19. package/dist/app/lib/blocks/InnerBlocks.d.ts +13 -3
  20. package/dist/app/lib/blocks/InnerBlocks.js +13 -5
  21. package/dist/app/lib/blocks/block-utils.d.ts +2 -2
  22. package/dist/app/lib/blocks/block-utils.js +2 -2
  23. package/dist/app/lib/blocks/editor/EditorSupport.js +4 -5
  24. package/dist/app/lib/blocks/editor/editor-config.d.ts +16 -3
  25. package/dist/app/lib/blocks/editor/editor-config.js +2 -4
  26. package/dist/app/lib/blocks/editor/installGutenbergHooks.js +17 -13
  27. package/dist/app/lib/blocks/editor/root-blocks.d.ts +6 -0
  28. package/dist/app/lib/blocks/editor/root-blocks.js +30 -0
  29. package/dist/app/lib/blocks/editor/usePostEditor.d.ts +1 -1
  30. package/dist/app/lib/blocks/index.d.ts +9 -9
  31. package/dist/app/lib/blocks/index.js +9 -9
  32. package/dist/app/lib/blocks/inline-editing.d.ts +1 -1
  33. package/dist/app/lib/blocks/inline-editing.js +7 -5
  34. package/dist/app/lib/devtools/components/BreakpointIndicator.js +6 -4
  35. package/dist/app/lib/devtools/components/DevUI.js +4 -3
  36. package/dist/app/lib/devtools/components/GridIndicator.d.ts +1 -0
  37. package/dist/app/lib/devtools/components/GridIndicator.js +24 -0
  38. package/dist/app/lib/devtools/dev-tools-store.d.ts +9 -0
  39. package/dist/app/lib/devtools/dev-tools-store.js +8 -0
  40. package/dist/app/lib/devtools/hooks/usePersistState.d.ts +1 -1
  41. package/dist/app/lib/devtools/hooks/usePersistState.js +11 -2
  42. package/dist/app/lib/devtools/hooks/useTailwind.d.ts +1094 -1095
  43. package/dist/app/lib/devtools/hooks/useTailwind.js +6 -3
  44. package/dist/app/lib/devtools/index.d.ts +1 -0
  45. package/dist/app/lib/devtools/index.js +1 -1
  46. package/dist/app/lib/devtools/loader.js +8 -7
  47. package/dist/app/lib/devtools/useQueryDebug.d.ts +7 -1
  48. package/dist/app/lib/devtools/useQueryDebug.js +5 -8
  49. package/dist/app/lib/dynamic/index.d.ts +1 -1
  50. package/dist/app/lib/dynamic/index.js +1 -1
  51. package/dist/app/lib/hooks/index.d.ts +4 -5
  52. package/dist/app/lib/hooks/index.js +4 -5
  53. package/dist/app/lib/hooks/queryUtils.d.ts +37 -3
  54. package/dist/app/lib/hooks/queryUtils.js +63 -26
  55. package/dist/app/lib/hooks/useAppData.js +1 -1
  56. package/dist/app/lib/hooks/useRPC.d.ts +0 -4
  57. package/dist/app/lib/hooks/useRPC.js +1 -8
  58. package/dist/app/lib/internal/finalize-rpc.d.ts +17 -0
  59. package/dist/app/lib/internal/finalize-rpc.js +3 -0
  60. package/dist/app/lib/internal/index.d.ts +5 -4
  61. package/dist/app/lib/internal/index.js +5 -4
  62. package/dist/app/lib/internal/internal-store.d.ts +0 -2
  63. package/dist/app/lib/internal/internal-store.js +1 -3
  64. package/dist/app/lib/internal/read-admin-manifest.d.ts +1 -1
  65. package/dist/app/lib/legacy-stitches/createStitches.d.ts +21 -21
  66. package/dist/app/lib/legacy-stitches/createStitches.js +1 -1
  67. package/dist/app/lib/legacy-stitches/index.d.ts +1 -1
  68. package/dist/app/lib/legacy-stitches/index.js +1 -1
  69. package/dist/app/lib/routing/components/BackButton.d.ts +49 -0
  70. package/dist/app/lib/routing/components/BackButton.js +47 -0
  71. package/dist/app/lib/routing/components/BrowserRouter.d.ts +4 -1
  72. package/dist/app/lib/routing/components/BrowserRouter.js +79 -11
  73. package/dist/app/lib/routing/components/ClientOnly.js +1 -1
  74. package/dist/app/lib/routing/components/Link.d.ts +1 -0
  75. package/dist/app/lib/routing/components/Link.js +9 -10
  76. package/dist/app/lib/routing/components/RouteRenderer.d.ts +1 -1
  77. package/dist/app/lib/routing/components/RouteRenderer.js +7 -6
  78. package/dist/app/lib/routing/components/SSRRouter.d.ts +2 -2
  79. package/dist/app/lib/routing/components/SSRRouter.js +5 -6
  80. package/dist/app/lib/routing/components/ScrollRestoration.js +1 -1
  81. package/dist/app/lib/routing/context.d.ts +8 -5
  82. package/dist/app/lib/routing/context.js +13 -96
  83. package/dist/app/lib/routing/hooks/useRestorableState.d.ts +2 -1
  84. package/dist/app/lib/routing/hooks/useRestorableState.js +2 -1
  85. package/dist/app/lib/routing/hooks/useRoute.d.ts +16 -1
  86. package/dist/app/lib/routing/hooks/useRoute.js +22 -1
  87. package/dist/app/lib/routing/hooks/useRouteMeta.d.ts +5 -0
  88. package/dist/app/lib/routing/hooks/useRouteMeta.js +9 -0
  89. package/dist/app/lib/routing/hooks/useRouteTransition.d.ts +1 -1
  90. package/dist/app/lib/routing/hooks/useRouteTransition.js +1 -1
  91. package/dist/app/lib/routing/hooks/useRouter.d.ts +1 -1
  92. package/dist/app/lib/routing/hooks/useRouter.js +1 -1
  93. package/dist/app/lib/routing/hooks/useRouterEvents.d.ts +1 -1
  94. package/dist/app/lib/routing/hooks/useRouterEvents.js +1 -1
  95. package/dist/app/lib/routing/hooks/useRouterState.d.ts +1 -1
  96. package/dist/app/lib/routing/hooks/useRouterState.js +1 -1
  97. package/dist/app/lib/routing/hooks/useSearchParams.js +2 -2
  98. package/dist/app/lib/routing/index.d.ts +14 -13
  99. package/dist/app/lib/routing/index.js +14 -13
  100. package/dist/app/lib/routing/loader.d.ts +2 -2
  101. package/dist/app/lib/routing/loader.js +7 -5
  102. package/dist/app/lib/routing/types.d.ts +35 -9
  103. package/dist/app/lib/routing/utils.d.ts +3 -1
  104. package/dist/app/lib/routing/utils.js +12 -1
  105. package/dist/app/lib/{hooks → runtime}/apiConfig.d.ts +6 -2
  106. package/dist/app/lib/runtime/apiConfig.js +6 -0
  107. package/dist/app/lib/runtime/errorHandling.d.ts +39 -0
  108. package/dist/app/lib/runtime/errorHandling.js +6 -0
  109. package/dist/app/lib/runtime/index.d.ts +2 -0
  110. package/dist/app/lib/runtime/index.js +2 -0
  111. package/dist/app/lib/views/index.d.ts +1 -1
  112. package/dist/app/lib/views/index.js +1 -1
  113. package/dist/app/server/defineRouter.d.ts +2 -0
  114. package/dist/app/server/defineRouter.js +4 -0
  115. package/dist/app/server/index.d.ts +5 -0
  116. package/dist/app/server/index.js +5 -0
  117. package/dist/app/server/proxy-wp-admin.d.ts +2 -0
  118. package/dist/app/server/proxy-wp-admin.js +112 -0
  119. package/dist/app/server/render-ssr-page.d.ts +11 -0
  120. package/dist/app/server/render-ssr-page.js +100 -0
  121. package/dist/app/server/rpc.d.ts +56 -0
  122. package/dist/app/server/rpc.js +18 -0
  123. package/dist/app/server/server-context.d.ts +53 -0
  124. package/dist/app/server/server-context.js +149 -0
  125. package/dist/app/server/utils/headers.d.ts +1 -0
  126. package/dist/app/server/utils/headers.js +17 -0
  127. package/dist/app/server/utils/replace-host.d.ts +6 -4
  128. package/dist/app/server/utils/replace-host.js +58 -11
  129. package/dist/app/utils/APIProvider.d.ts +2 -0
  130. package/dist/app/utils/APIProvider.js +5 -0
  131. package/dist/app/utils/BlockErrorBoundary.d.ts +19 -0
  132. package/dist/app/utils/BlockErrorBoundary.js +38 -0
  133. package/dist/app/utils/ErrorMessage.d.ts +5 -0
  134. package/dist/app/utils/ErrorMessage.js +14 -0
  135. package/dist/app/utils/RouteErrorBoundary.d.ts +18 -0
  136. package/dist/app/utils/RouteErrorBoundary.js +38 -0
  137. package/dist/app/utils/query-client.d.ts +2 -0
  138. package/dist/app/utils/query-client.js +5 -1
  139. package/dist/app/utils/trpc-client.d.ts +2 -0
  140. package/dist/app/utils/trpc-client.js +34 -0
  141. package/dist/node/cli/cli-worker.d.ts +1 -1
  142. package/dist/node/cli/cli-worker.js +12 -3
  143. package/dist/node/cli/cli.js +91 -13
  144. package/dist/node/cli/display/CLIApp.d.ts +1 -1
  145. package/dist/node/cli/display/CLIApp.js +4 -7
  146. package/dist/node/cli/display/components/LogEntries.d.ts +1 -1
  147. package/dist/node/cli/display/hooks/useStatefulLog.d.ts +1 -1
  148. package/dist/node/cli/display/tools/CreateBlock.d.ts +1 -1
  149. package/dist/node/cli/display/tools/cli-tools.d.ts +1 -11
  150. package/dist/node/cli/display/tools/cli-tools.js +9 -9
  151. package/dist/node/cli/display/util/colors.d.ts +2 -2
  152. package/dist/node/cli/version.d.ts +1 -1
  153. package/dist/node/cli/version.js +1 -1
  154. package/dist/node/compiler/build-vinxi.d.ts +8 -0
  155. package/dist/node/compiler/build-vinxi.js +38 -0
  156. package/dist/node/compiler/bundler.admin.d.ts +2 -2
  157. package/dist/node/compiler/bundler.admin.js +3 -4
  158. package/dist/node/compiler/bundler.frontend.d.ts +1 -1
  159. package/dist/node/compiler/bundler.frontend.js +3 -4
  160. package/dist/node/compiler/{serverless.dev.d.ts → dev-server.d.ts} +7 -5
  161. package/dist/node/compiler/dev-server.js +106 -0
  162. package/dist/node/compiler/get-vite-config.d.ts +19 -0
  163. package/dist/node/compiler/get-vite-config.js +200 -0
  164. package/dist/node/compiler/vinxi-app.d.ts +20 -0
  165. package/dist/node/compiler/vinxi-app.js +186 -0
  166. package/dist/node/compiler/vinxi-codegen.d.ts +12 -0
  167. package/dist/node/compiler/vinxi-codegen.js +515 -0
  168. package/dist/node/graphql/graphql-codegen.d.ts +12 -2
  169. package/dist/node/graphql/graphql-codegen.js +213 -36
  170. package/dist/node/graphql/graphql-schema-loader.js +15 -18
  171. package/dist/node/graphql/plugins/gql-plugin-queries.js +1 -1
  172. package/dist/node/graphql/query-files-loader.d.ts +3 -0
  173. package/dist/node/graphql/query-files-loader.js +5 -0
  174. package/dist/node/project/config.d.ts +31 -37
  175. package/dist/node/project/config.js +13 -11
  176. package/dist/node/project/env.d.ts +1 -1
  177. package/dist/node/project/env.js +1 -1
  178. package/dist/node/project/manifest/block-manifest.js +3 -2
  179. package/dist/node/project/manifest/manifest.d.ts +2 -1
  180. package/dist/node/project/manifest/manifest.js +15 -11
  181. package/dist/node/project/manifest/routes-manifest.d.ts +20 -0
  182. package/dist/node/project/manifest/routes-manifest.js +74 -0
  183. package/dist/node/project/manifest/view-manifest.js +2 -2
  184. package/dist/node/project/project.d.ts +5 -2
  185. package/dist/node/project/project.js +21 -20
  186. package/dist/node/project/wp-info.js +3 -2
  187. package/dist/node/types/block-type.d.ts +5 -0
  188. package/dist/node/types/block-type.js +1 -0
  189. package/dist/node/types/view-type.js +3 -4
  190. package/dist/node/utils/fs-codegen.d.ts +42 -0
  191. package/dist/node/utils/fs-codegen.js +98 -0
  192. package/dist/node/utils/fs.js +2 -0
  193. package/dist/node/utils/{selfSignedCert.js → self-signed-cert.js} +1 -1
  194. package/dist/node/utils/{statefulLog.js → stateful-log.js} +1 -1
  195. package/dist/node/utils/watch-file-tree.d.ts +25 -0
  196. package/dist/node/utils/{watchFileTree.js → watch-file-tree.js} +12 -5
  197. package/package.json +39 -32
  198. package/types.app.d.ts +4 -2
  199. package/types.app.internal.d.ts +2 -2
  200. package/types.node.d.ts +3 -3
  201. package/dist/app/entry/Root.d.ts +0 -1
  202. package/dist/app/entry/Root.js +0 -9
  203. package/dist/app/entry/main.admin.d.ts +0 -3
  204. package/dist/app/entry/main.admin.js +0 -10
  205. package/dist/app/entry/main.frontend.spa.d.ts +0 -3
  206. package/dist/app/entry/main.frontend.spa.js +0 -13
  207. package/dist/app/entry/main.frontend.ssr.d.ts +0 -21
  208. package/dist/app/entry/main.frontend.ssr.js +0 -79
  209. package/dist/app/entry/main.serverless.dev.d.ts +0 -4
  210. package/dist/app/entry/main.serverless.dev.js +0 -21
  211. package/dist/app/lib/blocks/ErrorBoundaryFrontend.d.ts +0 -15
  212. package/dist/app/lib/blocks/ErrorBoundaryFrontend.js +0 -35
  213. package/dist/app/lib/hooks/apiConfig.js +0 -4
  214. package/dist/app/lib/hooks/usePageLoad.d.ts +0 -6
  215. package/dist/app/lib/hooks/usePageLoad.js +0 -5
  216. package/dist/app/server/create-api-builtin-hono.d.ts +0 -8
  217. package/dist/app/server/create-api-builtin-hono.js +0 -80
  218. package/dist/app/server/create-ssr-hono.d.ts +0 -18
  219. package/dist/app/server/create-ssr-hono.js +0 -104
  220. package/dist/app/server/utils/index.html.d.ts +0 -2
  221. package/dist/app/server/utils/index.html.js +0 -14
  222. package/dist/node/compiler/index.html.d.ts +0 -2
  223. package/dist/node/compiler/index.html.js +0 -15
  224. package/dist/node/compiler/serverless.dev.js +0 -222
  225. package/dist/node/compiler/vite/get-vite-config.d.ts +0 -13
  226. package/dist/node/compiler/vite/get-vite-config.js +0 -315
  227. package/dist/node/compiler/vite/plugin-admin.d.ts +0 -4
  228. package/dist/node/compiler/vite/plugin-admin.js +0 -67
  229. package/dist/node/compiler/vite/plugin-blocks.d.ts +0 -4
  230. package/dist/node/compiler/vite/plugin-blocks.js +0 -73
  231. package/dist/node/compiler/vite/plugin-entry.d.ts +0 -6
  232. package/dist/node/compiler/vite/plugin-entry.js +0 -16
  233. package/dist/node/compiler/vite/plugin-resolved-tailwind.d.ts +0 -4
  234. package/dist/node/compiler/vite/plugin-resolved-tailwind.js +0 -29
  235. package/dist/node/compiler/vite/plugin-theme.d.ts +0 -4
  236. package/dist/node/compiler/vite/plugin-theme.js +0 -40
  237. package/dist/node/compiler/vite/plugin-views.d.ts +0 -4
  238. package/dist/node/compiler/vite/plugin-views.js +0 -51
  239. package/dist/node/utils/console.d.ts +0 -21
  240. package/dist/node/utils/console.js +0 -28
  241. package/dist/node/utils/unsafe-fetch.d.ts +0 -2
  242. package/dist/node/utils/unsafe-fetch.js +0 -19
  243. package/dist/node/utils/watchFileTree.d.ts +0 -11
  244. package/tsup.config.ts +0 -40
  245. package/types.manifests.d.ts +0 -22
  246. /package/dist/node/utils/{formatZodError.d.ts → format-zod-error.d.ts} +0 -0
  247. /package/dist/node/utils/{formatZodError.js → format-zod-error.js} +0 -0
  248. /package/dist/node/utils/{getRepoInfo.d.ts → get-repo-info.d.ts} +0 -0
  249. /package/dist/node/utils/{getRepoInfo.js → get-repo-info.js} +0 -0
  250. /package/dist/node/utils/{highlightCode.d.ts → highlight-code.d.ts} +0 -0
  251. /package/dist/node/utils/{highlightCode.js → highlight-code.js} +0 -0
  252. /package/dist/node/utils/{isDeploying.d.ts → is-deploying.d.ts} +0 -0
  253. /package/dist/node/utils/{isDeploying.js → is-deploying.js} +0 -0
  254. /package/dist/node/utils/{selfSignedCert.d.ts → self-signed-cert.d.ts} +0 -0
  255. /package/dist/node/utils/{statefulLog.d.ts → stateful-log.d.ts} +0 -0
  256. /package/dist/node/utils/{export-extractor.d.ts → ts-export-extractor.d.ts} +0 -0
  257. /package/dist/node/utils/{export-extractor.js → ts-export-extractor.js} +0 -0
@@ -0,0 +1,49 @@
1
+ import { ReactNode } from "react";
2
+ import { RouteState } from "../types";
3
+ type BackButtonProps = {
4
+ /**
5
+ * An optional matching function, which will stop the render button from appearing unless the function returns true.
6
+ *
7
+ * The below example will only render a back button if the last route was a project archive.
8
+ *
9
+ * eg. `filter={(route) => route.view === 'archive-projects'}`
10
+ *
11
+ * @param route The last route in the history stack.
12
+ */
13
+ filter?: (route: RouteState) => boolean;
14
+ /**
15
+ * Whether to use the top-most "global" route, or the "context" route.
16
+ *
17
+ * The "global" route is the top-most route, reflected in the URL bar.
18
+ *
19
+ * The "context" route will be the route that is currently being rendered, which may be different to the global route when using modals/overlays/route stacks/transitions.
20
+ *
21
+ * @default "context"
22
+ */
23
+ mode?: "global" | "context";
24
+ /**
25
+ * An optional href, which will be used if no back route is found.
26
+ *
27
+ * When used, the back button will always render.
28
+ */
29
+ fallbackHref?: string;
30
+ /**
31
+ * A function to render the back button, if one should be rendered.
32
+ *
33
+ * Receives a `route` prop to further inspect the route, and an `onClick` function to navigate back.
34
+ *
35
+ * @param props
36
+ * @returns
37
+ */
38
+ render: (props: {
39
+ route: RouteState;
40
+ onClick: (e?: any) => void;
41
+ }) => ReactNode;
42
+ };
43
+ /**
44
+ * Display a back button that will navigate to the previous page in the router's history.
45
+ *
46
+ * This will allow you to render a back button on the condition that the back button will not send the user to a different website.
47
+ */
48
+ export declare function BackButton(props: BackButtonProps): ReactNode;
49
+ export {};
@@ -0,0 +1,47 @@
1
+ import { useMemo } from "react";
2
+ import { useRoute } from "../hooks/useRoute";
3
+ import { useRouter } from "../hooks/useRouter";
4
+ import { useRouterState } from "../hooks/useRouterState";
5
+ import { getLinkHandlerMode } from "../utils";
6
+ /**
7
+ * Display a back button that will navigate to the previous page in the router's history.
8
+ *
9
+ * This will allow you to render a back button on the condition that the back button will not send the user to a different website.
10
+ */
11
+ export function BackButton(props) {
12
+ const router = useRouter();
13
+ const prevRoute = useRouterState((state) => state.history[state.history.length - 2]);
14
+ const contextRoute = useRoute();
15
+ const activeRoute = useRouterState((state) => state.activeRoute);
16
+ const route = props.mode === "global" ? activeRoute : contextRoute;
17
+ const backAction = useMemo(() => {
18
+ if (prevRoute && (!props.filter || props.filter(prevRoute))) {
19
+ return (e) => {
20
+ const { mode } = getLinkHandlerMode(e, prevRoute.uri);
21
+ if (mode === "navigate") {
22
+ e.preventDefault();
23
+ history.back();
24
+ // history.length
25
+ }
26
+ else if (mode === "ignore") {
27
+ e.preventDefault();
28
+ }
29
+ };
30
+ }
31
+ else if (props.fallbackHref) {
32
+ return (e) => {
33
+ const { mode } = getLinkHandlerMode(e, props.fallbackHref);
34
+ if (mode === "navigate") {
35
+ e.preventDefault();
36
+ router.navigate(props.fallbackHref);
37
+ }
38
+ else if (mode === "ignore") {
39
+ e.preventDefault();
40
+ }
41
+ };
42
+ }
43
+ }, [route, props.filter, props.fallbackHref]);
44
+ if (backAction) {
45
+ return props.render ? props.render({ route: prevRoute, onClick: backAction }) : null;
46
+ }
47
+ }
@@ -1,4 +1,7 @@
1
1
  import { PropsWithChildren } from "react";
2
- type Props = PropsWithChildren<{}>;
2
+ import { type RouterAPI } from "../types.js";
3
+ type Props = PropsWithChildren<{
4
+ routerRef?: React.MutableRefObject<RouterAPI | null>;
5
+ }>;
3
6
  export declare function BrowserRouter(props: Props): import("react/jsx-runtime").JSX.Element;
4
7
  export {};
@@ -1,11 +1,20 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useEffect, useMemo, useRef, useState, useTransition } from "react";
3
- import { isRelative, parseURL, resolveURL } from "ufo";
4
- import { RouterContext, RouterStateContext } from "../context";
5
- import { RouteLoader } from "../loader";
6
- import { getLinkHandlerMode, normalizeRoute, parseQuery, stringifyRouteLink } from "../utils";
7
- import { AppRenderer } from "./RouteRenderer";
3
+ import { isEqual, isRelative, parseURL, resolveURL } from "ufo";
4
+ import { clientMetaTags, RouterContext, RouterStateContext } from "../context.js";
5
+ import { $routeMetaStore } from "../hooks/useRouteMeta.js";
6
+ import { RouteLoader } from "../loader.js";
7
+ import { getLinkHandlerMode, getRouteMeta, isSamePathname, normalizeRoute, parseQuery, stringifyRouteLink, } from "../utils.js";
8
+ import { AppRenderer } from "./RouteRenderer.js";
9
+ // Create a global RouteLoader instance
8
10
  const loader = new RouteLoader();
11
+ // Create a unique ID for each history entry
12
+ let historyStamp = String(new Date().getTime());
13
+ let historyIndex = 0;
14
+ function getHistoryId() {
15
+ return historyStamp + historyIndex++;
16
+ }
17
+ // Set up the initial route data
9
18
  let initialRoute;
10
19
  let initialRouteHydrated = false;
11
20
  if (env.client && !env.admin) {
@@ -23,7 +32,10 @@ if (env.client && !env.admin) {
23
32
  search: "",
24
33
  query: {},
25
34
  view: initialData.view,
35
+ meta: getRouteMeta(initialData),
26
36
  });
37
+ history.replaceState(historyStateForRoute(initialRoute), "", document.location.href);
38
+ $routeMetaStore.data = getRouteMeta(initialData);
27
39
  }
28
40
  function parseHrefPath(url) {
29
41
  if (isRelative(url)) {
@@ -54,14 +66,9 @@ function historyStateForRoute(route) {
54
66
  state: route.returnState,
55
67
  };
56
68
  }
57
- let index = 0;
58
- function getHistoryId() {
59
- return String(index++);
60
- }
61
69
  let lastRouterState = null;
62
70
  export function BrowserRouter(props) {
63
71
  const pendingRoute = useRef(null);
64
- // const [activeRoute, setActiveRoute] = useState<RouteState>(initialRoute)
65
72
  const [transitioning, startTransition] = useTransition();
66
73
  const [routerState, setRouterState] = useState(() => ({
67
74
  activeRoute: initialRoute,
@@ -79,6 +86,16 @@ export function BrowserRouter(props) {
79
86
  ...state,
80
87
  ...update,
81
88
  };
89
+ if (state?.activeRoute?.meta?.tags) {
90
+ if (env.serverless) {
91
+ clientMetaTags.setMetaTags(state.activeRoute.meta.tags ?? []);
92
+ }
93
+ else {
94
+ const title = state.activeRoute.meta.tags.find((tag) => tag.tagName === "title")?.inner;
95
+ if (title)
96
+ document.title = title;
97
+ }
98
+ }
82
99
  setRouterState(state);
83
100
  };
84
101
  const internals = {
@@ -116,6 +133,7 @@ export function BrowserRouter(props) {
116
133
  }
117
134
  internals.poppedState = (href, data) => {
118
135
  const stack = state.history;
136
+ // console.log("Popped state", stack)
119
137
  // Is the route in our history stack? (going back)
120
138
  const index = stack.findIndex((item) => item.id === data.id);
121
139
  if (index >= 0) {
@@ -201,6 +219,7 @@ export function BrowserRouter(props) {
201
219
  props: data.viewData?.data ?? {},
202
220
  component: lazyComponent,
203
221
  returnState: args.restoreState ?? {},
222
+ meta: getRouteMeta(data),
204
223
  });
205
224
  setState({
206
225
  pendingRoute: route,
@@ -229,6 +248,7 @@ export function BrowserRouter(props) {
229
248
  lastRoute: currentRoute,
230
249
  link,
231
250
  });
251
+ $routeMetaStore.data = route.meta;
232
252
  };
233
253
  startTransition(() => {
234
254
  pendingRoute.current = route;
@@ -247,6 +267,9 @@ export function BrowserRouter(props) {
247
267
  goingBack: false,
248
268
  });
249
269
  },
270
+ getState() {
271
+ return state;
272
+ },
250
273
  replaceHash(hash) {
251
274
  replaceRoute({
252
275
  ...getActiveRoute(),
@@ -257,6 +280,7 @@ export function BrowserRouter(props) {
257
280
  replaceRoute({
258
281
  ...getActiveRoute(),
259
282
  query,
283
+ returnState: captureState(),
260
284
  });
261
285
  },
262
286
  async prefetch(url) {
@@ -297,7 +321,7 @@ export function BrowserRouter(props) {
297
321
  subscribers.delete(fn);
298
322
  };
299
323
  },
300
- handleClickEvent(e, originalHref) {
324
+ handleClickEvent(e, originalHref, preferBack) {
301
325
  const { mode, href } = getLinkHandlerMode(e, originalHref);
302
326
  if (mode === "ignore") {
303
327
  e.preventDefault();
@@ -308,10 +332,53 @@ export function BrowserRouter(props) {
308
332
  }
309
333
  else if (mode === "navigate" && href) {
310
334
  e.preventDefault();
335
+ if (preferBack) {
336
+ const lastState = state.history.length > 1 && state.history[state.history.length - 2];
337
+ if (lastState) {
338
+ const doesMatch = preferBack === "exact" ? isEqual(href, lastState.uri) : isSamePathname(href, lastState.uri);
339
+ if (doesMatch) {
340
+ history.back();
341
+ return;
342
+ }
343
+ }
344
+ }
311
345
  api.navigate(href);
312
346
  }
313
347
  },
314
348
  emitEvent,
349
+ restoreRoute(route) {
350
+ const stack = state.history;
351
+ // Is the route in our history stack? (going back)
352
+ const index = stack.findIndex((item) => item.id === route.id);
353
+ if (index >= 0) {
354
+ return doRouteTransition({
355
+ url: route.uri,
356
+ route,
357
+ goingBack: true,
358
+ history: stack.slice(0, index),
359
+ restoreState: route.returnState,
360
+ shouldPush: false,
361
+ });
362
+ }
363
+ // Is the route in our history _cache_? (probably going forward)
364
+ if (historyCache.has(route.id)) {
365
+ return doRouteTransition({
366
+ url: route.uri,
367
+ route,
368
+ goingBack: false,
369
+ history: stack,
370
+ restoreState: route.returnState,
371
+ shouldPush: false,
372
+ });
373
+ }
374
+ return doRouteTransition({
375
+ url: route.uri,
376
+ goingBack: false,
377
+ history: stack,
378
+ restoreState: route.returnState,
379
+ shouldPush: false,
380
+ });
381
+ },
315
382
  };
316
383
  return {
317
384
  api,
@@ -340,6 +407,7 @@ export function BrowserRouter(props) {
340
407
  // Handle popState
341
408
  // const router = useRouterStore.getState()
342
409
  const onPopState = (e) => {
410
+ // console.log("Popped", e.state)
343
411
  internals.poppedState?.(document.location.href, e.state ?? {});
344
412
  };
345
413
  window.addEventListener("popstate", onPopState);
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Fragment } from "react";
3
- import { useIsSSR } from "../hooks/useIsSSR";
3
+ import { useIsSSR } from "../hooks/useIsSSR.js";
4
4
  /**
5
5
  * Renders children, but only on the client.
6
6
  *
@@ -3,6 +3,7 @@ type Props<T extends ElementType = "a"> = NoInfer<Omit<ComponentPropsWithRef<T>,
3
3
  href?: string | null;
4
4
  target?: string | null;
5
5
  as?: T;
6
+ preferBack?: boolean | "exact";
6
7
  };
7
8
  export declare const Link: <T extends ElementType = "a">(props: Props<T>) => ReactElement;
8
9
  /**
@@ -1,12 +1,12 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { forwardRef, useMemo } from "react";
3
3
  import { parseURL, resolveURL, withoutTrailingSlash } from "ufo";
4
- import { useIsSSR } from "../hooks/useIsSSR";
5
- import { useRouter } from "../hooks/useRouter";
6
- import { isSameOrigin } from "../utils";
7
- import { useRoute } from "../hooks/useRoute";
8
- import { useRouterState } from "../hooks/useRouterState";
9
- export const Link = forwardRef((props, ref) => {
4
+ import { useIsSSR } from "../hooks/useIsSSR.js";
5
+ import { useRouter } from "../hooks/useRouter.js";
6
+ import { isSameOrigin } from "../utils.js";
7
+ import { useRoute } from "../hooks/useRoute.js";
8
+ import { useRouterState } from "../hooks/useRouterState.js";
9
+ export const Link = forwardRef(({ preferBack, ...props }, ref) => {
10
10
  const Comp = props.as || "a";
11
11
  if (env.admin) {
12
12
  return (_jsx(Comp, { ref: ref, ...props, href: props.href ?? undefined, onClick: (e) => {
@@ -15,17 +15,16 @@ export const Link = forwardRef((props, ref) => {
15
15
  } }));
16
16
  }
17
17
  else {
18
- const preload = useRouter((r) => r.preload);
19
- const handleClickEvent = useRouter((r) => r.handleClickEvent);
18
+ const router = useRouter();
20
19
  const state = useLinkState(props.href ?? "");
21
20
  return (_jsx(Comp, { ref: ref, "data-active": state.active ?? undefined, "data-child-active": state.childActive ?? undefined, "data-pending": state.pending ?? undefined, ...props, href: props.href ?? undefined, onMouseEnter: (e) => {
22
21
  if (props.onMouseEnter) {
23
22
  props.onMouseEnter(e);
24
23
  }
25
- preload(props.href);
24
+ router.preload(props.href);
26
25
  }, onClick: (e) => {
27
26
  props.onClick?.(e);
28
- handleClickEvent(e, props.href ?? undefined);
27
+ router.handleClickEvent(e, props.href ?? undefined, preferBack);
29
28
  } }));
30
29
  }
31
30
  });
@@ -1,4 +1,4 @@
1
- import { RouteState } from "../types";
1
+ import { RouteState } from "../types.js";
2
2
  export declare const AppRenderer: import("react").MemoExoticComponent<() => import("react/jsx-runtime").JSX.Element>;
3
3
  export declare function MainRoute(): import("react/jsx-runtime").JSX.Element;
4
4
  export declare function RouteDisplay(props: {
@@ -1,15 +1,16 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { memo, Suspense, useMemo } from "react";
3
- import { RouteItemContext } from "../context";
4
- import { useRouter } from "../hooks/useRouter";
5
- import { useRouterState } from "../hooks/useRouterState";
2
+ import { memo, useMemo } from "react";
3
+ import { RouteErrorBoundary } from "../../../utils/RouteErrorBoundary.js";
4
+ import { RouteItemContext } from "../context.js";
5
+ import { useRouter } from "../hooks/useRouter.js";
6
+ import { useRouterState } from "../hooks/useRouterState.js";
6
7
  export const AppRenderer = memo(() => {
7
8
  const { appData, appComponent: AppComponent } = useRouter().loader;
8
9
  const { activeRoute } = useRouterState();
9
10
  const app = useMemo(() => {
10
11
  return (_jsx(AppComponent, { ...appData, children: _jsx(MainRoute, {}) }));
11
12
  }, [AppComponent, appData]);
12
- return (_jsx(Suspense, { children: _jsx(RouteItemContext.Provider, { value: activeRoute, children: app }) }));
13
+ return _jsx(RouteItemContext.Provider, { value: activeRoute, children: app });
13
14
  });
14
15
  export function MainRoute() {
15
16
  const activeRoute = useRouterState((s) => s.activeRoute);
@@ -22,7 +23,7 @@ export function RouteDisplay(props) {
22
23
  }
23
24
  return useMemo(() => {
24
25
  let child = !!Component && _jsx(Component, { ...props.route.props });
25
- return _jsx(RouteItemContext.Provider, { value: props.route, children: child });
26
+ return (_jsx(RouteErrorBoundary, { route: props.route, children: _jsx(RouteItemContext.Provider, { value: props.route, children: child }) }));
26
27
  }, [Component, props.route, props.route]);
27
28
  }
28
29
  RouteDisplay.displayName = "RouteDisplay";
@@ -1,6 +1,6 @@
1
1
  import { PropsWithChildren } from "react";
2
- import { RouteLoader } from "../loader";
3
- import { RouteState } from "../types";
2
+ import { RouteLoader } from "../loader.js";
3
+ import { RouteState } from "../types.js";
4
4
  type Props = PropsWithChildren<{
5
5
  route: RouteState;
6
6
  loader: RouteLoader;
@@ -1,14 +1,13 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { Suspense } from "react";
3
- import { RouterContext, RouterStateContext } from "../context";
4
- import { useRouter } from "../hooks/useRouter";
5
- import { useRouterState } from "../hooks/useRouterState";
6
- import { AppRenderer } from "./RouteRenderer";
2
+ import { RouterContext, RouterStateContext } from "../context.js";
3
+ import { useRouter } from "../hooks/useRouter.js";
4
+ import { useRouterState } from "../hooks/useRouterState.js";
5
+ import { AppRenderer } from "./RouteRenderer.js";
7
6
  export function SSRRouter(props) {
8
7
  const router = useRouter();
9
8
  const routerState = useRouterState();
10
9
  router.loader = props.loader;
11
10
  routerState.history = [props.route];
12
11
  routerState.activeRoute = props.route;
13
- return (_jsx(Suspense, { children: _jsx(RouterContext.Provider, { value: router, children: _jsx(RouterStateContext.Provider, { value: routerState, children: _jsx(AppRenderer, {}) }) }) }));
12
+ return (_jsx(RouterContext.Provider, { value: router, children: _jsx(RouterStateContext.Provider, { value: routerState, children: _jsx(AppRenderer, {}) }) }));
14
13
  }
@@ -1,4 +1,4 @@
1
- import { useRouterEvents } from "../hooks/useRouterEvents";
1
+ import { useRouterEvents } from "../hooks/useRouterEvents.js";
2
2
  /**
3
3
  * Enables scroll restoration when navigation backwards, as well as resetting scroll position when navigating forwards.
4
4
  */
@@ -1,5 +1,8 @@
1
- import { Context } from "react";
2
- import { RouterAPI, RouterAPIState } from "./types";
3
- export declare const RouterContext: Context<RouterAPI>;
4
- export declare const RouterStateContext: Context<RouterAPIState>;
5
- export declare const RouteItemContext: Context<import("./types").TypedRouteState<"_unknown", {}>>;
1
+ import { RouteMetaTag, RouterAPI, RouterAPIState } from "./types.js";
2
+ export declare const RouterContext: import("react").Context<RouterAPI>;
3
+ export declare const RouterStateContext: import("react").Context<RouterAPIState>;
4
+ export declare const RouteItemContext: import("react").Context<import("./types.js").TypedRouteState<"_unknown", {}>>;
5
+ export declare const clientMetaTags: {
6
+ tags: null | RouteMetaTag[];
7
+ setMetaTags(tags: RouteMetaTag[]): void;
8
+ };
@@ -1,5 +1,6 @@
1
1
  import { createContext } from "react";
2
- import { RouteLoader } from "./loader";
2
+ import { RouteLoader } from "./loader.js";
3
+ import { proxy } from "valtio";
3
4
  const NOOP_ROUTE = {
4
5
  component: () => null,
5
6
  id: "initial",
@@ -12,6 +13,7 @@ const NOOP_ROUTE = {
12
13
  search: "",
13
14
  query: {},
14
15
  returnState: undefined,
16
+ meta: {},
15
17
  };
16
18
  export const RouterContext = createContext({
17
19
  loader: new RouteLoader(),
@@ -25,6 +27,10 @@ export const RouterContext = createContext({
25
27
  replaceQuery(query) { },
26
28
  handleClickEvent(e, originalHref) { },
27
29
  emitEvent(event) { },
30
+ getState() {
31
+ return null;
32
+ },
33
+ restoreRoute(route) { },
28
34
  });
29
35
  export const RouterStateContext = createContext({
30
36
  history: [NOOP_ROUTE],
@@ -32,98 +38,9 @@ export const RouterStateContext = createContext({
32
38
  blockers: [],
33
39
  });
34
40
  export const RouteItemContext = createContext(NOOP_ROUTE);
35
- // type StoreHook<State> = <Slice = State>(
36
- // selector?: (state: State) => Slice,
37
- // areEqual?: (a: Slice, b: Slice) => boolean,
38
- // ) => Slice
39
- // type Store<T> = {
40
- // subscribe(sub: (value: T) => void): () => void
41
- // value: T
42
- // update(next: T): void
43
- // }
44
- // function createStore<T>(initial: T): Store<T> {
45
- // let value = initial
46
- // const subscribers = new Set<(value: T) => void>()
47
- // return {
48
- // subscribe(sub: (value: T) => void) {
49
- // subscribers.add(sub)
50
- // return () => {
51
- // subscribers.delete(sub)
52
- // }
53
- // },
54
- // get value() {
55
- // return value
56
- // },
57
- // update(nextValue: T) {
58
- // value = nextValue
59
- // if (subscribers.size) {
60
- // console.log("UPDATE", value)
61
- // startTransition(() => {
62
- // for (let sub of subscribers) {
63
- // sub(value)
64
- // }
65
- // })
66
- // }
67
- // },
68
- // }
69
- // }
70
- // export function createStoreHook<T>(store: Store<T>): StoreHook<T> {
71
- // const hook = (selector: any) => {
72
- // const get = () => (selector ? selector(store.value) : store.value)
73
- // return useSyncExternalStore(store.subscribe, get, get)
74
- // }
75
- // return hook as StoreHook<T>
76
- // }
77
- // export function createStoreContextHook<T>(ctx: Context<Store<T>>): StoreHook<T> {
78
- // const hook = (selector: any) => {
79
- // const store = useContext(ctx)
80
- // const get = () => (selector ? selector(store.value) : store.value)
81
- // return useSyncExternalStore(store.subscribe, get, get)
82
- // }
83
- // return hook as StoreHook<T>
84
- // }
85
- // export const RouterContext = createContext<Store<RouterAPI>>(null!)
86
- // export const RouterStateContext = createContext<Store<RouterAPIState>>(null!)
87
- // export const RouteContext = createContext<Store<RouteState>>(null!)
88
- // const NOOP_ROUTE: RouteState = {
89
- // component: () => null,
90
- // id: "initial",
91
- // hash: "",
92
- // key: "initial",
93
- // pathname: "",
94
- // props: {},
95
- // uri: "",
96
- // view: "_unknown",
97
- // search: "",
98
- // query: {},
99
- // returnState: undefined,
100
- // }
101
- // export const createRouteItemStore = (initial?: RouteState) => {
102
- // return createStore<RouteState>(initial ?? NOOP_ROUTE)
103
- // }
104
- // export function createRouterAPIStore(initial?: RouterAPI) {
105
- // return createStore<RouterAPI>(
106
- // initial ?? {
107
- // loader: new RouteLoader(),
108
- // async navigate(url) {},
109
- // async prefetch(url) {},
110
- // async preload(url) {},
111
- // subscribe(fn) {
112
- // return () => {}
113
- // },
114
- // replaceHash(hash) {},
115
- // replaceQuery(query) {},
116
- // handleClickEvent(e, originalHref) {},
117
- // emitEvent(event) {},
118
- // },
119
- // )
120
- // }
121
- // export function createRouterStateStore(initial?: RouterAPIState) {
122
- // return createStore<RouterAPIState>(
123
- // initial ?? {
124
- // history: [],
125
- // activeRoute: NOOP_ROUTE,
126
- // blockers: [],
127
- // },
128
- // )
129
- // }
41
+ export const clientMetaTags = proxy({
42
+ tags: null,
43
+ setMetaTags(tags) {
44
+ clientMetaTags.tags = tags;
45
+ },
46
+ });
@@ -1,5 +1,6 @@
1
+ import { Dispatch } from "react";
1
2
  /**
2
3
  * Works exactly like useState, but allows back and forward navigation to restore the previous state.
3
4
  * You must pass a unique ID as an additional first parameter to ensure the state is restored correctly.
4
5
  */
5
- export declare function useRestorableState<T>(key: string, fallback?: T): any[];
6
+ export declare function useRestorableState<T>(key: string, fallback: T): [T, Dispatch<T>];
@@ -1,5 +1,6 @@
1
1
  import { useState } from "react";
2
- import { useRoute, useRouterEvents } from "..";
2
+ import { useRouterEvents } from "./useRouterEvents.js";
3
+ import { useRoute } from "./useRoute.js";
3
4
  /**
4
5
  * Works exactly like useState, but allows back and forward navigation to restore the previous state.
5
6
  * You must pass a unique ID as an additional first parameter to ensure the state is restored correctly.
@@ -1,2 +1,17 @@
1
- import { RouteState } from "../types";
1
+ import type { RouteState } from "../types.js";
2
+ /**
3
+ * Returns the current route object.
4
+ *
5
+ * In most circumstances, this will be the active top-level route.
6
+ *
7
+ * In cases where manual rendering of routes is taking place, such as during page transitions or in some modal cases.
8
+ *
9
+ * @returns The current route
10
+ */
2
11
  export declare function useRoute(): RouteState;
12
+ /**
13
+ * Returns the current route, if it matches the specified view, otherwise null.
14
+ */
15
+ export declare function useViewRoute<V extends keyof ViewProps>(view: V): Extract<RouteState, {
16
+ view: V;
17
+ }> | null;
@@ -1,5 +1,26 @@
1
1
  import { useContext } from "react";
2
- import { RouteItemContext } from "../context";
2
+ import { RouteItemContext } from "../context.js";
3
+ /**
4
+ * Returns the current route object.
5
+ *
6
+ * In most circumstances, this will be the active top-level route.
7
+ *
8
+ * In cases where manual rendering of routes is taking place, such as during page transitions or in some modal cases.
9
+ *
10
+ * @returns The current route
11
+ */
3
12
  export function useRoute() {
4
13
  return useContext(RouteItemContext);
5
14
  }
15
+ /**
16
+ * Returns the current route, if it matches the specified view, otherwise null.
17
+ */
18
+ export function useViewRoute(view) {
19
+ const route = useContext(RouteItemContext);
20
+ if (route.view === view) {
21
+ return route;
22
+ }
23
+ else {
24
+ return null;
25
+ }
26
+ }
@@ -0,0 +1,5 @@
1
+ import { RouteMeta } from "../types";
2
+ export declare const $routeMetaStore: {
3
+ data: RouteMeta;
4
+ };
5
+ export declare function useRouteMeta(): RouteMeta;
@@ -0,0 +1,9 @@
1
+ import { proxy, useSnapshot } from "valtio";
2
+ export const $routeMetaStore = proxy({
3
+ data: {},
4
+ });
5
+ export function useRouteMeta() {
6
+ return useSnapshot($routeMetaStore, {
7
+ sync: true,
8
+ }).data;
9
+ }
@@ -1,4 +1,4 @@
1
- import type { RouteState } from "../types";
1
+ import type { RouteState } from "../types.js";
2
2
  type TransitionFunction = (currentRoute: RouteState, nextRoute: RouteState) => void | Promise<any | void>;
3
3
  export declare function useRouteTransition(func: TransitionFunction): void;
4
4
  export {};