@backtickjs/hono 0.3.0 → 0.3.1
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/README.md +4 -5
- package/dist/index.d.ts +17 -18
- package/dist/index.js +32 -25
- package/dist/index.js.map +1 -1
- package/dist/runtime.d.ts +18 -13
- package/dist/runtime.js +11 -11
- package/dist/runtime.js.map +1 -1
- package/package.json +8 -8
- package/src/index.ts +39 -33
- package/src/runtime.tsx +206 -100
package/README.md
CHANGED
|
@@ -19,18 +19,17 @@ import { Stack } from "expo-router" with { backtick: "client" };
|
|
|
19
19
|
import { Hono } from "hono";
|
|
20
20
|
import { Home } from "./Home.js";
|
|
21
21
|
|
|
22
|
-
// The root layout, around every screen: the navigator.
|
|
23
|
-
const RootLayout = cs`() => <$Stack />`;
|
|
24
|
-
|
|
25
22
|
const app = new Hono();
|
|
26
23
|
|
|
27
|
-
app.use(backtickApp(app
|
|
24
|
+
app.use(backtickApp(app));
|
|
25
|
+
// The root layout, around every screen: the navigator.
|
|
26
|
+
app.get("/_layout", (context) => context.render(cs`() => <$Stack />`));
|
|
28
27
|
app.get("/", (context) => context.render(<Home />));
|
|
29
28
|
|
|
30
29
|
export default app;
|
|
31
30
|
```
|
|
32
31
|
|
|
33
|
-
The Backtick app opens an app from one answer, which `backtickApp(app
|
|
32
|
+
The Backtick app opens an app from one answer, which `backtickApp(app)` answers: the client code that fetches each screen and keeps it while it shows. Navigation works as in Next.js, whose folders are routes here. `/_layout` is the root layout, a client component that draws the navigator; unlike Next.js's, it takes no `children`, as the navigator renders the screens. An app without one doesn't open. A screen is each segment's `_layout` (`/day/:id/_layout`, rendered for its path, answering a client component given `children`), around its `_loading` while what's under it loads, around the page. A loading state takes no params, as in Next.js: it's fetched once for its pattern, and reading a param throws; what depends on the path, such as the title, goes in a `_layout`. Every link fetches ahead what its screen needs to show, its layouts down to its first loading state and that loading state, as Next.js's `Link` prefetches; `<Link prefetch>` adds the page, and `router.prefetch(href)` fetches as a link does. A navigation pushes once those are in, at once if they were fetched ahead; with no loading state, it holds the current screen until all of it is in, as expo-router's `unstable_useIsNavigating()` says, for a progress bar. Going back shows a screen as it was. A client with a navigator of its own uses `backtickRenderer()` alone.
|
|
34
33
|
|
|
35
34
|
The runtime gives the app a [TanStack Query](https://tanstack.com/query) client whose query keys are paths: a query of `"/cart/items"` fetches that route, and its answer is what the route renders. For a screen whose parts load on their own, each in its own `Suspense`, and refetch on their own:
|
|
36
35
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { ComponentType } from "react";
|
|
1
|
+
import type { Spliceable, SplicesAs } from "@backtickjs/core";
|
|
3
2
|
import type { Hono, MiddlewareHandler } from "hono";
|
|
4
3
|
export type { Runtime } from "./runtime.js";
|
|
5
4
|
declare module "hono" {
|
|
@@ -17,30 +16,30 @@ declare module "hono" {
|
|
|
17
16
|
*
|
|
18
17
|
* The status is the context's, so `context.status(404)` makes a not-found
|
|
19
18
|
* screen, and screens are `no-store`, kept out of HTTP caches: a reload or
|
|
20
|
-
* a new open always gets the latest copy. (The Backtick app
|
|
21
|
-
*
|
|
19
|
+
* a new open always gets the latest copy. (The Backtick app fetches a page anew
|
|
20
|
+
* for each navigation, as Next.js's router does.) A client
|
|
22
21
|
* without a module the screen needs gets a 426, and any other refusal of the
|
|
23
22
|
* bundler's a 400, each with `{ name, message }`. An app the Backtick app
|
|
24
|
-
* opens uses `backtickApp(app
|
|
23
|
+
* opens uses `backtickApp(app)` instead.
|
|
25
24
|
*/
|
|
26
25
|
export declare function backtickRenderer(): MiddlewareHandler;
|
|
27
26
|
/**
|
|
28
27
|
* Hono's renderer for an app the Backtick app opens, as `backtickRenderer()`,
|
|
29
28
|
* which also answers the runtime the Backtick app fetches when it opens
|
|
30
|
-
* `app`: the client code that fetches, keeps and shows its screens
|
|
31
|
-
* its root layout, a client component that draws its `Stack`.
|
|
29
|
+
* `app`: the client code that fetches, keeps and shows its screens.
|
|
32
30
|
*
|
|
33
|
-
*
|
|
34
|
-
* app.
|
|
31
|
+
* app.use(backtickApp(app));
|
|
32
|
+
* app.get("/_layout", (context) => context.render(cs`() => <$Stack />`));
|
|
35
33
|
* app.get("/", (context) => context.render(<Home />));
|
|
36
34
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
35
|
+
* Routes nest as Next.js's folders. `/_layout` is the root layout, a client
|
|
36
|
+
* component drawing the navigator; an app without one doesn't open. A screen
|
|
37
|
+
* is each segment's `_layout` (`/city/:id/_layout`, rendered for its path,
|
|
38
|
+
* answering a client component given `children`), around its `_loading`
|
|
39
|
+
* while what's under it loads, around the page. A loading state takes no
|
|
40
|
+
* params, as in Next.js: it's fetched once for its pattern, and reading a
|
|
41
|
+
* param throws. A navigation pushes once its layouts down to its first
|
|
42
|
+
* loading state, and that loading state, are in; with none, once all of it
|
|
43
|
+
* is. Layout and loading routes written with a trailing slash are refused.
|
|
45
44
|
*/
|
|
46
|
-
export declare function backtickApp(app: Hono<any, any, any
|
|
45
|
+
export declare function backtickApp(app: Hono<any, any, any>): MiddlewareHandler;
|
package/dist/index.js
CHANGED
|
@@ -10,11 +10,11 @@ import { clientRuntime } from "./runtime.js";
|
|
|
10
10
|
*
|
|
11
11
|
* The status is the context's, so `context.status(404)` makes a not-found
|
|
12
12
|
* screen, and screens are `no-store`, kept out of HTTP caches: a reload or
|
|
13
|
-
* a new open always gets the latest copy. (The Backtick app
|
|
14
|
-
*
|
|
13
|
+
* a new open always gets the latest copy. (The Backtick app fetches a page anew
|
|
14
|
+
* for each navigation, as Next.js's router does.) A client
|
|
15
15
|
* without a module the screen needs gets a 426, and any other refusal of the
|
|
16
16
|
* bundler's a 400, each with `{ name, message }`. An app the Backtick app
|
|
17
|
-
* opens uses `backtickApp(app
|
|
17
|
+
* opens uses `backtickApp(app)` instead.
|
|
18
18
|
*/
|
|
19
19
|
export function backtickRenderer() {
|
|
20
20
|
return async (context, next) => {
|
|
@@ -25,39 +25,46 @@ export function backtickRenderer() {
|
|
|
25
25
|
/**
|
|
26
26
|
* Hono's renderer for an app the Backtick app opens, as `backtickRenderer()`,
|
|
27
27
|
* which also answers the runtime the Backtick app fetches when it opens
|
|
28
|
-
* `app`: the client code that fetches, keeps and shows its screens
|
|
29
|
-
* its root layout, a client component that draws its `Stack`.
|
|
28
|
+
* `app`: the client code that fetches, keeps and shows its screens.
|
|
30
29
|
*
|
|
31
|
-
*
|
|
32
|
-
* app.
|
|
30
|
+
* app.use(backtickApp(app));
|
|
31
|
+
* app.get("/_layout", (context) => context.render(cs`() => <$Stack />`));
|
|
33
32
|
* app.get("/", (context) => context.render(<Home />));
|
|
34
33
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
34
|
+
* Routes nest as Next.js's folders. `/_layout` is the root layout, a client
|
|
35
|
+
* component drawing the navigator; an app without one doesn't open. A screen
|
|
36
|
+
* is each segment's `_layout` (`/city/:id/_layout`, rendered for its path,
|
|
37
|
+
* answering a client component given `children`), around its `_loading`
|
|
38
|
+
* while what's under it loads, around the page. A loading state takes no
|
|
39
|
+
* params, as in Next.js: it's fetched once for its pattern, and reading a
|
|
40
|
+
* param throws. A navigation pushes once its layouts down to its first
|
|
41
|
+
* loading state, and that loading state, are in; with none, once all of it
|
|
42
|
+
* is. Layout and loading routes written with a trailing slash are refused.
|
|
43
43
|
*/
|
|
44
|
-
export function backtickApp(app
|
|
44
|
+
export function backtickApp(app) {
|
|
45
45
|
const renderer = backtickRenderer();
|
|
46
46
|
return async (context, next) => {
|
|
47
|
+
if (context.req.path.endsWith("/_loading")) {
|
|
48
|
+
context.req.param = () => {
|
|
49
|
+
throw new Error(`${context.req.routePath} reads a param: a loading state takes none, as in Next.js. What depends on the path goes in a _layout.`);
|
|
50
|
+
};
|
|
51
|
+
}
|
|
47
52
|
if (context.req.method !== "GET" || context.req.path !== runtimePath) {
|
|
48
53
|
return renderer(context, next);
|
|
49
54
|
}
|
|
50
|
-
const
|
|
55
|
+
const patterns = (name) => [
|
|
56
|
+
...new Set(app.routes
|
|
57
|
+
.filter(({ method, path }) => method === "GET" && path.endsWith(name))
|
|
58
|
+
.map(({ path }) => path)),
|
|
59
|
+
];
|
|
60
|
+
const misplaced = app.routes.find(({ path }) => path.endsWith("/_layout/") || path.endsWith("/_loading/"));
|
|
51
61
|
if (misplaced !== undefined) {
|
|
52
|
-
throw new Error(misplaced.path.
|
|
53
|
-
|
|
54
|
-
|
|
62
|
+
throw new Error(`The app's ${misplaced.path} route ends with a slash: write it ${misplaced.path.slice(0, -1)}.`);
|
|
63
|
+
}
|
|
64
|
+
if (!patterns("/_layout").includes("/_layout")) {
|
|
65
|
+
throw new Error("The app has no /_layout route: it's the root layout, a client component drawing the navigator, as cs`() => <$Stack />`.");
|
|
55
66
|
}
|
|
56
|
-
|
|
57
|
-
const loadings = app.routes
|
|
58
|
-
.filter(({ method, path }) => method === "GET" && path.endsWith("/_loading"))
|
|
59
|
-
.map(({ path }) => path);
|
|
60
|
-
return bundled(context, clientRuntime(new URL(context.req.url).origin, context.req.header("x-backtick-modules") ?? "{}", RootLayout, [...new Set(loadings)]));
|
|
67
|
+
return bundled(context, clientRuntime(new URL(context.req.url).origin, context.req.header("x-backtick-modules") ?? "{}", { layouts: patterns("/_layout"), loadings: patterns("/_loading") }));
|
|
61
68
|
};
|
|
62
69
|
}
|
|
63
70
|
// Where the Backtick app fetches the runtime it opens an app with.
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAgB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime.d.ts
CHANGED
|
@@ -8,16 +8,18 @@ export interface Runtime {
|
|
|
8
8
|
/**
|
|
9
9
|
* The app's root layout, given the href on top. A navigation holds the
|
|
10
10
|
* current screen until the next can show, as navigations are transitions
|
|
11
|
-
* (`router.setTransitionMode("always")`):
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* (`router.setTransitionMode("always")`): once its layouts down to its
|
|
12
|
+
* first loading state, and that loading state, are in, at once if they
|
|
13
|
+
* were prefetched; with no loading state, once all of it is in. Suspends
|
|
14
|
+
* until the first screen can show.
|
|
14
15
|
*/
|
|
15
16
|
Navigator?: ComponentType<{
|
|
16
17
|
href: string;
|
|
17
18
|
}>;
|
|
18
19
|
/**
|
|
19
|
-
* A route's screen
|
|
20
|
-
*
|
|
20
|
+
* A route's screen, nested as Next.js nests a page: each segment's layout,
|
|
21
|
+
* around its loading state while what's under it loads. One not `active`
|
|
22
|
+
* yet shows nothing.
|
|
21
23
|
*/
|
|
22
24
|
Screen?: ComponentType<{
|
|
23
25
|
href: string;
|
|
@@ -29,11 +31,11 @@ export interface Runtime {
|
|
|
29
31
|
*/
|
|
30
32
|
reload?(href: string): Promise<void>;
|
|
31
33
|
/**
|
|
32
|
-
* Fetches an href ahead, as Next.js prefetches
|
|
33
|
-
*
|
|
34
|
-
*
|
|
34
|
+
* Fetches an href ahead, as Next.js's `Link` prefetches: its layouts down
|
|
35
|
+
* to its first loading state, and that loading state (nothing if it has
|
|
36
|
+
* none); with `page`, its page too, as `<Link prefetch>`.
|
|
35
37
|
*/
|
|
36
|
-
prefetch?(href: string): void;
|
|
38
|
+
prefetch?(href: string, page?: boolean): void;
|
|
37
39
|
}
|
|
38
40
|
/**
|
|
39
41
|
* A route's answer, run. Any bundle is an answer, whatever its status: an
|
|
@@ -42,8 +44,11 @@ export interface Runtime {
|
|
|
42
44
|
*/
|
|
43
45
|
export declare const fetchAnswer: Client<unknown>;
|
|
44
46
|
/**
|
|
45
|
-
* The runtime of an open: for the phone at `origin` with `modules`,
|
|
46
|
-
* the app's
|
|
47
|
-
*
|
|
47
|
+
* The runtime of an open: for the phone at `origin` with `modules`, with the
|
|
48
|
+
* patterns of the app's `_layout` and `_loading` routes (`/city/:id/_layout`),
|
|
49
|
+
* so a screen asks only for those it has.
|
|
48
50
|
*/
|
|
49
|
-
export declare function clientRuntime(origin: string, modules: string,
|
|
51
|
+
export declare function clientRuntime(origin: string, modules: string, routes: {
|
|
52
|
+
layouts: readonly string[];
|
|
53
|
+
loadings: readonly string[];
|
|
54
|
+
}): Client<Runtime>;
|
package/dist/runtime.js
CHANGED
|
@@ -12,19 +12,19 @@ const Component = { "@backtickjs": "ClientImport", name: "Component", from: "rea
|
|
|
12
12
|
const Suspense = { "@backtickjs": "ClientImport", name: "Suspense", from: "react", version: "19.3.0" };
|
|
13
13
|
const useDeferredValue = { "@backtickjs": "ClientImport", name: "useDeferredValue", from: "react", version: "19.3.0" };
|
|
14
14
|
const $module0 = {
|
|
15
|
-
id: "
|
|
15
|
+
id: "3t7t976h189wg:61:27",
|
|
16
16
|
code: "(module, exports, require) => {\n\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.default = $splice0 => async (url, modules, notFoundIsNull) => {\n var response = await fetch(url, {\n headers: {\n \"x-backtick-modules\": modules\n }\n });\n if (notFoundIsNull && response.status === 404) {\n return null;\n }\n var body = await response.text();\n if (!(response.headers.get(\"content-type\") ?? \"\").startsWith(\"text/javascript\")) {\n var reason = body;\n try {\n reason = JSON.parse(body).message ?? body;\n }\n catch { }\n throw new Error(\"The screen couldn't be opened (\" + response.status + \"): \" + reason);\n }\n return await $splice0()(body);\n};\n}",
|
|
17
|
-
map: "{\"version\":3,\"file\":\"module.jsx\",\"mappings\":\";;;
|
|
17
|
+
map: "{\"version\":3,\"file\":\"module.jsx\",\"mappings\":\";;;kBA4D8BA,QAAA,WAC5BC,GAAW,EACXC,OAAe,EACfC,cAAuB;IAEvB,IAAMC,QAAQ,GAAG,MAAMC,KAAK,CAACJ,GAAG,EAAE;QAChCK,OAAO,EAAE;YAAE,oBAAoB,EAAEJ;SAAO;KACzC,CAAC;IACF,IAAIC,cAAc,IAAIC,QAAQ,CAACG,MAAM,KAAK,GAAG,EAAE;QAC7C,OAAO,IAAI;IACb;IACA,IAAMC,IAAI,GAAG,MAAMJ,QAAQ,CAACK,IAAI,EAAE;IAClC,IACE,CAAC,CAACL,QAAQ,CAACE,OAAO,CAACI,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,EAAEC,UAAU,CAAC,iBAAiB,CAAC,EAC3E;QACA,IAAIC,MAAM,GAAGJ,IAAI;QACjB,IAAI;YACFI,MAAM,GAAGC,IAAI,CAACC,KAAK,CAACN,IAAI,CAAC,CAACO,OAAO,IAAIP,IAAI;QAC3C,CAAC;QAAC,MAAM,CAAC;QACT,MAAM,IAAIQ,KAAK,CACb,iCAAiC,GAAGZ,QAAQ,CAACG,MAAM,GAAG,KAAK,GAAGK,MAAM,CACrE;IACH;IACA,OAAQ,MAAMZ,QAAA,EAAK,CAACQ,IAAa,CAAC;AACpC,CAAC\",\"names\":[\"$splice0\",\"url\",\"modules\",\"notFoundIsNull\",\"response\",\"fetch\",\"headers\",\"status\",\"body\",\"text\",\"get\",\"startsWith\",\"reason\",\"JSON\",\"parse\",\"message\",\"Error\"],\"ignoreList\":[],\"sources\":[\"@backtickjs/hono/src/runtime.tsx\"]}",
|
|
18
18
|
dependencies: [],
|
|
19
19
|
params: [{ kind: "splice", bindings: [] }],
|
|
20
20
|
kind: "function"
|
|
21
21
|
};
|
|
22
22
|
const $module1 = {
|
|
23
|
-
id: "
|
|
24
|
-
code: "(module, exports, require) => {\n\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst jsx_runtime_1 = require(\"react/jsx-runtime\");\nexports.default = ($splice0, $splice1, $splice2, $splice3, $splice4, $splice5, $splice6, $splice7, $splice8, $splice9, $splice10, $splice11, $splice12, $splice13, $splice14, $splice15, $splice16, $splice17, $splice18) => {\n var
|
|
25
|
-
map: "{\"version\":3,\"file\":\"module.jsx\",\"mappings\":\"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\",\"names\":[\"$splice0\",\"$splice1\",\"$splice2\",\"$splice3\",\"$splice4\",\"$splice5\",\"$splice6\",\"$splice7\",\"$splice8\",\"$splice9\",\"$splice10\",\"$splice11\",\"$splice12\",\"$splice13\",\"$splice14\",\"$splice15\",\"$splice16\",\"$splice17\",\"$splice18\",\"pageStaleTime\",\"loadingStaleTime\",\"queryClient\",\"defaultOptions\",\"queries\",\"queryFn\",\"context\",\"queryKey\",\"staleTime\",\"structuralSharing\",\"retry\",\"loadingQueryOptions\",\"path\",\"value\",\"loadingRouter\",\"pattern\",\"add\",\"loadingPathOf\",\"href\",\"searchStart\",\"indexOf\",\"slice\",\"loading\",\"match\",\"length\",\"undefined\",\"dropStaleAnswer\",\"startedAt\",\"query\",\"getQueryCache\",\"find\",\"exact\",\"getObserversCount\",\"state\",\"data\",\"dataUpdatedAt\",\"isStaleByTime\",\"removeQueries\",\"Page\",\"props\",\"PageWithLoading\",\"loadingResult\",\"_jsx\",\"$Suspense\",\"fallback\",\"children\",\"prefetch\",\"catch\",\"then\",\"answer\",\"Screen\",\"active\",\"AwaitQuery\",\"refetchOnMount\",\"currentNavigation\",\"NavigationHold\",\"Date\",\"now\",\"SilentErrorBoundary\",\"failed\",\"getDerivedStateFromError\",\"render\",\"Navigator\",\"$QueryClientProvider\",\"_jsxs\",\"client\",\"$RootLayout\",\"runtime\",\"reload\",\"Promise\",\"allSettled\",\"map\",\"getQueryState\",\"status\",\"resetQueries\",\"refetchQueries\"],\"ignoreList\":[],\"sources\":[\"@backtickjs/hono/src/runtime.tsx\"]}",
|
|
23
|
+
id: "3t7t976h189wg:97:9",
|
|
24
|
+
code: "(module, exports, require) => {\n\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst jsx_runtime_1 = require(\"react/jsx-runtime\");\nexports.default = ($splice0, $splice1, $splice2, $splice3, $splice4, $splice5, $splice6, $splice7, $splice8, $splice9, $splice10, $splice11, $splice12, $splice13, $splice14, $splice15, $splice16, $splice17, $splice18, $splice19, $splice20, $splice21, $splice22) => {\n var segmentStaleTime = 300000;\n var currentNavigation = {\n href: \"\",\n startedAt: 0\n };\n var fetchedAhead = new Set();\n var pageStaleTime = query => query.state.dataUpdatedAt >= currentNavigation.startedAt ? Infinity : fetchedAhead.has(query.queryKey[0]) ? segmentStaleTime : 0;\n var queryClient = new ($splice0())({\n defaultOptions: {\n queries: {\n queryFn: async (context) => $splice1()($splice2() + context.queryKey[0], $splice3(), false),\n staleTime: pageStaleTime,\n structuralSharing: false,\n retry: false\n }\n }\n });\n var pageQuery = href => ({\n queryKey: [href]\n });\n var layoutQuery = path => ({\n queryKey: [path],\n staleTime: segmentStaleTime\n });\n var loadingQuery = pattern => ({\n queryKey: [pattern],\n staleTime: segmentStaleTime,\n queryFn: async () => ({\n value: await $splice4()($splice5() + pattern, $splice6(), false)\n })\n });\n var layoutRouter = new ($splice7())();\n for (var pattern of $splice8().layouts) {\n layoutRouter.add(\"GET\", pattern, pattern);\n }\n var loadingRouter = new ($splice9())();\n for (var _pattern of $splice10().loadings) {\n loadingRouter.add(\"GET\", _pattern, _pattern);\n }\n var segmentsOf = href => {\n var searchStart = href.indexOf(\"?\");\n var path = searchStart === -1 ? href : href.slice(0, searchStart);\n var names = path.split(\"/\").filter(Boolean);\n var bases = [\"\", ...names.map((_, i) => \"/\" + names.slice(0, i + 1).join(\"/\"))];\n return bases.map(base => {\n var layout = base + \"/_layout\";\n return {\n layout: base !== \"\" && layoutRouter.match(\"GET\", layout)[0].length > 0 ? layout : undefined,\n loading: loadingRouter.match(\"GET\", base + \"/_loading\")[0][0]?.[0]\n };\n });\n };\n var shellOf = href => {\n var queries = [];\n for (var segment of segmentsOf(href)) {\n if (segment.layout !== undefined) {\n queries.push(layoutQuery(segment.layout));\n }\n if (segment.loading !== undefined) {\n queries.push(loadingQuery(segment.loading));\n return {\n queries,\n loads: true\n };\n }\n }\n queries.push(pageQuery(href));\n return {\n queries,\n loads: false\n };\n };\n var dropStaleAnswer = (query, startedAt) => {\n var cached = queryClient.getQueryCache().find({\n queryKey: query.queryKey,\n exact: true\n });\n if (cached !== undefined && cached.getObserversCount() === 0 && cached.state.data !== undefined && cached.state.dataUpdatedAt < startedAt && cached.isStaleByTime(query.staleTime ?? pageStaleTime(cached))) {\n queryClient.removeQueries({\n queryKey: query.queryKey,\n exact: true\n });\n }\n };\n var Page = props => $splice11()(pageQuery(props.href)).data;\n var Loading = props => $splice12()(loadingQuery(props.pattern)).data.value;\n var Layout = props => {\n var answer = $splice13()(layoutQuery(props.path)).data;\n if (typeof answer !== \"function\") {\n return answer;\n }\n var Answer = answer;\n return (0, jsx_runtime_1.jsx)(Answer, {\n children: props.children\n });\n };\n var Segments = props => {\n $splice14()(pageQuery(props.href));\n var node = (0, jsx_runtime_1.jsx)(Page, {\n href: props.href\n });\n var _loop = function (segment) {\n if (segment.loading !== undefined) {\n node = ($Suspense => (0, jsx_runtime_1.jsx)($Suspense, {\n fallback: (0, jsx_runtime_1.jsx)(Loading, {\n pattern: segment.loading\n }),\n children: node\n }))($splice15());\n }\n if (segment.layout !== undefined) {\n node = (0, jsx_runtime_1.jsx)(Layout, {\n path: segment.layout,\n children: node\n });\n }\n };\n for (var segment of segmentsOf(props.href).reverse()) {\n _loop(segment);\n }\n return node;\n };\n var prefetch = (href, page = false) => {\n var shell = shellOf(href);\n if (page) {\n fetchedAhead.add(href);\n }\n var queries = page ? [...shell.queries, pageQuery(href)] : shell.loads ? shell.queries : [];\n for (var query of queries) {\n void queryClient.query(query).catch(() => { });\n }\n };\n for (var _pattern2 of $splice16().loadings) {\n void queryClient.query(loadingQuery(_pattern2)).catch(() => { });\n }\n var Screen = props => {\n var href = $splice17()(props.href);\n return props.active ? ($Suspense => (0, jsx_runtime_1.jsx)($Suspense, {\n fallback: null,\n children: (0, jsx_runtime_1.jsx)(Segments, {\n href: href\n })\n }))($splice18()) : null;\n };\n var AwaitQueries = props => {\n $splice19()({\n queries: props.queries.map(query => ({\n ...query,\n refetchOnMount: false\n }))\n });\n return null;\n };\n var NavigationHold = props => {\n if (currentNavigation.href !== props.href) {\n currentNavigation = {\n href: props.href,\n startedAt: Date.now()\n };\n }\n var shell = shellOf(props.href);\n for (var query of [...shell.queries, pageQuery(props.href)]) {\n dropStaleAnswer(query, currentNavigation.startedAt);\n }\n var shown = (queryClient.getQueryCache().find({\n queryKey: [props.href],\n exact: true\n })?.getObserversCount() ?? 0) > 0;\n if (!shown) {\n void queryClient.query(pageQuery(props.href)).catch(() => { });\n }\n return (0, jsx_runtime_1.jsx)(AwaitQueries, {\n queries: shell.queries\n });\n };\n class SilentErrorBoundary extends $splice20() {\n state = {\n failed: false\n };\n static getDerivedStateFromError() {\n return {\n failed: true\n };\n }\n render() {\n return this.state.failed ? null : this.props.children;\n }\n }\n var RootLayout = () => {\n var answer = $splice21()({\n queryKey: [\"/_layout\"],\n staleTime: Infinity\n }).data;\n if (typeof answer !== \"function\") {\n throw new Error(\"The app's /_layout answers no component: it's the root layout, a client component drawing the navigator (a Stack).\");\n }\n var Answer = answer;\n return (0, jsx_runtime_1.jsx)(Answer, {});\n };\n var Navigator = props => ($QueryClientProvider => (0, jsx_runtime_1.jsxs)($QueryClientProvider, {\n client: queryClient,\n children: [(0, jsx_runtime_1.jsx)(SilentErrorBoundary, {\n children: (0, jsx_runtime_1.jsx)(NavigationHold, {\n href: props.href\n })\n }, props.href), (0, jsx_runtime_1.jsx)(RootLayout, {})]\n }))($splice22());\n var runtime = {\n Navigator,\n Screen,\n prefetch,\n reload: async (href) => {\n var paths = [href, ...segmentsOf(href).flatMap(segment => segment.layout === undefined ? [] : [segment.layout])];\n await Promise.allSettled(paths.map(path => queryClient.getQueryState([path])?.status === \"error\" ? queryClient.resetQueries({\n queryKey: [path],\n exact: true\n }) : queryClient.refetchQueries({\n queryKey: [path],\n exact: true\n })));\n }\n };\n return runtime;\n};\n}",
|
|
25
|
+
map: "{\"version\":3,\"file\":\"module.jsx\",\"mappings\":\";;;;kBAgGY,CAAAA,QAAA,EAAAC,QAAA,EAAAC,QAAA,EAAAC,QAAA,EAAAC,QAAA,EAAAC,QAAA,EAAAC,QAAA,EAAAC,QAAA,EAAAC,QAAA,EAAAC,QAAA,EAAAC,SAAA,EAAAC,SAAA,EAAAC,SAAA,EAAAC,SAAA,EAAAC,SAAA,EAAAC,SAAA,EAAAC,SAAA,EAAAC,SAAA,EAAAC,SAAA,EAAAC,SAAA,EAAAC,SAAA,EAAAC,SAAA,EAAAC,SAAA;IAMR,IAAMC,gBAAgB,GAAG,MAAM;IAG/B,IAAIC,iBAAiB,GAAG;QAAEC,IAAI,EAAE,EAAE;QAAEC,SAAS,EAAE;KAAG;IAClD,IAAMC,YAAY,GAAG,IAAIC,GAAG,EAAU;IACtC,IAAMC,aAAa,GAAIC,KAGtB,IACCA,KAAK,CAACC,KAAK,CAACC,aAAa,IAAIR,iBAAiB,CAACE,SAAS,GACpDO,QAAQ,GACRN,YAAY,CAACO,GAAG,CAACJ,KAAK,CAACK,QAAQ,CAAC,CAAC,CAAW,CAAC,GAC3CZ,gBAAgB,GAChB,CAAC;IACT,IAAMa,WAAW,GAAG,KAAIpC,QAAA,EAAY,EAAC;QACnCqC,cAAc,EAAE;YACdC,OAAO,EAAE;gBACPC,OAAO,EAAE,OAAOC,OAAyC,KACvDvC,QAAA,EAAY,CACVC,QAAA,EAAO,GAAIsC,OAAO,CAACL,QAAQ,CAAC,CAAC,CAAY,EACzChC,QAAA,EAAQ,EACR,KAAK,CACN;gBACHsC,SAAS,EAAEZ,aAAa;gBACxBa,iBAAiB,EAAE,KAAK;gBACxBC,KAAK,EAAE;;;KAGZ,CAAC;IAMF,IAAMC,SAAS,GAAInB,IAAY,KAAa;QAAEU,QAAQ,EAAE,CAACV,IAAI;KAAG,CAAC;IACjE,IAAMoB,WAAW,GAAIC,IAAY,KAAa;QAC5CX,QAAQ,EAAE,CAACW,IAAI,CAAC;QAChBL,SAAS,EAAElB;KACZ,CAAC;IAGF,IAAMwB,YAAY,GAAIC,OAAe,KAAM;QACzCb,QAAQ,EAAE,CAACa,OAAO,CAAC;QACnBP,SAAS,EAAElB,gBAAgB;QAC3BgB,OAAO,EAAE,aAAa;YACpBU,KAAK,EAAG,MAAM7C,QAAA,EAAY,CACxBC,QAAA,EAAO,GAAG2C,OAAO,EACjB1C,QAAA,EAAQ,EACR,KAAK;SAER;KACF,CAAC;IAGF,IAAM4C,YAAY,GAAG,KAAI3C,QAAA,EAAc,GAAU;IACjD,KAAK,IAAMyC,OAAO,IAAIxC,QAAA,EAAO,CAAC2C,OAAO,EAAE;QACrCD,YAAY,CAACE,GAAG,CAAC,KAAK,EAAEJ,OAAO,EAAEA,OAAO,CAAC;IAC3C;IACA,IAAMK,aAAa,GAAG,KAAI5C,QAAA,EAAc,GAAU;IAClD,KAAK,IAAMuC,QAAO,IAAItC,SAAA,EAAO,CAAC4C,QAAQ,EAAE;QACtCD,aAAa,CAACD,GAAG,CAAC,KAAK,EAAEJ,QAAO,EAAEA,QAAO,CAAC;IAC5C;IAIA,IAAMO,UAAU,GAAI9B,IAAY;QAC9B,IAAM+B,WAAW,GAAG/B,IAAI,CAACgC,OAAO,CAAC,GAAG,CAAC;QACrC,IAAMX,IAAI,GAAGU,WAAW,KAAK,CAAC,CAAC,GAAG/B,IAAI,GAAGA,IAAI,CAACiC,KAAK,CAAC,CAAC,EAAEF,WAAW,CAAC;QACnE,IAAMG,KAAK,GAAGb,IAAI,CAACc,KAAK,CAAC,GAAG,CAAC,CAACC,MAAM,CAACC,OAAO,CAAC;QAC7C,IAAMC,KAAK,GAAG,CACZ,EAAE,EACF,GAAGJ,KAAK,CAACK,GAAG,CAAC,CAACC,CAAC,EAAEC,CAAC,KAAK,GAAG,GAAGP,KAAK,CAACD,KAAK,CAAC,CAAC,EAAEQ,CAAC,GAAG,CAAC,CAAC,CAACC,IAAI,CAAC,GAAG,CAAC,CAAC,CAC9D;QACD,OAAOJ,KAAK,CAACC,GAAG,CAAEI,IAAI;YACpB,IAAMC,MAAM,GAAGD,IAAI,GAAG,UAAU;YAChC,OAAO;gBACLC,MAAM,EACJD,IAAI,KAAK,EAAE,IAAIlB,YAAY,CAACoB,KAAK,CAAC,KAAK,EAAED,MAAM,CAAC,CAAC,CAAC,CAAC,CAACE,MAAM,GAAG,CAAC,GAC1DF,MAAM,GACNG,SAAS;gBACfC,OAAO,EAAEpB,aAAa,CAACiB,KAAK,CAAC,KAAK,EAAEF,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;aAClE;QACH,CAAC,CAAC;IACJ,CAAC;IAID,IAAMM,OAAO,GAAIjD,IAAY;QAC3B,IAAMa,OAAO,GAAY,EAAE;QAC3B,KAAK,IAAMqC,OAAO,IAAIpB,UAAU,CAAC9B,IAAI,CAAC,EAAE;YACtC,IAAIkD,OAAO,CAACN,MAAM,KAAKG,SAAS,EAAE;gBAChClC,OAAO,CAACsC,IAAI,CAAC/B,WAAW,CAAC8B,OAAO,CAACN,MAAM,CAAC,CAAC;YAC3C;YACA,IAAIM,OAAO,CAACF,OAAO,KAAKD,SAAS,EAAE;gBACjClC,OAAO,CAACsC,IAAI,CAAC7B,YAAY,CAAC4B,OAAO,CAACF,OAAO,CAAC,CAAC;gBAC3C,OAAO;oBAAEnC,OAAO;oBAAEuC,KAAK,EAAE;iBAAM;YACjC;QACF;QACAvC,OAAO,CAACsC,IAAI,CAAChC,SAAS,CAACnB,IAAI,CAAC,CAAC;QAC7B,OAAO;YAAEa,OAAO;YAAEuC,KAAK,EAAE;SAAO;IAClC,CAAC;IAKD,IAAMC,eAAe,GAAGA,CAAChD,KAAY,EAAEJ,SAAiB;QACtD,IAAMqD,MAAM,GAAG3C,WAAW,CACvB4C,aAAa,EAAE,CACfC,IAAI,CAAC;YAAE9C,QAAQ,EAAEL,KAAK,CAACK,QAAQ;YAAE+C,KAAK,EAAE;SAAM,CAAC;QAClD,IACEH,MAAM,KAAKP,SAAS,IACpBO,MAAM,CAACI,iBAAiB,EAAE,KAAK,CAAC,IAChCJ,MAAM,CAAChD,KAAK,CAACqD,IAAI,KAAKZ,SAAS,IAC/BO,MAAM,CAAChD,KAAK,CAACC,aAAa,GAAGN,SAAS,IACtCqD,MAAM,CAACM,aAAa,CAACvD,KAAK,CAACW,SAAS,IAAIZ,aAAa,CAACkD,MAAM,CAAC,CAAC,EAC9D;YACA3C,WAAW,CAACkD,aAAa,CAAC;gBAAEnD,QAAQ,EAAEL,KAAK,CAACK,QAAQ;gBAAE+C,KAAK,EAAE;aAAM,CAAC;QACtE;IACF,CAAC;IAED,IAAMK,IAAI,GAAIC,KAAuB,IACnC7E,SAAA,EAAiB,CAACiC,SAAS,CAAC4C,KAAK,CAAC/D,IAAI,CAAC,CAAC,CAAC2D,IAAiB;IAC5D,IAAMK,OAAO,GAAID,KAA0B,IACzC5E,SAAA,EAAiB,CAACmC,YAAY,CAACyC,KAAK,CAACxC,OAAO,CAAC,CAAC,CAACoC,IAAI,CAACnC,KAAK;IAG3D,IAAMyC,MAAM,GAAIF,KAA4C;QAC1D,IAAMG,MAAM,GAAG9E,SAAA,EAAiB,CAACgC,WAAW,CAAC2C,KAAK,CAAC1C,IAAI,CAAC,CAAC,CAACsC,IAAI;QAC9D,IAAI,OAAOO,MAAM,KAAK,UAAU,EAAE;YAChC,OAAOA,MAAmB;QAC5B;QACA,IAAMC,MAAM,GAAGD,MAAgD;QAC/D,OAAOE,qBAAA,EAACD,MAAM;YAAAE,QAAA,EAAEN,KAAK,CAACM;SAAQ,CAAU;IAC1C,CAAC;IAID,IAAMC,QAAQ,GAAIP,KAAuB;QACvC1E,SAAA,EAAiB,CAAC8B,SAAS,CAAC4C,KAAK,CAAC/D,IAAI,CAAC,CAAC;QACxC,IAAIuE,IAAI,GAAcH,qBAAA,EAACN,IAAI;YAAC9D,IAAI,EAAE+D,KAAK,CAAC/D;SAAI,CAAI;QAAC,IAAAwE,KAAA,aAAAtB,OAAA;YAE/C,IAAIA,OAAO,CAACF,OAAO,KAAKD,SAAS,EAAE;gBACjCwB,IAAI,GACF,CAAAE,SAAA,IAAAL,qBAAA,EAACK,SAAS;oBAACC,QAAQ,EAAEN,qBAAA,EAACJ,OAAO;wBAACzC,OAAO,EAAE2B,OAAO,CAACF;qBAAO,CAAI;oBAAAqB,QAAA,EACvDE;iBAAI,CACK,EAFXjF,SAAA,EAAS,CAGX;YACH;YACA,IAAI4D,OAAO,CAACN,MAAM,KAAKG,SAAS,EAAE;gBAChCwB,IAAI,GAAGH,qBAAA,EAACH,MAAM;oBAAC5C,IAAI,EAAE6B,OAAO,CAACN,MAAM;oBAAAyB,QAAA,EAAGE;iBAAI,CAAU;YACtD;QACF,CAAC;QAXD,KAAK,IAAMrB,OAAO,IAAIpB,UAAU,CAACiC,KAAK,CAAC/D,IAAI,CAAC,CAAC2E,OAAO,EAAE;YAAAH,KAAA,CAAAtB,OAAA;QAAA;QAYtD,OAAOqB,IAAI;IACb,CAAC;IAKD,IAAMK,QAAQ,GAAGA,CAAC5E,IAAY,EAAE6E,IAAI,GAAG,KAAK;QAC1C,IAAMC,KAAK,GAAG7B,OAAO,CAACjD,IAAI,CAAC;QAC3B,IAAI6E,IAAI,EAAE;YACR3E,YAAY,CAACyB,GAAG,CAAC3B,IAAI,CAAC;QACxB;QACA,IAAMa,OAAO,GAAGgE,IAAI,GAChB,CAAC,GAAGC,KAAK,CAACjE,OAAO,EAAEM,SAAS,CAACnB,IAAI,CAAC,CAAC,GACnC8E,KAAK,CAAC1B,KAAK,GACT0B,KAAK,CAACjE,OAAO,GACb,EAAE;QACR,KAAK,IAAMR,KAAK,IAAIQ,OAAO,EAAE;YAC3B,KAAKF,WAAW,CAACN,KAAK,CAACA,KAAK,CAAC,CAAC0E,KAAK,CAAC,QAAO,CAAC,CAAC;QAC/C;IACF,CAAC;IAED,KAAK,IAAMxD,SAAO,IAAIhC,SAAA,EAAO,CAACsC,QAAQ,EAAE;QACtC,KAAKlB,WAAW,CAACN,KAAK,CAACiB,YAAY,CAACC,SAAO,CAAC,CAAC,CAACwD,KAAK,CAAC,QAAO,CAAC,CAAC;IAC/D;IAIA,IAAMC,MAAM,GAAIjB,KAAwC;QACtD,IAAM/D,IAAI,GAAGR,SAAA,EAAiB,CAACuE,KAAK,CAAC/D,IAAI,CAAC;QAC1C,OAAO+D,KAAK,CAACkB,MAAM,GACjB,CAAAR,SAAA,IAAAL,qBAAA,EAACK,SAAS;YAACC,QAAQ,EAAE,IAAI;YAAAL,QAAA,EACvBD,qBAAA,EAACE,QAAQ;gBAACtE,IAAI,EAAEA;aAAI;SACtB,CAAY,EAFXP,SAAA,EAAS,CAEE,GACV,IAAI;IACV,CAAC;IAID,IAAMyF,YAAY,GAAInB,KAA2B;QAC/CrE,SAAA,EAAmB,CAAC;YAClBmB,OAAO,EAAEkD,KAAK,CAAClD,OAAO,CAAC0B,GAAG,CAAElC,KAAK,KAAM;gBACrC,GAAGA,KAAK;gBACR8E,cAAc,EAAE;aACjB,CAAC;SACH,CAAC;QACF,OAAO,IAAI;IACb,CAAC;IAKD,IAAMC,cAAc,GAAIrB,KAAuB;QAC7C,IAAIhE,iBAAiB,CAACC,IAAI,KAAK+D,KAAK,CAAC/D,IAAI,EAAE;YACzCD,iBAAiB,GAAG;gBAAEC,IAAI,EAAE+D,KAAK,CAAC/D,IAAI;gBAAEC,SAAS,EAAEoF,IAAI,CAACC,GAAG;aAAI;QACjE;QACA,IAAMR,KAAK,GAAG7B,OAAO,CAACc,KAAK,CAAC/D,IAAI,CAAC;QACjC,KAAK,IAAMK,KAAK,IAAI,CAAC,GAAGyE,KAAK,CAACjE,OAAO,EAAEM,SAAS,CAAC4C,KAAK,CAAC/D,IAAI,CAAC,CAAC,EAAE;YAC7DqD,eAAe,CAAChD,KAAK,EAAEN,iBAAiB,CAACE,SAAS,CAAC;QACrD;QAGA,IAAMsF,KAAK,GACT,CAAC5E,WAAW,CACT4C,aAAa,EAAE,CACfC,IAAI,CAAC;YAAE9C,QAAQ,EAAE,CAACqD,KAAK,CAAC/D,IAAI,CAAC;YAAEyD,KAAK,EAAE;SAAM,CAAC,EAC5CC,iBAAiB,EAAE,IAAI,CAAC,IAAI,CAAC;QACnC,IAAI,CAAC6B,KAAK,EAAE;YACV,KAAK5E,WAAW,CAACN,KAAK,CAACc,SAAS,CAAC4C,KAAK,CAAC/D,IAAI,CAAC,CAAC,CAAC+E,KAAK,CAAC,QAAO,CAAC,CAAC;QAC/D;QACA,OAAOX,qBAAA,EAACc,YAAY;YAACrE,OAAO,EAAEiE,KAAK,CAACjE;SAAO,CAAI;IACjD,CAAC;IACD,MAAM2E,mBAAoB,SAAQ7F,SAAA,EAGjC;QACCW,KAAK,GAAG;YAAEmF,MAAM,EAAE;SAAO;QACzB,OAAOC,wBAAwBA;YAC7B,OAAO;gBAAED,MAAM,EAAE;aAAM;QACzB;QACAE,MAAMA;YACJ,OAAO,IAAI,CAACrF,KAAK,CAACmF,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC1B,KAAK,CAACM,QAAQ;QACvD;;IAKF,IAAMuB,UAAU,GAAGA,GAAA;QACjB,IAAM1B,MAAM,GAAGtE,SAAA,EAAiB,CAAC;YAC/Bc,QAAQ,EAAE,CAAC,UAAU,CAAC;YACtBM,SAAS,EAAER;SACZ,CAAC,CAACmD,IAAI;QACP,IAAI,OAAOO,MAAM,KAAK,UAAU,EAAE;YAChC,MAAM,IAAI2B,KAAK,CACb,oHAAoH,CACrH;QACH;QACA,IAAM1B,MAAM,GAAGD,MAAuB;QACtC,OAAOE,qBAAA,EAACD,MAAM,KAAG;IACnB,CAAC;IAED,IAAM2B,SAAS,GAAI/B,KAAuB,IACxC,CAAAgC,oBAAA,IAAAC,sBAAA,EAACD,oBAAoB;QAACE,MAAM,EAAEtF,WAAW;QAAA0D,QAAA,GACvCD,qBAAA,EAACoB,mBAAmB;gBAAAnB,QAAA,EAClBD,qBAAA,EAACgB,cAAc;oBAACpF,IAAI,EAAE+D,KAAK,CAAC/D;iBAAI;aAClC,EAF0B+D,KAAK,CAAC/D,IAAI,CAGpC,EAAAoE,qBAAA,EAACwB,UAAU,KACb;KAAA,CAAuB,EALtB/F,SAAA,EAAoB,CAMtB;IAED,IAAMqG,OAAO,GAAY;QACvBJ,SAAS;QACTd,MAAM;QACNJ,QAAQ;QAGRuB,MAAM,EAAE,OAAOnG,IAAI;YACjB,IAAMoG,KAAK,GAAG,CACZpG,IAAI,EACJ,GAAG8B,UAAU,CAAC9B,IAAI,CAAC,CAACqG,OAAO,CAAEnD,OAAO,IAClCA,OAAO,CAACN,MAAM,KAAKG,SAAS,GAAG,EAAE,GAAG,CAACG,OAAO,CAACN,MAAM,CAAC,CACrD,CACF;YACD,MAAM0D,OAAO,CAACC,UAAU,CACtBH,KAAK,CAAC7D,GAAG,CAAElB,IAAI,IACbV,WAAW,CAAC6F,aAAa,CAAC,CAACnF,IAAI,CAAC,CAAC,EAAEoF,MAAM,KAAK,OAAO,GACjD9F,WAAW,CAAC+F,YAAY,CAAC;gBAAEhG,QAAQ,EAAE,CAACW,IAAI,CAAC;gBAAEoC,KAAK,EAAE;aAAM,CAAC,GAC3D9C,WAAW,CAACgG,cAAc,CAAC;gBAAEjG,QAAQ,EAAE,CAACW,IAAI,CAAC;gBAAEoC,KAAK,EAAE;aAAM,CAAC,CAClE,CACF;QACH;KACD;IACD,OAAOyC,OAAO;AAChB,CAAC\",\"names\":[\"$splice0\",\"$splice1\",\"$splice2\",\"$splice3\",\"$splice4\",\"$splice5\",\"$splice6\",\"$splice7\",\"$splice8\",\"$splice9\",\"$splice10\",\"$splice11\",\"$splice12\",\"$splice13\",\"$splice14\",\"$splice15\",\"$splice16\",\"$splice17\",\"$splice18\",\"$splice19\",\"$splice20\",\"$splice21\",\"$splice22\",\"segmentStaleTime\",\"currentNavigation\",\"href\",\"startedAt\",\"fetchedAhead\",\"Set\",\"pageStaleTime\",\"query\",\"state\",\"dataUpdatedAt\",\"Infinity\",\"has\",\"queryKey\",\"queryClient\",\"defaultOptions\",\"queries\",\"queryFn\",\"context\",\"staleTime\",\"structuralSharing\",\"retry\",\"pageQuery\",\"layoutQuery\",\"path\",\"loadingQuery\",\"pattern\",\"value\",\"layoutRouter\",\"layouts\",\"add\",\"loadingRouter\",\"loadings\",\"segmentsOf\",\"searchStart\",\"indexOf\",\"slice\",\"names\",\"split\",\"filter\",\"Boolean\",\"bases\",\"map\",\"_\",\"i\",\"join\",\"base\",\"layout\",\"match\",\"length\",\"undefined\",\"loading\",\"shellOf\",\"segment\",\"push\",\"loads\",\"dropStaleAnswer\",\"cached\",\"getQueryCache\",\"find\",\"exact\",\"getObserversCount\",\"data\",\"isStaleByTime\",\"removeQueries\",\"Page\",\"props\",\"Loading\",\"Layout\",\"answer\",\"Answer\",\"_jsx\",\"children\",\"Segments\",\"node\",\"_loop\",\"$Suspense\",\"fallback\",\"reverse\",\"prefetch\",\"page\",\"shell\",\"catch\",\"Screen\",\"active\",\"AwaitQueries\",\"refetchOnMount\",\"NavigationHold\",\"Date\",\"now\",\"shown\",\"SilentErrorBoundary\",\"failed\",\"getDerivedStateFromError\",\"render\",\"RootLayout\",\"Error\",\"Navigator\",\"$QueryClientProvider\",\"_jsxs\",\"client\",\"runtime\",\"reload\",\"paths\",\"flatMap\",\"Promise\",\"allSettled\",\"getQueryState\",\"status\",\"resetQueries\",\"refetchQueries\"],\"ignoreList\":[],\"sources\":[\"@backtickjs/hono/src/runtime.tsx\"]}",
|
|
26
26
|
dependencies: ["react/jsx-runtime"],
|
|
27
|
-
params: [{ kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }],
|
|
27
|
+
params: [{ kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }, { kind: "splice", bindings: [] }],
|
|
28
28
|
kind: "block"
|
|
29
29
|
};
|
|
30
30
|
/**
|
|
@@ -34,11 +34,11 @@ const $module1 = {
|
|
|
34
34
|
*/
|
|
35
35
|
export const fetchAnswer = cs.create($module0, [exec]);
|
|
36
36
|
/**
|
|
37
|
-
* The runtime of an open: for the phone at `origin` with `modules`,
|
|
38
|
-
* the app's
|
|
39
|
-
*
|
|
37
|
+
* The runtime of an open: for the phone at `origin` with `modules`, with the
|
|
38
|
+
* patterns of the app's `_layout` and `_loading` routes (`/city/:id/_layout`),
|
|
39
|
+
* so a screen asks only for those it has.
|
|
40
40
|
*/
|
|
41
|
-
export function clientRuntime(origin, modules,
|
|
42
|
-
return cs.create($module1, [QueryClient, fetchAnswer, origin, modules, fetchAnswer, origin, modules, PatternRouter,
|
|
41
|
+
export function clientRuntime(origin, modules, routes) {
|
|
42
|
+
return cs.create($module1, [QueryClient, fetchAnswer, origin, modules, fetchAnswer, origin, modules, PatternRouter, routes, PatternRouter, routes, useSuspenseQuery, useSuspenseQuery, useSuspenseQuery, usePrefetchQuery, Suspense, routes, useDeferredValue, Suspense, useSuspenseQueries, Component, useSuspenseQuery, QueryClientProvider]);
|
|
43
43
|
}
|
|
44
44
|
//# sourceMappingURL=runtime.js.map
|
package/dist/runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.tsx"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,2EAA2E;AAC3E,mCAAmC;AACnC,OAAO,EAAe,EAAE,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.tsx"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,2EAA2E;AAC3E,mCAAmC;AACnC,OAAO,EAAe,EAAE,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDzD;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,8BAwBtB,CAAC;AAEH;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAc,EACd,OAAe,EACf,MAAmE;IAEnE,gVAkSG;AACL,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backtickjs/hono",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Hono routes as Backtick screens: a route's answer is its server components, bundled for the client that asked",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"backtick",
|
|
@@ -37,18 +37,18 @@
|
|
|
37
37
|
"access": "public"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@backtickjs/bundler": "0.3.
|
|
41
|
-
"@backtickjs/core": "0.3.
|
|
40
|
+
"@backtickjs/bundler": "0.3.1",
|
|
41
|
+
"@backtickjs/core": "0.3.1"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"hono": "^4.13.13"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@backtickjs/expo": "0.3.
|
|
48
|
-
"@backtickjs/jsx-react": "0.3.
|
|
49
|
-
"@backtickjs/prettier-plugin": "0.3.
|
|
50
|
-
"@backtickjs/tsc": "0.3.
|
|
51
|
-
"@backtickjs/tspatch-plugin": "0.3.
|
|
47
|
+
"@backtickjs/expo": "0.3.1",
|
|
48
|
+
"@backtickjs/jsx-react": "0.3.1",
|
|
49
|
+
"@backtickjs/prettier-plugin": "0.3.1",
|
|
50
|
+
"@backtickjs/tsc": "0.3.1",
|
|
51
|
+
"@backtickjs/tspatch-plugin": "0.3.1",
|
|
52
52
|
"@tanstack/react-query": "5.104.0",
|
|
53
53
|
"@types/react": "19.3.0",
|
|
54
54
|
"hono": "^4.13.13",
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { bundler, BundlerError, type Modules } from "@backtickjs/bundler";
|
|
2
|
-
import type {
|
|
3
|
-
import type { ComponentType } from "react";
|
|
2
|
+
import type { Spliceable, SplicesAs } from "@backtickjs/core";
|
|
4
3
|
import type { Context, Hono, MiddlewareHandler } from "hono";
|
|
5
4
|
import { clientRuntime } from "./runtime.js";
|
|
6
5
|
|
|
@@ -26,11 +25,11 @@ declare module "hono" {
|
|
|
26
25
|
*
|
|
27
26
|
* The status is the context's, so `context.status(404)` makes a not-found
|
|
28
27
|
* screen, and screens are `no-store`, kept out of HTTP caches: a reload or
|
|
29
|
-
* a new open always gets the latest copy. (The Backtick app
|
|
30
|
-
*
|
|
28
|
+
* a new open always gets the latest copy. (The Backtick app fetches a page anew
|
|
29
|
+
* for each navigation, as Next.js's router does.) A client
|
|
31
30
|
* without a module the screen needs gets a 426, and any other refusal of the
|
|
32
31
|
* bundler's a 400, each with `{ name, message }`. An app the Backtick app
|
|
33
|
-
* opens uses `backtickApp(app
|
|
32
|
+
* opens uses `backtickApp(app)` instead.
|
|
34
33
|
*/
|
|
35
34
|
export function backtickRenderer(): MiddlewareHandler {
|
|
36
35
|
return async (context, next) => {
|
|
@@ -42,54 +41,61 @@ export function backtickRenderer(): MiddlewareHandler {
|
|
|
42
41
|
/**
|
|
43
42
|
* Hono's renderer for an app the Backtick app opens, as `backtickRenderer()`,
|
|
44
43
|
* which also answers the runtime the Backtick app fetches when it opens
|
|
45
|
-
* `app`: the client code that fetches, keeps and shows its screens
|
|
46
|
-
* its root layout, a client component that draws its `Stack`.
|
|
44
|
+
* `app`: the client code that fetches, keeps and shows its screens.
|
|
47
45
|
*
|
|
48
|
-
*
|
|
49
|
-
* app.
|
|
46
|
+
* app.use(backtickApp(app));
|
|
47
|
+
* app.get("/_layout", (context) => context.render(cs`() => <$Stack />`));
|
|
50
48
|
* app.get("/", (context) => context.render(<Home />));
|
|
51
49
|
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
50
|
+
* Routes nest as Next.js's folders. `/_layout` is the root layout, a client
|
|
51
|
+
* component drawing the navigator; an app without one doesn't open. A screen
|
|
52
|
+
* is each segment's `_layout` (`/city/:id/_layout`, rendered for its path,
|
|
53
|
+
* answering a client component given `children`), around its `_loading`
|
|
54
|
+
* while what's under it loads, around the page. A loading state takes no
|
|
55
|
+
* params, as in Next.js: it's fetched once for its pattern, and reading a
|
|
56
|
+
* param throws. A navigation pushes once its layouts down to its first
|
|
57
|
+
* loading state, and that loading state, are in; with none, once all of it
|
|
58
|
+
* is. Layout and loading routes written with a trailing slash are refused.
|
|
60
59
|
*/
|
|
61
|
-
export function backtickApp(
|
|
62
|
-
app: Hono<any, any, any>,
|
|
63
|
-
RootLayout: Client<ComponentType>,
|
|
64
|
-
): MiddlewareHandler {
|
|
60
|
+
export function backtickApp(app: Hono<any, any, any>): MiddlewareHandler {
|
|
65
61
|
const renderer = backtickRenderer();
|
|
66
62
|
return async (context, next) => {
|
|
63
|
+
if (context.req.path.endsWith("/_loading")) {
|
|
64
|
+
context.req.param = () => {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`${context.req.routePath} reads a param: a loading state takes none, as in Next.js. What depends on the path goes in a _layout.`,
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
}
|
|
67
70
|
if (context.req.method !== "GET" || context.req.path !== runtimePath) {
|
|
68
71
|
return renderer(context, next);
|
|
69
72
|
}
|
|
73
|
+
const patterns = (name: string) => [
|
|
74
|
+
...new Set(
|
|
75
|
+
app.routes
|
|
76
|
+
.filter(({ method, path }) => method === "GET" && path.endsWith(name))
|
|
77
|
+
.map(({ path }) => path),
|
|
78
|
+
),
|
|
79
|
+
];
|
|
70
80
|
const misplaced = app.routes.find(
|
|
71
|
-
({ path }) => path.endsWith("/
|
|
81
|
+
({ path }) => path.endsWith("/_layout/") || path.endsWith("/_loading/"),
|
|
72
82
|
);
|
|
73
83
|
if (misplaced !== undefined) {
|
|
74
84
|
throw new Error(
|
|
75
|
-
misplaced.path.
|
|
76
|
-
|
|
77
|
-
|
|
85
|
+
`The app's ${misplaced.path} route ends with a slash: write it ${misplaced.path.slice(0, -1)}.`,
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
if (!patterns("/_layout").includes("/_layout")) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
"The app has no /_layout route: it's the root layout, a client component drawing the navigator, as cs`() => <$Stack />`.",
|
|
78
91
|
);
|
|
79
92
|
}
|
|
80
|
-
// The app's loading states, by pattern.
|
|
81
|
-
const loadings = app.routes
|
|
82
|
-
.filter(
|
|
83
|
-
({ method, path }) => method === "GET" && path.endsWith("/_loading"),
|
|
84
|
-
)
|
|
85
|
-
.map(({ path }) => path);
|
|
86
93
|
return bundled(
|
|
87
94
|
context,
|
|
88
95
|
clientRuntime(
|
|
89
96
|
new URL(context.req.url).origin,
|
|
90
97
|
context.req.header("x-backtick-modules") ?? "{}",
|
|
91
|
-
|
|
92
|
-
[...new Set(loadings)],
|
|
98
|
+
{ layouts: patterns("/_layout"), loadings: patterns("/_loading") },
|
|
93
99
|
),
|
|
94
100
|
);
|
|
95
101
|
};
|
package/src/runtime.tsx
CHANGED
|
@@ -28,14 +28,16 @@ export interface Runtime {
|
|
|
28
28
|
/**
|
|
29
29
|
* The app's root layout, given the href on top. A navigation holds the
|
|
30
30
|
* current screen until the next can show, as navigations are transitions
|
|
31
|
-
* (`router.setTransitionMode("always")`):
|
|
32
|
-
*
|
|
33
|
-
*
|
|
31
|
+
* (`router.setTransitionMode("always")`): once its layouts down to its
|
|
32
|
+
* first loading state, and that loading state, are in, at once if they
|
|
33
|
+
* were prefetched; with no loading state, once all of it is in. Suspends
|
|
34
|
+
* until the first screen can show.
|
|
34
35
|
*/
|
|
35
36
|
Navigator?: ComponentType<{ href: string }>;
|
|
36
37
|
/**
|
|
37
|
-
* A route's screen
|
|
38
|
-
*
|
|
38
|
+
* A route's screen, nested as Next.js nests a page: each segment's layout,
|
|
39
|
+
* around its loading state while what's under it loads. One not `active`
|
|
40
|
+
* yet shows nothing.
|
|
39
41
|
*/
|
|
40
42
|
Screen?: ComponentType<{ href: string; active: boolean }>;
|
|
41
43
|
/**
|
|
@@ -44,11 +46,11 @@ export interface Runtime {
|
|
|
44
46
|
*/
|
|
45
47
|
reload?(href: string): Promise<void>;
|
|
46
48
|
/**
|
|
47
|
-
* Fetches an href ahead, as Next.js prefetches
|
|
48
|
-
*
|
|
49
|
-
*
|
|
49
|
+
* Fetches an href ahead, as Next.js's `Link` prefetches: its layouts down
|
|
50
|
+
* to its first loading state, and that loading state (nothing if it has
|
|
51
|
+
* none); with `page`, its page too, as `<Link prefetch>`.
|
|
50
52
|
*/
|
|
51
|
-
prefetch?(href: string): void;
|
|
53
|
+
prefetch?(href: string, page?: boolean): void;
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
/**
|
|
@@ -83,24 +85,35 @@ export const fetchAnswer = cs`async (
|
|
|
83
85
|
}`;
|
|
84
86
|
|
|
85
87
|
/**
|
|
86
|
-
* The runtime of an open: for the phone at `origin` with `modules`,
|
|
87
|
-
* the app's
|
|
88
|
-
*
|
|
88
|
+
* The runtime of an open: for the phone at `origin` with `modules`, with the
|
|
89
|
+
* patterns of the app's `_layout` and `_loading` routes (`/city/:id/_layout`),
|
|
90
|
+
* so a screen asks only for those it has.
|
|
89
91
|
*/
|
|
90
92
|
export function clientRuntime(
|
|
91
93
|
origin: string,
|
|
92
94
|
modules: string,
|
|
93
|
-
|
|
94
|
-
loadingPatterns: readonly string[],
|
|
95
|
+
routes: { layouts: readonly string[]; loadings: readonly string[] },
|
|
95
96
|
): Client<Runtime> {
|
|
96
97
|
return cs`{
|
|
97
|
-
// Every answer is a query, keyed by
|
|
98
|
-
//
|
|
99
|
-
//
|
|
100
|
-
//
|
|
98
|
+
// Every answer is a query, keyed by where it was fetched, and reused in
|
|
99
|
+
// memory as Next.js's router cache does: a layout or a loading state for 5
|
|
100
|
+
// minutes; a page only for the navigation it was fetched for (0 s), or, fetched
|
|
101
|
+
// ahead by <Link prefetch>, for 5 minutes. A screen's no-store keeps it
|
|
101
102
|
// out of HTTP caches, not this one.
|
|
102
|
-
const
|
|
103
|
-
|
|
103
|
+
const segmentStaleTime = 300000;
|
|
104
|
+
// When the navigation to the href on top started: kept outside React, as
|
|
105
|
+
// a hold that suspends keeps no state.
|
|
106
|
+
let currentNavigation = { href: "", startedAt: 0 };
|
|
107
|
+
const fetchedAhead = new Set<string>();
|
|
108
|
+
const pageStaleTime = (query: {
|
|
109
|
+
queryKey: readonly unknown[];
|
|
110
|
+
state: { dataUpdatedAt: number };
|
|
111
|
+
}) =>
|
|
112
|
+
query.state.dataUpdatedAt >= currentNavigation.startedAt
|
|
113
|
+
? Infinity
|
|
114
|
+
: fetchedAhead.has(query.queryKey[0] as string)
|
|
115
|
+
? segmentStaleTime
|
|
116
|
+
: 0;
|
|
104
117
|
const queryClient = new $QueryClient({
|
|
105
118
|
defaultOptions: {
|
|
106
119
|
queries: {
|
|
@@ -116,88 +129,153 @@ export function clientRuntime(
|
|
|
116
129
|
},
|
|
117
130
|
},
|
|
118
131
|
});
|
|
119
|
-
|
|
120
|
-
|
|
132
|
+
type Query = {
|
|
133
|
+
queryKey: string[];
|
|
134
|
+
staleTime?: number;
|
|
135
|
+
queryFn?: () => Promise<unknown>;
|
|
136
|
+
};
|
|
137
|
+
const pageQuery = (href: string): Query => ({ queryKey: [href] });
|
|
138
|
+
const layoutQuery = (path: string): Query => ({
|
|
121
139
|
queryKey: [path],
|
|
122
|
-
staleTime:
|
|
140
|
+
staleTime: segmentStaleTime,
|
|
141
|
+
});
|
|
142
|
+
// A loading state takes no params, as in Next.js: it's fetched at its
|
|
143
|
+
// pattern (/city/:id/_loading), once for every href it applies to.
|
|
144
|
+
const loadingQuery = (pattern: string) => ({
|
|
145
|
+
queryKey: [pattern],
|
|
146
|
+
staleTime: segmentStaleTime,
|
|
123
147
|
queryFn: async () => ({
|
|
124
148
|
value: (await $fetchAnswer(
|
|
125
|
-
$origin +
|
|
149
|
+
$origin + pattern,
|
|
126
150
|
$modules,
|
|
127
|
-
|
|
151
|
+
false,
|
|
128
152
|
)) as ReactNode,
|
|
129
153
|
}),
|
|
130
154
|
});
|
|
131
|
-
|
|
132
|
-
// matched by Hono's own router.
|
|
133
|
-
const
|
|
134
|
-
for (const pattern of $
|
|
135
|
-
|
|
155
|
+
|
|
156
|
+
// The app's layouts and loading states, matched by Hono's own router.
|
|
157
|
+
const layoutRouter = new $PatternRouter<string>();
|
|
158
|
+
for (const pattern of $routes.layouts) {
|
|
159
|
+
layoutRouter.add("GET", pattern, pattern);
|
|
160
|
+
}
|
|
161
|
+
const loadingRouter = new $PatternRouter<string>();
|
|
162
|
+
for (const pattern of $routes.loadings) {
|
|
163
|
+
loadingRouter.add("GET", pattern, pattern);
|
|
136
164
|
}
|
|
137
|
-
|
|
165
|
+
// An href's segments, as Next.js's folders: each path prefix, with its
|
|
166
|
+
// layout's path and its loading state's pattern, where the app has them.
|
|
167
|
+
// The root's layout is the app's RootLayout.
|
|
168
|
+
const segmentsOf = (href: string) => {
|
|
138
169
|
const searchStart = href.indexOf("?");
|
|
139
170
|
const path = searchStart === -1 ? href : href.slice(0, searchStart);
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
171
|
+
const names = path.split("/").filter(Boolean);
|
|
172
|
+
const bases = [
|
|
173
|
+
"",
|
|
174
|
+
...names.map((_, i) => "/" + names.slice(0, i + 1).join("/")),
|
|
175
|
+
];
|
|
176
|
+
return bases.map((base) => {
|
|
177
|
+
const layout = base + "/_layout";
|
|
178
|
+
return {
|
|
179
|
+
layout:
|
|
180
|
+
base !== "" && layoutRouter.match("GET", layout)[0].length > 0
|
|
181
|
+
? layout
|
|
182
|
+
: undefined,
|
|
183
|
+
loading: loadingRouter.match("GET", base + "/_loading")[0][0]?.[0],
|
|
184
|
+
};
|
|
185
|
+
});
|
|
186
|
+
};
|
|
187
|
+
// What an href's screen needs before it can show, as Next.js prefetches
|
|
188
|
+
// and holds: its layouts down to the first loading state, and that
|
|
189
|
+
// loading state; or, with none, all its layouts and its page.
|
|
190
|
+
const shellOf = (href: string) => {
|
|
191
|
+
const queries: Query[] = [];
|
|
192
|
+
for (const segment of segmentsOf(href)) {
|
|
193
|
+
if (segment.layout !== undefined) {
|
|
194
|
+
queries.push(layoutQuery(segment.layout));
|
|
195
|
+
}
|
|
196
|
+
if (segment.loading !== undefined) {
|
|
197
|
+
queries.push(loadingQuery(segment.loading));
|
|
198
|
+
return { queries, loads: true };
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
queries.push(pageQuery(href));
|
|
202
|
+
return { queries, loads: false };
|
|
144
203
|
};
|
|
145
204
|
// A stale answer no screen shows, in before a navigation started, is
|
|
146
205
|
// dropped as the navigation reads it, so the navigation waits for a fresh
|
|
147
206
|
// one, as Next.js's does; one a screen still shows, going back to it, is
|
|
148
207
|
// kept.
|
|
149
|
-
const dropStaleAnswer = (
|
|
150
|
-
const
|
|
208
|
+
const dropStaleAnswer = (query: Query, startedAt: number) => {
|
|
209
|
+
const cached = queryClient
|
|
151
210
|
.getQueryCache()
|
|
152
|
-
.find({ queryKey:
|
|
211
|
+
.find({ queryKey: query.queryKey, exact: true });
|
|
153
212
|
if (
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
213
|
+
cached !== undefined &&
|
|
214
|
+
cached.getObserversCount() === 0 &&
|
|
215
|
+
cached.state.data !== undefined &&
|
|
216
|
+
cached.state.dataUpdatedAt < startedAt &&
|
|
217
|
+
cached.isStaleByTime(query.staleTime ?? pageStaleTime(cached))
|
|
159
218
|
) {
|
|
160
|
-
queryClient.removeQueries({ queryKey:
|
|
219
|
+
queryClient.removeQueries({ queryKey: query.queryKey, exact: true });
|
|
161
220
|
}
|
|
162
221
|
};
|
|
163
222
|
|
|
164
223
|
const Page = (props: { href: string }) =>
|
|
165
|
-
$useSuspenseQuery(
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
//
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
$
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
224
|
+
$useSuspenseQuery(pageQuery(props.href)).data as ReactNode;
|
|
225
|
+
const Loading = (props: { pattern: string }) =>
|
|
226
|
+
$useSuspenseQuery(loadingQuery(props.pattern)).data.value;
|
|
227
|
+
// A layout answers a client component, given what's under it; any other
|
|
228
|
+
// answer (its not-found screen) is what the screen shows.
|
|
229
|
+
const Layout = (props: { path: string; children: ReactNode }) => {
|
|
230
|
+
const answer = $useSuspenseQuery(layoutQuery(props.path)).data;
|
|
231
|
+
if (typeof answer !== "function") {
|
|
232
|
+
return answer as ReactNode;
|
|
233
|
+
}
|
|
234
|
+
const Answer = answer as ComponentType<{ children: ReactNode }>;
|
|
235
|
+
return <Answer>{props.children}</Answer>;
|
|
236
|
+
};
|
|
237
|
+
// A screen as Next.js nests a page: each segment's layout, around a
|
|
238
|
+
// Suspense showing its loading state, around what's under it. The page
|
|
239
|
+
// is fetched meanwhile.
|
|
240
|
+
const Segments = (props: { href: string }) => {
|
|
241
|
+
$usePrefetchQuery(pageQuery(props.href));
|
|
242
|
+
let node: ReactNode = <Page href={props.href} />;
|
|
243
|
+
for (const segment of segmentsOf(props.href).reverse()) {
|
|
244
|
+
if (segment.loading !== undefined) {
|
|
245
|
+
node = (
|
|
246
|
+
<$Suspense fallback={<Loading pattern={segment.loading} />}>
|
|
247
|
+
{node}
|
|
248
|
+
</$Suspense>
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
if (segment.layout !== undefined) {
|
|
252
|
+
node = <Layout path={segment.layout}>{node}</Layout>;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return node;
|
|
182
256
|
};
|
|
183
257
|
|
|
184
|
-
// Fetches an href ahead, as Next.js
|
|
185
|
-
//
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
258
|
+
// Fetches an href ahead, as Next.js's Link: what its screen needs to
|
|
259
|
+
// show, if that ends at a loading state, and its page too when asked
|
|
260
|
+
// (<Link prefetch>).
|
|
261
|
+
const prefetch = (href: string, page = false) => {
|
|
262
|
+
const shell = shellOf(href);
|
|
263
|
+
if (page) {
|
|
264
|
+
fetchedAhead.add(href);
|
|
265
|
+
}
|
|
266
|
+
const queries = page
|
|
267
|
+
? [...shell.queries, pageQuery(href)]
|
|
268
|
+
: shell.loads
|
|
269
|
+
? shell.queries
|
|
270
|
+
: [];
|
|
271
|
+
for (const query of queries) {
|
|
272
|
+
void queryClient.query(query).catch(() => {});
|
|
191
273
|
}
|
|
192
|
-
void queryClient
|
|
193
|
-
.query(loadingQueryOptions(loading))
|
|
194
|
-
.then((answer) =>
|
|
195
|
-
answer.value === null
|
|
196
|
-
? queryClient.query({ queryKey: [href] })
|
|
197
|
-
: undefined,
|
|
198
|
-
)
|
|
199
|
-
.catch(() => {});
|
|
200
274
|
};
|
|
275
|
+
// Every loading state, as the app opens: one per pattern, for any href.
|
|
276
|
+
for (const pattern of $routes.loadings) {
|
|
277
|
+
void queryClient.query(loadingQuery(pattern)).catch(() => {});
|
|
278
|
+
}
|
|
201
279
|
|
|
202
280
|
// An href changed in place (router.setParams) shows once it's in: the
|
|
203
281
|
// screen stays meanwhile.
|
|
@@ -205,38 +283,45 @@ export function clientRuntime(
|
|
|
205
283
|
const href = $useDeferredValue(props.href);
|
|
206
284
|
return props.active ? (
|
|
207
285
|
<$Suspense fallback={null}>
|
|
208
|
-
<
|
|
286
|
+
<Segments href={href} />
|
|
209
287
|
</$Suspense>
|
|
210
288
|
) : null;
|
|
211
289
|
};
|
|
212
290
|
|
|
213
|
-
// Suspends until
|
|
214
|
-
//
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
291
|
+
// Suspends until each query is in. One that is, however old, holds
|
|
292
|
+
// nothing: stale ones were dropped above.
|
|
293
|
+
const AwaitQueries = (props: { queries: Query[] }) => {
|
|
294
|
+
$useSuspenseQueries({
|
|
295
|
+
queries: props.queries.map((query) => ({
|
|
296
|
+
...query,
|
|
297
|
+
refetchOnMount: false,
|
|
298
|
+
})),
|
|
299
|
+
});
|
|
218
300
|
return null;
|
|
219
301
|
};
|
|
220
|
-
// When the navigation to the href on top started: kept outside React, as
|
|
221
|
-
// a hold that suspends keeps no state.
|
|
222
|
-
let currentNavigation = { href: "", startedAt: 0 };
|
|
223
302
|
// Suspends a navigation's render, above the Stack, until the href's
|
|
224
|
-
//
|
|
225
|
-
//
|
|
226
|
-
// the screen to show why.
|
|
303
|
+
// screen can show (shellOf). As navigations are transitions, the screen on
|
|
304
|
+
// top stays meanwhile. The page is fetched alongside. One that fails ends
|
|
305
|
+
// the hold, for the screen to show why.
|
|
227
306
|
const NavigationHold = (props: { href: string }) => {
|
|
228
307
|
if (currentNavigation.href !== props.href) {
|
|
229
308
|
currentNavigation = { href: props.href, startedAt: Date.now() };
|
|
230
309
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
const loading = loadingPathOf(props.href);
|
|
235
|
-
if (loading !== undefined) {
|
|
236
|
-
void queryClient.query({ queryKey: [props.href] }).catch(() => {});
|
|
237
|
-
return <AwaitQuery query={loadingQueryOptions(loading)} />;
|
|
310
|
+
const shell = shellOf(props.href);
|
|
311
|
+
for (const query of [...shell.queries, pageQuery(props.href)]) {
|
|
312
|
+
dropStaleAnswer(query, currentNavigation.startedAt);
|
|
238
313
|
}
|
|
239
|
-
|
|
314
|
+
// Going back, the screen shows its page as it was: only a page no
|
|
315
|
+
// screen shows is fetched.
|
|
316
|
+
const shown =
|
|
317
|
+
(queryClient
|
|
318
|
+
.getQueryCache()
|
|
319
|
+
.find({ queryKey: [props.href], exact: true })
|
|
320
|
+
?.getObserversCount() ?? 0) > 0;
|
|
321
|
+
if (!shown) {
|
|
322
|
+
void queryClient.query(pageQuery(props.href)).catch(() => {});
|
|
323
|
+
}
|
|
324
|
+
return <AwaitQueries queries={shell.queries} />;
|
|
240
325
|
};
|
|
241
326
|
class SilentErrorBoundary extends $Component<
|
|
242
327
|
{ children: ReactNode },
|
|
@@ -251,12 +336,28 @@ export function clientRuntime(
|
|
|
251
336
|
}
|
|
252
337
|
}
|
|
253
338
|
|
|
339
|
+
// The root layout, /_layout, which draws the navigator: fetched once per
|
|
340
|
+
// open, as a new one would remount the navigator, and its screens with it.
|
|
341
|
+
const RootLayout = () => {
|
|
342
|
+
const answer = $useSuspenseQuery({
|
|
343
|
+
queryKey: ["/_layout"],
|
|
344
|
+
staleTime: Infinity,
|
|
345
|
+
}).data;
|
|
346
|
+
if (typeof answer !== "function") {
|
|
347
|
+
throw new Error(
|
|
348
|
+
"The app's /_layout answers no component: it's the root layout, a client component drawing the navigator (a Stack).",
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
const Answer = answer as ComponentType;
|
|
352
|
+
return <Answer />;
|
|
353
|
+
};
|
|
354
|
+
|
|
254
355
|
const Navigator = (props: { href: string }) => (
|
|
255
356
|
<$QueryClientProvider client={queryClient}>
|
|
256
357
|
<SilentErrorBoundary key={props.href}>
|
|
257
358
|
<NavigationHold href={props.href} />
|
|
258
359
|
</SilentErrorBoundary>
|
|
259
|
-
|
|
360
|
+
<RootLayout />
|
|
260
361
|
</$QueryClientProvider>
|
|
261
362
|
);
|
|
262
363
|
|
|
@@ -264,12 +365,17 @@ export function clientRuntime(
|
|
|
264
365
|
Navigator,
|
|
265
366
|
Screen,
|
|
266
367
|
prefetch,
|
|
267
|
-
//
|
|
368
|
+
// Its page and layouts again: one that failed, for its screen to wait
|
|
268
369
|
// for it; the others kept until the new answer is in.
|
|
269
370
|
reload: async (href) => {
|
|
270
|
-
const
|
|
371
|
+
const paths = [
|
|
372
|
+
href,
|
|
373
|
+
...segmentsOf(href).flatMap((segment) =>
|
|
374
|
+
segment.layout === undefined ? [] : [segment.layout],
|
|
375
|
+
),
|
|
376
|
+
];
|
|
271
377
|
await Promise.allSettled(
|
|
272
|
-
|
|
378
|
+
paths.map((path) =>
|
|
273
379
|
queryClient.getQueryState([path])?.status === "error"
|
|
274
380
|
? queryClient.resetQueries({ queryKey: [path], exact: true })
|
|
275
381
|
: queryClient.refetchQueries({ queryKey: [path], exact: true }),
|