@pracht/core 0.8.0 → 0.8.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/dist/{app-BvC1uQG5.mjs → app-w-P1wf5T.mjs} +1 -1
- package/dist/browser.mjs +3 -3
- package/dist/client.mjs +2 -2
- package/dist/index.mjs +4 -4
- package/dist/manifest.mjs +1 -1
- package/dist/{prefetch-B50kX9RL.mjs → prefetch-D9amIQtw.mjs} +1 -1
- package/dist/{prerender-D3E2H96p.mjs → prerender-CoMyuJKm.mjs} +6 -8
- package/dist/{router-B7J4YYwg.mjs → router-BkkyNjqB.mjs} +93 -10
- package/dist/server.mjs +3 -3
- package/dist/{types-idmK5omD.mjs → types-DQv2poC5.mjs} +2 -9
- package/package.json +1 -1
|
@@ -26,7 +26,7 @@ function route(path, fileOrConfig, meta = {}) {
|
|
|
26
26
|
function resolveModuleRef(ref) {
|
|
27
27
|
if (ref === void 0) return void 0;
|
|
28
28
|
if (typeof ref === "string") return ref;
|
|
29
|
-
|
|
29
|
+
throw new Error("Invalid ModuleRef: expected a string path, but received a function at runtime. Use a plain string path (e.g. \"./routes/home.tsx\"), or ensure the Vite plugin rewrites inline `() => import(\"./file\")` refs in the app manifest.");
|
|
30
30
|
}
|
|
31
31
|
function group(meta, routes) {
|
|
32
32
|
return {
|
package/dist/browser.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { c as resolveApp, i as group, l as route, n as buildPathFromSegments, o as matchAppRoute, r as defineApp, t as buildHref, u as timeRevalidate } from "./app-
|
|
2
|
-
import { S as createHref, a as useParams, i as useLocation, n as Form, o as useRevalidate, r as Link, s as useRouteData, t as PrachtHttpError, u as redirect } from "./types-
|
|
1
|
+
import { c as resolveApp, i as group, l as route, n as buildPathFromSegments, o as matchAppRoute, r as defineApp, t as buildHref, u as timeRevalidate } from "./app-w-P1wf5T.mjs";
|
|
2
|
+
import { S as createHref, a as useParams, i as useLocation, n as Form, o as useRevalidate, r as Link, s as useRouteData, t as PrachtHttpError, u as redirect } from "./types-DQv2poC5.mjs";
|
|
3
3
|
import { t as forwardRef } from "./forwardRef-grZ6t4GS.mjs";
|
|
4
|
-
import { n as useNavigate, r as useIsHydrated, t as initClientRouter } from "./router-
|
|
4
|
+
import { n as useNavigate, r as useIsHydrated, t as initClientRouter } from "./router-BkkyNjqB.mjs";
|
|
5
5
|
import { l as parseSafeNavigationUrl, s as fetchPrachtRouteState } from "./prefetch-cache-DzP2Bj9H.mjs";
|
|
6
6
|
import { i as startApp, r as readHydrationState, t as PrachtRuntimeProvider } from "./runtime-context-B5pREhcM.mjs";
|
|
7
7
|
import { Suspense, lazy } from "preact-suspense";
|
package/dist/client.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as resolveApp } from "./app-
|
|
2
|
-
import { t as initClientRouter } from "./router-
|
|
1
|
+
import { c as resolveApp } from "./app-w-P1wf5T.mjs";
|
|
2
|
+
import { t as initClientRouter } from "./router-BkkyNjqB.mjs";
|
|
3
3
|
import { r as readHydrationState } from "./runtime-context-B5pREhcM.mjs";
|
|
4
4
|
export { initClientRouter, readHydrationState, resolveApp };
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as matchApiRoute, c as resolveApp, i as group, l as route, n as buildPathFromSegments, o as matchAppRoute, r as defineApp, s as resolveApiRoutes, t as buildHref, u as timeRevalidate } from "./app-
|
|
2
|
-
import { S as createHref, _ as applyDefaultSecurityHeaders, a as useParams, i as useLocation, n as Form, o as useRevalidate, r as Link, s as useRouteData, t as PrachtHttpError, u as redirect } from "./types-
|
|
1
|
+
import { a as matchApiRoute, c as resolveApp, i as group, l as route, n as buildPathFromSegments, o as matchAppRoute, r as defineApp, s as resolveApiRoutes, t as buildHref, u as timeRevalidate } from "./app-w-P1wf5T.mjs";
|
|
2
|
+
import { S as createHref, _ as applyDefaultSecurityHeaders, a as useParams, i as useLocation, n as Form, o as useRevalidate, r as Link, s as useRouteData, t as PrachtHttpError, u as redirect } from "./types-DQv2poC5.mjs";
|
|
3
3
|
import { t as forwardRef } from "./forwardRef-grZ6t4GS.mjs";
|
|
4
|
-
import { n as useNavigate, r as useIsHydrated, t as initClientRouter } from "./router-
|
|
4
|
+
import { n as useNavigate, r as useIsHydrated, t as initClientRouter } from "./router-BkkyNjqB.mjs";
|
|
5
5
|
import { i as startApp, r as readHydrationState, t as PrachtRuntimeProvider } from "./runtime-context-B5pREhcM.mjs";
|
|
6
|
-
import { n as handlePrachtRequest, t as prerenderApp } from "./prerender-
|
|
6
|
+
import { n as handlePrachtRequest, t as prerenderApp } from "./prerender-CoMyuJKm.mjs";
|
|
7
7
|
import { Suspense, lazy } from "preact-suspense";
|
|
8
8
|
export { Form, Link, PrachtHttpError, PrachtRuntimeProvider, Suspense, applyDefaultSecurityHeaders, buildHref, buildPathFromSegments, createHref, defineApp, forwardRef, group, handlePrachtRequest, initClientRouter, lazy, matchApiRoute, matchAppRoute, prerenderApp, readHydrationState, redirect, resolveApiRoutes, resolveApp, route, startApp, timeRevalidate, useIsHydrated, useLocation, useNavigate, useParams, useRevalidate, useRouteData };
|
package/dist/manifest.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as group, l as route, r as defineApp, u as timeRevalidate } from "./app-
|
|
1
|
+
import { i as group, l as route, r as defineApp, u as timeRevalidate } from "./app-w-P1wf5T.mjs";
|
|
2
2
|
export { defineApp, group, route, timeRevalidate };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as matchAppRoute } from "./app-
|
|
1
|
+
import { o as matchAppRoute } from "./app-w-P1wf5T.mjs";
|
|
2
2
|
import { a as trimMapToSize, i as getCachedRouteState, n as cacheRouteState, s as fetchPrachtRouteState, t as EMPTY_ROUTE_STATE_PROMISE, u as routeNeedsServerFetch } from "./prefetch-cache-DzP2Bj9H.mjs";
|
|
3
3
|
//#region src/prefetch.ts
|
|
4
4
|
const MAX_MATCH_CACHE_ENTRIES = 250;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as matchApiRoute, c as resolveApp, n as buildPathFromSegments, o as matchAppRoute } from "./app-
|
|
2
|
-
import { _ as applyDefaultSecurityHeaders, b as withDefaultSecurityHeaders, c as mergeDocumentHeaders, d as runMiddlewareChain, f as resolveDataFunctions, g as appendVaryHeader, h as resolveRegistryModule, l as mergeHeadMetadata, m as resolvePageJsUrls, p as resolvePageCssUrls, v as applyHeaders, x as withRouteResponseHeaders, y as applySecurityAndRouteHeaders } from "./types-
|
|
1
|
+
import { a as matchApiRoute, c as resolveApp, n as buildPathFromSegments, o as matchAppRoute } from "./app-w-P1wf5T.mjs";
|
|
2
|
+
import { _ as applyDefaultSecurityHeaders, b as withDefaultSecurityHeaders, c as mergeDocumentHeaders, d as runMiddlewareChain, f as resolveDataFunctions, g as appendVaryHeader, h as resolveRegistryModule, l as mergeHeadMetadata, m as resolvePageJsUrls, p as resolvePageCssUrls, v as applyHeaders, x as withRouteResponseHeaders, y as applySecurityAndRouteHeaders } from "./types-DQv2poC5.mjs";
|
|
3
3
|
import { f as HYDRATION_STATE_ELEMENT_ID, h as SAFE_METHODS, m as ROUTE_STATE_REQUEST_HEADER, o as buildRouteStateUrl } from "./prefetch-cache-DzP2Bj9H.mjs";
|
|
4
4
|
import { a as buildRuntimeDiagnostics, c as normalizeRouteError, l as shouldExposeServerErrors, o as createSerializedRouteError, s as deserializeRouteError, t as PrachtRuntimeProvider } from "./runtime-context-B5pREhcM.mjs";
|
|
5
5
|
import { h } from "preact";
|
|
@@ -249,11 +249,9 @@ function prefersMarkdown(accept) {
|
|
|
249
249
|
if (!html) return true;
|
|
250
250
|
return md.quality >= html.quality;
|
|
251
251
|
}
|
|
252
|
-
function markdownResponse(source) {
|
|
253
|
-
const headers = new Headers(
|
|
254
|
-
|
|
255
|
-
"cache-control": "public, max-age=0, must-revalidate"
|
|
256
|
-
});
|
|
252
|
+
function markdownResponse(source, initHeaders) {
|
|
253
|
+
const headers = new Headers(initHeaders);
|
|
254
|
+
headers.set("content-type", "text/markdown; charset=utf-8");
|
|
257
255
|
appendVaryHeader(headers, "Accept");
|
|
258
256
|
applyDefaultSecurityHeaders(headers);
|
|
259
257
|
return new Response(source, {
|
|
@@ -444,7 +442,6 @@ async function handlePrachtRequest(options) {
|
|
|
444
442
|
currentPhase = "render";
|
|
445
443
|
routeModule = await routeModulePromise;
|
|
446
444
|
if (!routeModule) throw new Error("Route module not found");
|
|
447
|
-
if (!isRouteStateRequest && typeof routeModule.markdown === "string" && prefersMarkdown(options.request.headers.get("accept"))) return markdownResponse(routeModule.markdown);
|
|
448
445
|
currentPhase = "loader";
|
|
449
446
|
const { loader, loaderFile: resolvedLoaderFile } = await dataFunctionsPromise;
|
|
450
447
|
loaderFile = resolvedLoaderFile;
|
|
@@ -455,6 +452,7 @@ async function handlePrachtRequest(options) {
|
|
|
455
452
|
currentPhase = "render";
|
|
456
453
|
shellModule = await shellModulePromise;
|
|
457
454
|
const [head, documentHeaders] = await Promise.all([mergeHeadMetadata(shellModule, routeModule, routeArgs, data), mergeDocumentHeaders(shellModule, routeModule, routeArgs, data)]);
|
|
455
|
+
if (!isRouteStateRequest && typeof routeModule.markdown === "string" && prefersMarkdown(options.request.headers.get("accept"))) return markdownResponse(routeModule.markdown, documentHeaders);
|
|
458
456
|
const cssUrls = resolvePageCssUrls(options.cssManifest, match.route.shellFile, match.route.file);
|
|
459
457
|
const modulePreloadUrls = resolvePageJsUrls(options.jsManifest, match.route.shellFile, match.route.file);
|
|
460
458
|
if (match.route.render === "spa") {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { o as matchAppRoute, t as buildHref } from "./app-
|
|
1
|
+
import { o as matchAppRoute, t as buildHref } from "./app-w-P1wf5T.mjs";
|
|
2
2
|
import { i as getCachedRouteState, l as parseSafeNavigationUrl, s as fetchPrachtRouteState, u as routeNeedsServerFetch } from "./prefetch-cache-DzP2Bj9H.mjs";
|
|
3
3
|
import { s as deserializeRouteError, t as PrachtRuntimeProvider } from "./runtime-context-B5pREhcM.mjs";
|
|
4
4
|
import { createContext, h, hydrate, options, render } from "preact";
|
|
5
5
|
import { useContext, useEffect, useMemo, useState } from "preact/hooks";
|
|
6
6
|
import { Suspense } from "preact-suspense";
|
|
7
7
|
//#region src/hydration.ts
|
|
8
|
-
const MODE_HYDRATE = 32;
|
|
8
|
+
const MODE_HYDRATE$1 = 32;
|
|
9
9
|
let _hydrating = false;
|
|
10
10
|
let _suspensionCount = 0;
|
|
11
11
|
let _hydrated = false;
|
|
@@ -13,7 +13,7 @@ new Suspense({});
|
|
|
13
13
|
const oldCatchError = options.__e;
|
|
14
14
|
options.__e = (err, newVNode, oldVNode, errorInfo) => {
|
|
15
15
|
if (_hydrating && !_hydrated && err && err.then) {
|
|
16
|
-
if (!!(newVNode && newVNode.__u && newVNode.__u & MODE_HYDRATE) || !!(newVNode && newVNode.__h)) {
|
|
16
|
+
if (!!(newVNode && newVNode.__u && newVNode.__u & MODE_HYDRATE$1) || !!(newVNode && newVNode.__h)) {
|
|
17
17
|
_suspensionCount++;
|
|
18
18
|
let settled = false;
|
|
19
19
|
const onSettled = () => {
|
|
@@ -55,21 +55,102 @@ function useIsHydrated() {
|
|
|
55
55
|
//#endregion
|
|
56
56
|
//#region src/hydration-mismatch.ts
|
|
57
57
|
const HYDRATION_BANNER_ID = "__pracht_hydration_mismatch__";
|
|
58
|
+
const MODE_HYDRATE = 32;
|
|
58
59
|
let installed = false;
|
|
60
|
+
let prevMismatch;
|
|
61
|
+
let prevCatchError;
|
|
62
|
+
let prevCommit;
|
|
63
|
+
const pendingSuspenseChecks = /* @__PURE__ */ new Set();
|
|
64
|
+
let flushScheduled = false;
|
|
59
65
|
function installHydrationMismatchWarning() {
|
|
60
66
|
if (installed) return;
|
|
61
67
|
installed = true;
|
|
62
|
-
const
|
|
63
|
-
|
|
68
|
+
const opts = options;
|
|
69
|
+
prevMismatch = opts.__m;
|
|
70
|
+
prevCatchError = opts.__e;
|
|
71
|
+
prevCommit = opts.__c;
|
|
72
|
+
opts.__m = function(vnode) {
|
|
64
73
|
appendHydrationWarning(vnode);
|
|
65
|
-
if (
|
|
74
|
+
if (prevMismatch) prevMismatch(vnode);
|
|
75
|
+
};
|
|
76
|
+
opts.__e = function(err, newVNode, oldVNode, errorInfo) {
|
|
77
|
+
trackSuspendingVNode(err, newVNode);
|
|
78
|
+
if (prevCatchError) prevCatchError(err, newVNode, oldVNode, errorInfo);
|
|
79
|
+
};
|
|
80
|
+
opts.__c = function(vnode, commitQueue) {
|
|
81
|
+
if (prevCommit) prevCommit(vnode, commitQueue);
|
|
82
|
+
scheduleSuspenseCheckFlush();
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function trackSuspendingVNode(err, vnode) {
|
|
86
|
+
if (!vnode) return;
|
|
87
|
+
if (!err || typeof err.then !== "function") return;
|
|
88
|
+
if (!!!(vnode.__u && vnode.__u & MODE_HYDRATE || vnode.__h)) return;
|
|
89
|
+
const promise = err;
|
|
90
|
+
const onSettle = () => {
|
|
91
|
+
pendingSuspenseChecks.add(vnode);
|
|
66
92
|
};
|
|
93
|
+
promise.then(onSettle, onSettle);
|
|
94
|
+
}
|
|
95
|
+
function scheduleSuspenseCheckFlush() {
|
|
96
|
+
if (flushScheduled) return;
|
|
97
|
+
if (pendingSuspenseChecks.size === 0) return;
|
|
98
|
+
flushScheduled = true;
|
|
99
|
+
queueMicrotask(flushSuspenseChecks);
|
|
100
|
+
}
|
|
101
|
+
function flushSuspenseChecks() {
|
|
102
|
+
flushScheduled = false;
|
|
103
|
+
if (pendingSuspenseChecks.size === 0) return;
|
|
104
|
+
const checks = Array.from(pendingSuspenseChecks);
|
|
105
|
+
pendingSuspenseChecks.clear();
|
|
106
|
+
for (const vnode of checks) {
|
|
107
|
+
const rendered = currentVNode(vnode);
|
|
108
|
+
const count = countTopLevelDomNodes(rendered);
|
|
109
|
+
if (count !== 1) appendSuspenseOffsetWarning(pickReportableVNode(rendered), count);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function currentVNode(vnode) {
|
|
113
|
+
return vnode.__c?.__v ?? vnode;
|
|
114
|
+
}
|
|
115
|
+
function pickReportableVNode(vnode) {
|
|
116
|
+
let current = vnode;
|
|
117
|
+
for (let depth = 0; depth < 4; depth++) {
|
|
118
|
+
if (!isLazyWrapperVNode(current)) break;
|
|
119
|
+
const children = current.__k;
|
|
120
|
+
if (!Array.isArray(children) || children.length !== 1) break;
|
|
121
|
+
const child = children[0];
|
|
122
|
+
if (!child || typeof child.type !== "function") break;
|
|
123
|
+
current = currentVNode(child);
|
|
124
|
+
}
|
|
125
|
+
return current;
|
|
126
|
+
}
|
|
127
|
+
function isLazyWrapperVNode(vnode) {
|
|
128
|
+
const type = vnode.type;
|
|
129
|
+
if (typeof type !== "function") return false;
|
|
130
|
+
const fn = type;
|
|
131
|
+
return fn.displayName === "Lazy" || fn.name === "Lazy";
|
|
132
|
+
}
|
|
133
|
+
function countTopLevelDomNodes(vnode) {
|
|
134
|
+
if (!vnode || typeof vnode !== "object") return 0;
|
|
135
|
+
const type = vnode.type;
|
|
136
|
+
if (type === null) return 1;
|
|
137
|
+
if (typeof type === "string") return 1;
|
|
138
|
+
const children = vnode.__k;
|
|
139
|
+
if (!Array.isArray(children)) return 0;
|
|
140
|
+
let total = 0;
|
|
141
|
+
for (const child of children) total += countTopLevelDomNodes(child);
|
|
142
|
+
return total;
|
|
143
|
+
}
|
|
144
|
+
function appendSuspenseOffsetWarning(vnode, count) {
|
|
145
|
+
if (typeof document === "undefined") return;
|
|
146
|
+
appendBannerMessage(`Suspense boundary resolved during hydration: <${getVNodeName(vnode)}> ${count === 0 ? "rendered 0 DOM nodes" : `rendered ${count} DOM nodes`}. Components that unsuspend during hydration must render exactly one DOM node — otherwise sibling offsets can drift and later updates may bind to the wrong nodes.`);
|
|
67
147
|
}
|
|
68
148
|
function appendHydrationWarning(vnode) {
|
|
149
|
+
appendBannerMessage(`Hydration mismatch detected on <${getVNodeName(vnode)}>. The server-rendered HTML did not match the client.`);
|
|
150
|
+
}
|
|
151
|
+
function appendBannerMessage(message) {
|
|
69
152
|
if (typeof document === "undefined") return;
|
|
70
|
-
const componentName = getVNodeName(vnode);
|
|
71
153
|
let banner = document.getElementById(HYDRATION_BANNER_ID);
|
|
72
|
-
const message = `Hydration mismatch detected on <${componentName}>. The server-rendered HTML did not match the client.`;
|
|
73
154
|
if (banner) {
|
|
74
155
|
const list = banner.querySelector(`[data-pracht-mismatch-list]`);
|
|
75
156
|
if (list) {
|
|
@@ -246,7 +327,9 @@ async function initClientRouter(options) {
|
|
|
246
327
|
const navigationTarget = typeof to === "string" ? to : buildHref(app.routes, to.route, to);
|
|
247
328
|
const target = resolveBrowserRouteTarget(navigationTarget);
|
|
248
329
|
if (!target) {
|
|
249
|
-
window.location.href
|
|
330
|
+
const safeUrl = parseSafeNavigationUrl(navigationTarget, window.location.href);
|
|
331
|
+
if (safeUrl) window.location.href = safeUrl.toString();
|
|
332
|
+
else if (navigationTarget) console.error(`[pracht] refused to navigate to unsafe URL: ${navigationTarget}`);
|
|
250
333
|
return;
|
|
251
334
|
}
|
|
252
335
|
const match = matchAppRoute(app, target.pathname);
|
|
@@ -396,7 +479,7 @@ async function initClientRouter(options) {
|
|
|
396
479
|
startRouteImport(match);
|
|
397
480
|
startShellImport(match);
|
|
398
481
|
};
|
|
399
|
-
import("./prefetch-
|
|
482
|
+
import("./prefetch-D9amIQtw.mjs").then(({ setupPrefetching }) => {
|
|
400
483
|
setupPrefetching(app, warmModules);
|
|
401
484
|
});
|
|
402
485
|
}
|
package/dist/server.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as matchApiRoute, c as resolveApp, i as group, l as route, n as buildPathFromSegments, o as matchAppRoute, r as defineApp, s as resolveApiRoutes, t as buildHref, u as timeRevalidate } from "./app-
|
|
2
|
-
import { S as createHref, _ as applyDefaultSecurityHeaders, t as PrachtHttpError, u as redirect } from "./types-
|
|
1
|
+
import { a as matchApiRoute, c as resolveApp, i as group, l as route, n as buildPathFromSegments, o as matchAppRoute, r as defineApp, s as resolveApiRoutes, t as buildHref, u as timeRevalidate } from "./app-w-P1wf5T.mjs";
|
|
2
|
+
import { S as createHref, _ as applyDefaultSecurityHeaders, t as PrachtHttpError, u as redirect } from "./types-DQv2poC5.mjs";
|
|
3
3
|
import { t as PrachtRuntimeProvider } from "./runtime-context-B5pREhcM.mjs";
|
|
4
|
-
import { n as handlePrachtRequest, t as prerenderApp } from "./prerender-
|
|
4
|
+
import { n as handlePrachtRequest, t as prerenderApp } from "./prerender-CoMyuJKm.mjs";
|
|
5
5
|
export { PrachtHttpError, PrachtRuntimeProvider, applyDefaultSecurityHeaders, buildHref, buildPathFromSegments, createHref, defineApp, group, handlePrachtRequest, matchApiRoute, matchAppRoute, prerenderApp, redirect, resolveApiRoutes, resolveApp, route, timeRevalidate };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as buildHref } from "./app-
|
|
1
|
+
import { t as buildHref } from "./app-w-P1wf5T.mjs";
|
|
2
2
|
import { c as navigateToClientLocation, h as SAFE_METHODS, l as parseSafeNavigationUrl, m as ROUTE_STATE_REQUEST_HEADER, p as ROUTE_STATE_CACHE_CONTROL, r as clearPrefetchCache, s as fetchPrachtRouteState } from "./prefetch-cache-DzP2Bj9H.mjs";
|
|
3
3
|
import { n as RouteDataContext, s as deserializeRouteError } from "./runtime-context-B5pREhcM.mjs";
|
|
4
4
|
import { h } from "preact";
|
|
@@ -323,14 +323,7 @@ function Form(props) {
|
|
|
323
323
|
body: new FormData(form),
|
|
324
324
|
redirect: "manual"
|
|
325
325
|
});
|
|
326
|
-
if (response.type === "opaqueredirect" || response.status >= 300 && response.status < 400)
|
|
327
|
-
const location = response.headers.get("location");
|
|
328
|
-
if (location) {
|
|
329
|
-
await navigateToClientLocation(location);
|
|
330
|
-
return;
|
|
331
|
-
}
|
|
332
|
-
window.location.href = props.action ?? form.action;
|
|
333
|
-
}
|
|
326
|
+
if (response.type === "opaqueredirect" || response.status >= 300 && response.status < 400) await navigateToClientLocation(response.headers.get("location") ?? props.action ?? form.action);
|
|
334
327
|
}
|
|
335
328
|
});
|
|
336
329
|
}
|