@westacks/vortex
Version:
Server-based routing for SPAs
200 lines (199 loc) • 6.49 kB
JavaScript
import { g as getPage, s as setPage } from "../page-ILOxo6kg.js";
import { a as axios } from "../router-CgFdQeyO.js";
const inertia = (initialPage) => {
const afterInstall = (e) => {
if (e.detail === "inertia") {
loadDeferredProps(initialPage);
window.removeEventListener("vortex:extension-installed", afterInstall);
}
};
if (typeof window !== "undefined") {
window.addEventListener("vortex:extension-installed", afterInstall);
}
return ({ request, response }) => ({
name: "inertia",
request: request.use(function(request2) {
if (!request2.vortex) {
return request2;
}
const page = getPage();
const config = typeof request2.vortex === "object" ? request2.vortex : {};
request2.headers["accept"] = "text/html, application/xhtml+xml, application/json";
request2.headers["x-inertia"] = true;
request2.headers["x-inertia-version"] = page == null ? void 0 : page.version;
request2.headers["x-inertia-partial-component"] = page == null ? void 0 : page.component;
if (Array.isArray(config.only) && config.only.length > 0) {
request2.headers["x-inertia-partial-data"] = config.only.join(",");
}
if (Array.isArray(config.except) && config.except.length > 0) {
request2.headers["x-inertia-partial-except"] = config.except.join(",");
}
if (Array.isArray(config.reset) && config.reset.length > 0) {
request2.headers["x-inertia-reset"] = config.reset.join(",");
}
return request2;
}),
response: response.use(resolveResponse, function(error) {
var _a, _b;
if ((_a = error.response) == null ? void 0 : _a.headers["x-inertia-location"]) {
window.location.href = error.response.headers["x-inertia-location"];
return Promise.resolve(error.response);
}
if (!((_b = error.response) == null ? void 0 : _b.headers["x-inertia"])) {
renderError(error.response);
} else {
resolveResponse(error.response);
}
return Promise.reject(error);
})
});
};
function pageMutations(newPage, oldPage) {
if (newPage.deepMergeProps) {
for (const prop of newPage.deepMergeProps) {
newPage.props[prop] = deepMerge(oldPage.props[prop], newPage.props[prop]);
}
}
if (newPage.mergeProps) {
for (const prop of newPage.mergeProps) {
const incomingProp = newPage.props[prop];
if (Array.isArray(incomingProp)) {
newPage.props[prop] = [...oldPage.props[prop] || [], ...incomingProp];
} else if (typeof incomingProp === "object" && incomingProp !== null) {
newPage.props[prop] = {
...oldPage.props[prop] || [],
...incomingProp
};
}
}
}
return newPage;
}
function loadDeferredProps(page) {
if (!page.deferredProps) {
return;
}
for (const props of Object.values(page.deferredProps)) {
axios.reload({
vortex: {
only: props,
preserveHistory: true,
preserveScroll: true
}
});
}
}
function resolveResponse(response) {
if (!response.config.vortex || !response.headers["x-inertia"]) {
return response;
}
const page = getPage();
const config = typeof response.config.vortex === "object" ? response.config.vortex : {};
if (Array.isArray(config.only) && config.only.length > 0) {
const replace = {};
for (const prop of config.only) {
replace[prop] = response.data.props[prop];
}
response.data.props = { ...page.props, ...replace };
}
if (Array.isArray(config.except) && config.except.length > 0) {
const replace = {};
for (const prop of config.except) {
replace[prop] = page.props[prop];
}
response.data.props = { ...response.data.props, ...replace };
}
response.data = pageMutations(response.data, page);
if (config == null ? void 0 : config.preserveHistory) {
response.data.url = (page == null ? void 0 : page.url) || response.data.url;
} else if ((config == null ? void 0 : config.replaceHistory) || window.history.state.url === response.data.url && (config == null ? void 0 : config.replaceHistory) !== false) {
window.history.replaceState({ page: response.data }, "", response.data.url);
} else {
window.history.pushState({ page: response.data }, "", response.data.url);
}
setPage(response.data);
loadDeferredProps(response.data);
if (!(config == null ? void 0 : config.preserveScroll)) {
window.scrollTo(0, 0);
}
return response;
}
function renderError(response) {
const dialog = document.createElement("dialog");
Object.assign(dialog.style, {
position: "fixed",
inset: "0",
maxWidth: "none",
maxHeight: "none",
width: "100%",
height: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center",
background: "transparent",
backdropFilter: "blur(3px)",
outline: "none"
});
dialog.addEventListener("keydown", (event) => {
if (event.key === "Escape") {
dialog.close();
}
});
const form = document.createElement("form");
form.method = "dialog";
Object.assign(form.style, {
position: "absolute",
inset: "0",
zIndex: "-1",
margin: "0",
padding: "0",
border: "none"
});
const button = document.createElement("button");
button.type = "submit";
button.innerText = "close";
Object.assign(button.style, {
width: "100%",
height: "100%",
opacity: "0",
cursor: "pointer"
});
const iframe = document.createElement("iframe");
iframe.src = URL.createObjectURL(
new Blob([response.data], { type: response.headers["content-type"] })
);
Object.assign(iframe.style, {
width: "90vw",
height: "90vh"
});
form.appendChild(button);
dialog.appendChild(iframe);
dialog.appendChild(form);
dialog.onclose = () => {
URL.revokeObjectURL(iframe.src);
document.body.removeChild(dialog);
document.body.style.overflow = "";
};
document.body.appendChild(dialog);
document.body.style.overflow = "hidden";
dialog.showModal();
dialog.focus();
}
const deepMerge = (target, source) => {
if (Array.isArray(source)) {
return [...Array.isArray(target) ? target : [], ...source];
}
if (typeof source === "object" && source !== null) {
return Object.keys(source).reduce(
(acc, key) => {
acc[key] = deepMerge(target ? target[key] : void 0, source[key]);
return acc;
},
{ ...target }
);
}
return source;
};
export {
inertia as default
};