@alignable/bifrost 1.0.23 → 1.0.24

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.
@@ -4,6 +4,26 @@ import {
4
4
 
5
5
  // renderer/wrapped/onBeforeRender.client.ts
6
6
  import { redirect } from "vike/abort";
7
+
8
+ // lib/hardRedirect.ts
9
+ async function hardRedirect(url) {
10
+ if (url.startsWith("/")) {
11
+ window.location.href = url;
12
+ await new Promise(() => {
13
+ });
14
+ return;
15
+ }
16
+ const parsedUrl = new URL(url);
17
+ if (window.location.origin === parsedUrl.origin) {
18
+ window.location.href = parsedUrl.pathname + parsedUrl.search + parsedUrl.hash;
19
+ } else {
20
+ window.location.href = url;
21
+ }
22
+ await new Promise(() => {
23
+ });
24
+ }
25
+
26
+ // renderer/wrapped/onBeforeRender.client.ts
7
27
  async function wrappedOnBeforeRender(pageContext) {
8
28
  if (pageContext.isClientSide && !pageContext?._snapshot && !pageContext.isHydration) {
9
29
  const resp = await fetch(pageContext.urlParsed.href, {
@@ -11,9 +31,7 @@ async function wrappedOnBeforeRender(pageContext) {
11
31
  }).catch(() => {
12
32
  });
13
33
  if (!resp) {
14
- window.location.href = pageContext.urlParsed.href;
15
- await new Promise(() => {
16
- });
34
+ await hardRedirect(pageContext.urlParsed.href);
17
35
  return;
18
36
  }
19
37
  if (resp.redirected) {
@@ -21,18 +39,21 @@ async function wrappedOnBeforeRender(pageContext) {
21
39
  if (window.location.origin === parsedUrl.origin) {
22
40
  throw redirect(parsedUrl.pathname + parsedUrl.search + parsedUrl.hash);
23
41
  } else {
24
- throw redirect(resp.url);
42
+ await hardRedirect(resp.url);
43
+ return;
25
44
  }
26
45
  }
27
46
  if (!resp.ok) {
28
- throw redirect(resp.url);
47
+ await hardRedirect(resp.url);
48
+ return;
29
49
  }
30
50
  const html = await resp.text();
31
51
  const layoutInfo = pageContext.config.getLayout(
32
52
  Object.fromEntries(resp.headers.entries())
33
53
  );
34
54
  if (!layoutInfo) {
35
- throw redirect(resp.url);
55
+ await hardRedirect(resp.url);
56
+ return;
36
57
  }
37
58
  const parsed = document.createElement("html");
38
59
  parsed.innerHTML = html;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../renderer/wrapped/onBeforeRender.client.ts"],"sourcesContent":["import \"../../lib/type\";\nimport type { PageContextClient } from \"vike/types\";\nimport { redirect } from \"vike/abort\";\nimport { getElementAttributes } from \"../../lib/elementUtils\";\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 const resp = await fetch(pageContext.urlParsed.href, {\n headers: { ...pageContext.config.proxyHeaders, accept: \"text/html\" },\n }).catch(() => {});\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 // redirect needs to start with \"/\" or vike will do hard reload\n throw redirect(parsedUrl.pathname + parsedUrl.search + parsedUrl.hash);\n } else {\n // external redirect\n throw redirect(resp.url);\n }\n }\n if (!resp.ok) {\n throw redirect(resp.url);\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 // window.location.href = resp.url;\n throw redirect(resp.url);\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"],"mappings":";;;;;AAEA,SAAS,gBAAgB;AAMzB,eAAO,sBACL,aACA;AACA,MACE,YAAY,gBACZ,CAAC,aAAa,aACd,CAAC,YAAY,aACb;AAoCA,UAAM,OAAO,MAAM,MAAM,YAAY,UAAU,MAAM;AAAA,MACnD,SAAS,EAAE,GAAG,YAAY,OAAO,cAAc,QAAQ,YAAY;AAAA,IACrE,CAAC,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAEjB,QAAI,CAAC,MAAM;AAET,aAAO,SAAS,OAAO,YAAY,UAAU;AAE7C,YAAM,IAAI,QAAQ,MAAM;AAAA,MAAC,CAAC;AAC1B;AAAA,IACF;AAEA,QAAI,KAAK,YAAY;AACnB,YAAM,YAAY,IAAI,IAAI,KAAK,GAAG;AAIlC,UAAI,OAAO,SAAS,WAAW,UAAU,QAAQ;AAE/C,cAAM,SAAS,UAAU,WAAW,UAAU,SAAS,UAAU,IAAI;AAAA,MACvE,OAAO;AAEL,cAAM,SAAS,KAAK,GAAG;AAAA,MACzB;AAAA,IACF;AACA,QAAI,CAAC,KAAK,IAAI;AACZ,YAAM,SAAS,KAAK,GAAG;AAAA,IACzB;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;AAGf,YAAM,SAAS,KAAK,GAAG;AAAA,IACzB;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/hardRedirect.ts"],"sourcesContent":["import \"../../lib/type\";\nimport type { PageContextClient } from \"vike/types\";\nimport { redirect } from \"vike/abort\";\nimport { hardRedirect } from \"../../lib/hardRedirect\";\nimport { getElementAttributes } from \"../../lib/elementUtils\";\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 const resp = await fetch(pageContext.urlParsed.href, {\n headers: { ...pageContext.config.proxyHeaders, accept: \"text/html\" },\n }).catch(() => {});\n\n if (!resp) {\n // hard reload. can happen on cors errors when redirected to external page\n await hardRedirect(pageContext.urlParsed.href);\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 // redirect needs to start with \"/\" or vike will do hard reload\n throw redirect(parsedUrl.pathname + parsedUrl.search + parsedUrl.hash);\n } else {\n // external redirect\n await hardRedirect(resp.url);\n return;\n }\n }\n \n if (!resp.ok) {\n await hardRedirect(resp.url);\n return;\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 // window.location.href = resp.url;\n await hardRedirect(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 redirect (full page reload) that converts same-origin URLs to relative paths.\n * Turbolinks IOS requires relative URLs to open within the mobile app instead of safari.\n */\nexport async function hardRedirect(url: string) {\n if (url.startsWith(\"/\")) {\n window.location.href = url;\n await new Promise(() => {});\n return;\n }\n\n const parsedUrl = new URL(url);\n\n if (window.location.origin === parsedUrl.origin) {\n // Relative redirect\n window.location.href = parsedUrl.pathname + parsedUrl.search + parsedUrl.hash;\n } else {\n // External redirect\n window.location.href = url;\n }\n\n // stop vike rendering to let navigation happen\n await new Promise(() => {});\n}\n"],"mappings":";;;;;AAEA,SAAS,gBAAgB;;;ACEzB,eAAsB,aAAa,KAAa;AAC9C,MAAI,IAAI,WAAW,GAAG,GAAG;AACvB,WAAO,SAAS,OAAO;AACvB,UAAM,IAAI,QAAQ,MAAM;AAAA,IAAC,CAAC;AAC1B;AAAA,EACF;AAEA,QAAM,YAAY,IAAI,IAAI,GAAG;AAE7B,MAAI,OAAO,SAAS,WAAW,UAAU,QAAQ;AAE/C,WAAO,SAAS,OAAO,UAAU,WAAW,UAAU,SAAS,UAAU;AAAA,EAC3E,OAAO;AAEL,WAAO,SAAS,OAAO;AAAA,EACzB;AAGA,QAAM,IAAI,QAAQ,MAAM;AAAA,EAAC,CAAC;AAC5B;;;ADdA,eAAO,sBACL,aACA;AACA,MACE,YAAY,gBACZ,CAAC,aAAa,aACd,CAAC,YAAY,aACb;AAoCA,UAAM,OAAO,MAAM,MAAM,YAAY,UAAU,MAAM;AAAA,MACnD,SAAS,EAAE,GAAG,YAAY,OAAO,cAAc,QAAQ,YAAY;AAAA,IACrE,CAAC,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAEjB,QAAI,CAAC,MAAM;AAET,YAAM,aAAa,YAAY,UAAU,IAAI;AAC7C;AAAA,IACF;AAEA,QAAI,KAAK,YAAY;AACnB,YAAM,YAAY,IAAI,IAAI,KAAK,GAAG;AAIlC,UAAI,OAAO,SAAS,WAAW,UAAU,QAAQ;AAE/C,cAAM,SAAS,UAAU,WAAW,UAAU,SAAS,UAAU,IAAI;AAAA,MACvE,OAAO;AAEL,cAAM,aAAa,KAAK,GAAG;AAC3B;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,IAAI;AACZ,YAAM,aAAa,KAAK,GAAG;AAC3B;AAAA,IACF;AAEA,UAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,UAAM,aAAa,YAAY,OAAO;AAAA,MACpC,OAAO,YAAY,KAAK,QAAQ,QAAQ,CAAC;AAAA,IAC3C;AACA,QAAI,CAAC,YAAY;AAGf,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":[]}
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.23",
4
+ "version": "1.0.24",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
7
7
  "exports": {