Files
2026-04-13 09:30:59 +08:00

4130 lines
127 KiB
JavaScript

"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
FormComponentResetSymbol: () => FormComponentResetSymbol,
UseFormUtils: () => UseFormUtils,
config: () => config,
createHeadManager: () => createHeadManager,
formDataToObject: () => formDataToObject,
getInitialPageFromDOM: () => getInitialPageFromDOM,
getScrollableParent: () => getScrollableParent,
hideProgress: () => hide2,
hrefToUrl: () => hrefToUrl,
isUrlMethodPair: () => isUrlMethodPair,
mergeDataIntoQueryString: () => mergeDataIntoQueryString,
objectToFormData: () => objectToFormData,
progress: () => progress,
resetFormFields: () => resetFormFields,
revealProgress: () => reveal,
router: () => router,
setupProgress: () => setupProgress,
shouldIntercept: () => shouldIntercept,
shouldNavigate: () => shouldNavigate,
urlHasProtocol: () => urlHasProtocol,
urlToString: () => urlToString,
urlWithoutHash: () => urlWithoutHash,
useInfiniteScroll: () => useInfiniteScroll
});
module.exports = __toCommonJS(index_exports);
// src/router.ts
var import_lodash_es5 = require("lodash-es");
// src/config.ts
var import_lodash_es = require("lodash-es");
var Config = class {
constructor(defaults) {
this.config = {};
this.defaults = defaults;
}
extend(defaults) {
if (defaults) {
this.defaults = { ...this.defaults, ...defaults };
}
return this;
}
replace(newConfig) {
this.config = newConfig;
}
get(key) {
return (0, import_lodash_es.has)(this.config, key) ? (0, import_lodash_es.get)(this.config, key) : (0, import_lodash_es.get)(this.defaults, key);
}
set(keyOrValues, value) {
if (typeof keyOrValues === "string") {
(0, import_lodash_es.set)(this.config, keyOrValues, value);
} else {
Object.entries(keyOrValues).forEach(([key, val]) => {
(0, import_lodash_es.set)(this.config, key, val);
});
}
}
};
var config = new Config({
form: {
recentlySuccessfulDuration: 2e3,
forceIndicesArrayFormatInFormData: true
},
future: {
preserveEqualProps: false,
useDataInertiaHeadAttribute: false,
useDialogForErrorModal: false,
useScriptElementForInitialPage: false
},
prefetch: {
cacheFor: 3e4,
hoverDelay: 75
}
});
// src/debounce.ts
function debounce(fn, delay) {
let timeoutID;
return function(...args) {
clearTimeout(timeoutID);
timeoutID = setTimeout(() => fn.apply(this, args), delay);
};
}
// src/events.ts
function fireEvent(name, options) {
return document.dispatchEvent(new CustomEvent(`inertia:${name}`, options));
}
var fireBeforeEvent = (visit) => {
return fireEvent("before", { cancelable: true, detail: { visit } });
};
var fireErrorEvent = (errors) => {
return fireEvent("error", { detail: { errors } });
};
var fireExceptionEvent = (exception) => {
return fireEvent("exception", { cancelable: true, detail: { exception } });
};
var fireFinishEvent = (visit) => {
return fireEvent("finish", { detail: { visit } });
};
var fireInvalidEvent = (response) => {
return fireEvent("invalid", { cancelable: true, detail: { response } });
};
var fireBeforeUpdateEvent = (page2) => {
return fireEvent("beforeUpdate", { detail: { page: page2 } });
};
var fireNavigateEvent = (page2) => {
return fireEvent("navigate", { detail: { page: page2 } });
};
var fireProgressEvent = (progress3) => {
return fireEvent("progress", { detail: { progress: progress3 } });
};
var fireStartEvent = (visit) => {
return fireEvent("start", { detail: { visit } });
};
var fireSuccessEvent = (page2) => {
return fireEvent("success", { detail: { page: page2 } });
};
var firePrefetchedEvent = (response, visit) => {
return fireEvent("prefetched", { detail: { fetchedAt: Date.now(), response: response.data, visit } });
};
var firePrefetchingEvent = (visit) => {
return fireEvent("prefetching", { detail: { visit } });
};
var fireFlashEvent = (flash) => {
return fireEvent("flash", { detail: { flash } });
};
// src/history.ts
var import_lodash_es3 = require("lodash-es");
// src/sessionStorage.ts
var SessionStorage = class {
static set(key, value) {
if (typeof window !== "undefined") {
window.sessionStorage.setItem(key, JSON.stringify(value));
}
}
static get(key) {
if (typeof window !== "undefined") {
return JSON.parse(window.sessionStorage.getItem(key) || "null");
}
}
static merge(key, value) {
const existing = this.get(key);
if (existing === null) {
this.set(key, value);
} else {
this.set(key, { ...existing, ...value });
}
}
static remove(key) {
if (typeof window !== "undefined") {
window.sessionStorage.removeItem(key);
}
}
static removeNested(key, nestedKey) {
const existing = this.get(key);
if (existing !== null) {
delete existing[nestedKey];
this.set(key, existing);
}
}
static exists(key) {
try {
return this.get(key) !== null;
} catch (error) {
return false;
}
}
static clear() {
if (typeof window !== "undefined") {
window.sessionStorage.clear();
}
}
};
SessionStorage.locationVisitKey = "inertiaLocationVisit";
// src/encryption.ts
var encryptHistory = async (data) => {
if (typeof window === "undefined") {
throw new Error("Unable to encrypt history");
}
const iv = getIv();
const storedKey = await getKeyFromSessionStorage();
const key = await getOrCreateKey(storedKey);
if (!key) {
throw new Error("Unable to encrypt history");
}
const encrypted = await encryptData(iv, key, data);
return encrypted;
};
var historySessionStorageKeys = {
key: "historyKey",
iv: "historyIv"
};
var decryptHistory = async (data) => {
const iv = getIv();
const storedKey = await getKeyFromSessionStorage();
if (!storedKey) {
throw new Error("Unable to decrypt history");
}
return await decryptData(iv, storedKey, data);
};
var encryptData = async (iv, key, data) => {
if (typeof window === "undefined") {
throw new Error("Unable to encrypt history");
}
if (typeof window.crypto.subtle === "undefined") {
console.warn("Encryption is not supported in this environment. SSL is required.");
return Promise.resolve(data);
}
const textEncoder = new TextEncoder();
const str = JSON.stringify(data);
const encoded = new Uint8Array(str.length * 3);
const result = textEncoder.encodeInto(str, encoded);
return window.crypto.subtle.encrypt(
{
name: "AES-GCM",
iv
},
key,
encoded.subarray(0, result.written)
);
};
var decryptData = async (iv, key, data) => {
if (typeof window.crypto.subtle === "undefined") {
console.warn("Decryption is not supported in this environment. SSL is required.");
return Promise.resolve(data);
}
const decrypted = await window.crypto.subtle.decrypt(
{
name: "AES-GCM",
iv
},
key,
data
);
return JSON.parse(new TextDecoder().decode(decrypted));
};
var getIv = () => {
const ivString = SessionStorage.get(historySessionStorageKeys.iv);
if (ivString) {
return new Uint8Array(ivString);
}
const iv = window.crypto.getRandomValues(new Uint8Array(12));
SessionStorage.set(historySessionStorageKeys.iv, Array.from(iv));
return iv;
};
var createKey = async () => {
if (typeof window.crypto.subtle === "undefined") {
console.warn("Encryption is not supported in this environment. SSL is required.");
return Promise.resolve(null);
}
return window.crypto.subtle.generateKey(
{
name: "AES-GCM",
length: 256
},
true,
["encrypt", "decrypt"]
);
};
var saveKey = async (key) => {
if (typeof window.crypto.subtle === "undefined") {
console.warn("Encryption is not supported in this environment. SSL is required.");
return Promise.resolve();
}
const keyData = await window.crypto.subtle.exportKey("raw", key);
SessionStorage.set(historySessionStorageKeys.key, Array.from(new Uint8Array(keyData)));
};
var getOrCreateKey = async (key) => {
if (key) {
return key;
}
const newKey = await createKey();
if (!newKey) {
return null;
}
await saveKey(newKey);
return newKey;
};
var getKeyFromSessionStorage = async () => {
const stringKey = SessionStorage.get(historySessionStorageKeys.key);
if (!stringKey) {
return null;
}
const key = await window.crypto.subtle.importKey(
"raw",
new Uint8Array(stringKey),
{
name: "AES-GCM",
length: 256
},
true,
["encrypt", "decrypt"]
);
return key;
};
// src/prefetched.ts
var import_lodash_es2 = require("lodash-es");
// src/objectUtils.ts
var objectsAreEqual = (obj1, obj2, excludeKeys) => {
if (obj1 === obj2) {
return true;
}
for (const key in obj1) {
if (excludeKeys.includes(key)) {
continue;
}
if (obj1[key] === obj2[key]) {
continue;
}
if (!compareValues(obj1[key], obj2[key])) {
return false;
}
}
for (const key in obj2) {
if (excludeKeys.includes(key)) {
continue;
}
if (!(key in obj1)) {
return false;
}
}
return true;
};
var compareValues = (value1, value2) => {
switch (typeof value1) {
case "object":
return objectsAreEqual(value1, value2, []);
case "function":
return value1.toString() === value2.toString();
default:
return value1 === value2;
}
};
// src/time.ts
var conversionMap = {
ms: 1,
s: 1e3,
m: 1e3 * 60,
h: 1e3 * 60 * 60,
d: 1e3 * 60 * 60 * 24
};
var timeToMs = (time) => {
if (typeof time === "number") {
return time;
}
for (const [unit, conversion] of Object.entries(conversionMap)) {
if (time.endsWith(unit)) {
return parseFloat(time) * conversion;
}
}
return parseInt(time);
};
// src/prefetched.ts
var PrefetchedRequests = class {
constructor() {
this.cached = [];
this.inFlightRequests = [];
this.removalTimers = [];
this.currentUseId = null;
}
add(params, sendFunc, { cacheFor, cacheTags }) {
const inFlight = this.findInFlight(params);
if (inFlight) {
return Promise.resolve();
}
const existing = this.findCached(params);
if (!params.fresh && existing && existing.staleTimestamp > Date.now()) {
return Promise.resolve();
}
const [stale, prefetchExpiresIn] = this.extractStaleValues(cacheFor);
const promise = new Promise((resolve, reject) => {
sendFunc({
...params,
onCancel: () => {
this.remove(params);
params.onCancel();
reject();
},
onError: (error) => {
this.remove(params);
params.onError(error);
reject();
},
onPrefetching(visitParams) {
params.onPrefetching(visitParams);
},
onPrefetched(response, visit) {
params.onPrefetched(response, visit);
},
onPrefetchResponse(response) {
resolve(response);
},
onPrefetchError(error) {
prefetchedRequests.removeFromInFlight(params);
reject(error);
}
});
}).then((response) => {
this.remove(params);
const pageResponse = response.getPageResponse();
page.mergeOncePropsIntoResponse(pageResponse);
this.cached.push({
params: { ...params },
staleTimestamp: Date.now() + stale,
expiresAt: Date.now() + prefetchExpiresIn,
response: promise,
singleUse: prefetchExpiresIn === 0,
timestamp: Date.now(),
inFlight: false,
tags: Array.isArray(cacheTags) ? cacheTags : [cacheTags]
});
const oncePropExpiresIn = this.getShortestOncePropTtl(pageResponse);
this.scheduleForRemoval(
params,
oncePropExpiresIn ? Math.min(prefetchExpiresIn, oncePropExpiresIn) : prefetchExpiresIn
);
this.removeFromInFlight(params);
response.handlePrefetch();
return response;
});
this.inFlightRequests.push({
params: { ...params },
response: promise,
staleTimestamp: null,
inFlight: true
});
return promise;
}
removeAll() {
this.cached = [];
this.removalTimers.forEach((removalTimer) => {
clearTimeout(removalTimer.timer);
});
this.removalTimers = [];
}
removeByTags(tags) {
this.cached = this.cached.filter((prefetched) => {
return !prefetched.tags.some((tag) => tags.includes(tag));
});
}
remove(params) {
this.cached = this.cached.filter((prefetched) => {
return !this.paramsAreEqual(prefetched.params, params);
});
this.clearTimer(params);
}
removeFromInFlight(params) {
this.inFlightRequests = this.inFlightRequests.filter((prefetching) => {
return !this.paramsAreEqual(prefetching.params, params);
});
}
extractStaleValues(cacheFor) {
const [stale, expires] = this.cacheForToStaleAndExpires(cacheFor);
return [timeToMs(stale), timeToMs(expires)];
}
cacheForToStaleAndExpires(cacheFor) {
if (!Array.isArray(cacheFor)) {
return [cacheFor, cacheFor];
}
switch (cacheFor.length) {
case 0:
return [0, 0];
case 1:
return [cacheFor[0], cacheFor[0]];
default:
return [cacheFor[0], cacheFor[1]];
}
}
clearTimer(params) {
const timer = this.removalTimers.find((removalTimer) => {
return this.paramsAreEqual(removalTimer.params, params);
});
if (timer) {
clearTimeout(timer.timer);
this.removalTimers = this.removalTimers.filter((removalTimer) => removalTimer !== timer);
}
}
scheduleForRemoval(params, expiresIn) {
if (typeof window === "undefined") {
return;
}
this.clearTimer(params);
if (expiresIn > 0) {
const timer = window.setTimeout(() => this.remove(params), expiresIn);
this.removalTimers.push({
params,
timer
});
}
}
get(params) {
return this.findCached(params) || this.findInFlight(params);
}
use(prefetched, params) {
const id = `${params.url.pathname}-${Date.now()}-${Math.random().toString(36).substring(7)}`;
this.currentUseId = id;
return prefetched.response.then((response) => {
if (this.currentUseId !== id) {
return;
}
response.mergeParams({ ...params, onPrefetched: () => {
} });
this.removeSingleUseItems(params);
return response.handle();
});
}
removeSingleUseItems(params) {
this.cached = this.cached.filter((prefetched) => {
if (!this.paramsAreEqual(prefetched.params, params)) {
return true;
}
return !prefetched.singleUse;
});
}
findCached(params) {
return this.cached.find((prefetched) => {
return this.paramsAreEqual(prefetched.params, params);
}) || null;
}
findInFlight(params) {
return this.inFlightRequests.find((prefetched) => {
return this.paramsAreEqual(prefetched.params, params);
}) || null;
}
withoutPurposePrefetchHeader(params) {
const newParams = (0, import_lodash_es2.cloneDeep)(params);
if (newParams.headers["Purpose"] === "prefetch") {
delete newParams.headers["Purpose"];
}
return newParams;
}
paramsAreEqual(params1, params2) {
return objectsAreEqual(
this.withoutPurposePrefetchHeader(params1),
this.withoutPurposePrefetchHeader(params2),
[
"showProgress",
"replace",
"prefetch",
"preserveScroll",
"preserveState",
"onBefore",
"onBeforeUpdate",
"onStart",
"onProgress",
"onFinish",
"onCancel",
"onSuccess",
"onError",
"onFlash",
"onPrefetched",
"onCancelToken",
"onPrefetching",
"async",
"viewTransition"
]
);
}
updateCachedOncePropsFromCurrentPage() {
this.cached.forEach((prefetched) => {
prefetched.response.then((response) => {
const pageResponse = response.getPageResponse();
page.mergeOncePropsIntoResponse(pageResponse, { force: true });
for (const [group, deferredProps] of Object.entries(pageResponse.deferredProps ?? {})) {
const remaining = deferredProps.filter((prop) => pageResponse.props[prop] === void 0);
if (remaining.length > 0) {
pageResponse.deferredProps[group] = remaining;
} else {
delete pageResponse.deferredProps[group];
}
}
const oncePropExpiresIn = this.getShortestOncePropTtl(pageResponse);
if (oncePropExpiresIn === null) {
return;
}
const prefetchExpiresIn = prefetched.expiresAt - Date.now();
const expiresIn = Math.min(prefetchExpiresIn, oncePropExpiresIn);
if (expiresIn > 0) {
this.scheduleForRemoval(prefetched.params, expiresIn);
} else {
this.remove(prefetched.params);
}
});
});
}
getShortestOncePropTtl(page2) {
const expiryTimestamps = Object.values(page2.onceProps ?? {}).map((onceProp) => onceProp.expiresAt).filter((expiresAt) => !!expiresAt);
if (expiryTimestamps.length === 0) {
return null;
}
return Math.min(...expiryTimestamps) - Date.now();
}
};
var prefetchedRequests = new PrefetchedRequests();
// src/domUtils.ts
var elementInViewport = (el) => {
if (el.offsetParent === null) {
return false;
}
const rect = el.getBoundingClientRect();
const verticallyVisible = rect.top < window.innerHeight && rect.bottom >= 0;
const horizontallyVisible = rect.left < window.innerWidth && rect.right >= 0;
return verticallyVisible && horizontallyVisible;
};
var getScrollableParent = (element) => {
const allowsVerticalScroll = (el) => {
const computedStyle = window.getComputedStyle(el);
if (["scroll", "overlay"].includes(computedStyle.overflowY)) {
return true;
}
if (computedStyle.overflowY !== "auto") {
return false;
}
if (["visible", "clip"].includes(computedStyle.overflowX)) {
return true;
}
return hasDimensionConstraint(computedStyle.maxHeight, el.style.height);
};
const allowsHorizontalScroll = (el) => {
const computedStyle = window.getComputedStyle(el);
if (["scroll", "overlay"].includes(computedStyle.overflowX)) {
return true;
}
if (computedStyle.overflowX !== "auto") {
return false;
}
if (["visible", "clip"].includes(computedStyle.overflowY)) {
return true;
}
return hasDimensionConstraint(computedStyle.maxWidth, el.style.width);
};
const hasDimensionConstraint = (computedMaxDimension, inlineStyleDimension) => {
if (computedMaxDimension && computedMaxDimension !== "none" && computedMaxDimension !== "0px") {
return true;
}
if (inlineStyleDimension && inlineStyleDimension !== "auto" && inlineStyleDimension !== "0") {
return true;
}
return false;
};
let parent = element?.parentElement;
while (parent) {
const allowsScroll = allowsVerticalScroll(parent) || allowsHorizontalScroll(parent);
if (window.getComputedStyle(parent).display !== "contents" && allowsScroll) {
return parent;
}
parent = parent.parentElement;
}
return null;
};
var getElementsInViewportFromCollection = (elements, referenceElement) => {
if (!referenceElement) {
return elements.filter((element) => elementInViewport(element));
}
const referenceIndex = elements.indexOf(referenceElement);
const upwardElements = [];
const downwardElements = [];
for (let i = referenceIndex; i >= 0; i--) {
const element = elements[i];
if (elementInViewport(element)) {
upwardElements.push(element);
} else {
break;
}
}
for (let i = referenceIndex + 1; i < elements.length; i++) {
const element = elements[i];
if (elementInViewport(element)) {
downwardElements.push(element);
} else {
break;
}
}
return [...upwardElements.reverse(), ...downwardElements];
};
var requestAnimationFrame = (cb, times = 1) => {
window.requestAnimationFrame(() => {
if (times > 1) {
requestAnimationFrame(cb, times - 1);
} else {
cb();
}
});
};
var getInitialPageFromDOM = (id, useScriptElement = false) => {
if (typeof window === "undefined") {
return null;
}
if (!useScriptElement) {
const el = document.getElementById(id);
if (el?.dataset.page) {
return JSON.parse(el.dataset.page);
}
}
const scriptEl = document.querySelector(`script[data-page="${id}"][type="application/json"]`);
if (scriptEl?.textContent) {
return JSON.parse(scriptEl.textContent);
}
return null;
};
// src/scroll.ts
var isServer = typeof window === "undefined";
var isFirefox = !isServer && /Firefox/i.test(window.navigator.userAgent);
var Scroll = class {
static save() {
history.saveScrollPositions(this.getScrollRegions());
}
static getScrollRegions() {
return Array.from(this.regions()).map((region) => ({
top: region.scrollTop,
left: region.scrollLeft
}));
}
static regions() {
return document.querySelectorAll("[scroll-region]");
}
static scrollToTop() {
if (isFirefox && getComputedStyle(document.documentElement).scrollBehavior === "smooth") {
return requestAnimationFrame(() => window.scrollTo(0, 0), 2);
}
window.scrollTo(0, 0);
}
static reset() {
const anchorHash = isServer ? null : window.location.hash;
if (!anchorHash) {
this.scrollToTop();
}
this.regions().forEach((region) => {
if (typeof region.scrollTo === "function") {
region.scrollTo(0, 0);
} else {
region.scrollTop = 0;
region.scrollLeft = 0;
}
});
this.save();
this.scrollToAnchor();
}
static scrollToAnchor() {
const anchorHash = isServer ? null : window.location.hash;
if (anchorHash) {
setTimeout(() => {
const anchorElement = document.getElementById(anchorHash.slice(1));
anchorElement ? anchorElement.scrollIntoView() : this.scrollToTop();
});
}
}
static restore(scrollRegions) {
if (isServer) {
return;
}
window.requestAnimationFrame(() => {
this.restoreDocument();
this.restoreScrollRegions(scrollRegions);
});
}
static restoreScrollRegions(scrollRegions) {
if (isServer) {
return;
}
this.regions().forEach((region, index) => {
const scrollPosition = scrollRegions[index];
if (!scrollPosition) {
return;
}
if (typeof region.scrollTo === "function") {
region.scrollTo(scrollPosition.left, scrollPosition.top);
} else {
region.scrollTop = scrollPosition.top;
region.scrollLeft = scrollPosition.left;
}
});
}
static restoreDocument() {
const scrollPosition = history.getDocumentScrollPosition();
window.scrollTo(scrollPosition.left, scrollPosition.top);
}
static onScroll(event) {
const target = event.target;
if (typeof target.hasAttribute === "function" && target.hasAttribute("scroll-region")) {
this.save();
}
}
static onWindowScroll() {
history.saveDocumentScrollPosition({
top: window.scrollY,
left: window.scrollX
});
}
};
// src/url.ts
var qs = __toESM(require("qs"), 1);
// src/files.ts
var isFile = (value) => typeof File !== "undefined" && value instanceof File || value instanceof Blob || typeof FileList !== "undefined" && value instanceof FileList && value.length > 0;
function hasFiles(data) {
return isFile(data) || data instanceof FormData && Array.from(data.values()).some((value) => hasFiles(value)) || typeof data === "object" && data !== null && Object.values(data).some((value) => hasFiles(value));
}
// src/formData.ts
var isFormData = (value) => value instanceof FormData;
function objectToFormData(source, form = new FormData(), parentKey = null, queryStringArrayFormat = "brackets") {
source = source || {};
for (const key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
append(form, composeKey(parentKey, key, "indices"), source[key], queryStringArrayFormat);
}
}
return form;
}
function composeKey(parent, key, format) {
if (!parent) {
return key;
}
return format === "brackets" ? `${parent}[]` : `${parent}[${key}]`;
}
function append(form, key, value, format) {
if (Array.isArray(value)) {
return Array.from(value.keys()).forEach(
(index) => append(form, composeKey(key, index.toString(), format), value[index], format)
);
} else if (value instanceof Date) {
return form.append(key, value.toISOString());
} else if (value instanceof File) {
return form.append(key, value, value.name);
} else if (value instanceof Blob) {
return form.append(key, value);
} else if (typeof value === "boolean") {
return form.append(key, value ? "1" : "0");
} else if (typeof value === "string") {
return form.append(key, value);
} else if (typeof value === "number") {
return form.append(key, `${value}`);
} else if (value === null || value === void 0) {
return form.append(key, "");
}
objectToFormData(value, form, key, format);
}
// src/url.ts
function hrefToUrl(href) {
return new URL(href.toString(), typeof window === "undefined" ? void 0 : window.location.toString());
}
var transformUrlAndData = (href, data, method, forceFormData, queryStringArrayFormat) => {
let url = typeof href === "string" ? hrefToUrl(href) : href;
if ((hasFiles(data) || forceFormData) && !isFormData(data)) {
if (config.get("form.forceIndicesArrayFormatInFormData")) {
queryStringArrayFormat = "indices";
}
data = objectToFormData(data, new FormData(), null, queryStringArrayFormat);
}
if (isFormData(data)) {
return [url, data];
}
const [_href, _data] = mergeDataIntoQueryString(method, url, data, queryStringArrayFormat);
return [hrefToUrl(_href), _data];
};
function mergeDataIntoQueryString(method, href, data, qsArrayFormat = "brackets") {
const hasDataForQueryString = method === "get" && !isFormData(data) && Object.keys(data).length > 0;
const hasHost = urlHasProtocol(href.toString());
const hasAbsolutePath = hasHost || href.toString().startsWith("/") || href.toString() === "";
const hasRelativePath = !hasAbsolutePath && !href.toString().startsWith("#") && !href.toString().startsWith("?");
const hasRelativePathWithDotPrefix = /^[.]{1,2}([/]|$)/.test(href.toString());
const hasSearch = href.toString().includes("?") || hasDataForQueryString;
const hasHash = href.toString().includes("#");
const url = new URL(href.toString(), typeof window === "undefined" ? "http://localhost" : window.location.toString());
if (hasDataForQueryString) {
const hasIndices = /\[\d+\]/.test(decodeURIComponent(url.search));
const parseOptions = { ignoreQueryPrefix: true, allowSparse: true };
url.search = qs.stringify(
{ ...qs.parse(url.search, parseOptions), ...data },
{
encodeValuesOnly: true,
arrayFormat: hasIndices ? "indices" : qsArrayFormat
}
);
}
return [
[
hasHost ? `${url.protocol}//${url.host}` : "",
hasAbsolutePath ? url.pathname : "",
hasRelativePath ? url.pathname.substring(hasRelativePathWithDotPrefix ? 0 : 1) : "",
hasSearch ? url.search : "",
hasHash ? url.hash : ""
].join(""),
hasDataForQueryString ? {} : data
];
}
function urlWithoutHash(url) {
url = new URL(url.href);
url.hash = "";
return url;
}
var setHashIfSameUrl = (originUrl, destinationUrl) => {
if (originUrl.hash && !destinationUrl.hash && urlWithoutHash(originUrl).href === destinationUrl.href) {
destinationUrl.hash = originUrl.hash;
}
};
var isSameUrlWithoutHash = (url1, url2) => {
return urlWithoutHash(url1).href === urlWithoutHash(url2).href;
};
var isSameUrlWithoutQueryOrHash = (url1, url2) => {
return url1.origin === url2.origin && url1.pathname === url2.pathname;
};
function isUrlMethodPair(href) {
return href !== null && typeof href === "object" && href !== void 0 && "url" in href && "method" in href;
}
function urlHasProtocol(url) {
return /^([a-z][a-z0-9+.-]*:)?\/\/[^/]/i.test(url);
}
function urlToString(url, absolute) {
const urlObj = typeof url === "string" ? hrefToUrl(url) : url;
return absolute ? `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}${urlObj.search}${urlObj.hash}` : `${urlObj.pathname}${urlObj.search}${urlObj.hash}`;
}
// src/page.ts
var CurrentPage = class {
constructor() {
this.componentId = {};
this.listeners = [];
this.isFirstPageLoad = true;
this.cleared = false;
this.pendingDeferredProps = null;
this.historyQuotaExceeded = false;
}
init({
initialPage,
swapComponent,
resolveComponent,
onFlash
}) {
this.page = { ...initialPage, flash: initialPage.flash ?? {} };
this.swapComponent = swapComponent;
this.resolveComponent = resolveComponent;
this.onFlashCallback = onFlash;
eventHandler.on("historyQuotaExceeded", () => {
this.historyQuotaExceeded = true;
});
return this;
}
set(page2, {
replace = false,
preserveScroll = false,
preserveState = false,
viewTransition = false
} = {}) {
if (Object.keys(page2.deferredProps || {}).length) {
this.pendingDeferredProps = {
deferredProps: page2.deferredProps,
component: page2.component,
url: page2.url
};
if (page2.initialDeferredProps === void 0) {
page2.initialDeferredProps = page2.deferredProps;
}
}
this.componentId = {};
const componentId = this.componentId;
if (page2.clearHistory) {
history.clear();
}
return this.resolve(page2.component).then((component) => {
if (componentId !== this.componentId) {
return;
}
page2.rememberedState ?? (page2.rememberedState = {});
const isServer3 = typeof window === "undefined";
const location = !isServer3 ? window.location : new URL(page2.url);
const scrollRegions = !isServer3 && preserveScroll ? Scroll.getScrollRegions() : [];
replace = replace || isSameUrlWithoutHash(hrefToUrl(page2.url), location);
const pageForHistory = { ...page2, flash: {} };
return new Promise(
(resolve) => replace ? history.replaceState(pageForHistory, resolve) : history.pushState(pageForHistory, resolve)
).then(() => {
const isNewComponent = !this.isTheSame(page2);
if (!isNewComponent && Object.keys(page2.props.errors || {}).length > 0) {
viewTransition = false;
}
this.page = page2;
this.cleared = false;
if (this.hasOnceProps()) {
prefetchedRequests.updateCachedOncePropsFromCurrentPage();
}
if (isNewComponent) {
this.fireEventsFor("newComponent");
}
if (this.isFirstPageLoad) {
this.fireEventsFor("firstLoad");
}
this.isFirstPageLoad = false;
if (this.historyQuotaExceeded) {
this.historyQuotaExceeded = false;
return;
}
return this.swap({
component,
page: page2,
preserveState,
viewTransition
}).then(() => {
if (preserveScroll) {
window.requestAnimationFrame(() => Scroll.restoreScrollRegions(scrollRegions));
} else {
Scroll.reset();
}
if (this.pendingDeferredProps && this.pendingDeferredProps.component === page2.component && this.pendingDeferredProps.url === page2.url) {
eventHandler.fireInternalEvent("loadDeferredProps", this.pendingDeferredProps.deferredProps);
}
this.pendingDeferredProps = null;
if (!replace) {
fireNavigateEvent(page2);
}
});
});
});
}
setQuietly(page2, {
preserveState = false
} = {}) {
return this.resolve(page2.component).then((component) => {
this.page = page2;
this.cleared = false;
history.setCurrent(page2);
return this.swap({ component, page: page2, preserveState, viewTransition: false });
});
}
clear() {
this.cleared = true;
}
isCleared() {
return this.cleared;
}
get() {
return this.page;
}
getWithoutFlashData() {
return { ...this.page, flash: {} };
}
hasOnceProps() {
return Object.keys(this.page.onceProps ?? {}).length > 0;
}
merge(data) {
this.page = { ...this.page, ...data };
}
setFlash(flash) {
this.page = { ...this.page, flash };
this.onFlashCallback?.(flash);
}
setUrlHash(hash) {
if (!this.page.url.includes(hash)) {
this.page.url += hash;
}
}
remember(data) {
this.page.rememberedState = data;
}
swap({
component,
page: page2,
preserveState,
viewTransition
}) {
const doSwap = () => this.swapComponent({ component, page: page2, preserveState });
if (!viewTransition || !document?.startViewTransition) {
return doSwap();
}
const viewTransitionCallback = typeof viewTransition === "boolean" ? () => null : viewTransition;
return new Promise((resolve) => {
const transitionResult = document.startViewTransition(() => doSwap().then(resolve));
viewTransitionCallback(transitionResult);
});
}
resolve(component) {
return Promise.resolve(this.resolveComponent(component));
}
isTheSame(page2) {
return this.page.component === page2.component;
}
on(event, callback) {
this.listeners.push({ event, callback });
return () => {
this.listeners = this.listeners.filter((listener) => listener.event !== event && listener.callback !== callback);
};
}
fireEventsFor(event) {
this.listeners.filter((listener) => listener.event === event).forEach((listener) => listener.callback());
}
mergeOncePropsIntoResponse(response, { force = false } = {}) {
Object.entries(response.onceProps ?? {}).forEach(([key, onceProp]) => {
const existingOnceProp = this.page.onceProps?.[key];
if (existingOnceProp === void 0) {
return;
}
if (force || response.props[onceProp.prop] === void 0) {
response.props[onceProp.prop] = this.page.props[existingOnceProp.prop];
response.onceProps[key].expiresAt = existingOnceProp.expiresAt;
}
});
}
};
var page = new CurrentPage();
// src/queue.ts
var Queue = class {
constructor() {
this.items = [];
this.processingPromise = null;
}
add(item) {
this.items.push(item);
return this.process();
}
process() {
this.processingPromise ?? (this.processingPromise = this.processNext().finally(() => {
this.processingPromise = null;
}));
return this.processingPromise;
}
processNext() {
const next = this.items.shift();
if (next) {
return Promise.resolve(next()).then(() => this.processNext());
}
return Promise.resolve();
}
};
// src/history.ts
var isServer2 = typeof window === "undefined";
var queue = new Queue();
var isChromeIOS = !isServer2 && /CriOS/.test(window.navigator.userAgent);
var History = class {
constructor() {
this.rememberedState = "rememberedState";
this.scrollRegions = "scrollRegions";
this.preserveUrl = false;
this.current = {};
// We need initialState for `restore`
this.initialState = null;
}
remember(data, key) {
this.replaceState({
...page.getWithoutFlashData(),
rememberedState: {
...page.get()?.rememberedState ?? {},
[key]: data
}
});
}
restore(key) {
if (!isServer2) {
return this.current[this.rememberedState]?.[key] !== void 0 ? this.current[this.rememberedState]?.[key] : this.initialState?.[this.rememberedState]?.[key];
}
}
pushState(page2, cb = null) {
if (isServer2) {
return;
}
if (this.preserveUrl) {
cb && cb();
return;
}
this.current = page2;
queue.add(() => {
return this.getPageData(page2).then((data) => {
const doPush = () => this.doPushState({ page: data }, page2.url).then(() => cb?.());
if (isChromeIOS) {
return new Promise((resolve) => {
setTimeout(() => doPush().then(resolve));
});
}
return doPush();
});
});
}
clonePageProps(page2) {
try {
structuredClone(page2.props);
return page2;
} catch {
return {
...page2,
props: (0, import_lodash_es3.cloneDeep)(page2.props)
};
}
}
getPageData(page2) {
const pageWithClonedProps = this.clonePageProps(page2);
return new Promise((resolve) => {
return page2.encryptHistory ? encryptHistory(pageWithClonedProps).then(resolve) : resolve(pageWithClonedProps);
});
}
processQueue() {
return queue.process();
}
decrypt(page2 = null) {
if (isServer2) {
return Promise.resolve(page2 ?? page.get());
}
const pageData = page2 ?? window.history.state?.page;
return this.decryptPageData(pageData).then((data) => {
if (!data) {
throw new Error("Unable to decrypt history");
}
if (this.initialState === null) {
this.initialState = data ?? void 0;
} else {
this.current = data ?? {};
}
return data;
});
}
decryptPageData(pageData) {
return pageData instanceof ArrayBuffer ? decryptHistory(pageData) : Promise.resolve(pageData);
}
saveScrollPositions(scrollRegions) {
queue.add(() => {
return Promise.resolve().then(() => {
if (!window.history.state?.page) {
return;
}
if ((0, import_lodash_es3.isEqual)(this.getScrollRegions(), scrollRegions)) {
return;
}
return this.doReplaceState({
page: window.history.state.page,
scrollRegions
});
});
});
}
saveDocumentScrollPosition(scrollRegion) {
queue.add(() => {
return Promise.resolve().then(() => {
if (!window.history.state?.page) {
return;
}
if ((0, import_lodash_es3.isEqual)(this.getDocumentScrollPosition(), scrollRegion)) {
return;
}
return this.doReplaceState({
page: window.history.state.page,
documentScrollPosition: scrollRegion
});
});
});
}
getScrollRegions() {
return window.history.state?.scrollRegions || [];
}
getDocumentScrollPosition() {
return window.history.state?.documentScrollPosition || { top: 0, left: 0 };
}
replaceState(page2, cb = null) {
if ((0, import_lodash_es3.isEqual)(this.current, page2)) {
cb && cb();
return;
}
page.merge(page2);
if (isServer2) {
return;
}
if (this.preserveUrl) {
cb && cb();
return;
}
this.current = page2;
queue.add(() => {
return this.getPageData(page2).then((data) => {
const doReplace = () => this.doReplaceState({ page: data }, page2.url).then(() => cb?.());
if (isChromeIOS) {
return new Promise((resolve) => {
setTimeout(() => doReplace().then(resolve));
});
}
return doReplace();
});
});
}
isHistoryThrottleError(error) {
return error instanceof Error && error.name === "SecurityError" && (error.message.includes("history.pushState") || error.message.includes("history.replaceState"));
}
isQuotaExceededError(error) {
return error instanceof Error && error.name === "QuotaExceededError";
}
withThrottleProtection(cb) {
return Promise.resolve().then(() => {
try {
return cb();
} catch (error) {
if (!this.isHistoryThrottleError(error)) {
throw error;
}
console.error(error.message);
}
});
}
doReplaceState(data, url) {
return this.withThrottleProtection(() => {
window.history.replaceState(
{
...data,
scrollRegions: data.scrollRegions ?? window.history.state?.scrollRegions,
documentScrollPosition: data.documentScrollPosition ?? window.history.state?.documentScrollPosition
},
"",
url
);
});
}
doPushState(data, url) {
return this.withThrottleProtection(() => {
try {
window.history.pushState(data, "", url);
} catch (error) {
if (!this.isQuotaExceededError(error)) {
throw error;
}
eventHandler.fireInternalEvent("historyQuotaExceeded", url);
}
});
}
getState(key, defaultValue) {
return this.current?.[key] ?? defaultValue;
}
deleteState(key) {
if (this.current[key] !== void 0) {
delete this.current[key];
this.replaceState(this.current);
}
}
clearInitialState(key) {
if (this.initialState && this.initialState[key] !== void 0) {
delete this.initialState[key];
}
}
browserHasHistoryEntry() {
return !isServer2 && !!window.history.state?.page;
}
clear() {
SessionStorage.remove(historySessionStorageKeys.key);
SessionStorage.remove(historySessionStorageKeys.iv);
}
setCurrent(page2) {
this.current = page2;
}
isValidState(state) {
return !!state.page;
}
getAllState() {
return this.current;
}
};
if (typeof window !== "undefined" && window.history.scrollRestoration) {
window.history.scrollRestoration = "manual";
}
var history = new History();
// src/eventHandler.ts
var EventHandler = class {
constructor() {
this.internalListeners = [];
}
init() {
if (typeof window !== "undefined") {
window.addEventListener("popstate", this.handlePopstateEvent.bind(this));
window.addEventListener("scroll", debounce(Scroll.onWindowScroll.bind(Scroll), 100), true);
}
if (typeof document !== "undefined") {
document.addEventListener("scroll", debounce(Scroll.onScroll.bind(Scroll), 100), true);
}
}
onGlobalEvent(type, callback) {
const listener = ((event) => {
const response = callback(event);
if (event.cancelable && !event.defaultPrevented && response === false) {
event.preventDefault();
}
});
return this.registerListener(`inertia:${type}`, listener);
}
on(event, callback) {
this.internalListeners.push({ event, listener: callback });
return () => {
this.internalListeners = this.internalListeners.filter((listener) => listener.listener !== callback);
};
}
onMissingHistoryItem() {
page.clear();
this.fireInternalEvent("missingHistoryItem");
}
fireInternalEvent(event, ...args) {
this.internalListeners.filter((listener) => listener.event === event).forEach((listener) => listener.listener(...args));
}
registerListener(type, listener) {
document.addEventListener(type, listener);
return () => document.removeEventListener(type, listener);
}
handlePopstateEvent(event) {
const state = event.state || null;
if (state === null) {
const url = hrefToUrl(page.get().url);
url.hash = window.location.hash;
history.replaceState({ ...page.getWithoutFlashData(), url: url.href });
Scroll.reset();
return;
}
if (!history.isValidState(state)) {
return this.onMissingHistoryItem();
}
history.decrypt(state.page).then((data) => {
if (page.get().version !== data.version) {
this.onMissingHistoryItem();
return;
}
router.cancelAll({ prefetch: false });
page.setQuietly(data, { preserveState: false }).then(() => {
Scroll.restore(history.getScrollRegions());
fireNavigateEvent(page.get());
const pendingDeferred = {};
const pageProps = page.get().props;
for (const [group, props] of Object.entries(data.initialDeferredProps ?? data.deferredProps ?? {})) {
const missing = props.filter((prop) => pageProps[prop] === void 0);
if (missing.length > 0) {
pendingDeferred[group] = missing;
}
}
if (Object.keys(pendingDeferred).length > 0) {
this.fireInternalEvent("loadDeferredProps", pendingDeferred);
}
});
}).catch(() => {
this.onMissingHistoryItem();
});
}
};
var eventHandler = new EventHandler();
// src/navigationType.ts
var NavigationType = class {
constructor() {
this.type = this.resolveType();
}
resolveType() {
if (typeof window === "undefined") {
return "navigate";
}
if (window.performance && window.performance.getEntriesByType && window.performance.getEntriesByType("navigation").length > 0) {
return window.performance.getEntriesByType("navigation")[0].type;
}
return "navigate";
}
get() {
return this.type;
}
isBackForward() {
return this.type === "back_forward";
}
isReload() {
return this.type === "reload";
}
};
var navigationType = new NavigationType();
// src/initialVisit.ts
var InitialVisit = class {
static handle() {
this.clearRememberedStateOnReload();
const scenarios = [this.handleBackForward, this.handleLocation, this.handleDefault];
scenarios.find((handler) => handler.bind(this)());
}
static clearRememberedStateOnReload() {
if (navigationType.isReload()) {
history.deleteState(history.rememberedState);
history.clearInitialState(history.rememberedState);
}
}
static handleBackForward() {
if (!navigationType.isBackForward() || !history.browserHasHistoryEntry()) {
return false;
}
const scrollRegions = history.getScrollRegions();
history.decrypt().then((data) => {
page.set(data, { preserveScroll: true, preserveState: true }).then(() => {
Scroll.restore(scrollRegions);
fireNavigateEvent(page.get());
});
}).catch(() => {
eventHandler.onMissingHistoryItem();
});
return true;
}
/**
* @link https://inertiajs.com/redirects#external-redirects
*/
static handleLocation() {
if (!SessionStorage.exists(SessionStorage.locationVisitKey)) {
return false;
}
const locationVisit = SessionStorage.get(SessionStorage.locationVisitKey) || {};
SessionStorage.remove(SessionStorage.locationVisitKey);
if (typeof window !== "undefined") {
page.setUrlHash(window.location.hash);
}
history.decrypt(page.get()).then(() => {
const rememberedState = history.getState(history.rememberedState, {});
const scrollRegions = history.getScrollRegions();
page.remember(rememberedState);
page.set(page.get(), {
preserveScroll: locationVisit.preserveScroll,
preserveState: true
}).then(() => {
if (locationVisit.preserveScroll) {
Scroll.restore(scrollRegions);
}
fireNavigateEvent(page.get());
});
}).catch(() => {
eventHandler.onMissingHistoryItem();
});
return true;
}
static handleDefault() {
if (typeof window !== "undefined") {
page.setUrlHash(window.location.hash);
}
page.set(page.get(), { preserveScroll: true, preserveState: true }).then(() => {
if (navigationType.isReload()) {
Scroll.restore(history.getScrollRegions());
} else {
Scroll.scrollToAnchor();
}
const page2 = page.get();
fireNavigateEvent(page2);
const flash = page2.flash;
if (Object.keys(flash).length > 0) {
queueMicrotask(() => fireFlashEvent(flash));
}
});
}
};
// src/poll.ts
var Poll = class {
constructor(interval, cb, options) {
this.id = null;
this.throttle = false;
this.keepAlive = false;
this.cbCount = 0;
this.keepAlive = options.keepAlive ?? false;
this.cb = cb;
this.interval = interval;
if (options.autoStart ?? true) {
this.start();
}
}
stop() {
if (this.id) {
clearInterval(this.id);
}
}
start() {
if (typeof window === "undefined") {
return;
}
this.stop();
this.id = window.setInterval(() => {
if (!this.throttle || this.cbCount % 10 === 0) {
this.cb();
}
if (this.throttle) {
this.cbCount++;
}
}, this.interval);
}
isInBackground(hidden) {
this.throttle = this.keepAlive ? false : hidden;
if (this.throttle) {
this.cbCount = 0;
}
}
};
// src/polls.ts
var Polls = class {
constructor() {
this.polls = [];
this.setupVisibilityListener();
}
add(interval, cb, options) {
const poll = new Poll(interval, cb, options);
this.polls.push(poll);
return {
stop: () => poll.stop(),
start: () => poll.start()
};
}
clear() {
this.polls.forEach((poll) => poll.stop());
this.polls = [];
}
setupVisibilityListener() {
if (typeof document === "undefined") {
return;
}
document.addEventListener(
"visibilitychange",
() => {
this.polls.forEach((poll) => poll.isInBackground(document.hidden));
},
false
);
}
};
var polls = new Polls();
// src/request.ts
var import_axios = __toESM(require("axios"), 1);
// src/requestParams.ts
var RequestParams = class _RequestParams {
constructor(params) {
this.callbacks = [];
if (!params.prefetch) {
this.params = params;
} else {
const wrappedCallbacks = {
onBefore: this.wrapCallback(params, "onBefore"),
onBeforeUpdate: this.wrapCallback(params, "onBeforeUpdate"),
onStart: this.wrapCallback(params, "onStart"),
onProgress: this.wrapCallback(params, "onProgress"),
onFinish: this.wrapCallback(params, "onFinish"),
onCancel: this.wrapCallback(params, "onCancel"),
onSuccess: this.wrapCallback(params, "onSuccess"),
onError: this.wrapCallback(params, "onError"),
onFlash: this.wrapCallback(params, "onFlash"),
onCancelToken: this.wrapCallback(params, "onCancelToken"),
onPrefetched: this.wrapCallback(params, "onPrefetched"),
onPrefetching: this.wrapCallback(params, "onPrefetching")
};
this.params = {
...params,
...wrappedCallbacks,
onPrefetchResponse: params.onPrefetchResponse || (() => {
}),
onPrefetchError: params.onPrefetchError || (() => {
})
};
}
}
static create(params) {
return new _RequestParams(params);
}
data() {
return this.params.method === "get" ? null : this.params.data;
}
queryParams() {
return this.params.method === "get" ? this.params.data : {};
}
isPartial() {
return this.params.only.length > 0 || this.params.except.length > 0 || this.params.reset.length > 0;
}
isPrefetch() {
return this.params.prefetch === true;
}
isDeferredPropsRequest() {
return this.params.deferredProps === true;
}
onCancelToken(cb) {
this.params.onCancelToken({
cancel: cb
});
}
markAsFinished() {
this.params.completed = true;
this.params.cancelled = false;
this.params.interrupted = false;
}
markAsCancelled({ cancelled = true, interrupted = false }) {
this.params.onCancel();
this.params.completed = false;
this.params.cancelled = cancelled;
this.params.interrupted = interrupted;
}
wasCancelledAtAll() {
return this.params.cancelled || this.params.interrupted;
}
onFinish() {
this.params.onFinish(this.params);
}
onStart() {
this.params.onStart(this.params);
}
onPrefetching() {
this.params.onPrefetching(this.params);
}
onPrefetchResponse(response) {
if (this.params.onPrefetchResponse) {
this.params.onPrefetchResponse(response);
}
}
onPrefetchError(error) {
if (this.params.onPrefetchError) {
this.params.onPrefetchError(error);
}
}
all() {
return this.params;
}
headers() {
const headers = {
...this.params.headers
};
if (this.isPartial()) {
headers["X-Inertia-Partial-Component"] = page.get().component;
}
const only = this.params.only.concat(this.params.reset);
if (only.length > 0) {
headers["X-Inertia-Partial-Data"] = only.join(",");
}
if (this.params.except.length > 0) {
headers["X-Inertia-Partial-Except"] = this.params.except.join(",");
}
if (this.params.reset.length > 0) {
headers["X-Inertia-Reset"] = this.params.reset.join(",");
}
if (this.params.errorBag && this.params.errorBag.length > 0) {
headers["X-Inertia-Error-Bag"] = this.params.errorBag;
}
return headers;
}
setPreserveOptions(page2) {
this.params.preserveScroll = _RequestParams.resolvePreserveOption(this.params.preserveScroll, page2);
this.params.preserveState = _RequestParams.resolvePreserveOption(this.params.preserveState, page2);
}
runCallbacks() {
this.callbacks.forEach(({ name, args }) => {
this.params[name](...args);
});
}
merge(toMerge) {
this.params = {
...this.params,
...toMerge
};
}
wrapCallback(params, name) {
return (...args) => {
this.recordCallback(name, args);
params[name](...args);
};
}
recordCallback(name, args) {
this.callbacks.push({ name, args });
}
static resolvePreserveOption(value, page2) {
if (typeof value === "function") {
return value(page2);
}
if (value === "errors") {
return Object.keys(page2.props.errors || {}).length > 0;
}
return value;
}
};
// src/response.ts
var import_lodash_es4 = require("lodash-es");
// src/modal.ts
var modal_default = {
modal: null,
listener: null,
createIframeAndPage(html) {
if (typeof html === "object") {
html = `All Inertia requests must receive a valid Inertia response, however a plain JSON response was received.<hr>${JSON.stringify(
html
)}`;
}
const page2 = document.createElement("html");
page2.innerHTML = html;
page2.querySelectorAll("a").forEach((a) => a.setAttribute("target", "_top"));
const iframe = document.createElement("iframe");
iframe.style.backgroundColor = "white";
iframe.style.borderRadius = "5px";
iframe.style.width = "100%";
iframe.style.height = "100%";
return { iframe, page: page2 };
},
show(html) {
const { iframe, page: page2 } = this.createIframeAndPage(html);
this.modal = document.createElement("div");
this.modal.style.position = "fixed";
this.modal.style.width = "100vw";
this.modal.style.height = "100vh";
this.modal.style.padding = "50px";
this.modal.style.boxSizing = "border-box";
this.modal.style.backgroundColor = "rgba(0, 0, 0, .6)";
this.modal.style.zIndex = 2e5;
this.modal.addEventListener("click", () => this.hide());
this.modal.appendChild(iframe);
document.body.prepend(this.modal);
document.body.style.overflow = "hidden";
if (!iframe.contentWindow) {
throw new Error("iframe not yet ready.");
}
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(page2.outerHTML);
iframe.contentWindow.document.close();
this.listener = this.hideOnEscape.bind(this);
document.addEventListener("keydown", this.listener);
},
hide() {
this.modal.outerHTML = "";
this.modal = null;
document.body.style.overflow = "visible";
document.removeEventListener("keydown", this.listener);
},
hideOnEscape(event) {
if (event.keyCode === 27) {
this.hide();
}
}
};
// src/dialog.ts
var dialog_default = {
show(html) {
const { iframe, page: page2 } = modal_default.createIframeAndPage(html);
iframe.style.boxSizing = "border-box";
iframe.style.display = "block";
const dialog = document.createElement("dialog");
dialog.id = "inertia-error-dialog";
Object.assign(dialog.style, {
width: "calc(100vw - 100px)",
height: "calc(100vh - 100px)",
padding: "0",
margin: "auto",
border: "none",
backgroundColor: "transparent"
});
const dialogStyleElement = document.createElement("style");
dialogStyleElement.textContent = `
dialog#inertia-error-dialog::backdrop {
background-color: rgba(0, 0, 0, 0.6);
}
dialog#inertia-error-dialog:focus {
outline: none;
}
`;
document.head.appendChild(dialogStyleElement);
dialog.addEventListener("click", (event) => {
if (event.target === dialog) {
dialog.close();
}
});
dialog.addEventListener("close", () => {
dialogStyleElement.remove();
dialog.remove();
});
dialog.appendChild(iframe);
document.body.prepend(dialog);
dialog.showModal();
dialog.focus();
if (!iframe.contentWindow) {
throw new Error("iframe not yet ready.");
}
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(page2.outerHTML);
iframe.contentWindow.document.close();
}
};
// src/response.ts
var queue2 = new Queue();
var Response = class _Response {
constructor(requestParams, response, originatingPage) {
this.requestParams = requestParams;
this.response = response;
this.originatingPage = originatingPage;
this.wasPrefetched = false;
}
static create(params, response, originatingPage) {
return new _Response(params, response, originatingPage);
}
async handlePrefetch() {
if (isSameUrlWithoutHash(this.requestParams.all().url, window.location)) {
this.handle();
}
}
async handle() {
return queue2.add(() => this.process());
}
async process() {
if (this.requestParams.all().prefetch) {
this.wasPrefetched = true;
this.requestParams.all().prefetch = false;
this.requestParams.all().onPrefetched(this.response, this.requestParams.all());
firePrefetchedEvent(this.response, this.requestParams.all());
return Promise.resolve();
}
this.requestParams.runCallbacks();
if (!this.isInertiaResponse()) {
return this.handleNonInertiaResponse();
}
await history.processQueue();
history.preserveUrl = this.requestParams.all().preserveUrl;
const previousFlash = page.get().flash;
await this.setPage();
const errors = page.get().props.errors || {};
if (Object.keys(errors).length > 0) {
const scopedErrors = this.getScopedErrors(errors);
fireErrorEvent(scopedErrors);
return this.requestParams.all().onError(scopedErrors);
}
router.flushByCacheTags(this.requestParams.all().invalidateCacheTags || []);
if (!this.wasPrefetched) {
router.flush(page.get().url);
}
const { flash } = page.get();
if (Object.keys(flash).length > 0 && (!this.requestParams.isPartial() || !(0, import_lodash_es4.isEqual)(flash, previousFlash))) {
fireFlashEvent(flash);
this.requestParams.all().onFlash(flash);
}
fireSuccessEvent(page.get());
await this.requestParams.all().onSuccess(page.get());
history.preserveUrl = false;
}
mergeParams(params) {
this.requestParams.merge(params);
}
getPageResponse() {
const data = this.getDataFromResponse(this.response.data);
if (typeof data === "object") {
return this.response.data = { ...data, flash: data.flash ?? {} };
}
return this.response.data = data;
}
async handleNonInertiaResponse() {
if (this.isLocationVisit()) {
const locationUrl = hrefToUrl(this.getHeader("x-inertia-location"));
setHashIfSameUrl(this.requestParams.all().url, locationUrl);
return this.locationVisit(locationUrl);
}
const response = {
...this.response,
data: this.getDataFromResponse(this.response.data)
};
if (fireInvalidEvent(response)) {
return config.get("future.useDialogForErrorModal") ? dialog_default.show(response.data) : modal_default.show(response.data);
}
}
isInertiaResponse() {
return this.hasHeader("x-inertia");
}
hasStatus(status2) {
return this.response.status === status2;
}
getHeader(header) {
return this.response.headers[header];
}
hasHeader(header) {
return this.getHeader(header) !== void 0;
}
isLocationVisit() {
return this.hasStatus(409) && this.hasHeader("x-inertia-location");
}
/**
* @link https://inertiajs.com/redirects#external-redirects
*/
locationVisit(url) {
try {
SessionStorage.set(SessionStorage.locationVisitKey, {
preserveScroll: this.requestParams.all().preserveScroll === true
});
if (typeof window === "undefined") {
return;
}
if (isSameUrlWithoutHash(window.location, url)) {
window.location.reload();
} else {
window.location.href = url.href;
}
} catch (error) {
return false;
}
}
async setPage() {
const pageResponse = this.getPageResponse();
if (!this.shouldSetPage(pageResponse)) {
return Promise.resolve();
}
this.mergeProps(pageResponse);
page.mergeOncePropsIntoResponse(pageResponse);
this.preserveEqualProps(pageResponse);
await this.setRememberedState(pageResponse);
this.requestParams.setPreserveOptions(pageResponse);
pageResponse.url = history.preserveUrl ? page.get().url : this.pageUrl(pageResponse);
this.requestParams.all().onBeforeUpdate(pageResponse);
fireBeforeUpdateEvent(pageResponse);
return page.set(pageResponse, {
replace: this.requestParams.all().replace,
preserveScroll: this.requestParams.all().preserveScroll,
preserveState: this.requestParams.all().preserveState,
viewTransition: this.requestParams.all().viewTransition
});
}
getDataFromResponse(response) {
if (typeof response !== "string") {
return response;
}
try {
return JSON.parse(response);
} catch (error) {
return response;
}
}
shouldSetPage(pageResponse) {
if (!this.requestParams.all().async) {
return true;
}
if (this.originatingPage.component !== pageResponse.component) {
return true;
}
if (this.originatingPage.component !== page.get().component) {
return false;
}
const originatingUrl = hrefToUrl(this.originatingPage.url);
const currentPageUrl = hrefToUrl(page.get().url);
return originatingUrl.origin === currentPageUrl.origin && originatingUrl.pathname === currentPageUrl.pathname;
}
pageUrl(pageResponse) {
const responseUrl = hrefToUrl(pageResponse.url);
setHashIfSameUrl(this.requestParams.all().url, responseUrl);
return responseUrl.pathname + responseUrl.search + responseUrl.hash;
}
preserveEqualProps(pageResponse) {
if (pageResponse.component !== page.get().component || config.get("future.preserveEqualProps") !== true) {
return;
}
const currentPageProps = page.get().props;
Object.entries(pageResponse.props).forEach(([key, value]) => {
if ((0, import_lodash_es4.isEqual)(value, currentPageProps[key])) {
pageResponse.props[key] = currentPageProps[key];
}
});
}
mergeProps(pageResponse) {
if (!this.requestParams.isPartial() || pageResponse.component !== page.get().component) {
return;
}
const propsToAppend = pageResponse.mergeProps || [];
const propsToPrepend = pageResponse.prependProps || [];
const propsToDeepMerge = pageResponse.deepMergeProps || [];
const matchPropsOn = pageResponse.matchPropsOn || [];
const mergeProp = (prop, shouldAppend) => {
const currentProp = (0, import_lodash_es4.get)(page.get().props, prop);
const incomingProp = (0, import_lodash_es4.get)(pageResponse.props, prop);
if (Array.isArray(incomingProp)) {
const newArray = this.mergeOrMatchItems(
currentProp || [],
incomingProp,
prop,
matchPropsOn,
shouldAppend
);
(0, import_lodash_es4.set)(pageResponse.props, prop, newArray);
} else if (typeof incomingProp === "object" && incomingProp !== null) {
const newObject = {
...currentProp || {},
...incomingProp
};
(0, import_lodash_es4.set)(pageResponse.props, prop, newObject);
}
};
propsToAppend.forEach((prop) => mergeProp(prop, true));
propsToPrepend.forEach((prop) => mergeProp(prop, false));
propsToDeepMerge.forEach((prop) => {
const currentProp = page.get().props[prop];
const incomingProp = pageResponse.props[prop];
const deepMerge = (target, source, matchProp) => {
if (Array.isArray(source)) {
return this.mergeOrMatchItems(target, source, matchProp, matchPropsOn);
}
if (typeof source === "object" && source !== null) {
return Object.keys(source).reduce(
(acc, key) => {
acc[key] = deepMerge(target ? target[key] : void 0, source[key], `${matchProp}.${key}`);
return acc;
},
{ ...target }
);
}
return source;
};
pageResponse.props[prop] = deepMerge(currentProp, incomingProp, prop);
});
pageResponse.props = { ...page.get().props, ...pageResponse.props };
if (this.requestParams.isDeferredPropsRequest()) {
const currentErrors = page.get().props.errors;
if (currentErrors && Object.keys(currentErrors).length > 0) {
pageResponse.props.errors = currentErrors;
}
}
if (page.get().scrollProps) {
pageResponse.scrollProps = {
...page.get().scrollProps || {},
...pageResponse.scrollProps || {}
};
}
if (page.hasOnceProps()) {
pageResponse.onceProps = {
...page.get().onceProps || {},
...pageResponse.onceProps || {}
};
}
pageResponse.flash = {
...page.get().flash,
...this.requestParams.isDeferredPropsRequest() ? {} : pageResponse.flash
};
const currentOriginalDeferred = page.get().initialDeferredProps;
if (currentOriginalDeferred && Object.keys(currentOriginalDeferred).length > 0) {
pageResponse.initialDeferredProps = currentOriginalDeferred;
}
}
mergeOrMatchItems(existingItems, newItems, matchProp, matchPropsOn, shouldAppend = true) {
const items = Array.isArray(existingItems) ? existingItems : [];
const matchingKey = matchPropsOn.find((key) => {
const keyPath = key.split(".").slice(0, -1).join(".");
return keyPath === matchProp;
});
if (!matchingKey) {
return shouldAppend ? [...items, ...newItems] : [...newItems, ...items];
}
const uniqueProperty = matchingKey.split(".").pop() || "";
const newItemsMap = /* @__PURE__ */ new Map();
newItems.forEach((item) => {
if (this.hasUniqueProperty(item, uniqueProperty)) {
newItemsMap.set(item[uniqueProperty], item);
}
});
return shouldAppend ? this.appendWithMatching(items, newItems, newItemsMap, uniqueProperty) : this.prependWithMatching(items, newItems, newItemsMap, uniqueProperty);
}
appendWithMatching(existingItems, newItems, newItemsMap, uniqueProperty) {
const updatedExisting = existingItems.map((item) => {
if (this.hasUniqueProperty(item, uniqueProperty) && newItemsMap.has(item[uniqueProperty])) {
return newItemsMap.get(item[uniqueProperty]);
}
return item;
});
const newItemsToAdd = newItems.filter((item) => {
if (!this.hasUniqueProperty(item, uniqueProperty)) {
return true;
}
return !existingItems.some(
(existing) => this.hasUniqueProperty(existing, uniqueProperty) && existing[uniqueProperty] === item[uniqueProperty]
);
});
return [...updatedExisting, ...newItemsToAdd];
}
prependWithMatching(existingItems, newItems, newItemsMap, uniqueProperty) {
const untouchedExisting = existingItems.filter((item) => {
if (this.hasUniqueProperty(item, uniqueProperty)) {
return !newItemsMap.has(item[uniqueProperty]);
}
return true;
});
return [...newItems, ...untouchedExisting];
}
hasUniqueProperty(item, property) {
return item && typeof item === "object" && property in item;
}
async setRememberedState(pageResponse) {
const rememberedState = await history.getState(history.rememberedState, {});
if (this.requestParams.all().preserveState && rememberedState && pageResponse.component === page.get().component) {
pageResponse.rememberedState = rememberedState;
}
}
getScopedErrors(errors) {
if (!this.requestParams.all().errorBag) {
return errors;
}
return errors[this.requestParams.all().errorBag || ""] || {};
}
};
// src/request.ts
var Request = class _Request {
constructor(params, page2) {
this.page = page2;
this.requestHasFinished = false;
this.requestParams = RequestParams.create(params);
this.cancelToken = new AbortController();
}
static create(params, page2) {
return new _Request(params, page2);
}
isPrefetch() {
return this.requestParams.isPrefetch();
}
async send() {
this.requestParams.onCancelToken(() => this.cancel({ cancelled: true }));
fireStartEvent(this.requestParams.all());
this.requestParams.onStart();
if (this.requestParams.all().prefetch) {
this.requestParams.onPrefetching();
firePrefetchingEvent(this.requestParams.all());
}
const originallyPrefetch = this.requestParams.all().prefetch;
return (0, import_axios.default)({
method: this.requestParams.all().method,
url: urlWithoutHash(this.requestParams.all().url).href,
data: this.requestParams.data(),
params: this.requestParams.queryParams(),
signal: this.cancelToken.signal,
headers: this.getHeaders(),
onUploadProgress: this.onProgress.bind(this),
// Why text? This allows us to delay JSON.parse until we're ready to use the response,
// helps with performance particularly on large responses + history encryption
responseType: "text"
}).then((response) => {
this.response = Response.create(this.requestParams, response, this.page);
return this.response.handle();
}).catch((error) => {
if (error?.response) {
this.response = Response.create(this.requestParams, error.response, this.page);
return this.response.handle();
}
return Promise.reject(error);
}).catch((error) => {
if (import_axios.default.isCancel(error)) {
return;
}
if (fireExceptionEvent(error)) {
if (originallyPrefetch) {
this.requestParams.onPrefetchError(error);
}
return Promise.reject(error);
}
}).finally(() => {
this.finish();
if (originallyPrefetch && this.response) {
this.requestParams.onPrefetchResponse(this.response);
}
});
}
finish() {
if (this.requestParams.wasCancelledAtAll()) {
return;
}
this.requestParams.markAsFinished();
this.fireFinishEvents();
}
fireFinishEvents() {
if (this.requestHasFinished) {
return;
}
this.requestHasFinished = true;
fireFinishEvent(this.requestParams.all());
this.requestParams.onFinish();
}
cancel({ cancelled = false, interrupted = false }) {
if (this.requestHasFinished) {
return;
}
this.cancelToken.abort();
this.requestParams.markAsCancelled({ cancelled, interrupted });
this.fireFinishEvents();
}
onProgress(progress3) {
if (this.requestParams.data() instanceof FormData) {
progress3.percentage = progress3.progress ? Math.round(progress3.progress * 100) : 0;
fireProgressEvent(progress3);
this.requestParams.all().onProgress(progress3);
}
}
getHeaders() {
const headers = {
...this.requestParams.headers(),
Accept: "text/html, application/xhtml+xml",
"X-Requested-With": "XMLHttpRequest",
"X-Inertia": true
};
const page2 = page.get();
if (page2.version) {
headers["X-Inertia-Version"] = page2.version;
}
const onceProps = Object.entries(page2.onceProps || {}).filter(([, onceProp]) => {
if (page2.props[onceProp.prop] === void 0) {
return false;
}
return !onceProp.expiresAt || onceProp.expiresAt > Date.now();
}).map(([key]) => key);
if (onceProps.length > 0) {
headers["X-Inertia-Except-Once-Props"] = onceProps.join(",");
}
return headers;
}
};
// src/requestStream.ts
var RequestStream = class {
constructor({ maxConcurrent, interruptible }) {
this.requests = [];
this.maxConcurrent = maxConcurrent;
this.interruptible = interruptible;
}
send(request) {
this.requests.push(request);
request.send().then(() => {
this.requests = this.requests.filter((r) => r !== request);
});
}
interruptInFlight() {
this.cancel({ interrupted: true }, false);
}
cancelInFlight({ prefetch = true } = {}) {
this.requests.filter((request) => prefetch || !request.isPrefetch()).forEach((request) => request.cancel({ cancelled: true }));
}
cancel({ cancelled = false, interrupted = false } = {}, force = false) {
if (!force && !this.shouldCancel()) {
return;
}
const request = this.requests.shift();
request?.cancel({ cancelled, interrupted });
}
shouldCancel() {
return this.interruptible && this.requests.length >= this.maxConcurrent;
}
};
// src/router.ts
var Router = class {
constructor() {
this.syncRequestStream = new RequestStream({
maxConcurrent: 1,
interruptible: true
});
this.asyncRequestStream = new RequestStream({
maxConcurrent: Infinity,
interruptible: false
});
this.clientVisitQueue = new Queue();
}
init({
initialPage,
resolveComponent,
swapComponent,
onFlash
}) {
page.init({
initialPage,
resolveComponent,
swapComponent,
onFlash
});
InitialVisit.handle();
eventHandler.init();
eventHandler.on("missingHistoryItem", () => {
if (typeof window !== "undefined") {
this.visit(window.location.href, { preserveState: true, preserveScroll: true, replace: true });
}
});
eventHandler.on("loadDeferredProps", (deferredProps) => {
this.loadDeferredProps(deferredProps);
});
eventHandler.on("historyQuotaExceeded", (url) => {
window.location.href = url;
});
}
get(url, data = {}, options = {}) {
return this.visit(url, { ...options, method: "get", data });
}
post(url, data = {}, options = {}) {
return this.visit(url, { preserveState: true, ...options, method: "post", data });
}
put(url, data = {}, options = {}) {
return this.visit(url, { preserveState: true, ...options, method: "put", data });
}
patch(url, data = {}, options = {}) {
return this.visit(url, { preserveState: true, ...options, method: "patch", data });
}
delete(url, options = {}) {
return this.visit(url, { preserveState: true, ...options, method: "delete" });
}
reload(options = {}) {
return this.doReload(options);
}
doReload(options = {}) {
if (typeof window === "undefined") {
return;
}
return this.visit(window.location.href, {
...options,
preserveScroll: true,
preserveState: true,
async: true,
headers: {
...options.headers || {},
"Cache-Control": "no-cache"
}
});
}
remember(data, key = "default") {
history.remember(data, key);
}
restore(key = "default") {
return history.restore(key);
}
on(type, callback) {
if (typeof window === "undefined") {
return () => {
};
}
return eventHandler.onGlobalEvent(type, callback);
}
/**
* @deprecated Use cancelAll() instead.
*/
cancel() {
this.syncRequestStream.cancelInFlight();
}
cancelAll({ async = true, prefetch = true, sync = true } = {}) {
if (async) {
this.asyncRequestStream.cancelInFlight({ prefetch });
}
if (sync) {
this.syncRequestStream.cancelInFlight();
}
}
poll(interval, requestOptions = {}, options = {}) {
return polls.add(interval, () => this.reload(requestOptions), {
autoStart: options.autoStart ?? true,
keepAlive: options.keepAlive ?? false
});
}
visit(href, options = {}) {
const visit = this.getPendingVisit(href, {
...options,
showProgress: options.showProgress ?? !options.async
});
const events = this.getVisitEvents(options);
if (events.onBefore(visit) === false || !fireBeforeEvent(visit)) {
return;
}
const currentPageUrl = hrefToUrl(page.get().url);
const isPartialReload = visit.only.length > 0 || visit.except.length > 0 || visit.reset.length > 0;
const isSamePage = isPartialReload ? isSameUrlWithoutQueryOrHash(visit.url, currentPageUrl) : isSameUrlWithoutHash(visit.url, currentPageUrl);
if (!isSamePage) {
this.asyncRequestStream.cancelInFlight({ prefetch: false });
}
if (!visit.async) {
this.syncRequestStream.interruptInFlight();
}
if (!page.isCleared() && !visit.preserveUrl) {
Scroll.save();
}
const requestParams = {
...visit,
...events
};
const prefetched = prefetchedRequests.get(requestParams);
if (prefetched) {
progress.reveal(prefetched.inFlight);
prefetchedRequests.use(prefetched, requestParams);
} else {
progress.reveal(true);
const requestStream = visit.async ? this.asyncRequestStream : this.syncRequestStream;
requestStream.send(Request.create(requestParams, page.get()));
}
}
getCached(href, options = {}) {
return prefetchedRequests.findCached(this.getPrefetchParams(href, options));
}
flush(href, options = {}) {
prefetchedRequests.remove(this.getPrefetchParams(href, options));
}
flushAll() {
prefetchedRequests.removeAll();
}
flushByCacheTags(tags) {
prefetchedRequests.removeByTags(Array.isArray(tags) ? tags : [tags]);
}
getPrefetching(href, options = {}) {
return prefetchedRequests.findInFlight(this.getPrefetchParams(href, options));
}
prefetch(href, options = {}, prefetchOptions = {}) {
const method = options.method ?? (isUrlMethodPair(href) ? href.method : "get");
if (method !== "get") {
throw new Error("Prefetch requests must use the GET method");
}
const visit = this.getPendingVisit(href, {
...options,
async: true,
showProgress: false,
prefetch: true,
viewTransition: false
});
const visitUrl = visit.url.origin + visit.url.pathname + visit.url.search;
const currentUrl = window.location.origin + window.location.pathname + window.location.search;
if (visitUrl === currentUrl) {
return;
}
const events = this.getVisitEvents(options);
if (events.onBefore(visit) === false || !fireBeforeEvent(visit)) {
return;
}
progress.hide();
this.asyncRequestStream.interruptInFlight();
const requestParams = {
...visit,
...events
};
const ensureCurrentPageIsSet = () => {
return new Promise((resolve) => {
const checkIfPageIsDefined = () => {
if (page.get()) {
resolve();
} else {
setTimeout(checkIfPageIsDefined, 50);
}
};
checkIfPageIsDefined();
});
};
ensureCurrentPageIsSet().then(() => {
prefetchedRequests.add(
requestParams,
(params) => {
this.asyncRequestStream.send(Request.create(params, page.get()));
},
{
cacheFor: config.get("prefetch.cacheFor"),
cacheTags: [],
...prefetchOptions
}
);
});
}
clearHistory() {
history.clear();
}
decryptHistory() {
return history.decrypt();
}
resolveComponent(component) {
return page.resolve(component);
}
replace(params) {
this.clientVisit(params, { replace: true });
}
replaceProp(name, value, options) {
this.replace({
preserveScroll: true,
preserveState: true,
props(currentProps) {
const newValue = typeof value === "function" ? value((0, import_lodash_es5.get)(currentProps, name), currentProps) : value;
return (0, import_lodash_es5.set)((0, import_lodash_es5.cloneDeep)(currentProps), name, newValue);
},
...options || {}
});
}
appendToProp(name, value, options) {
this.replaceProp(
name,
(currentValue, currentProps) => {
const newValue = typeof value === "function" ? value(currentValue, currentProps) : value;
if (!Array.isArray(currentValue)) {
currentValue = currentValue !== void 0 ? [currentValue] : [];
}
return [...currentValue, newValue];
},
options
);
}
prependToProp(name, value, options) {
this.replaceProp(
name,
(currentValue, currentProps) => {
const newValue = typeof value === "function" ? value(currentValue, currentProps) : value;
if (!Array.isArray(currentValue)) {
currentValue = currentValue !== void 0 ? [currentValue] : [];
}
return [newValue, ...currentValue];
},
options
);
}
push(params) {
this.clientVisit(params);
}
flash(keyOrData, value) {
const current = page.get().flash;
let flash;
if (typeof keyOrData === "function") {
flash = keyOrData(current);
} else if (typeof keyOrData === "string") {
flash = { ...current, [keyOrData]: value };
} else if (keyOrData && Object.keys(keyOrData).length) {
flash = { ...current, ...keyOrData };
} else {
return;
}
page.setFlash(flash);
if (Object.keys(flash).length) {
fireFlashEvent(flash);
}
}
clientVisit(params, { replace = false } = {}) {
this.clientVisitQueue.add(() => this.performClientVisit(params, { replace }));
}
performClientVisit(params, { replace = false } = {}) {
const current = page.get();
const onceProps = typeof params.props === "function" ? Object.fromEntries(
Object.values(current.onceProps ?? {}).map((onceProp) => [onceProp.prop, current.props[onceProp.prop]])
) : {};
const props = typeof params.props === "function" ? params.props(current.props, onceProps) : params.props ?? current.props;
const flash = typeof params.flash === "function" ? params.flash(current.flash) : params.flash;
const { viewTransition, onError, onFinish, onFlash, onSuccess, ...pageParams } = params;
const page2 = {
...current,
...pageParams,
flash: flash ?? {},
props
};
const preserveScroll = RequestParams.resolvePreserveOption(params.preserveScroll ?? false, page2);
const preserveState = RequestParams.resolvePreserveOption(params.preserveState ?? false, page2);
return page.set(page2, {
replace,
preserveScroll,
preserveState,
viewTransition
}).then(() => {
const currentFlash = page.get().flash;
if (Object.keys(currentFlash).length > 0) {
fireFlashEvent(currentFlash);
onFlash?.(currentFlash);
}
const errors = page.get().props.errors || {};
if (Object.keys(errors).length === 0) {
onSuccess?.(page.get());
return;
}
const scopedErrors = params.errorBag ? errors[params.errorBag || ""] || {} : errors;
onError?.(scopedErrors);
}).finally(() => onFinish?.(params));
}
getPrefetchParams(href, options) {
return {
...this.getPendingVisit(href, {
...options,
async: true,
showProgress: false,
prefetch: true,
viewTransition: false
}),
...this.getVisitEvents(options)
};
}
getPendingVisit(href, options, pendingVisitOptions = {}) {
if (isUrlMethodPair(href)) {
const urlMethodPair = href;
href = urlMethodPair.url;
options.method = options.method ?? urlMethodPair.method;
}
const defaultVisitOptionsCallback = config.get("visitOptions");
const configuredOptions = defaultVisitOptionsCallback ? defaultVisitOptionsCallback(href.toString(), (0, import_lodash_es5.cloneDeep)(options)) || {} : {};
const mergedOptions = {
method: "get",
data: {},
replace: false,
preserveScroll: false,
preserveState: false,
only: [],
except: [],
headers: {},
errorBag: "",
forceFormData: false,
queryStringArrayFormat: "brackets",
async: false,
showProgress: true,
fresh: false,
reset: [],
preserveUrl: false,
prefetch: false,
invalidateCacheTags: [],
viewTransition: false,
...options,
...configuredOptions
};
const [url, _data] = transformUrlAndData(
href,
mergedOptions.data,
mergedOptions.method,
mergedOptions.forceFormData,
mergedOptions.queryStringArrayFormat
);
const visit = {
cancelled: false,
completed: false,
interrupted: false,
...mergedOptions,
...pendingVisitOptions,
url,
data: _data
};
if (visit.prefetch) {
visit.headers["Purpose"] = "prefetch";
}
return visit;
}
getVisitEvents(options) {
return {
onCancelToken: options.onCancelToken || (() => {
}),
onBefore: options.onBefore || (() => {
}),
onBeforeUpdate: options.onBeforeUpdate || (() => {
}),
onStart: options.onStart || (() => {
}),
onProgress: options.onProgress || (() => {
}),
onFinish: options.onFinish || (() => {
}),
onCancel: options.onCancel || (() => {
}),
onSuccess: options.onSuccess || (() => {
}),
onError: options.onError || (() => {
}),
onFlash: options.onFlash || (() => {
}),
onPrefetched: options.onPrefetched || (() => {
}),
onPrefetching: options.onPrefetching || (() => {
})
};
}
loadDeferredProps(deferred) {
if (deferred) {
Object.entries(deferred).forEach(([_, group]) => {
this.doReload({ only: group, deferredProps: true });
});
}
}
};
// src/useFormUtils.ts
var UseFormUtils = class {
/**
* Creates a callback that returns a UrlMethodPair.
*
* createWayfinderCallback(urlMethodPair)
* createWayfinderCallback(method, url)
* createWayfinderCallback(() => urlMethodPair)
* createWayfinderCallback(() => method, () => url)
*/
static createWayfinderCallback(...args) {
return () => {
if (args.length === 1) {
return isUrlMethodPair(args[0]) ? args[0] : args[0]();
}
return {
method: typeof args[0] === "function" ? args[0]() : args[0],
url: typeof args[1] === "function" ? args[1]() : args[1]
};
};
}
/**
* Parses all useForm() arguments into { rememberKey, data, precognitionEndpoint }.
*
* useForm()
* useForm(data)
* useForm(rememberKey, data)
* useForm(method, url, data)
* useForm(urlMethodPair, data)
*
*/
static parseUseFormArguments(...args) {
if (args.length === 0) {
return {
rememberKey: null,
data: {},
precognitionEndpoint: null
};
}
if (args.length === 1) {
return {
rememberKey: null,
data: args[0],
precognitionEndpoint: null
};
}
if (args.length === 2) {
if (typeof args[0] === "string") {
return {
rememberKey: args[0],
data: args[1],
precognitionEndpoint: null
};
}
return {
rememberKey: null,
data: args[1],
precognitionEndpoint: this.createWayfinderCallback(args[0])
};
}
return {
rememberKey: null,
data: args[2],
precognitionEndpoint: this.createWayfinderCallback(args[0], args[1])
};
}
/**
* Parses all submission arguments into { method, url, options }.
* It uses the Precognition endpoint if no explicit method/url are provided.
*
* form.submit(method, url)
* form.submit(method, url, options)
* form.submit(urlMethodPair)
* form.submit(urlMethodPair, options)
* form.submit()
* form.submit(options)
*/
static parseSubmitArguments(args, precognitionEndpoint) {
if (args.length === 3 || args.length === 2 && typeof args[0] === "string") {
return { method: args[0], url: args[1], options: args[2] ?? {} };
}
if (isUrlMethodPair(args[0])) {
return { ...args[0], options: args[1] ?? {} };
}
return { ...precognitionEndpoint(), options: args[0] ?? {} };
}
/**
* Merges headers into the Precognition validate() arguments.
*/
static mergeHeadersForValidation(field, config2, headers) {
const merge = (config3) => {
config3.headers = {
...headers ?? {},
...config3.headers ?? {}
};
return config3;
};
if (field && typeof field === "object" && !("target" in field)) {
field = merge(field);
} else if (config2 && typeof config2 === "object") {
config2 = merge(config2);
} else if (typeof field === "string") {
config2 = merge(config2 ?? {});
} else {
field = merge(field ?? {});
}
return [field, config2];
}
};
// src/formObject.ts
var import_lodash_es6 = require("lodash-es");
function undotKey(key) {
if (!key.includes(".")) {
return key;
}
const transformSegment = (segment) => {
if (segment.startsWith("[") && segment.endsWith("]")) {
return segment;
}
return segment.split(".").reduce((result, part, index) => index === 0 ? part : `${result}[${part}]`);
};
return key.replace(/\\\./g, "__ESCAPED_DOT__").split(/(\[[^\]]*\])/).filter(Boolean).map(transformSegment).join("").replace(/__ESCAPED_DOT__/g, ".");
}
function parseKey(key) {
const path = [];
const pattern = /([^\[\]]+)|\[(\d*)\]/g;
let match;
while ((match = pattern.exec(key)) !== null) {
if (match[1] !== void 0) {
path.push(match[1]);
} else if (match[2] !== void 0) {
path.push(match[2] === "" ? "" : Number(match[2]));
}
}
return path;
}
function setNestedObject(obj, path, value) {
let current = obj;
for (let i = 0; i < path.length - 1; i++) {
if (!(path[i] in current)) {
current[path[i]] = {};
}
current = current[path[i]];
}
current[path[path.length - 1]] = value;
}
function objectHasSequentialNumericKeys(value) {
const keys = Object.keys(value);
const numericKeys = keys.filter((k) => /^\d+$/.test(k)).map(Number).sort((a, b) => a - b);
return keys.length === numericKeys.length && numericKeys.length > 0 && numericKeys[0] === 0 && numericKeys.every((n, i) => n === i);
}
function convertSequentialObjectsToArrays(value) {
if (Array.isArray(value)) {
return value.map(convertSequentialObjectsToArrays);
}
if (typeof value !== "object" || value === null || isFile(value)) {
return value;
}
if (objectHasSequentialNumericKeys(value)) {
const result2 = [];
for (let i = 0; i < Object.keys(value).length; i++) {
result2[i] = convertSequentialObjectsToArrays(value[i]);
}
return result2;
}
const result = {};
for (const key in value) {
result[key] = convertSequentialObjectsToArrays(value[key]);
}
return result;
}
function formDataToObject(source) {
const form = {};
for (const [key, value] of source.entries()) {
if (value instanceof File && value.size === 0 && value.name === "") {
continue;
}
const path = parseKey(undotKey(key));
if (path[path.length - 1] === "") {
const arrayPath = path.slice(0, -1);
const existing = (0, import_lodash_es6.get)(form, arrayPath);
if (Array.isArray(existing)) {
existing.push(value);
} else if (existing && typeof existing === "object" && !isFile(existing)) {
const numericKeys = Object.keys(existing).filter((k) => /^\d+$/.test(k)).map(Number).sort((a, b) => a - b);
(0, import_lodash_es6.set)(form, arrayPath, numericKeys.length > 0 ? [...numericKeys.map((k) => existing[k]), value] : [value]);
} else {
(0, import_lodash_es6.set)(form, arrayPath, [value]);
}
continue;
}
setNestedObject(form, path.map(String), value);
}
return convertSequentialObjectsToArrays(form);
}
// src/head.ts
var Renderer = {
preferredAttribute() {
return config.get("future.useDataInertiaHeadAttribute") ? "data-inertia" : "inertia";
},
buildDOMElement(tag) {
const template = document.createElement("template");
template.innerHTML = tag;
const node = template.content.firstChild;
if (!tag.startsWith("<script ")) {
return node;
}
const script = document.createElement("script");
script.innerHTML = node.innerHTML;
node.getAttributeNames().forEach((name) => {
script.setAttribute(name, node.getAttribute(name) || "");
});
return script;
},
isInertiaManagedElement(element) {
return element.nodeType === Node.ELEMENT_NODE && element.getAttribute(this.preferredAttribute()) !== null;
},
findMatchingElementIndex(element, elements) {
const attribute = this.preferredAttribute();
const key = element.getAttribute(attribute);
if (key !== null) {
return elements.findIndex((element2) => element2.getAttribute(attribute) === key);
}
return -1;
},
update: debounce(function(elements) {
const sourceElements = elements.map((element) => this.buildDOMElement(element));
const targetElements = Array.from(document.head.childNodes).filter(
(element) => this.isInertiaManagedElement(element)
);
targetElements.forEach((targetElement) => {
const index = this.findMatchingElementIndex(targetElement, sourceElements);
if (index === -1) {
targetElement?.parentNode?.removeChild(targetElement);
return;
}
const sourceElement = sourceElements.splice(index, 1)[0];
if (sourceElement && !targetElement.isEqualNode(sourceElement)) {
targetElement?.parentNode?.replaceChild(sourceElement, targetElement);
}
});
sourceElements.forEach((element) => document.head.appendChild(element));
}, 1)
};
function createHeadManager(isServer3, titleCallback, onUpdate) {
const states = {};
let lastProviderId = 0;
function connect() {
const id = lastProviderId += 1;
states[id] = [];
return id.toString();
}
function disconnect(id) {
if (id === null || Object.keys(states).indexOf(id) === -1) {
return;
}
delete states[id];
commit();
}
function reconnect(id) {
if (Object.keys(states).indexOf(id) === -1) {
states[id] = [];
}
}
function update(id, elements = []) {
if (id !== null && Object.keys(states).indexOf(id) > -1) {
states[id] = elements;
}
commit();
}
function collect() {
const title = titleCallback("");
const attribute = Renderer.preferredAttribute();
const defaults = {
...title ? { title: `<title ${attribute}="">${title}</title>` } : {}
};
const elements = Object.values(states).reduce((carry, elements2) => carry.concat(elements2), []).reduce((carry, element) => {
if (element.indexOf("<") === -1) {
return carry;
}
if (element.indexOf("<title ") === 0) {
const title2 = element.match(/(<title [^>]+>)(.*?)(<\/title>)/);
carry.title = title2 ? `${title2[1]}${titleCallback(title2[2])}${title2[3]}` : element;
return carry;
}
const match = element.match(attribute === "inertia" ? / inertia="[^"]+"/ : / data-inertia="[^"]+"/);
if (match) {
carry[match[0]] = element;
} else {
carry[Object.keys(carry).length] = element;
}
return carry;
}, defaults);
return Object.values(elements);
}
function commit() {
isServer3 ? onUpdate(collect()) : Renderer.update(collect());
}
commit();
return {
forceUpdate: commit,
createProvider: function() {
const id = connect();
return {
preferredAttribute: Renderer.preferredAttribute,
reconnect: () => reconnect(id),
update: (elements) => update(id, elements),
disconnect: () => disconnect(id)
};
}
};
}
// src/infiniteScroll/data.ts
var MERGE_INTENT_HEADER = "X-Inertia-Infinite-Scroll-Merge-Intent";
var useInfiniteScrollData = (options) => {
const getScrollPropFromCurrentPage = () => {
const scrollProp = page.get().scrollProps?.[options.getPropName()];
if (scrollProp) {
return scrollProp;
}
throw new Error(`The page object does not contain a scroll prop named "${options.getPropName()}".`);
};
const state = {
component: null,
loading: false,
previousPage: null,
nextPage: null,
lastLoadedPage: null,
requestCount: 0
};
const resetState = () => {
const scrollProp = getScrollPropFromCurrentPage();
state.component = page.get().component;
state.loading = false;
state.previousPage = scrollProp.previousPage;
state.nextPage = scrollProp.nextPage;
state.lastLoadedPage = scrollProp.currentPage;
state.requestCount = 0;
};
const getRememberKey = () => `inertia:infinite-scroll-data:${options.getPropName()}`;
if (typeof window !== "undefined") {
resetState();
const rememberedState = router.restore(getRememberKey());
if (rememberedState && typeof rememberedState === "object" && rememberedState.lastLoadedPage === getScrollPropFromCurrentPage().currentPage) {
state.previousPage = rememberedState.previousPage;
state.nextPage = rememberedState.nextPage;
state.lastLoadedPage = rememberedState.lastLoadedPage;
state.requestCount = rememberedState.requestCount || 0;
}
}
const removeEventListener = router.on("success", (event) => {
if (state.component === event.detail.page.component && getScrollPropFromCurrentPage().reset) {
resetState();
options.onReset?.();
}
});
const getScrollPropKeyForSide = (side) => {
return side === "next" ? "nextPage" : "previousPage";
};
const findPageToLoad = (side) => {
const pagePropName = getScrollPropKeyForSide(side);
return state[pagePropName];
};
const syncStateOnSuccess = (side) => {
const scrollProp = getScrollPropFromCurrentPage();
const paginationProp = getScrollPropKeyForSide(side);
state.lastLoadedPage = scrollProp.currentPage;
state[paginationProp] = scrollProp[paginationProp];
state.requestCount += 1;
router.remember(
{
previousPage: state.previousPage,
nextPage: state.nextPage,
lastLoadedPage: state.lastLoadedPage,
requestCount: state.requestCount
},
getRememberKey()
);
};
const getPageName = () => getScrollPropFromCurrentPage().pageName;
const getRequestCount = () => state.requestCount;
const fetchPage = (side, reloadOptions = {}) => {
const page2 = findPageToLoad(side);
if (state.loading || page2 === null) {
return;
}
state.loading = true;
router.reload({
...reloadOptions,
data: { [getPageName()]: page2 },
only: [options.getPropName()],
preserveUrl: true,
// we handle URL updates manually via useInfiniteScrollQueryString()
headers: {
[MERGE_INTENT_HEADER]: side === "previous" ? "prepend" : "append",
...reloadOptions.headers
},
onBefore: (visit) => {
side === "next" ? options.onBeforeNextRequest() : options.onBeforePreviousRequest();
reloadOptions.onBefore?.(visit);
},
onBeforeUpdate: (page3) => {
options.onBeforeUpdate();
reloadOptions.onBeforeUpdate?.(page3);
},
onSuccess: (page3) => {
syncStateOnSuccess(side);
reloadOptions.onSuccess?.(page3);
},
onFinish: (visit) => {
state.loading = false;
side === "next" ? options.onCompleteNextRequest(state.lastLoadedPage) : options.onCompletePreviousRequest(state.lastLoadedPage);
reloadOptions.onFinish?.(visit);
}
});
};
const getLastLoadedPage = () => state.lastLoadedPage;
const hasPrevious = () => !!state.previousPage;
const hasNext = () => !!state.nextPage;
const fetchPrevious = (reloadOptions) => fetchPage("previous", reloadOptions);
const fetchNext = (reloadOptions) => fetchPage("next", reloadOptions);
return {
getLastLoadedPage,
getPageName,
getRequestCount,
hasPrevious,
hasNext,
fetchNext,
fetchPrevious,
removeEventListener
};
};
// src/intersectionObservers.ts
var useIntersectionObservers = () => {
const intersectionObservers = [];
const newIntersectionObserver = (callback, options = {}) => {
const observer = new IntersectionObserver((entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
callback(entry);
}
}
}, options);
intersectionObservers.push(observer);
return observer;
};
const flushAll = () => {
intersectionObservers.forEach((observer) => observer.disconnect());
intersectionObservers.length = 0;
};
return {
new: newIntersectionObserver,
flushAll
};
};
// src/infiniteScroll/elements.ts
var INFINITE_SCROLL_PAGE_KEY = "infiniteScrollPage";
var INFINITE_SCROLL_IGNORE_KEY = "infiniteScrollIgnore";
var getPageFromElement = (element) => element.dataset[INFINITE_SCROLL_PAGE_KEY];
var useInfiniteScrollElementManager = (options) => {
const intersectionObservers = useIntersectionObservers();
let itemsObserver;
let startElementObserver;
let endElementObserver;
let itemsMutationObserver;
let triggersEnabled = false;
const setupObservers = () => {
itemsMutationObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.nodeType !== Node.ELEMENT_NODE) {
return;
}
addedElements.add(node);
});
});
rememberElementsDebounced();
});
itemsMutationObserver.observe(options.getItemsElement(), { childList: true });
itemsObserver = intersectionObservers.new(
(entry) => options.onItemIntersected(entry.target)
);
const observerOptions = {
root: options.getScrollableParent(),
rootMargin: `${Math.max(1, options.getTriggerMargin())}px`
};
startElementObserver = intersectionObservers.new(options.onPreviousTriggered, observerOptions);
endElementObserver = intersectionObservers.new(options.onNextTriggered, observerOptions);
};
const enableTriggers = () => {
if (triggersEnabled) {
disableTriggers();
}
const startElement = options.getStartElement();
const endElement = options.getEndElement();
if (startElement && options.shouldFetchPrevious()) {
startElementObserver.observe(startElement);
}
if (endElement && options.shouldFetchNext()) {
endElementObserver.observe(endElement);
}
triggersEnabled = true;
};
const disableTriggers = () => {
if (!triggersEnabled) {
return;
}
startElementObserver.disconnect();
endElementObserver.disconnect();
triggersEnabled = false;
};
const refreshTriggers = () => {
if (triggersEnabled) {
enableTriggers();
}
};
const flushAll = () => {
disableTriggers();
intersectionObservers.flushAll();
itemsMutationObserver?.disconnect();
};
const addedElements = /* @__PURE__ */ new Set();
const elementIsUntagged = (element) => !(INFINITE_SCROLL_PAGE_KEY in element.dataset) && !(INFINITE_SCROLL_IGNORE_KEY in element.dataset);
const processManuallyAddedElements = () => {
Array.from(addedElements).forEach((element) => {
if (elementIsUntagged(element)) {
element.dataset[INFINITE_SCROLL_IGNORE_KEY] = "true";
}
itemsObserver.observe(element);
});
addedElements.clear();
};
const findUntaggedElements = (containerElement) => {
return Array.from(
containerElement.querySelectorAll(
`:scope > *:not([data-infinite-scroll-page]):not([data-infinite-scroll-ignore])`
)
);
};
let hasRestoredElements = false;
const processServerLoadedElements = (loadedPage) => {
if (!hasRestoredElements) {
hasRestoredElements = true;
if (restoreElements()) {
return;
}
}
findUntaggedElements(options.getItemsElement()).forEach((element) => {
if (elementIsUntagged(element)) {
element.dataset[INFINITE_SCROLL_PAGE_KEY] = loadedPage?.toString() || "1";
}
itemsObserver.observe(element);
});
rememberElements();
};
const getElementsRememberKey = () => `inertia:infinite-scroll-elements:${options.getPropName()}`;
const rememberElements = () => {
const pageElementRange = {};
const childNodes = options.getItemsElement().childNodes;
for (let index = 0; index < childNodes.length; index++) {
const node = childNodes[index];
if (node.nodeType !== Node.ELEMENT_NODE) {
continue;
}
const page2 = getPageFromElement(node);
if (typeof page2 === "undefined") {
continue;
}
if (!(page2 in pageElementRange)) {
pageElementRange[page2] = { from: index, to: index };
} else {
pageElementRange[page2].to = index;
}
}
router.remember(pageElementRange, getElementsRememberKey());
};
const rememberElementsDebounced = debounce(rememberElements, 250);
const restoreElements = () => {
const pageElementRange = router.restore(getElementsRememberKey());
if (!pageElementRange || typeof pageElementRange !== "object") {
return false;
}
const childNodes = options.getItemsElement().childNodes;
for (let index = 0; index < childNodes.length; index++) {
const node = childNodes[index];
if (node.nodeType !== Node.ELEMENT_NODE) {
continue;
}
const element = node;
let elementPage;
for (const [page2, range] of Object.entries(pageElementRange)) {
if (index >= range.from && index <= range.to) {
elementPage = page2;
break;
}
}
if (elementPage) {
element.dataset[INFINITE_SCROLL_PAGE_KEY] = elementPage;
} else if (!elementIsUntagged(element)) {
continue;
} else {
element.dataset[INFINITE_SCROLL_IGNORE_KEY] = "true";
}
itemsObserver.observe(element);
}
return true;
};
return {
setupObservers,
enableTriggers,
disableTriggers,
refreshTriggers,
flushAll,
processManuallyAddedElements,
processServerLoadedElements
};
};
// src/infiniteScroll/queryString.ts
var queue3 = new Queue();
var initialUrl;
var payloadUrl;
var initialUrlWasAbsolute = null;
var useInfiniteScrollQueryString = (options) => {
let enabled = true;
const queuePageUpdate = (page2) => {
queue3.add(() => {
return new Promise((resolve) => {
if (!enabled) {
initialUrl = payloadUrl = null;
return resolve();
}
if (!initialUrl || !payloadUrl) {
const currentPageUrl = page.get().url;
initialUrl = hrefToUrl(currentPageUrl);
payloadUrl = hrefToUrl(currentPageUrl);
initialUrlWasAbsolute = urlHasProtocol(currentPageUrl);
}
const pageName = options.getPageName();
const searchParams = payloadUrl.searchParams;
if (page2 === "1") {
searchParams.delete(pageName);
} else {
searchParams.set(pageName, page2);
}
setTimeout(() => resolve());
});
}).finally(() => {
if (enabled && initialUrl && payloadUrl && initialUrl.href !== payloadUrl.href && initialUrlWasAbsolute !== null) {
router.replace({
url: urlToString(payloadUrl, initialUrlWasAbsolute),
preserveScroll: true,
preserveState: true
});
}
initialUrl = payloadUrl = initialUrlWasAbsolute = null;
});
};
const onItemIntersected = debounce((itemElement) => {
const itemsElement = options.getItemsElement();
if (!enabled || options.shouldPreserveUrl() || !itemElement || !itemsElement) {
return;
}
const pageMap = /* @__PURE__ */ new Map();
const elements = [...itemsElement.children];
getElementsInViewportFromCollection(elements, itemElement).forEach((element) => {
const page2 = getPageFromElement(element) ?? "1";
if (pageMap.has(page2)) {
pageMap.set(page2, pageMap.get(page2) + 1);
} else {
pageMap.set(page2, 1);
}
});
const sortedPages = Array.from(pageMap.entries()).sort((a, b) => b[1] - a[1]);
const mostVisiblePage = sortedPages[0]?.[0];
if (mostVisiblePage !== void 0) {
queuePageUpdate(mostVisiblePage);
}
}, 250);
return {
onItemIntersected,
cancel: () => enabled = false
};
};
// src/infiniteScroll/scrollPreservation.ts
var useInfiniteScrollPreservation = (options) => {
const createCallbacks = () => {
let currentScrollTop;
let referenceElement = null;
let referenceElementTop = 0;
const captureScrollPosition = () => {
const scrollableContainer = options.getScrollableParent();
const itemsElement = options.getItemsElement();
currentScrollTop = scrollableContainer?.scrollTop || window.scrollY;
const visibleElements = getElementsInViewportFromCollection([...itemsElement.children]);
if (visibleElements.length > 0) {
referenceElement = visibleElements[0];
const containerRect = scrollableContainer?.getBoundingClientRect() || { top: 0 };
const containerTop = scrollableContainer ? containerRect.top : 0;
const rect = referenceElement.getBoundingClientRect();
referenceElementTop = rect.top - containerTop;
}
};
const restoreScrollPosition = () => {
if (!referenceElement) {
return;
}
let attempts = 0;
let restored = false;
const restore = () => {
attempts++;
if (restored || attempts > 10) {
return false;
}
const scrollableContainer = options.getScrollableParent();
const containerRect = scrollableContainer?.getBoundingClientRect() || { top: 0 };
const containerTop = scrollableContainer ? containerRect.top : 0;
const newRect = referenceElement.getBoundingClientRect();
const newElementTop = newRect.top - containerTop;
const adjustment = newElementTop - referenceElementTop;
if (adjustment === 0) {
window.requestAnimationFrame(restore);
return;
}
if (scrollableContainer) {
scrollableContainer.scrollTo({ top: currentScrollTop + adjustment });
} else {
window.scrollTo(0, window.scrollY + adjustment);
}
restored = true;
};
window.requestAnimationFrame(restore);
};
return {
captureScrollPosition,
restoreScrollPosition
};
};
return {
createCallbacks
};
};
// src/infiniteScroll.ts
function useInfiniteScroll(options) {
const queryStringManager = useInfiniteScrollQueryString({ ...options, getPageName: () => dataManager.getPageName() });
const scrollPreservation = useInfiniteScrollPreservation(options);
const elementManager = useInfiniteScrollElementManager({
...options,
// As items enter viewport, update URL to reflect the most visible page
onItemIntersected: queryStringManager.onItemIntersected,
onPreviousTriggered: () => dataManager.fetchPrevious(),
onNextTriggered: () => dataManager.fetchNext()
});
const dataManager = useInfiniteScrollData({
...options,
// Before updating page data, tag any manually added DOM elements
// so they don't get confused with server-loaded content
onBeforeUpdate: elementManager.processManuallyAddedElements,
// After successful request, tag new server content
onCompletePreviousRequest: (loadedPage) => {
options.onCompletePreviousRequest();
requestAnimationFrame(() => elementManager.processServerLoadedElements(loadedPage), 2);
},
onCompleteNextRequest: (loadedPage) => {
options.onCompleteNextRequest();
requestAnimationFrame(() => elementManager.processServerLoadedElements(loadedPage), 2);
},
onReset: options.onDataReset
});
const addScrollPreservationCallbacks = (reloadOptions) => {
const { captureScrollPosition, restoreScrollPosition } = scrollPreservation.createCallbacks();
const originalOnBeforeUpdate = reloadOptions.onBeforeUpdate || (() => {
});
const originalOnSuccess = reloadOptions.onSuccess || (() => {
});
reloadOptions.onBeforeUpdate = (page2) => {
originalOnBeforeUpdate(page2);
captureScrollPosition();
};
reloadOptions.onSuccess = (page2) => {
originalOnSuccess(page2);
restoreScrollPosition();
};
return reloadOptions;
};
const originalFetchNext = dataManager.fetchNext;
dataManager.fetchNext = (reloadOptions = {}) => {
if (options.inReverseMode()) {
reloadOptions = addScrollPreservationCallbacks(reloadOptions);
}
originalFetchNext(reloadOptions);
};
const originalFetchPrevious = dataManager.fetchPrevious;
dataManager.fetchPrevious = (reloadOptions = {}) => {
if (!options.inReverseMode()) {
reloadOptions = addScrollPreservationCallbacks(reloadOptions);
}
originalFetchPrevious(reloadOptions);
};
const removeEventListener = router.on("success", () => requestAnimationFrame(elementManager.refreshTriggers, 2));
return {
dataManager,
elementManager,
flush: () => {
removeEventListener();
dataManager.removeEventListener();
elementManager.flushAll();
queryStringManager.cancel();
}
};
}
// src/navigationEvents.ts
function isContentEditableOrPrevented(event) {
return event.target instanceof HTMLElement && event.target.isContentEditable || event.defaultPrevented;
}
function shouldIntercept(event) {
const isLink = event.currentTarget.tagName.toLowerCase() === "a";
return !(isContentEditableOrPrevented(event) || isLink && event.altKey || isLink && event.ctrlKey || isLink && event.metaKey || isLink && event.shiftKey || isLink && "button" in event && event.button !== 0);
}
function shouldNavigate(event) {
const isButton = event.currentTarget.tagName.toLowerCase() === "button";
return !isContentEditableOrPrevented(event) && (event.key === "Enter" || isButton && event.key === " ");
}
// src/progress-component.ts
var baseComponentSelector = "nprogress";
var progress2;
var settings = {
minimum: 0.08,
easing: "linear",
positionUsing: "translate3d",
speed: 200,
trickle: true,
trickleSpeed: 200,
showSpinner: true,
barSelector: '[role="bar"]',
spinnerSelector: '[role="spinner"]',
parent: "body",
color: "#29d",
includeCSS: true,
template: [
'<div class="bar" role="bar">',
'<div class="peg"></div>',
"</div>",
'<div class="spinner" role="spinner">',
'<div class="spinner-icon"></div>',
"</div>"
].join("")
};
var status = null;
var configure = (options) => {
Object.assign(settings, options);
if (settings.includeCSS) {
injectCSS(settings.color);
}
progress2 = document.createElement("div");
progress2.id = baseComponentSelector;
progress2.innerHTML = settings.template;
};
var set5 = (n) => {
const started = isStarted();
n = clamp(n, settings.minimum, 1);
status = n === 1 ? null : n;
const progress3 = render(!started);
const bar = progress3.querySelector(settings.barSelector);
const speed = settings.speed;
const ease = settings.easing;
progress3.offsetWidth;
queue4((next) => {
const barStyles = (() => {
if (settings.positionUsing === "translate3d") {
return {
transition: `all ${speed}ms ${ease}`,
transform: `translate3d(${toBarPercentage(n)}%,0,0)`
};
}
if (settings.positionUsing === "translate") {
return {
transition: `all ${speed}ms ${ease}`,
transform: `translate(${toBarPercentage(n)}%,0)`
};
}
return { marginLeft: `${toBarPercentage(n)}%` };
})();
for (const key in barStyles) {
bar.style[key] = barStyles[key];
}
if (n !== 1) {
return setTimeout(next, speed);
}
progress3.style.transition = "none";
progress3.style.opacity = "1";
progress3.offsetWidth;
setTimeout(() => {
progress3.style.transition = `all ${speed}ms linear`;
progress3.style.opacity = "0";
setTimeout(() => {
remove();
progress3.style.transition = "";
progress3.style.opacity = "";
next();
}, speed);
}, speed);
});
};
var isStarted = () => typeof status === "number";
var start = () => {
if (!status) {
set5(0);
}
const work = function() {
setTimeout(function() {
if (!status) {
return;
}
increaseByRandom();
work();
}, settings.trickleSpeed);
};
if (settings.trickle) {
work();
}
};
var done = (force) => {
if (!force && !status) {
return;
}
increaseByRandom(0.3 + 0.5 * Math.random());
set5(1);
};
var increaseByRandom = (amount) => {
const n = status;
if (n === null) {
return start();
}
if (n > 1) {
return;
}
amount = typeof amount === "number" ? amount : (() => {
const ranges = {
0.1: [0, 0.2],
0.04: [0.2, 0.5],
0.02: [0.5, 0.8],
5e-3: [0.8, 0.99]
};
for (const r in ranges) {
if (n >= ranges[r][0] && n < ranges[r][1]) {
return parseFloat(r);
}
}
return 0;
})();
return set5(clamp(n + amount, 0, 0.994));
};
var render = (fromStart) => {
if (isRendered()) {
return document.getElementById(baseComponentSelector);
}
document.documentElement.classList.add(`${baseComponentSelector}-busy`);
const bar = progress2.querySelector(settings.barSelector);
const perc = fromStart ? "-100" : toBarPercentage(status || 0);
const parent = getParent();
bar.style.transition = "all 0 linear";
bar.style.transform = `translate3d(${perc}%,0,0)`;
if (!settings.showSpinner) {
progress2.querySelector(settings.spinnerSelector)?.remove();
}
if (parent !== document.body) {
parent.classList.add(`${baseComponentSelector}-custom-parent`);
}
parent.appendChild(progress2);
return progress2;
};
var getParent = () => {
return isDOM(settings.parent) ? settings.parent : document.querySelector(settings.parent);
};
var remove = () => {
document.documentElement.classList.remove(`${baseComponentSelector}-busy`);
getParent().classList.remove(`${baseComponentSelector}-custom-parent`);
progress2?.remove();
};
var isRendered = () => {
return document.getElementById(baseComponentSelector) !== null;
};
var isDOM = (obj) => {
if (typeof HTMLElement === "object") {
return obj instanceof HTMLElement;
}
return obj && typeof obj === "object" && obj.nodeType === 1 && typeof obj.nodeName === "string";
};
function clamp(n, min, max) {
if (n < min) {
return min;
}
if (n > max) {
return max;
}
return n;
}
var toBarPercentage = (n) => (-1 + n) * 100;
var queue4 = /* @__PURE__ */ (() => {
const pending = [];
const next = () => {
const fn = pending.shift();
if (fn) {
fn(next);
}
};
return (fn) => {
pending.push(fn);
if (pending.length === 1) {
next();
}
};
})();
var injectCSS = (color) => {
const element = document.createElement("style");
element.textContent = `
#${baseComponentSelector} {
pointer-events: none;
}
#${baseComponentSelector} .bar {
background: ${color};
position: fixed;
z-index: 1031;
top: 0;
left: 0;
width: 100%;
height: 2px;
}
#${baseComponentSelector} .peg {
display: block;
position: absolute;
right: 0px;
width: 100px;
height: 100%;
box-shadow: 0 0 10px ${color}, 0 0 5px ${color};
opacity: 1.0;
transform: rotate(3deg) translate(0px, -4px);
}
#${baseComponentSelector} .spinner {
display: block;
position: fixed;
z-index: 1031;
top: 15px;
right: 15px;
}
#${baseComponentSelector} .spinner-icon {
width: 18px;
height: 18px;
box-sizing: border-box;
border: solid 2px transparent;
border-top-color: ${color};
border-left-color: ${color};
border-radius: 50%;
animation: ${baseComponentSelector}-spinner 400ms linear infinite;
}
.${baseComponentSelector}-custom-parent {
overflow: hidden;
position: relative;
}
.${baseComponentSelector}-custom-parent #${baseComponentSelector} .spinner,
.${baseComponentSelector}-custom-parent #${baseComponentSelector} .bar {
position: absolute;
}
@keyframes ${baseComponentSelector}-spinner {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
`;
document.head.appendChild(element);
};
var show = () => {
if (progress2) {
progress2.style.display = "";
}
};
var hide = () => {
if (progress2) {
progress2.style.display = "none";
}
};
var progress_component_default = {
configure,
isStarted,
done,
set: set5,
remove,
start,
status,
show,
hide
};
// src/progress.ts
var Progress = class {
constructor() {
this.hideCount = 0;
}
start() {
progress_component_default.start();
}
reveal(force = false) {
this.hideCount = Math.max(0, this.hideCount - 1);
if (force || this.hideCount === 0) {
progress_component_default.show();
}
}
hide() {
this.hideCount++;
progress_component_default.hide();
}
set(status2) {
progress_component_default.set(Math.max(0, Math.min(1, status2)));
}
finish() {
progress_component_default.done();
}
reset() {
progress_component_default.set(0);
}
remove() {
progress_component_default.done();
progress_component_default.remove();
}
isStarted() {
return progress_component_default.isStarted();
}
getStatus() {
return progress_component_default.status;
}
};
var progress = new Progress();
var reveal = progress.reveal;
var hide2 = progress.hide;
function addEventListeners(delay) {
document.addEventListener("inertia:start", (e) => handleStartEvent(e, delay));
document.addEventListener("inertia:progress", handleProgressEvent);
}
function handleStartEvent(event, delay) {
if (!event.detail.visit.showProgress) {
progress.hide();
}
const timeout = setTimeout(() => progress.start(), delay);
document.addEventListener("inertia:finish", (e) => finish(e, timeout), { once: true });
}
function handleProgressEvent(event) {
if (progress.isStarted() && event.detail.progress?.percentage) {
progress.set(Math.max(progress.getStatus(), event.detail.progress.percentage / 100 * 0.9));
}
}
function finish(event, timeout) {
clearTimeout(timeout);
if (!progress.isStarted()) {
return;
}
if (event.detail.visit.completed) {
progress.finish();
} else if (event.detail.visit.interrupted) {
progress.reset();
} else if (event.detail.visit.cancelled) {
progress.remove();
}
}
function setupProgress({
delay = 250,
color = "#29d",
includeCSS = true,
showSpinner = false
} = {}) {
addEventListeners(delay);
progress_component_default.configure({ showSpinner, includeCSS, color });
}
// src/resetFormFields.ts
var FormComponentResetSymbol = /* @__PURE__ */ Symbol("FormComponentReset");
function isFormElement(element) {
return element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement;
}
function resetInputElement(input, defaultValues) {
const oldValue = input.value;
const oldChecked = input.checked;
switch (input.type.toLowerCase()) {
case "checkbox":
input.checked = defaultValues.includes(input.value);
break;
case "radio":
input.checked = defaultValues[0] === input.value;
break;
case "file":
input.value = "";
break;
case "button":
case "submit":
case "reset":
case "image":
break;
default:
input.value = defaultValues[0] !== null && defaultValues[0] !== void 0 ? String(defaultValues[0]) : "";
}
return input.value !== oldValue || input.checked !== oldChecked;
}
function resetSelectElement(select, defaultValues) {
const oldValue = select.value;
const oldSelectedOptions = Array.from(select.selectedOptions).map((opt) => opt.value);
if (select.multiple) {
const defaultStrings = defaultValues.map((value) => String(value));
Array.from(select.options).forEach((option) => {
option.selected = defaultStrings.includes(option.value);
});
} else {
select.value = defaultValues[0] !== void 0 ? String(defaultValues[0]) : "";
}
const newSelectedOptions = Array.from(select.selectedOptions).map((opt) => opt.value);
const hasChanged = select.multiple ? JSON.stringify(oldSelectedOptions.sort()) !== JSON.stringify(newSelectedOptions.sort()) : select.value !== oldValue;
return hasChanged;
}
function resetFormElement(element, defaultValues) {
if (element.disabled) {
if (element instanceof HTMLInputElement) {
const oldValue = element.value;
const oldChecked = element.checked;
switch (element.type.toLowerCase()) {
case "checkbox":
case "radio":
element.checked = element.defaultChecked;
return element.checked !== oldChecked;
case "file":
element.value = "";
return oldValue !== "";
case "button":
case "submit":
case "reset":
case "image":
return false;
default:
element.value = element.defaultValue;
return element.value !== oldValue;
}
} else if (element instanceof HTMLSelectElement) {
const oldSelectedOptions = Array.from(element.selectedOptions).map((opt) => opt.value);
Array.from(element.options).forEach((option) => {
option.selected = option.defaultSelected;
});
const newSelectedOptions = Array.from(element.selectedOptions).map((opt) => opt.value);
return JSON.stringify(oldSelectedOptions.sort()) !== JSON.stringify(newSelectedOptions.sort());
} else if (element instanceof HTMLTextAreaElement) {
const oldValue = element.value;
element.value = element.defaultValue;
return element.value !== oldValue;
}
return false;
}
if (element instanceof HTMLInputElement) {
return resetInputElement(element, defaultValues);
} else if (element instanceof HTMLSelectElement) {
return resetSelectElement(element, defaultValues);
} else if (element instanceof HTMLTextAreaElement) {
const oldValue = element.value;
element.value = defaultValues[0] !== void 0 ? String(defaultValues[0]) : "";
return element.value !== oldValue;
}
return false;
}
function resetFieldElements(elements, defaultValues) {
let hasChanged = false;
if (elements instanceof RadioNodeList || elements instanceof HTMLCollection) {
Array.from(elements).forEach((node, index) => {
if (node instanceof Element && isFormElement(node)) {
if (node instanceof HTMLInputElement && ["checkbox", "radio"].includes(node.type.toLowerCase())) {
if (resetFormElement(node, defaultValues)) {
hasChanged = true;
}
} else {
const indexedDefaultValues = defaultValues[index] !== void 0 ? [defaultValues[index]] : [defaultValues[0] ?? null].filter(Boolean);
if (resetFormElement(node, indexedDefaultValues)) {
hasChanged = true;
}
}
}
});
} else if (isFormElement(elements)) {
hasChanged = resetFormElement(elements, defaultValues);
}
return hasChanged;
}
function resetFormFields(formElement, defaults, fieldNames) {
if (!formElement) {
return;
}
const resetEntireForm = !fieldNames || fieldNames.length === 0;
if (resetEntireForm) {
const formData = new FormData(formElement);
const formElementNames = Array.from(formElement.elements).map((el) => isFormElement(el) ? el.name : "").filter(Boolean);
fieldNames = [.../* @__PURE__ */ new Set([...defaults.keys(), ...formData.keys(), ...formElementNames])];
}
let hasChanged = false;
fieldNames.forEach((fieldName) => {
const elements = formElement.elements.namedItem(fieldName);
if (elements) {
if (resetFieldElements(elements, defaults.getAll(fieldName))) {
hasChanged = true;
}
}
});
if (hasChanged && resetEntireForm) {
formElement.dispatchEvent(
new CustomEvent("reset", { bubbles: true, cancelable: true, detail: { [FormComponentResetSymbol]: true } })
);
}
}
// src/index.ts
var router = new Router();
/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress
* @license MIT */
//# sourceMappingURL=index.js.map