@alignable/bifrost 1.0.31 → 1.0.32

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.
@@ -35,16 +35,10 @@ var config_default = {
35
35
  Page: "import:@alignable/bifrost/__internal/renderer/wrapped/Page:default",
36
36
  onRenderHtml: "import:@alignable/bifrost/__internal/renderer/wrapped/onRenderHtml:default",
37
37
  onBeforeRenderHtml: "import:@alignable/bifrost/__internal/renderer/wrapped/onBeforeRenderHtml:default",
38
+ onAfterRenderHtml: "import:@alignable/bifrost/__internal/renderer/wrapped/onAfterRenderHtml:default",
38
39
  onBeforeRender: "import:@alignable/bifrost/__internal/renderer/wrapped/onBeforeRender.client:default",
39
40
  onBeforeRenderClient: "import:@alignable/bifrost/__internal/renderer/wrapped/onBeforeRenderClient:default",
40
41
  onAfterRenderClient: "import:@alignable/bifrost/__internal/renderer/wrapped/onAfterRenderClient:default",
41
- // Disable onRenderClient timeout since we wait for head scripts to load in onAfterRenderClient
42
- // onWrappedReactRenderTimeout will fire when vike-react's onRenderClient times out.
43
- // Ideally, we could only disable timeout for onAfterRenderClient
44
- // https://github.com/vikejs/vike/issues/3147
45
- hooksTimeout: {
46
- onRenderClient: false
47
- },
48
42
  meta: {
49
43
  onBeforeRender: { env: { client: true, server: false } }
50
44
  }
@@ -67,4 +61,4 @@ var config_default = {
67
61
  export {
68
62
  config_default
69
63
  };
70
- //# sourceMappingURL=chunk-DI7YJ6WP.js.map
64
+ //# sourceMappingURL=chunk-YBO6H2JC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../renderer/config.ts"],"sourcesContent":["import { type Config } from \"vike/types\";\n\nexport default {\n name: \"@alignable/bifrost\",\n require: {\n vike: \">=0.4.244\",\n \"vike-react\": \">=0.6.11\",\n },\n\n headHtmlBegin:\n \"import:@alignable/bifrost/__internal/renderer/headHtmlBegin:default\",\n headHtmlEnd:\n \"import:@alignable/bifrost/__internal/renderer/headHtmlEnd:default\",\n onBeforeRoute:\n \"import:@alignable/bifrost/__internal/renderer/onBeforeRoute:default\",\n Wrapper: \"import:@alignable/bifrost/__internal/renderer/Wrapper:default\",\n\n passToClient: [\"proxyLayoutInfo\"],\n\n meta: {\n bodyAttributes: {\n // vike-react bodyAttributes are server-only, but legacy backend may change bodyAttributes and we need to reset on return to bifrost pages\n env: { server: true, client: true },\n global: true,\n cumulative: true,\n },\n getLayout: { env: { server: true, client: true } },\n layoutHeaders: { env: { server: true, client: false } },\n proxyHeaders: { env: { server: true, client: true } },\n onWrappedReactRenderTimeout: { env: { server: false, client: true } },\n proxyMode: {\n env: { server: true, client: true, config: true },\n effect({ configDefinedAt, configValue }) {\n switch (configValue) {\n case false:\n return {\n onBeforeRenderClient:\n \"import:@alignable/bifrost/__internal/renderer/bifrost/onBeforeRenderClient:default\",\n onAfterRenderClient:\n \"import:@alignable/bifrost/__internal/renderer/bifrost/onAfterRenderClient:default\",\n };\n case \"wrapped\":\n return {\n Page: \"import:@alignable/bifrost/__internal/renderer/wrapped/Page:default\" as any,\n onRenderHtml:\n \"import:@alignable/bifrost/__internal/renderer/wrapped/onRenderHtml:default\",\n onBeforeRenderHtml:\n \"import:@alignable/bifrost/__internal/renderer/wrapped/onBeforeRenderHtml:default\",\n onAfterRenderHtml:\n \"import:@alignable/bifrost/__internal/renderer/wrapped/onAfterRenderHtml:default\",\n onBeforeRender:\n \"import:@alignable/bifrost/__internal/renderer/wrapped/onBeforeRender.client:default\",\n onBeforeRenderClient:\n \"import:@alignable/bifrost/__internal/renderer/wrapped/onBeforeRenderClient:default\",\n onAfterRenderClient:\n \"import:@alignable/bifrost/__internal/renderer/wrapped/onAfterRenderClient:default\",\n meta: {\n onBeforeRender: { env: { client: true, server: false } },\n },\n };\n case \"passthru\":\n // tell Vike to hit the server for all passthru pages (which will get load balanced to legacy backend)\n return {\n onRenderHtml:\n \"import:@alignable/bifrost/__internal/renderer/passthru/onRenderHtml:default\",\n clientRouting: false,\n };\n default:\n throw new Error(\n `${configDefinedAt} should be one of: false, \"wrapped\", \"passthru\"`\n );\n }\n },\n },\n },\n} satisfies Config;\n\n/**\n * Returning null tells Bifrost to run passthru proxy\n */\nexport type GetLayout = (\n headers: Record<string, number | string | string[] | undefined>\n) => Vike.ProxyLayoutInfo | null;\n\ndeclare global {\n namespace Vike {\n interface Config {\n proxyMode?: false | \"wrapped\" | \"passthru\";\n proxyHeaders?: Record<string, string>;\n getLayout?: GetLayout;\n /** Response headers that should be consumed server-side and stripped before sending to the client. */\n layoutHeaders?: string[];\n /**\n * Fired when react render times out on the client in the wrapped proxy\n */\n onWrappedReactRenderTimeout?: (pageContext: PageContext) => void;\n }\n interface PageContext {\n proxyLayoutInfo?: ProxyLayoutInfo;\n }\n interface ProxyLayoutInfo {}\n }\n}\n\n// This is only used for fastify integration\nexport { type WrappedServerOnly } from \"../lib/type\";\n"],"mappings":";AAEA,IAAO,iBAAQ;AAAA,EACb,MAAM;AAAA,EACN,SAAS;AAAA,IACP,MAAM;AAAA,IACN,cAAc;AAAA,EAChB;AAAA,EAEA,eACE;AAAA,EACF,aACE;AAAA,EACF,eACE;AAAA,EACF,SAAS;AAAA,EAET,cAAc,CAAC,iBAAiB;AAAA,EAEhC,MAAM;AAAA,IACJ,gBAAgB;AAAA;AAAA,MAEd,KAAK,EAAE,QAAQ,MAAM,QAAQ,KAAK;AAAA,MAClC,QAAQ;AAAA,MACR,YAAY;AAAA,IACd;AAAA,IACA,WAAW,EAAE,KAAK,EAAE,QAAQ,MAAM,QAAQ,KAAK,EAAE;AAAA,IACjD,eAAe,EAAE,KAAK,EAAE,QAAQ,MAAM,QAAQ,MAAM,EAAE;AAAA,IACtD,cAAc,EAAE,KAAK,EAAE,QAAQ,MAAM,QAAQ,KAAK,EAAE;AAAA,IACpD,6BAA6B,EAAE,KAAK,EAAE,QAAQ,OAAO,QAAQ,KAAK,EAAE;AAAA,IACpE,WAAW;AAAA,MACT,KAAK,EAAE,QAAQ,MAAM,QAAQ,MAAM,QAAQ,KAAK;AAAA,MAChD,OAAO,EAAE,iBAAiB,YAAY,GAAG;AACvC,gBAAQ,aAAa;AAAA,UACnB,KAAK;AACH,mBAAO;AAAA,cACL,sBACE;AAAA,cACF,qBACE;AAAA,YACJ;AAAA,UACF,KAAK;AACH,mBAAO;AAAA,cACL,MAAM;AAAA,cACN,cACE;AAAA,cACF,oBACE;AAAA,cACF,mBACE;AAAA,cACF,gBACE;AAAA,cACF,sBACE;AAAA,cACF,qBACE;AAAA,cACF,MAAM;AAAA,gBACJ,gBAAgB,EAAE,KAAK,EAAE,QAAQ,MAAM,QAAQ,MAAM,EAAE;AAAA,cACzD;AAAA,YACF;AAAA,UACF,KAAK;AAEH,mBAAO;AAAA,cACL,cACE;AAAA,cACF,eAAe;AAAA,YACjB;AAAA,UACF;AACE,kBAAM,IAAI;AAAA,cACR,GAAG,eAAe;AAAA,YACpB;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  config_default
3
- } from "../chunk-DI7YJ6WP.js";
3
+ } from "../chunk-YBO6H2JC.js";
4
4
  export {
5
5
  config_default as default
6
6
  };
@@ -1,5 +1,5 @@
1
1
  // renderer/Wrapper.tsx
2
- import React from "react";
2
+ import React, { useEffect } from "react";
3
3
  import { usePageContext } from "vike-react/usePageContext";
4
4
  function Wrapper({ children }) {
5
5
  const pageContext = usePageContext();
@@ -7,10 +7,12 @@ function Wrapper({ children }) {
7
7
  window.Turbolinks.controller.viewWillRender();
8
8
  pageContext._shouldEmitBeforeRender = false;
9
9
  }
10
- if (pageContext.isClientSide && pageContext._reactRenderTimeout) {
11
- clearTimeout(pageContext._reactRenderTimeout);
12
- pageContext._reactRenderTimeout = void 0;
13
- }
10
+ useEffect(() => {
11
+ if (pageContext.isClientSide && pageContext._reactRenderTimeout) {
12
+ clearTimeout(pageContext._reactRenderTimeout);
13
+ pageContext._reactRenderTimeout = void 0;
14
+ }
15
+ }, [pageContext]);
14
16
  return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
15
17
  }
16
18
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../renderer/Wrapper.tsx"],"sourcesContent":["import React from \"react\";\nimport { usePageContext } from \"vike-react/usePageContext\";\n\nexport default function Wrapper({ children }: { children: React.ReactNode }) {\n const pageContext = usePageContext();\n\n // We want to fire `turbolinks:before-render` as late as possible - synchronously before rendering the page.\n // This is important because before-render scripts may clear the DOM, and we want to paint the new page immediately\n // onBeforeRenderClient awaits for promises so there is a delay\n if (pageContext.isClientSide && pageContext._shouldEmitBeforeRender) {\n window.Turbolinks.controller.viewWillRender();\n pageContext._shouldEmitBeforeRender = false;\n }\n\n if (pageContext.isClientSide && pageContext._reactRenderTimeout) {\n clearTimeout(pageContext._reactRenderTimeout);\n pageContext._reactRenderTimeout = undefined;\n }\n \n return <>{children}</>;\n}\n"],"mappings":";AAAA,OAAO,WAAW;AAClB,SAAS,sBAAsB;AAEhB,SAAR,QAAyB,EAAE,SAAS,GAAkC;AAC3E,QAAM,cAAc,eAAe;AAKnC,MAAI,YAAY,gBAAgB,YAAY,yBAAyB;AACnE,WAAO,WAAW,WAAW,eAAe;AAC5C,gBAAY,0BAA0B;AAAA,EACxC;AAEA,MAAI,YAAY,gBAAgB,YAAY,qBAAqB;AAC/D,iBAAa,YAAY,mBAAmB;AAC5C,gBAAY,sBAAsB;AAAA,EACpC;AAEA,SAAO,0DAAG,QAAS;AACrB;","names":[]}
1
+ {"version":3,"sources":["../../renderer/Wrapper.tsx"],"sourcesContent":["import React, { useEffect } from \"react\";\nimport { usePageContext } from \"vike-react/usePageContext\";\n\nexport default function Wrapper({ children }: { children: React.ReactNode }) {\n const pageContext = usePageContext();\n\n // We want to fire `turbolinks:before-render` as late as possible - synchronously before rendering the page.\n // This is important because before-render scripts may clear the DOM, and we want to paint the new page immediately\n // onBeforeRenderClient awaits for promises so there is a delay\n if (pageContext.isClientSide && pageContext._shouldEmitBeforeRender) {\n window.Turbolinks.controller.viewWillRender();\n pageContext._shouldEmitBeforeRender = false;\n }\n\n useEffect(() => {\n if (pageContext.isClientSide && pageContext._reactRenderTimeout) {\n clearTimeout(pageContext._reactRenderTimeout);\n pageContext._reactRenderTimeout = undefined;\n }\n }, [pageContext]);\n \n return <>{children}</>;\n}\n"],"mappings":";AAAA,OAAO,SAAS,iBAAiB;AACjC,SAAS,sBAAsB;AAEhB,SAAR,QAAyB,EAAE,SAAS,GAAkC;AAC3E,QAAM,cAAc,eAAe;AAKnC,MAAI,YAAY,gBAAgB,YAAY,yBAAyB;AACnE,WAAO,WAAW,WAAW,eAAe;AAC5C,gBAAY,0BAA0B;AAAA,EACxC;AAEA,YAAU,MAAM;AACd,QAAI,YAAY,gBAAgB,YAAY,qBAAqB;AAC/D,mBAAa,YAAY,mBAAmB;AAC5C,kBAAY,sBAAsB;AAAA,IACpC;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAEhB,SAAO,0DAAG,QAAS;AACrB;","names":[]}
@@ -1,5 +1,5 @@
1
1
  import { PageContextClient } from 'vike/types';
2
- import '../../type-5bab0608.js';
2
+ import '../../type-00ab9e9c.js';
3
3
  import '../../controller-962fb27d.js';
4
4
 
5
5
  declare const _default: (pageContext: PageContextClient) => void;
@@ -1,4 +1,4 @@
1
- export { W as WrappedServerOnly } from '../type-5bab0608.js';
1
+ export { W as WrappedServerOnly } from '../type-00ab9e9c.js';
2
2
  import '../controller-962fb27d.js';
3
3
  import 'vike/types';
4
4
 
@@ -61,20 +61,18 @@ declare const _default: {
61
61
  Page?: undefined;
62
62
  onRenderHtml?: undefined;
63
63
  onBeforeRenderHtml?: undefined;
64
+ onAfterRenderHtml?: undefined;
64
65
  onBeforeRender?: undefined;
65
- hooksTimeout?: undefined;
66
66
  meta?: undefined;
67
67
  clientRouting?: undefined;
68
68
  } | {
69
69
  Page: any;
70
70
  onRenderHtml: "import:@alignable/bifrost/__internal/renderer/wrapped/onRenderHtml:default";
71
71
  onBeforeRenderHtml: "import:@alignable/bifrost/__internal/renderer/wrapped/onBeforeRenderHtml:default";
72
+ onAfterRenderHtml: "import:@alignable/bifrost/__internal/renderer/wrapped/onAfterRenderHtml:default";
72
73
  onBeforeRender: "import:@alignable/bifrost/__internal/renderer/wrapped/onBeforeRender.client:default";
73
74
  onBeforeRenderClient: "import:@alignable/bifrost/__internal/renderer/wrapped/onBeforeRenderClient:default";
74
75
  onAfterRenderClient: "import:@alignable/bifrost/__internal/renderer/wrapped/onAfterRenderClient:default";
75
- hooksTimeout: {
76
- onRenderClient: false;
77
- };
78
76
  meta: {
79
77
  onBeforeRender: {
80
78
  env: {
@@ -91,8 +89,8 @@ declare const _default: {
91
89
  onAfterRenderClient?: undefined;
92
90
  Page?: undefined;
93
91
  onBeforeRenderHtml?: undefined;
92
+ onAfterRenderHtml?: undefined;
94
93
  onBeforeRender?: undefined;
95
- hooksTimeout?: undefined;
96
94
  meta?: undefined;
97
95
  };
98
96
  };
@@ -1,5 +1,5 @@
1
1
  import { PageContextServer } from 'vike/types';
2
- import '../type-5bab0608.js';
2
+ import '../type-00ab9e9c.js';
3
3
  import '../controller-962fb27d.js';
4
4
 
5
5
  declare function headHtmlEnd(pageContext: PageContextServer): string;
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import '../config.js';
3
- import '../../type-5bab0608.js';
3
+ import '../../type-00ab9e9c.js';
4
4
  import '../../controller-962fb27d.js';
5
5
  import 'vike/types';
6
6
 
@@ -1,4 +1,4 @@
1
- import "../../chunk-DI7YJ6WP.js";
1
+ import "../../chunk-YBO6H2JC.js";
2
2
 
3
3
  // renderer/wrapped/Page.tsx
4
4
  import React from "react";
@@ -6,6 +6,9 @@ import { usePageContext } from "vike-react/usePageContext";
6
6
  function Page() {
7
7
  const pageContext = usePageContext();
8
8
  const bodyHtml = pageContext.isClientSide ? pageContext._turbolinksProxy?.body?.innerHTML : pageContext._wrappedServerOnly?.bodyInnerHtml;
9
+ if (bodyHtml && !pageContext.isClientSide && pageContext._wrappedServerOnly) {
10
+ pageContext._wrappedServerOnly.renderedBody = true;
11
+ }
9
12
  if (bodyHtml) {
10
13
  return /* @__PURE__ */ React.createElement(
11
14
  "div",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../renderer/wrapped/Page.tsx"],"sourcesContent":["import React from \"react\";\nimport { usePageContext } from \"vike-react/usePageContext\";\nimport \"../config\";\nimport \"../../lib/type\";\n\nexport default function Page() {\n const pageContext = usePageContext();\n\n const bodyHtml = pageContext.isClientSide\n ? pageContext._turbolinksProxy?.body?.innerHTML\n : pageContext._wrappedServerOnly?.bodyInnerHtml;\n\n if (bodyHtml) {\n return (\n <div\n id=\"proxied-body\"\n dangerouslySetInnerHTML={{\n __html: bodyHtml,\n }}\n />\n );\n }\n return <></>;\n}\n"],"mappings":";;;AAAA,OAAO,WAAW;AAClB,SAAS,sBAAsB;AAIhB,SAAR,OAAwB;AAC7B,QAAM,cAAc,eAAe;AAEnC,QAAM,WAAW,YAAY,eACzB,YAAY,kBAAkB,MAAM,YACpC,YAAY,oBAAoB;AAEpC,MAAI,UAAU;AACZ,WACE;AAAA,MAAC;AAAA;AAAA,QACC,IAAG;AAAA,QACH,yBAAyB;AAAA,UACvB,QAAQ;AAAA,QACV;AAAA;AAAA,IACF;AAAA,EAEJ;AACA,SAAO,wDAAE;AACX;","names":[]}
1
+ {"version":3,"sources":["../../../renderer/wrapped/Page.tsx"],"sourcesContent":["import React from \"react\";\nimport { usePageContext } from \"vike-react/usePageContext\";\nimport \"../config\";\nimport \"../../lib/type\";\n\nexport default function Page() {\n const pageContext = usePageContext();\n\n const bodyHtml = pageContext.isClientSide\n ? pageContext._turbolinksProxy?.body?.innerHTML\n : pageContext._wrappedServerOnly?.bodyInnerHtml;\n\n // Set marker so we can render error if failed to render body due to error in surrounding Layout\n if (bodyHtml && !pageContext.isClientSide && pageContext._wrappedServerOnly) {\n pageContext._wrappedServerOnly.renderedBody = true;\n }\n\n if (bodyHtml) {\n return (\n <div\n id=\"proxied-body\"\n dangerouslySetInnerHTML={{\n __html: bodyHtml,\n }}\n />\n );\n }\n return <></>;\n}\n"],"mappings":";;;AAAA,OAAO,WAAW;AAClB,SAAS,sBAAsB;AAIhB,SAAR,OAAwB;AAC7B,QAAM,cAAc,eAAe;AAEnC,QAAM,WAAW,YAAY,eACzB,YAAY,kBAAkB,MAAM,YACpC,YAAY,oBAAoB;AAGpC,MAAI,YAAY,CAAC,YAAY,gBAAgB,YAAY,oBAAoB;AAC3E,gBAAY,mBAAmB,eAAe;AAAA,EAChD;AAEA,MAAI,UAAU;AACZ,WACE;AAAA,MAAC;AAAA;AAAA,QACC,IAAG;AAAA,QACH,yBAAyB;AAAA,UACvB,QAAQ;AAAA,QACV;AAAA;AAAA,IACF;AAAA,EAEJ;AACA,SAAO,wDAAE;AACX;","names":[]}
@@ -1,4 +1,4 @@
1
- import '../../type-5bab0608.js';
1
+ import '../../type-00ab9e9c.js';
2
2
  import { PageContextClient } from 'vike/types';
3
3
  import '../../controller-962fb27d.js';
4
4
 
@@ -0,0 +1,5 @@
1
+ import { PageContextServer } from 'vike/types';
2
+
3
+ declare function wrappedOnAfterRenderHtml(pageContext: PageContextServer): void;
4
+
5
+ export { wrappedOnAfterRenderHtml as default };
@@ -0,0 +1,14 @@
1
+ // renderer/wrapped/onAfterRenderHtml.ts
2
+ import { render } from "vike/abort";
3
+ function wrappedOnAfterRenderHtml(pageContext) {
4
+ if (pageContext._wrappedServerOnly && !pageContext._wrappedServerOnly.renderedBody) {
5
+ throw render(
6
+ 500,
7
+ "proxied-body not found in DOM after SSR. This likely means the Layout threw during SSR (e.g. accessing `window` or `document`). Fix the SSR error in your Layout component."
8
+ );
9
+ }
10
+ }
11
+ export {
12
+ wrappedOnAfterRenderHtml as default
13
+ };
14
+ //# sourceMappingURL=onAfterRenderHtml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../renderer/wrapped/onAfterRenderHtml.ts"],"sourcesContent":["import { PageContextServer } from \"vike/types\";\nimport { render } from \"vike/abort\";\n\nexport default function wrappedOnAfterRenderHtml(\n pageContext: PageContextServer\n) {\n if (\n pageContext._wrappedServerOnly &&\n !pageContext._wrappedServerOnly.renderedBody\n ) {\n // We set wrapped serverOnly but we never rendered the body\n throw render(\n 500,\n \"proxied-body not found in DOM after SSR. This likely means the Layout threw during SSR (e.g. accessing `window` or `document`). Fix the SSR error in your Layout component.\"\n );\n }\n}\n"],"mappings":";AACA,SAAS,cAAc;AAER,SAAR,yBACL,aACA;AACA,MACE,YAAY,sBACZ,CAAC,YAAY,mBAAmB,cAChC;AAEA,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -1,4 +1,4 @@
1
- import '../../type-5bab0608.js';
1
+ import '../../type-00ab9e9c.js';
2
2
  import { PageContextClient } from 'vike/types';
3
3
  import '../../controller-962fb27d.js';
4
4
 
@@ -41,7 +41,7 @@ async function wrappedOnBeforeRender(pageContext) {
41
41
  throw redirect(resp.url);
42
42
  }
43
43
  }
44
- if (!resp.ok) {
44
+ if (!resp.ok || !resp.headers.get("content-type")?.includes("text/html")) {
45
45
  await hardNavigate(resp.url);
46
46
  }
47
47
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../renderer/wrapped/onBeforeRender.client.ts","../../../lib/hardNavigate.ts"],"sourcesContent":["import \"../../lib/type\";\nimport type { PageContextClient } from \"vike/types\";\nimport { redirect } from \"vike/abort\";\nimport { getElementAttributes } from \"../../lib/elementUtils\";\nimport { hardNavigate } from \"../../lib/hardNavigate\";\n\n// onBeforeRender runs before changing the browser location, so `throw redirect` works\n// we wait for onBeforeRenderClient to call mergeHead, which runs after browser location change\n// Possibly could move this back into onBeforeRenderClient: https://github.com/vikejs/vike/pull/2820\nexport default async function wrappedOnBeforeRender(\n pageContext: PageContextClient\n) {\n if (\n pageContext.isClientSide &&\n !pageContext?._snapshot &&\n !pageContext.isHydration\n ) {\n /*\n Mermaid diagram of client side navigation logic:\n\n Vike Router --> Proxy Mode\n Proxy Mode -->|wrapped| Request Legacy Backend\n Request Legacy Backend -->|redirect| Vike Router\n Request Legacy Backend -->|html| Render Wrapped Page\n Proxy Mode -->|false| Render Vike Page\n Proxy Mode -->|passthru| Browser Navigation\n\n ┌─────────────┐ ┌────────────┐ ┌────────────────────────┐ ┌─────────────────────┐\n │ │ │ │ │ │ │ │\n │ Vike Router ├────►│ Proxy Mode ├─wrapped►│ Request Legacy Backend ├html─►│ Render Wrapped Page │\n │ │ │ │ │ │ │ │\n └─────────────┘ └──────┬─────┘ └────────────┬───────────┘ └─────────────────────┘\n ▲ │ redirect \n └───────────────────┼────────────────────────────┘ \n false \n │ ┌────────────────────────┐ \n │ │ │ \n ├──────────────►│ Render Vike Page │ \n passthru │ │ \n │ └────────────────────────┘ \n │ \n │ ┌────────────────────────┐ \n │ │ │ \n └──────────────►│ Browser Navigation │ \n │ │ \n └────────────────────────┘ \n\n The Vike router must run on every redirect, because the legacy backend could redirect to a Vike page.\n The browser follows redirects automatically, which hits the vike server, which will passthru if needed\n It would be more performant to run the Vike router on the client, but the browser does not expose redirect info.\n Optimization: use serviceworker to intercept redirects.\n */\n\n // Recover response from previous redirect to prevent double request on redirect\n const respFromPreviousRedirect =\n pageContext?._turbolinksVisit?.redirectResponse;\n let resp =\n respFromPreviousRedirect?.url ===\n new URL(pageContext.urlParsed.href, location.origin).href\n ? respFromPreviousRedirect\n : undefined;\n if (!resp) {\n resp = await fetch(pageContext.urlParsed.href, {\n headers: { ...pageContext.config.proxyHeaders, accept: \"text/html\" },\n }).catch(() => undefined);\n\n if (!resp) {\n // hard reload. can happen on cors errors when redirected to external page\n window.location.href = pageContext.urlParsed.href;\n // stop vike rendering to let navigation happen\n await new Promise(() => {});\n return;\n }\n\n if (resp.redirected) {\n const parsedUrl = new URL(resp.url);\n // Need to redirect to run vike router (in case redirect is not wrapped page)\n // Downside is we will make another network request\n // TODO: Can we prevent the double request? Move to server side and throw redirect on 3xx?\n if (window.location.origin === parsedUrl.origin) {\n if (pageContext._turbolinksVisit) {\n pageContext._turbolinksVisit.redirectResponse = resp;\n }\n // redirect needs to start with \"/\" or vike will do hard reload\n throw redirect(\n parsedUrl.pathname + parsedUrl.search + parsedUrl.hash\n );\n } else {\n // external redirect\n throw redirect(resp.url);\n }\n }\n if (!resp.ok) {\n await hardNavigate(resp.url);\n }\n }\n const html = await resp.text();\n const layoutInfo = pageContext.config.getLayout!(\n Object.fromEntries(resp.headers.entries())\n );\n if (!layoutInfo) {\n // Fallback to full reload if layout not found\n await hardNavigate(resp.url);\n return;\n }\n\n const parsed = document.createElement(\"html\");\n parsed.innerHTML = html;\n const bodyEl = parsed.querySelector(\"body\")!;\n const headEl = parsed.querySelector(\"head\")!;\n pageContext.proxyLayoutInfo = layoutInfo;\n pageContext._turbolinksProxy = {\n body: bodyEl,\n head: headEl,\n bodyAttrs: getElementAttributes(bodyEl),\n };\n }\n}\n","/**\n * Hard navigate to a URL using `history.pushState` and `window.location.reload` instead of\n * `window.location.href`. This prevents the mobile apps from opening the URL in a browser tab.\n */\nexport async function hardNavigate(url: string): Promise<never> {\n history.pushState(null, \"\", url);\n window.Turbolinks.controller.viewInvalidated();\n // stop vike rendering to let navigation happen\n await new Promise(() => {});\n}\n"],"mappings":";;;;;AAEA,SAAS,gBAAgB;;;ACEzB,eAAsB,aAAa,KAA6B;AAC9D,UAAQ,UAAU,MAAM,IAAI,GAAG;AAC/B,SAAO,WAAW,WAAW,gBAAgB;AAE7C,QAAM,IAAI,QAAQ,MAAM;AAAA,EAAC,CAAC;AAC5B;;;ADAA,eAAO,sBACL,aACA;AACA,MACE,YAAY,gBACZ,CAAC,aAAa,aACd,CAAC,YAAY,aACb;AAsCA,UAAM,2BACJ,aAAa,kBAAkB;AACjC,QAAI,OACF,0BAA0B,QAC1B,IAAI,IAAI,YAAY,UAAU,MAAM,SAAS,MAAM,EAAE,OACjD,2BACA;AACN,QAAI,CAAC,MAAM;AACT,aAAO,MAAM,MAAM,YAAY,UAAU,MAAM;AAAA,QAC7C,SAAS,EAAE,GAAG,YAAY,OAAO,cAAc,QAAQ,YAAY;AAAA,MACrE,CAAC,EAAE,MAAM,MAAM,MAAS;AAExB,UAAI,CAAC,MAAM;AAET,eAAO,SAAS,OAAO,YAAY,UAAU;AAE7C,cAAM,IAAI,QAAQ,MAAM;AAAA,QAAC,CAAC;AAC1B;AAAA,MACF;AAEA,UAAI,KAAK,YAAY;AACnB,cAAM,YAAY,IAAI,IAAI,KAAK,GAAG;AAIlC,YAAI,OAAO,SAAS,WAAW,UAAU,QAAQ;AAC/C,cAAI,YAAY,kBAAkB;AAChC,wBAAY,iBAAiB,mBAAmB;AAAA,UAClD;AAEA,gBAAM;AAAA,YACJ,UAAU,WAAW,UAAU,SAAS,UAAU;AAAA,UACpD;AAAA,QACF,OAAO;AAEL,gBAAM,SAAS,KAAK,GAAG;AAAA,QACzB;AAAA,MACF;AACA,UAAI,CAAC,KAAK,IAAI;AACZ,cAAM,aAAa,KAAK,GAAG;AAAA,MAC7B;AAAA,IACF;AACA,UAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,UAAM,aAAa,YAAY,OAAO;AAAA,MACpC,OAAO,YAAY,KAAK,QAAQ,QAAQ,CAAC;AAAA,IAC3C;AACA,QAAI,CAAC,YAAY;AAEf,YAAM,aAAa,KAAK,GAAG;AAC3B;AAAA,IACF;AAEA,UAAM,SAAS,SAAS,cAAc,MAAM;AAC5C,WAAO,YAAY;AACnB,UAAM,SAAS,OAAO,cAAc,MAAM;AAC1C,UAAM,SAAS,OAAO,cAAc,MAAM;AAC1C,gBAAY,kBAAkB;AAC9B,gBAAY,mBAAmB;AAAA,MAC7B,MAAM;AAAA,MACN,MAAM;AAAA,MACN,WAAW,qBAAqB,MAAM;AAAA,IACxC;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../renderer/wrapped/onBeforeRender.client.ts","../../../lib/hardNavigate.ts"],"sourcesContent":["import \"../../lib/type\";\nimport type { PageContextClient } from \"vike/types\";\nimport { redirect } from \"vike/abort\";\nimport { getElementAttributes } from \"../../lib/elementUtils\";\nimport { hardNavigate } from \"../../lib/hardNavigate\";\n\n// onBeforeRender runs before changing the browser location, so `throw redirect` works\n// we wait for onBeforeRenderClient to call mergeHead, which runs after browser location change\n// Possibly could move this back into onBeforeRenderClient: https://github.com/vikejs/vike/pull/2820\nexport default async function wrappedOnBeforeRender(\n pageContext: PageContextClient\n) {\n if (\n pageContext.isClientSide &&\n !pageContext?._snapshot &&\n !pageContext.isHydration\n ) {\n /*\n Mermaid diagram of client side navigation logic:\n\n Vike Router --> Proxy Mode\n Proxy Mode -->|wrapped| Request Legacy Backend\n Request Legacy Backend -->|redirect| Vike Router\n Request Legacy Backend -->|html| Render Wrapped Page\n Proxy Mode -->|false| Render Vike Page\n Proxy Mode -->|passthru| Browser Navigation\n\n ┌─────────────┐ ┌────────────┐ ┌────────────────────────┐ ┌─────────────────────┐\n │ │ │ │ │ │ │ │\n │ Vike Router ├────►│ Proxy Mode ├─wrapped►│ Request Legacy Backend ├html─►│ Render Wrapped Page │\n │ │ │ │ │ │ │ │\n └─────────────┘ └──────┬─────┘ └────────────┬───────────┘ └─────────────────────┘\n ▲ │ redirect \n └───────────────────┼────────────────────────────┘ \n false \n │ ┌────────────────────────┐ \n │ │ │ \n ├──────────────►│ Render Vike Page │ \n passthru │ │ \n │ └────────────────────────┘ \n │ \n │ ┌────────────────────────┐ \n │ │ │ \n └──────────────►│ Browser Navigation │ \n │ │ \n └────────────────────────┘ \n\n The Vike router must run on every redirect, because the legacy backend could redirect to a Vike page.\n The browser follows redirects automatically, which hits the vike server, which will passthru if needed\n It would be more performant to run the Vike router on the client, but the browser does not expose redirect info.\n Optimization: use serviceworker to intercept redirects.\n */\n\n // Recover response from previous redirect to prevent double request on redirect\n const respFromPreviousRedirect =\n pageContext?._turbolinksVisit?.redirectResponse;\n let resp =\n respFromPreviousRedirect?.url ===\n new URL(pageContext.urlParsed.href, location.origin).href\n ? respFromPreviousRedirect\n : undefined;\n if (!resp) {\n resp = await fetch(pageContext.urlParsed.href, {\n headers: { ...pageContext.config.proxyHeaders, accept: \"text/html\" },\n }).catch(() => undefined);\n\n if (!resp) {\n // hard reload. can happen on cors errors when redirected to external page\n window.location.href = pageContext.urlParsed.href;\n // stop vike rendering to let navigation happen\n await new Promise(() => {});\n return;\n }\n\n if (resp.redirected) {\n const parsedUrl = new URL(resp.url);\n // Need to redirect to run vike router (in case redirect is not wrapped page)\n // Downside is we will make another network request\n // TODO: Can we prevent the double request? Move to server side and throw redirect on 3xx?\n if (window.location.origin === parsedUrl.origin) {\n if (pageContext._turbolinksVisit) {\n pageContext._turbolinksVisit.redirectResponse = resp;\n }\n // redirect needs to start with \"/\" or vike will do hard reload\n throw redirect(\n parsedUrl.pathname + parsedUrl.search + parsedUrl.hash\n );\n } else {\n // external redirect\n throw redirect(resp.url);\n }\n }\n if (!resp.ok || !resp.headers.get(\"content-type\")?.includes(\"text/html\")) {\n await hardNavigate(resp.url);\n }\n }\n const html = await resp.text();\n const layoutInfo = pageContext.config.getLayout!(\n Object.fromEntries(resp.headers.entries())\n );\n if (!layoutInfo) {\n // Fallback to full reload if layout not found\n await hardNavigate(resp.url);\n return;\n }\n\n const parsed = document.createElement(\"html\");\n parsed.innerHTML = html;\n const bodyEl = parsed.querySelector(\"body\")!;\n const headEl = parsed.querySelector(\"head\")!;\n pageContext.proxyLayoutInfo = layoutInfo;\n pageContext._turbolinksProxy = {\n body: bodyEl,\n head: headEl,\n bodyAttrs: getElementAttributes(bodyEl),\n };\n }\n}\n","/**\n * Hard navigate to a URL using `history.pushState` and `window.location.reload` instead of\n * `window.location.href`. This prevents the mobile apps from opening the URL in a browser tab.\n */\nexport async function hardNavigate(url: string): Promise<never> {\n history.pushState(null, \"\", url);\n window.Turbolinks.controller.viewInvalidated();\n // stop vike rendering to let navigation happen\n await new Promise(() => {});\n}\n"],"mappings":";;;;;AAEA,SAAS,gBAAgB;;;ACEzB,eAAsB,aAAa,KAA6B;AAC9D,UAAQ,UAAU,MAAM,IAAI,GAAG;AAC/B,SAAO,WAAW,WAAW,gBAAgB;AAE7C,QAAM,IAAI,QAAQ,MAAM;AAAA,EAAC,CAAC;AAC5B;;;ADAA,eAAO,sBACL,aACA;AACA,MACE,YAAY,gBACZ,CAAC,aAAa,aACd,CAAC,YAAY,aACb;AAsCA,UAAM,2BACJ,aAAa,kBAAkB;AACjC,QAAI,OACF,0BAA0B,QAC1B,IAAI,IAAI,YAAY,UAAU,MAAM,SAAS,MAAM,EAAE,OACjD,2BACA;AACN,QAAI,CAAC,MAAM;AACT,aAAO,MAAM,MAAM,YAAY,UAAU,MAAM;AAAA,QAC7C,SAAS,EAAE,GAAG,YAAY,OAAO,cAAc,QAAQ,YAAY;AAAA,MACrE,CAAC,EAAE,MAAM,MAAM,MAAS;AAExB,UAAI,CAAC,MAAM;AAET,eAAO,SAAS,OAAO,YAAY,UAAU;AAE7C,cAAM,IAAI,QAAQ,MAAM;AAAA,QAAC,CAAC;AAC1B;AAAA,MACF;AAEA,UAAI,KAAK,YAAY;AACnB,cAAM,YAAY,IAAI,IAAI,KAAK,GAAG;AAIlC,YAAI,OAAO,SAAS,WAAW,UAAU,QAAQ;AAC/C,cAAI,YAAY,kBAAkB;AAChC,wBAAY,iBAAiB,mBAAmB;AAAA,UAClD;AAEA,gBAAM;AAAA,YACJ,UAAU,WAAW,UAAU,SAAS,UAAU;AAAA,UACpD;AAAA,QACF,OAAO;AAEL,gBAAM,SAAS,KAAK,GAAG;AAAA,QACzB;AAAA,MACF;AACA,UAAI,CAAC,KAAK,MAAM,CAAC,KAAK,QAAQ,IAAI,cAAc,GAAG,SAAS,WAAW,GAAG;AACxE,cAAM,aAAa,KAAK,GAAG;AAAA,MAC7B;AAAA,IACF;AACA,UAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,UAAM,aAAa,YAAY,OAAO;AAAA,MACpC,OAAO,YAAY,KAAK,QAAQ,QAAQ,CAAC;AAAA,IAC3C;AACA,QAAI,CAAC,YAAY;AAEf,YAAM,aAAa,KAAK,GAAG;AAC3B;AAAA,IACF;AAEA,UAAM,SAAS,SAAS,cAAc,MAAM;AAC5C,WAAO,YAAY;AACnB,UAAM,SAAS,OAAO,cAAc,MAAM;AAC1C,UAAM,SAAS,OAAO,cAAc,MAAM;AAC1C,gBAAY,kBAAkB;AAC9B,gBAAY,mBAAmB;AAAA,MAC7B,MAAM;AAAA,MACN,MAAM;AAAA,MACN,WAAW,qBAAqB,MAAM;AAAA,IACxC;AAAA,EACF;AACF;","names":[]}
@@ -1,4 +1,4 @@
1
- import '../../type-5bab0608.js';
1
+ import '../../type-00ab9e9c.js';
2
2
  import { PageContextClient } from 'vike/types';
3
3
  import '../../controller-962fb27d.js';
4
4
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../lib/turbolinks/mergeHead.ts","../../../renderer/wrapped/onBeforeRenderClient.ts"],"sourcesContent":["import { createScriptElement } from \"./util\";\nimport { instrument } from \"../diagnostic.client\";\n\ninterface ElementDetails {\n tracked: boolean;\n}\nconst allHeadScriptsEverRun: { [outerHTML: string]: ElementDetails } = {};\nlet firstMerge = true;\nlet lastTrackedScriptSignature: string;\n\nexport const recordExistingHeadScripts = instrument(\"recordExistingHeadScripts\", function recordExistingHeadScripts(categorizedHead?: CategorizedHead) {\n categorizedHead ||= categorizeHead(document.head);\n // record all existing head scripts as having been run, because they were run by browser, not mergeHead\n for (const element of categorizedHead.scripts) {\n allHeadScriptsEverRun[element.outerHTML] = {\n tracked: elementIsTracked(element),\n };\n }\n lastTrackedScriptSignature =\n lastTrackedScriptSignature || trackedElementSignature(categorizedHead);\n firstMerge = false;\n});\n\n// Returns function which resolves when all new blocking head scripts have loaded\nexport function mergeHead(head: HTMLHeadElement) {\n const newHead = categorizeHead(head);\n const oldHead = categorizeHead(document.head);\n const reload = () => {\n window.Turbolinks.controller.viewInvalidated();\n return {\n waitForReload: instrument(\"_waitForReload\", () => new Promise<void>(() => {})),\n waitForHeadScripts: instrument(\"_waitForHeadScripts\", () => new Promise<void>(() => {})),\n };\n };\n\n if (\n head\n .querySelector('meta[name=\"turbolinks-visit-control\"]')\n ?.getAttribute(\"content\") === \"reload\"\n ) {\n return reload();\n }\n\n if (!firstMerge) {\n // IMPORTANT: we allow first merge to always proceed without reload\n const newTrackedScriptSignature = trackedElementSignature(newHead);\n if (lastTrackedScriptSignature !== newTrackedScriptSignature) {\n return reload();\n }\n }\n firstMerge = false;\n lastTrackedScriptSignature =\n lastTrackedScriptSignature || trackedElementSignature(newHead);\n\n copyNewHeadStylesheetElements(newHead.stylesheets, oldHead.stylesheets);\n removeCurrentHeadProvisionalElements(oldHead.provisional);\n copyNewHeadProvisionalElements(newHead.provisional);\n\n return {\n waitForReload: instrument(\"_waitForReload\", () => Promise.resolve()),\n waitForHeadScripts: instrument(\"_waitForHeadScripts\", copyNewHeadScriptElements(newHead.scripts)),\n };\n}\n\nfunction trackedElementSignature(head: CategorizedHead) {\n return [...head.scripts, ...head.stylesheets]\n .filter(elementIsTracked)\n .map((s) => s.outerHTML)\n .join();\n}\n\nfunction copyNewHeadStylesheetElements(next: Element[], prev: Element[]) {\n const existing = prev.map((s) => s.outerHTML);\n for (const element of next) {\n if (!existing.includes(element.outerHTML)) {\n document.head.appendChild(element);\n }\n }\n}\n\nfunction copyNewHeadScriptElements(next: Element[]): () => Promise<void> {\n const deferredScripts: Element[] = [];\n let blockingLoaded: boolean[] = [];\n const scriptsLoadedPromise = new Promise<void>((onScriptsLoaded) => {\n for (const element of next as HTMLScriptElement[]) {\n const runBefore = element.outerHTML in allHeadScriptsEverRun;\n if (!runBefore) {\n let cb;\n if (!element.defer && element.src) {\n const idx = blockingLoaded.length;\n cb = () => {\n blockingLoaded[idx] = true;\n if (blockingLoaded.every((v) => v)) {\n onScriptsLoaded();\n }\n };\n blockingLoaded.push(false);\n }\n const newElement = createScriptElement(element, cb);\n if (element.defer) {\n deferredScripts.push(newElement);\n } else {\n document.head.appendChild(newElement);\n }\n allHeadScriptsEverRun[element.outerHTML] = {\n tracked: elementIsTracked(element),\n };\n }\n }\n if (blockingLoaded.length === 0) {\n // raf waits for react to finish\n onScriptsLoaded();\n }\n });\n return () => {\n deferredScripts.forEach((s) => document.head.appendChild(s));\n return scriptsLoadedPromise;\n };\n}\n\nfunction removeCurrentHeadProvisionalElements(prev: Element[]) {\n for (const element of prev) {\n document.head.removeChild(element);\n }\n}\n\nfunction copyNewHeadProvisionalElements(next: Element[]) {\n for (const element of next) {\n document.head.appendChild(element);\n }\n}\n\nfunction elementIsTracked(element: Element) {\n return element.getAttribute(\"data-turbolinks-track\") == \"reload\";\n}\n\nfunction elementIsScript(element: Element) {\n const tagName = element.tagName.toLowerCase();\n return tagName == \"script\";\n}\n\nfunction elementIsStylesheet(element: Element) {\n const tagName = element.tagName.toLowerCase();\n return (\n tagName == \"style\" ||\n (tagName == \"link\" && element.getAttribute(\"rel\") == \"stylesheet\")\n );\n}\n\nfunction elementIsFavicon(element: Element) {\n const tagName = element.tagName.toLowerCase();\n\n return tagName == \"link\" && element.getAttribute(\"rel\") == \"icon\";\n}\n\nfunction categorizeHead(head: ParentNode) {\n const scripts = [];\n const stylesheets = [];\n const provisional = [];\n for (const element of head.children) {\n // we want to keep the same favicon on page transitions\n if (elementIsFavicon(element)) {\n continue;\n }\n\n if (elementIsScript(element)) {\n scripts.push(element);\n } else if (elementIsStylesheet(element)) {\n stylesheets.push(element);\n } else {\n provisional.push(element);\n }\n }\n return { scripts, stylesheets, provisional };\n}\ntype CategorizedHead = ReturnType<typeof categorizeHead>;\n","import \"../../lib/type\";\nimport type { PageContextClient } from \"vike/types\";\nimport { Turbolinks } from \"../../lib/turbolinks\";\nimport {\n mergeHead,\n recordExistingHeadScripts,\n} from \"../../lib/turbolinks/mergeHead\";\nimport {\n setBodyAttributes,\n getElementAttributes,\n} from \"../../lib/elementUtils\";\nimport { instrument } from \"../../lib/diagnostic.client\";\n\nexport default instrument(\"wrappedOnBeforeRenderClient\", async function wrappedOnBeforeRenderClient(\n pageContext: PageContextClient\n) {\n if (pageContext.isHydration) {\n // Vike scripts load async so can run before document.body exists. we need to delay rendering.\n // This is only an issue if user sets `injectScriptsAt: \"HTML_BEGIN\"` in +config.ts\n if (document.readyState === \"loading\") {\n await instrument(\"_waitForDOMContentLoaded\", () => new Promise((resolve) =>\n document.addEventListener(\"DOMContentLoaded\", () => resolve(null), { once: true})\n ))();\n }\n\n const proxiedBody = document.getElementById(\"proxied-body\");\n if (!proxiedBody) {\n throw new Error(\n \"proxied-body not found in DOM after SSR. This likely means the Layout threw during SSR (e.g. accessing `window` or `document`). Fix the SSR error in your Layout component.\"\n );\n }\n pageContext._turbolinksProxy = {\n body: proxiedBody,\n };\n Turbolinks._vpsCachePageContext({\n proxyLayoutInfo: pageContext.proxyLayoutInfo,\n });\n recordExistingHeadScripts();\n return;\n }\n\n if (pageContext?._snapshot) {\n if (pageContext.isHydration) {\n throw new Error(\n \"restoration visit should never happen on initial render\"\n );\n }\n const { proxyLayoutInfo } = pageContext._snapshot.pageContext;\n const { bodyEl, headEl } = pageContext._snapshot;\n const proxyBodyEl = bodyEl.querySelector(\"#proxied-body\")!;\n if (!proxyBodyEl || !(proxyBodyEl instanceof HTMLElement)) {\n throw new Error(\"proxied body not found in cached snapshot\");\n }\n pageContext.proxyLayoutInfo = proxyLayoutInfo;\n pageContext._turbolinksProxy = {\n bodyAttrs: getElementAttributes(bodyEl),\n body: proxyBodyEl,\n head: headEl,\n };\n }\n const { head, bodyAttrs } = pageContext._turbolinksProxy!;\n pageContext._shouldEmitBeforeRender = true;\n\n await Turbolinks._vikeBeforeRender(pageContext._turbolinksVisit, {\n proxyLayoutInfo: pageContext.proxyLayoutInfo,\n });\n const { waitForReload, waitForHeadScripts } = mergeHead(head!);\n\n // If a full reload is required, wait for it here\n await waitForReload();\n pageContext._waitForHeadScripts = waitForHeadScripts;\n\n if (bodyAttrs) setBodyAttributes(bodyAttrs);\n\n pageContext._reactRenderTimeout = setTimeout(() => {\n pageContext.config.onWrappedReactRenderTimeout?.(pageContext);\n }, 30000);\n});\n"],"mappings":";;;;;;;;;;;;;AAMA,IAAM,wBAAiE,CAAC;AACxE,IAAI,aAAa;AACjB,IAAI;AAEG,IAAM,4BAA4B,WAAW,6BAA6B,SAASA,2BAA0B,iBAAmC;AACrJ,wCAAoB,eAAe,SAAS,IAAI;AAEhD,aAAW,WAAW,gBAAgB,SAAS;AAC7C,0BAAsB,QAAQ,SAAS,IAAI;AAAA,MACzC,SAAS,iBAAiB,OAAO;AAAA,IACnC;AAAA,EACF;AACA,+BACE,8BAA8B,wBAAwB,eAAe;AACvE,eAAa;AACf,CAAC;AAGM,SAAS,UAAU,MAAuB;AAC/C,QAAM,UAAU,eAAe,IAAI;AACnC,QAAM,UAAU,eAAe,SAAS,IAAI;AAC5C,QAAM,SAAS,MAAM;AACnB,WAAO,WAAW,WAAW,gBAAgB;AAC7C,WAAO;AAAA,MACL,eAAe,WAAW,kBAAkB,MAAM,IAAI,QAAc,MAAM;AAAA,MAAC,CAAC,CAAC;AAAA,MAC7E,oBAAoB,WAAW,uBAAuB,MAAM,IAAI,QAAc,MAAM;AAAA,MAAC,CAAC,CAAC;AAAA,IACzF;AAAA,EACF;AAEA,MACE,KACG,cAAc,uCAAuC,GACpD,aAAa,SAAS,MAAM,UAChC;AACA,WAAO,OAAO;AAAA,EAChB;AAEA,MAAI,CAAC,YAAY;AAEf,UAAM,4BAA4B,wBAAwB,OAAO;AACjE,QAAI,+BAA+B,2BAA2B;AAC5D,aAAO,OAAO;AAAA,IAChB;AAAA,EACF;AACA,eAAa;AACb,+BACE,8BAA8B,wBAAwB,OAAO;AAE/D,gCAA8B,QAAQ,aAAa,QAAQ,WAAW;AACtE,uCAAqC,QAAQ,WAAW;AACxD,iCAA+B,QAAQ,WAAW;AAElD,SAAO;AAAA,IACL,eAAe,WAAW,kBAAkB,MAAM,QAAQ,QAAQ,CAAC;AAAA,IACnE,oBAAoB,WAAW,uBAAuB,0BAA0B,QAAQ,OAAO,CAAC;AAAA,EAClG;AACF;AAEA,SAAS,wBAAwB,MAAuB;AACtD,SAAO,CAAC,GAAG,KAAK,SAAS,GAAG,KAAK,WAAW,EACzC,OAAO,gBAAgB,EACvB,IAAI,CAAC,MAAM,EAAE,SAAS,EACtB,KAAK;AACV;AAEA,SAAS,8BAA8B,MAAiB,MAAiB;AACvE,QAAM,WAAW,KAAK,IAAI,CAAC,MAAM,EAAE,SAAS;AAC5C,aAAW,WAAW,MAAM;AAC1B,QAAI,CAAC,SAAS,SAAS,QAAQ,SAAS,GAAG;AACzC,eAAS,KAAK,YAAY,OAAO;AAAA,IACnC;AAAA,EACF;AACF;AAEA,SAAS,0BAA0B,MAAsC;AACvE,QAAM,kBAA6B,CAAC;AACpC,MAAI,iBAA4B,CAAC;AACjC,QAAM,uBAAuB,IAAI,QAAc,CAAC,oBAAoB;AAClE,eAAW,WAAW,MAA6B;AACjD,YAAM,YAAY,QAAQ,aAAa;AACvC,UAAI,CAAC,WAAW;AACd,YAAI;AACJ,YAAI,CAAC,QAAQ,SAAS,QAAQ,KAAK;AACjC,gBAAM,MAAM,eAAe;AAC3B,eAAK,MAAM;AACT,2BAAe,GAAG,IAAI;AACtB,gBAAI,eAAe,MAAM,CAAC,MAAM,CAAC,GAAG;AAClC,8BAAgB;AAAA,YAClB;AAAA,UACF;AACA,yBAAe,KAAK,KAAK;AAAA,QAC3B;AACA,cAAM,aAAa,oBAAoB,SAAS,EAAE;AAClD,YAAI,QAAQ,OAAO;AACjB,0BAAgB,KAAK,UAAU;AAAA,QACjC,OAAO;AACL,mBAAS,KAAK,YAAY,UAAU;AAAA,QACtC;AACA,8BAAsB,QAAQ,SAAS,IAAI;AAAA,UACzC,SAAS,iBAAiB,OAAO;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AACA,QAAI,eAAe,WAAW,GAAG;AAE/B,sBAAgB;AAAA,IAClB;AAAA,EACF,CAAC;AACD,SAAO,MAAM;AACX,oBAAgB,QAAQ,CAAC,MAAM,SAAS,KAAK,YAAY,CAAC,CAAC;AAC3D,WAAO;AAAA,EACT;AACF;AAEA,SAAS,qCAAqC,MAAiB;AAC7D,aAAW,WAAW,MAAM;AAC1B,aAAS,KAAK,YAAY,OAAO;AAAA,EACnC;AACF;AAEA,SAAS,+BAA+B,MAAiB;AACvD,aAAW,WAAW,MAAM;AAC1B,aAAS,KAAK,YAAY,OAAO;AAAA,EACnC;AACF;AAEA,SAAS,iBAAiB,SAAkB;AAC1C,SAAO,QAAQ,aAAa,uBAAuB,KAAK;AAC1D;AAEA,SAAS,gBAAgB,SAAkB;AACzC,QAAM,UAAU,QAAQ,QAAQ,YAAY;AAC5C,SAAO,WAAW;AACpB;AAEA,SAAS,oBAAoB,SAAkB;AAC7C,QAAM,UAAU,QAAQ,QAAQ,YAAY;AAC5C,SACE,WAAW,WACV,WAAW,UAAU,QAAQ,aAAa,KAAK,KAAK;AAEzD;AAEA,SAAS,iBAAiB,SAAkB;AAC1C,QAAM,UAAU,QAAQ,QAAQ,YAAY;AAE5C,SAAO,WAAW,UAAU,QAAQ,aAAa,KAAK,KAAK;AAC7D;AAEA,SAAS,eAAe,MAAkB;AACxC,QAAM,UAAU,CAAC;AACjB,QAAM,cAAc,CAAC;AACrB,QAAM,cAAc,CAAC;AACrB,aAAW,WAAW,KAAK,UAAU;AAEnC,QAAI,iBAAiB,OAAO,GAAG;AAC7B;AAAA,IACF;AAEA,QAAI,gBAAgB,OAAO,GAAG;AAC5B,cAAQ,KAAK,OAAO;AAAA,IACtB,WAAW,oBAAoB,OAAO,GAAG;AACvC,kBAAY,KAAK,OAAO;AAAA,IAC1B,OAAO;AACL,kBAAY,KAAK,OAAO;AAAA,IAC1B;AAAA,EACF;AACA,SAAO,EAAE,SAAS,aAAa,YAAY;AAC7C;;;ACjKA,IAAO,+BAAQ,WAAW,+BAA+B,eAAe,4BACtE,aACA;AACA,MAAI,YAAY,aAAa;AAG3B,QAAI,SAAS,eAAe,WAAW;AACrC,YAAM,WAAW,4BAA4B,MAAM,IAAI;AAAA,QAAQ,CAAC,YAC9D,SAAS,iBAAiB,oBAAoB,MAAM,QAAQ,IAAI,GAAG,EAAE,MAAM,KAAI,CAAC;AAAA,MAClF,CAAC,EAAE;AAAA,IACL;AAEA,UAAM,cAAc,SAAS,eAAe,cAAc;AAC1D,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,gBAAY,mBAAmB;AAAA,MAC7B,MAAM;AAAA,IACR;AACA,eAAW,qBAAqB;AAAA,MAC9B,iBAAiB,YAAY;AAAA,IAC/B,CAAC;AACD,8BAA0B;AAC1B;AAAA,EACF;AAEA,MAAI,aAAa,WAAW;AAC1B,QAAI,YAAY,aAAa;AAC3B,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,UAAM,EAAE,gBAAgB,IAAI,YAAY,UAAU;AAClD,UAAM,EAAE,QAAQ,OAAO,IAAI,YAAY;AACvC,UAAM,cAAc,OAAO,cAAc,eAAe;AACxD,QAAI,CAAC,eAAe,EAAE,uBAAuB,cAAc;AACzD,YAAM,IAAI,MAAM,2CAA2C;AAAA,IAC7D;AACA,gBAAY,kBAAkB;AAC9B,gBAAY,mBAAmB;AAAA,MAC7B,WAAW,qBAAqB,MAAM;AAAA,MACtC,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AACA,QAAM,EAAE,MAAM,UAAU,IAAI,YAAY;AACxC,cAAY,0BAA0B;AAEtC,QAAM,WAAW,kBAAkB,YAAY,kBAAkB;AAAA,IAC/D,iBAAiB,YAAY;AAAA,EAC/B,CAAC;AACD,QAAM,EAAE,eAAe,mBAAmB,IAAI,UAAU,IAAK;AAG7D,QAAM,cAAc;AACpB,cAAY,sBAAsB;AAElC,MAAI;AAAW,sBAAkB,SAAS;AAE1C,cAAY,sBAAsB,WAAW,MAAM;AACjD,gBAAY,OAAO,8BAA8B,WAAW;AAAA,EAC9D,GAAG,GAAK;AACV,CAAC;","names":["recordExistingHeadScripts"]}
1
+ {"version":3,"sources":["../../../lib/turbolinks/mergeHead.ts","../../../renderer/wrapped/onBeforeRenderClient.ts"],"sourcesContent":["import { createScriptElement } from \"./util\";\nimport { instrument } from \"../diagnostic.client\";\n\ninterface ElementDetails {\n tracked: boolean;\n}\nconst allHeadScriptsEverRun: { [outerHTML: string]: ElementDetails } = {};\nlet firstMerge = true;\nlet lastTrackedScriptSignature: string;\n\nexport const recordExistingHeadScripts = instrument(\"recordExistingHeadScripts\", function recordExistingHeadScripts(categorizedHead?: CategorizedHead) {\n categorizedHead ||= categorizeHead(document.head);\n // record all existing head scripts as having been run, because they were run by browser, not mergeHead\n for (const element of categorizedHead.scripts) {\n allHeadScriptsEverRun[element.outerHTML] = {\n tracked: elementIsTracked(element),\n };\n }\n lastTrackedScriptSignature =\n lastTrackedScriptSignature || trackedElementSignature(categorizedHead);\n firstMerge = false;\n});\n\n// Returns function which resolves when all new blocking head scripts have loaded\nexport function mergeHead(head: HTMLHeadElement) {\n const newHead = categorizeHead(head);\n const oldHead = categorizeHead(document.head);\n const reload = () => {\n window.Turbolinks.controller.viewInvalidated();\n return {\n waitForReload: instrument(\"_waitForReload\", () => new Promise<void>(() => {})),\n waitForHeadScripts: instrument(\"_waitForHeadScripts\", () => new Promise<void>(() => {})),\n };\n };\n\n if (\n head\n .querySelector('meta[name=\"turbolinks-visit-control\"]')\n ?.getAttribute(\"content\") === \"reload\"\n ) {\n return reload();\n }\n\n if (!firstMerge) {\n // IMPORTANT: we allow first merge to always proceed without reload\n const newTrackedScriptSignature = trackedElementSignature(newHead);\n if (lastTrackedScriptSignature !== newTrackedScriptSignature) {\n return reload();\n }\n }\n firstMerge = false;\n lastTrackedScriptSignature =\n lastTrackedScriptSignature || trackedElementSignature(newHead);\n\n copyNewHeadStylesheetElements(newHead.stylesheets, oldHead.stylesheets);\n removeCurrentHeadProvisionalElements(oldHead.provisional);\n copyNewHeadProvisionalElements(newHead.provisional);\n\n return {\n waitForReload: instrument(\"_waitForReload\", () => Promise.resolve()),\n waitForHeadScripts: instrument(\"_waitForHeadScripts\", copyNewHeadScriptElements(newHead.scripts)),\n };\n}\n\nfunction trackedElementSignature(head: CategorizedHead) {\n return [...head.scripts, ...head.stylesheets]\n .filter(elementIsTracked)\n .map((s) => s.outerHTML)\n .join();\n}\n\nfunction copyNewHeadStylesheetElements(next: Element[], prev: Element[]) {\n const existing = prev.map((s) => s.outerHTML);\n for (const element of next) {\n if (!existing.includes(element.outerHTML)) {\n document.head.appendChild(element);\n }\n }\n}\n\nfunction copyNewHeadScriptElements(next: Element[]): () => Promise<void> {\n const deferredScripts: Element[] = [];\n let blockingLoaded: boolean[] = [];\n const scriptsLoadedPromise = new Promise<void>((onScriptsLoaded) => {\n for (const element of next as HTMLScriptElement[]) {\n const runBefore = element.outerHTML in allHeadScriptsEverRun;\n if (!runBefore) {\n let cb;\n if (!element.defer && element.src) {\n const idx = blockingLoaded.length;\n cb = () => {\n blockingLoaded[idx] = true;\n if (blockingLoaded.every((v) => v)) {\n onScriptsLoaded();\n }\n };\n blockingLoaded.push(false);\n }\n const newElement = createScriptElement(element, cb);\n if (element.defer) {\n deferredScripts.push(newElement);\n } else {\n document.head.appendChild(newElement);\n }\n allHeadScriptsEverRun[element.outerHTML] = {\n tracked: elementIsTracked(element),\n };\n }\n }\n if (blockingLoaded.length === 0) {\n // raf waits for react to finish\n onScriptsLoaded();\n }\n });\n return () => {\n deferredScripts.forEach((s) => document.head.appendChild(s));\n return scriptsLoadedPromise;\n };\n}\n\nfunction removeCurrentHeadProvisionalElements(prev: Element[]) {\n for (const element of prev) {\n document.head.removeChild(element);\n }\n}\n\nfunction copyNewHeadProvisionalElements(next: Element[]) {\n for (const element of next) {\n document.head.appendChild(element);\n }\n}\n\nfunction elementIsTracked(element: Element) {\n return element.getAttribute(\"data-turbolinks-track\") == \"reload\";\n}\n\nfunction elementIsScript(element: Element) {\n const tagName = element.tagName.toLowerCase();\n return tagName == \"script\";\n}\n\nfunction elementIsStylesheet(element: Element) {\n const tagName = element.tagName.toLowerCase();\n return (\n tagName == \"style\" ||\n (tagName == \"link\" && element.getAttribute(\"rel\") == \"stylesheet\")\n );\n}\n\nfunction elementIsFavicon(element: Element) {\n const tagName = element.tagName.toLowerCase();\n\n return tagName == \"link\" && element.getAttribute(\"rel\") == \"icon\";\n}\n\nfunction categorizeHead(head: ParentNode) {\n const scripts = [];\n const stylesheets = [];\n const provisional = [];\n for (const element of head.children) {\n // we want to keep the same favicon on page transitions\n if (elementIsFavicon(element)) {\n continue;\n }\n\n if (elementIsScript(element)) {\n scripts.push(element);\n } else if (elementIsStylesheet(element)) {\n stylesheets.push(element);\n } else {\n provisional.push(element);\n }\n }\n return { scripts, stylesheets, provisional };\n}\ntype CategorizedHead = ReturnType<typeof categorizeHead>;\n","import \"../../lib/type\";\nimport type { PageContextClient } from \"vike/types\";\nimport { Turbolinks } from \"../../lib/turbolinks\";\nimport {\n mergeHead,\n recordExistingHeadScripts,\n} from \"../../lib/turbolinks/mergeHead\";\nimport {\n setBodyAttributes,\n getElementAttributes,\n} from \"../../lib/elementUtils\";\nimport { instrument } from \"../../lib/diagnostic.client\";\n\nexport default instrument(\"wrappedOnBeforeRenderClient\", async function wrappedOnBeforeRenderClient(\n pageContext: PageContextClient\n) {\n if (pageContext.isHydration) {\n // Vike scripts load async so can run before document.body exists. we need to delay rendering.\n // This is only an issue if user sets `injectScriptsAt: \"HTML_BEGIN\"` in +config.ts\n if (document.readyState === \"loading\") {\n await instrument(\"_waitForDOMContentLoaded\", () => new Promise((resolve) =>\n document.addEventListener(\"DOMContentLoaded\", () => resolve(null), { once: true})\n ))();\n }\n\n // This should be caught by onAfterRenderHtml, but just in case, check again on client side\n const proxiedBody = document.getElementById(\"proxied-body\");\n if (!proxiedBody) {\n throw new Error(\n \"proxied-body not found in DOM after SSR. This likely means the Layout threw during SSR (e.g. accessing `window` or `document`). Fix the SSR error in your Layout component.\"\n );\n }\n pageContext._turbolinksProxy = {\n body: proxiedBody,\n };\n Turbolinks._vpsCachePageContext({\n proxyLayoutInfo: pageContext.proxyLayoutInfo,\n });\n recordExistingHeadScripts();\n return;\n }\n\n if (pageContext?._snapshot) {\n if (pageContext.isHydration) {\n throw new Error(\n \"restoration visit should never happen on initial render\"\n );\n }\n const { proxyLayoutInfo } = pageContext._snapshot.pageContext;\n const { bodyEl, headEl } = pageContext._snapshot;\n const proxyBodyEl = bodyEl.querySelector(\"#proxied-body\")!;\n if (!proxyBodyEl || !(proxyBodyEl instanceof HTMLElement)) {\n throw new Error(\"proxied body not found in cached snapshot\");\n }\n pageContext.proxyLayoutInfo = proxyLayoutInfo;\n pageContext._turbolinksProxy = {\n bodyAttrs: getElementAttributes(bodyEl),\n body: proxyBodyEl,\n head: headEl,\n };\n }\n const { head, bodyAttrs } = pageContext._turbolinksProxy!;\n pageContext._shouldEmitBeforeRender = true;\n\n await Turbolinks._vikeBeforeRender(pageContext._turbolinksVisit, {\n proxyLayoutInfo: pageContext.proxyLayoutInfo,\n });\n const { waitForReload, waitForHeadScripts } = mergeHead(head!);\n\n // If a full reload is required, wait for it here\n await waitForReload();\n pageContext._waitForHeadScripts = waitForHeadScripts;\n\n if (bodyAttrs) setBodyAttributes(bodyAttrs);\n\n pageContext._reactRenderTimeout = setTimeout(() => {\n pageContext.config.onWrappedReactRenderTimeout?.(pageContext);\n }, 30000);\n});\n"],"mappings":"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","names":["recordExistingHeadScripts"]}
@@ -5,6 +5,7 @@ interface WrappedServerOnly {
5
5
  bodyInnerHtml: string;
6
6
  headInnerHtml: string;
7
7
  proxyLayoutInfo: Vike.ProxyLayoutInfo;
8
+ renderedBody?: boolean;
8
9
  }
9
10
  declare global {
10
11
  namespace Vike {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@alignable/bifrost",
3
3
  "repository": "https://github.com/Alignable/bifrost.git",
4
- "version": "1.0.31",
4
+ "version": "1.0.32",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
7
7
  "exports": {
@@ -45,8 +45,8 @@
45
45
  "peerDependencies": {
46
46
  "react": ">=18",
47
47
  "typescript": ">=4.7",
48
- "vike": ">=0.4.253",
49
- "vike-react": ">=0.6.18"
48
+ "vike": ">=0.4.255",
49
+ "vike-react": ">=0.6.21"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/jsdom": "^21.1.2",
@@ -58,9 +58,9 @@
58
58
  "tsup": "^7.1.0",
59
59
  "turbolinks": "5.3.0-beta.1",
60
60
  "typescript": "^5.0.4",
61
- "vike-react": "0.6.18",
61
+ "vike-react": "0.6.21",
62
62
  "vite": "^6.3.5",
63
- "vike": "0.4.253",
63
+ "vike": "0.4.255",
64
64
  "cross-env": "^7.0.3"
65
65
  }
66
66
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../renderer/config.ts"],"sourcesContent":["import { type Config } from \"vike/types\";\n\nexport default {\n name: \"@alignable/bifrost\",\n require: {\n vike: \">=0.4.244\",\n \"vike-react\": \">=0.6.11\",\n },\n\n headHtmlBegin:\n \"import:@alignable/bifrost/__internal/renderer/headHtmlBegin:default\",\n headHtmlEnd:\n \"import:@alignable/bifrost/__internal/renderer/headHtmlEnd:default\",\n onBeforeRoute:\n \"import:@alignable/bifrost/__internal/renderer/onBeforeRoute:default\",\n Wrapper: \"import:@alignable/bifrost/__internal/renderer/Wrapper:default\",\n\n passToClient: [\"proxyLayoutInfo\"],\n\n meta: {\n bodyAttributes: {\n // vike-react bodyAttributes are server-only, but legacy backend may change bodyAttributes and we need to reset on return to bifrost pages\n env: { server: true, client: true },\n global: true,\n cumulative: true,\n },\n getLayout: { env: { server: true, client: true } },\n layoutHeaders: { env: { server: true, client: false } },\n proxyHeaders: { env: { server: true, client: true } },\n onWrappedReactRenderTimeout: { env: { server: false, client: true} },\n proxyMode: {\n env: { server: true, client: true, config: true },\n effect({ configDefinedAt, configValue }) {\n switch (configValue) {\n case false:\n return {\n onBeforeRenderClient:\n \"import:@alignable/bifrost/__internal/renderer/bifrost/onBeforeRenderClient:default\",\n onAfterRenderClient:\n \"import:@alignable/bifrost/__internal/renderer/bifrost/onAfterRenderClient:default\",\n };\n case \"wrapped\":\n return {\n Page: \"import:@alignable/bifrost/__internal/renderer/wrapped/Page:default\" as any,\n onRenderHtml:\n \"import:@alignable/bifrost/__internal/renderer/wrapped/onRenderHtml:default\",\n onBeforeRenderHtml:\n \"import:@alignable/bifrost/__internal/renderer/wrapped/onBeforeRenderHtml:default\",\n onBeforeRender:\n \"import:@alignable/bifrost/__internal/renderer/wrapped/onBeforeRender.client:default\",\n onBeforeRenderClient:\n \"import:@alignable/bifrost/__internal/renderer/wrapped/onBeforeRenderClient:default\",\n onAfterRenderClient:\n \"import:@alignable/bifrost/__internal/renderer/wrapped/onAfterRenderClient:default\",\n // Disable onRenderClient timeout since we wait for head scripts to load in onAfterRenderClient\n // onWrappedReactRenderTimeout will fire when vike-react's onRenderClient times out.\n // Ideally, we could only disable timeout for onAfterRenderClient\n // https://github.com/vikejs/vike/issues/3147\n hooksTimeout: {\n onRenderClient: false,\n },\n meta: {\n onBeforeRender: { env: { client: true, server: false } },\n },\n };\n case \"passthru\":\n // tell Vike to hit the server for all passthru pages (which will get load balanced to legacy backend)\n return {\n onRenderHtml:\n \"import:@alignable/bifrost/__internal/renderer/passthru/onRenderHtml:default\",\n clientRouting: false,\n };\n default:\n throw new Error(\n `${configDefinedAt} should be one of: false, \"wrapped\", \"passthru\"`\n );\n }\n },\n },\n },\n} satisfies Config;\n\n/**\n * Returning null tells Bifrost to run passthru proxy\n */\nexport type GetLayout = (\n headers: Record<string, number | string | string[] | undefined>\n) => Vike.ProxyLayoutInfo | null;\n\ndeclare global {\n namespace Vike {\n interface Config {\n proxyMode?: false | \"wrapped\" | \"passthru\";\n proxyHeaders?: Record<string, string>;\n getLayout?: GetLayout;\n /** Response headers that should be consumed server-side and stripped before sending to the client. */\n layoutHeaders?: string[];\n /**\n * Fired when react render times out on the client in the wrapped proxy\n */\n onWrappedReactRenderTimeout?: (pageContext: PageContext) => void;\n }\n interface PageContext {\n proxyLayoutInfo?: ProxyLayoutInfo;\n }\n interface ProxyLayoutInfo {}\n }\n}\n\n// This is only used for fastify integration\nexport { type WrappedServerOnly } from \"../lib/type\";\n"],"mappings":";AAEA,IAAO,iBAAQ;AAAA,EACb,MAAM;AAAA,EACN,SAAS;AAAA,IACP,MAAM;AAAA,IACN,cAAc;AAAA,EAChB;AAAA,EAEA,eACE;AAAA,EACF,aACE;AAAA,EACF,eACE;AAAA,EACF,SAAS;AAAA,EAET,cAAc,CAAC,iBAAiB;AAAA,EAEhC,MAAM;AAAA,IACJ,gBAAgB;AAAA;AAAA,MAEd,KAAK,EAAE,QAAQ,MAAM,QAAQ,KAAK;AAAA,MAClC,QAAQ;AAAA,MACR,YAAY;AAAA,IACd;AAAA,IACA,WAAW,EAAE,KAAK,EAAE,QAAQ,MAAM,QAAQ,KAAK,EAAE;AAAA,IACjD,eAAe,EAAE,KAAK,EAAE,QAAQ,MAAM,QAAQ,MAAM,EAAE;AAAA,IACtD,cAAc,EAAE,KAAK,EAAE,QAAQ,MAAM,QAAQ,KAAK,EAAE;AAAA,IACpD,6BAA6B,EAAE,KAAK,EAAE,QAAQ,OAAO,QAAQ,KAAI,EAAE;AAAA,IACnE,WAAW;AAAA,MACT,KAAK,EAAE,QAAQ,MAAM,QAAQ,MAAM,QAAQ,KAAK;AAAA,MAChD,OAAO,EAAE,iBAAiB,YAAY,GAAG;AACvC,gBAAQ,aAAa;AAAA,UACnB,KAAK;AACH,mBAAO;AAAA,cACL,sBACE;AAAA,cACF,qBACE;AAAA,YACJ;AAAA,UACF,KAAK;AACH,mBAAO;AAAA,cACL,MAAM;AAAA,cACN,cACE;AAAA,cACF,oBACE;AAAA,cACF,gBACE;AAAA,cACF,sBACE;AAAA,cACF,qBACE;AAAA;AAAA;AAAA;AAAA;AAAA,cAKF,cAAc;AAAA,gBACZ,gBAAgB;AAAA,cAClB;AAAA,cACA,MAAM;AAAA,gBACJ,gBAAgB,EAAE,KAAK,EAAE,QAAQ,MAAM,QAAQ,MAAM,EAAE;AAAA,cACzD;AAAA,YACF;AAAA,UACF,KAAK;AAEH,mBAAO;AAAA,cACL,cACE;AAAA,cACF,eAAe;AAAA,YACjB;AAAA,UACF;AACE,kBAAM,IAAI;AAAA,cACR,GAAG,eAAe;AAAA,YACpB;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":[]}