vue-qs
Version:
Type‑safe, reactive URL query params for Vue
912 lines (899 loc) • 29.2 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
areValuesEqual: () => areValuesEqual,
booleanCodec: () => booleanCodec,
buildSearchString: () => buildSearchString,
createArrayCodec: () => createArrayCodec,
createEnumCodec: () => createEnumCodec,
createHistoryAdapter: () => createHistoryAdapter,
createJsonCodec: () => createJsonCodec,
createRuntimeEnvironment: () => createRuntimeEnvironment,
createVueQsPlugin: () => createVueQsPlugin,
createVueRouterAdapter: () => createVueRouterAdapter,
dateISOCodec: () => dateISOCodec,
isBrowserEnvironment: () => isBrowserEnvironment,
mergeObjects: () => mergeObjects,
numberCodec: () => numberCodec,
parseSearchString: () => parseSearchString,
provideQueryAdapter: () => provideQueryAdapter,
removeUndefinedValues: () => removeUndefinedValues,
serializers: () => serializers_exports,
stringCodec: () => stringCodec,
useQueryAdapter: () => useQueryAdapter,
useQueryReactive: () => useQueryReactive,
useQueryRef: () => useQueryRef
});
module.exports = __toCommonJS(index_exports);
// src/composables/use-query-ref.ts
var import_vue3 = require("vue");
// src/adapter-context.ts
var import_vue = require("vue");
// src/core/injection-keys.ts
var QUERY_ADAPTER_INJECTION_KEY = Symbol.for("vue-qs:query-adapter");
// src/adapter-context.ts
function provideQueryAdapter(queryAdapter) {
try {
(0, import_vue.provide)(QUERY_ADAPTER_INJECTION_KEY, queryAdapter);
} catch (error) {
console.warn("Failed to provide query adapter:", error);
}
}
function useQueryAdapter() {
try {
return (0, import_vue.inject)(QUERY_ADAPTER_INJECTION_KEY, void 0, false);
} catch (error) {
console.warn("Failed to inject query adapter:", error);
return void 0;
}
}
function createVueQsPlugin(options) {
const { queryAdapter } = options;
return {
install(app) {
try {
app.provide(QUERY_ADAPTER_INJECTION_KEY, queryAdapter);
} catch (error) {
console.error("Failed to install vue-qs plugin:", error);
}
}
};
}
// src/adapters/history-adapter.ts
var import_vue2 = require("vue");
// src/utils/core-helpers.ts
function isBrowserEnvironment() {
try {
return typeof window !== "undefined" && typeof document !== "undefined";
} catch {
return false;
}
}
function createRuntimeEnvironment() {
const isBrowser = isBrowserEnvironment();
return {
isBrowser,
windowObject: isBrowser ? window : null
};
}
function parseSearchString(searchString) {
try {
const urlParams = new URLSearchParams(
searchString.startsWith("?") ? searchString : `?${searchString}`
);
const result = {};
urlParams.forEach((value, key) => {
result[key] = value;
});
return result;
} catch (error) {
console.warn("Failed to parse search string:", error);
return {};
}
}
function buildSearchString(queryObject) {
try {
const urlParams = new URLSearchParams();
Object.entries(queryObject).forEach(([key, value]) => {
if (value !== void 0) {
urlParams.set(key, value);
}
});
const searchString = urlParams.toString();
return searchString ? `?${searchString}` : "";
} catch (error) {
console.warn("Failed to build search string:", error);
return "";
}
}
function areValuesEqual(valueA, valueB, customEquals) {
try {
return customEquals ? customEquals(valueA, valueB) : Object.is(valueA, valueB);
} catch (error) {
console.warn("Error comparing values:", error);
return false;
}
}
function mergeObjects(baseObject, updateObject) {
try {
return { ...baseObject, ...updateObject };
} catch (error) {
console.warn("Error merging objects:", error);
return baseObject;
}
}
function removeUndefinedValues(sourceObject) {
try {
const cleanedObject = {};
Object.entries(sourceObject).forEach(([key, value]) => {
if (value !== void 0) {
cleanedObject[key] = value;
}
});
return cleanedObject;
} catch (error) {
console.warn("Error removing undefined values:", error);
return sourceObject;
}
}
// src/adapters/history-adapter.ts
var isHistoryPatched = false;
function patchHistoryAPI(windowObject) {
if (isHistoryPatched) {
return;
}
try {
isHistoryPatched = true;
const { history } = windowObject;
let shouldSuppressEvent = false;
history.__vueQsSuppress = (operation) => {
shouldSuppressEvent = true;
try {
operation();
} finally {
shouldSuppressEvent = false;
}
};
const dispatchHistoryChangeEvent = () => {
try {
windowObject.dispatchEvent(new Event("vue-qs:history-change"));
} catch (error) {
console.warn("Failed to dispatch history change event:", error);
}
};
const wrapHistoryMethod = (methodName) => {
const originalMethod = history[methodName];
history[methodName] = function(...args) {
try {
const result = originalMethod.apply(this, args);
if (!shouldSuppressEvent) {
dispatchHistoryChangeEvent();
}
return result;
} catch (error) {
console.warn(`Error in patched ${methodName}:`, error);
return originalMethod.apply(this, args);
}
};
};
wrapHistoryMethod("pushState");
wrapHistoryMethod("replaceState");
} catch (error) {
console.warn("Failed to patch history API:", error);
isHistoryPatched = false;
}
}
function createHistoryAdapter(options = {}) {
const runtimeEnvironment = createRuntimeEnvironment();
const { suppressHistoryEvents = false } = options;
const serverCache = (0, import_vue2.reactive)({
queryParams: {}
});
const queryAdapter = {
getCurrentQuery() {
try {
if (!runtimeEnvironment.isBrowser || !runtimeEnvironment.windowObject) {
return { ...serverCache.queryParams };
}
const searchString = runtimeEnvironment.windowObject.location.search;
return parseSearchString(searchString);
} catch (error) {
console.warn("Error getting current query:", error);
return {};
}
},
updateQuery(queryUpdates, updateOptions) {
try {
if (!runtimeEnvironment.isBrowser || !runtimeEnvironment.windowObject) {
serverCache.queryParams = mergeObjects(serverCache.queryParams, queryUpdates);
return;
}
const windowObject = runtimeEnvironment.windowObject;
const currentUrl = new URL(windowObject.location.href);
const currentQuery = parseSearchString(currentUrl.search);
const mergedQuery = mergeObjects(currentQuery, queryUpdates);
const newSearchString = buildSearchString(mergedQuery);
if (currentUrl.search === newSearchString) {
return;
}
currentUrl.search = newSearchString;
const newPath = `${currentUrl.pathname}${currentUrl.search}${currentUrl.hash}`;
const historyStrategy = updateOptions?.historyStrategy ?? "replace";
const historyMethod = historyStrategy === "push" ? "pushState" : "replaceState";
if (!suppressHistoryEvents) {
const historyWithSuppression = windowObject.history;
if (historyWithSuppression.__vueQsSuppress) {
historyWithSuppression.__vueQsSuppress(() => {
windowObject.history[historyMethod]({}, "", newPath);
});
} else {
windowObject.history[historyMethod]({}, "", newPath);
}
} else {
windowObject.history[historyMethod]({}, "", newPath);
}
if (windowObject.location.search !== newSearchString) {
try {
windowObject.location.href = newPath;
} catch (error) {
console.warn("Failed to update location directly:", error);
}
}
} catch (error) {
console.warn("Error updating query:", error);
}
},
onQueryChange(callback) {
try {
if (!runtimeEnvironment.isBrowser || !runtimeEnvironment.windowObject) {
return () => {
};
}
const windowObject = runtimeEnvironment.windowObject;
if (!suppressHistoryEvents) {
patchHistoryAPI(windowObject);
}
const handleQueryChange = () => {
try {
callback();
} catch (error) {
console.warn("Error in query change callback:", error);
}
};
windowObject.addEventListener("popstate", handleQueryChange);
if (!suppressHistoryEvents) {
windowObject.addEventListener("vue-qs:history-change", handleQueryChange);
}
return () => {
try {
windowObject.removeEventListener("popstate", handleQueryChange);
if (!suppressHistoryEvents) {
windowObject.removeEventListener("vue-qs:history-change", handleQueryChange);
}
} catch (error) {
console.warn("Error unsubscribing from query changes:", error);
}
};
} catch (error) {
console.warn("Error setting up query change listener:", error);
return () => {
};
}
}
};
return {
queryAdapter,
runtimeEnvironment
};
}
// src/serializers.ts
var serializers_exports = {};
__export(serializers_exports, {
booleanCodec: () => booleanCodec,
createArrayCodec: () => createArrayCodec,
createEnumCodec: () => createEnumCodec,
createJsonCodec: () => createJsonCodec,
dateISOCodec: () => dateISOCodec,
numberCodec: () => numberCodec,
stringCodec: () => stringCodec
});
var stringCodec = {
parse: (rawValue) => {
try {
return rawValue ?? "";
} catch (error) {
console.warn("Error parsing string value:", error);
return "";
}
},
serialize: (stringValue) => {
try {
return String(stringValue);
} catch (error) {
console.warn("Error serializing string value:", error);
return null;
}
}
};
var numberCodec = {
parse: (rawValue) => {
try {
if (rawValue === null || rawValue === "") {
return NaN;
}
const numericValue = Number(rawValue);
return numericValue;
} catch (error) {
console.warn("Error parsing number value:", error);
return NaN;
}
},
serialize: (numericValue) => {
try {
return Number.isFinite(numericValue) ? String(numericValue) : null;
} catch (error) {
console.warn("Error serializing number value:", error);
return null;
}
}
};
var booleanCodec = {
parse: (rawValue) => {
try {
return rawValue === "true" || rawValue === "1";
} catch (error) {
console.warn("Error parsing boolean value:", error);
return false;
}
},
serialize: (booleanValue) => {
try {
return booleanValue ? "true" : "false";
} catch (error) {
console.warn("Error serializing boolean value:", error);
return "false";
}
}
};
var dateISOCodec = {
parse: (rawValue) => {
try {
return rawValue !== null && rawValue !== "" ? new Date(rawValue) : /* @__PURE__ */ new Date(NaN);
} catch (error) {
console.warn("Error parsing date value:", error);
return /* @__PURE__ */ new Date(NaN);
}
},
serialize: (dateValue) => {
try {
if (dateValue instanceof Date && !isNaN(dateValue.getTime())) {
return dateValue.toISOString();
}
return null;
} catch (error) {
console.warn("Error serializing date value:", error);
return null;
}
}
};
function createJsonCodec() {
return {
parse: (rawValue) => {
try {
if (rawValue === null || rawValue === "") {
return null;
}
return JSON.parse(rawValue);
} catch (error) {
console.warn("Error parsing JSON value:", error);
return null;
}
},
serialize: (objectValue) => {
try {
if (objectValue === null || objectValue === void 0) {
return null;
}
return JSON.stringify(objectValue);
} catch (error) {
console.warn("Error serializing JSON value:", error);
return null;
}
}
};
}
function createArrayCodec(elementCodec, delimiter = ",") {
return {
parse: (rawValue) => {
try {
if (rawValue === null || rawValue === "") {
return [];
}
const arrayElements = rawValue.split(delimiter);
return arrayElements.map((element) => elementCodec.parse(element));
} catch (error) {
console.warn("Error parsing array value:", error);
return [];
}
},
serialize: (arrayValue) => {
try {
if (!Array.isArray(arrayValue) || arrayValue.length === 0) {
return null;
}
const serializedElements = arrayValue.map((element) => elementCodec.serialize(element)).filter((serialized) => serialized !== null);
return serializedElements.length > 0 ? serializedElements.join(delimiter) : null;
} catch (error) {
console.warn("Error serializing array value:", error);
return null;
}
}
};
}
function createEnumCodec(allowedValues) {
const defaultValue = allowedValues[0];
return {
parse: (rawValue) => {
try {
if (allowedValues.includes(rawValue)) {
return rawValue;
}
return defaultValue;
} catch (error) {
console.warn("Error parsing enum value:", error);
return defaultValue;
}
},
serialize: (enumValue) => {
try {
return allowedValues.includes(enumValue) ? enumValue : defaultValue;
} catch (error) {
console.warn("Error serializing enum value:", error);
return defaultValue;
}
}
};
}
// src/composables/use-query-ref.ts
var sharedHistoryAdapterInstance;
function getSharedHistoryAdapter() {
if (!sharedHistoryAdapterInstance) {
const { queryAdapter } = createHistoryAdapter();
sharedHistoryAdapterInstance = queryAdapter;
}
return sharedHistoryAdapterInstance;
}
function selectQueryAdapter(providedAdapter) {
if (providedAdapter !== void 0) {
return providedAdapter;
}
const componentInstance = (0, import_vue3.getCurrentInstance)();
const injectedAdapter = componentInstance !== null ? useQueryAdapter() : void 0;
return injectedAdapter ?? getSharedHistoryAdapter();
}
function getCodecFunctions(parseFunction, serializeFunction, codec) {
return {
parseValue: parseFunction ?? codec?.parse ?? stringCodec.parse,
serializeValue: serializeFunction ?? codec?.serialize ?? stringCodec.serialize
};
}
function useQueryRef(parameterName, options = {}) {
const {
defaultValue,
codec,
parseFunction,
serializeFunction,
isEqual: customEquals,
shouldOmitDefault = true,
historyStrategy = "replace",
queryAdapter: providedAdapter,
enableTwoWaySync = false
} = options;
const selectedAdapter = selectQueryAdapter(providedAdapter);
const { parseValue, serializeValue } = getCodecFunctions(parseFunction, serializeFunction, codec);
function getInitialValue() {
try {
const currentQuery = selectedAdapter.getCurrentQuery();
const rawValue = currentQuery[parameterName] ?? null;
if (typeof rawValue === "string" && rawValue.length > 0) {
return parseValue(rawValue);
}
return defaultValue;
} catch (error) {
console.warn(`Error getting initial value for parameter "${parameterName}":`, error);
return defaultValue;
}
}
const initialValue = getInitialValue();
const internalRef = (0, import_vue3.ref)(initialValue);
const queryRef = internalRef;
function isDefaultValue(value) {
if (defaultValue === void 0) {
return false;
}
return areValuesEqual(value, defaultValue, customEquals);
}
function updateURL(value) {
try {
const serializedValue = serializeValue(value);
const shouldOmit = shouldOmitDefault && isDefaultValue(value);
const queryUpdate = {
[parameterName]: shouldOmit ? void 0 : serializedValue ?? void 0
};
selectedAdapter.updateQuery(queryUpdate, { historyStrategy });
} catch (error) {
console.warn(`Error updating URL for parameter "${parameterName}":`, error);
}
}
if (defaultValue !== void 0 && !shouldOmitDefault) {
const currentQuery = selectedAdapter.getCurrentQuery();
if (!(parameterName in currentQuery)) {
updateURL(defaultValue);
}
}
let isSyncingFromURL = false;
const stopWatcher = (0, import_vue3.watch)(
queryRef,
(newValue) => {
if (isSyncingFromURL) {
return;
}
updateURL(newValue);
},
{ flush: "sync" }
// Sync immediately to avoid batching delays
);
queryRef.syncToUrl = () => {
updateURL(queryRef.value);
};
let unsubscribeFromURLChanges;
if (enableTwoWaySync) {
let syncFromURL2 = function() {
try {
const currentQuery = selectedAdapter.getCurrentQuery();
const rawValue = currentQuery[parameterName] ?? null;
const parsedValue = typeof rawValue === "string" && rawValue.length > 0 ? parseValue(rawValue) : defaultValue;
isSyncingFromURL = true;
try {
internalRef.value = parsedValue;
} finally {
queueMicrotask(() => {
isSyncingFromURL = false;
});
}
} catch (error) {
console.warn(`Error syncing from URL for parameter "${parameterName}":`, error);
}
};
var syncFromURL = syncFromURL2;
if (selectedAdapter.onQueryChange) {
unsubscribeFromURLChanges = selectedAdapter.onQueryChange(syncFromURL2);
} else if (typeof window !== "undefined") {
const handlePopState = () => syncFromURL2();
window.addEventListener("popstate", handlePopState);
unsubscribeFromURLChanges = () => {
window.removeEventListener("popstate", handlePopState);
};
}
}
const componentInstance = (0, import_vue3.getCurrentInstance)();
if (componentInstance !== null) {
(0, import_vue3.onBeforeUnmount)(() => {
try {
stopWatcher();
unsubscribeFromURLChanges?.();
} catch (error) {
console.warn("Error during useQueryRef cleanup:", error);
}
});
}
return queryRef;
}
// src/composables/use-query-reactive.ts
var import_vue4 = require("vue");
var sharedHistoryAdapterInstance2;
function getSharedHistoryAdapter2() {
if (!sharedHistoryAdapterInstance2) {
const { queryAdapter } = createHistoryAdapter();
sharedHistoryAdapterInstance2 = queryAdapter;
}
return sharedHistoryAdapterInstance2;
}
function useQueryReactive(parameterSchema, options = {}) {
const {
historyStrategy = "replace",
queryAdapter: providedAdapter,
enableTwoWaySync = false
} = options;
const componentInstance = (0, import_vue4.getCurrentInstance)();
const injectedAdapter = componentInstance ? useQueryAdapter() : void 0;
const selectedAdapter = providedAdapter ?? injectedAdapter ?? getSharedHistoryAdapter2();
const currentURLQuery = selectedAdapter.getCurrentQuery();
const reactiveState = (0, import_vue4.reactive)({});
Object.keys(parameterSchema).forEach((paramKey) => {
const paramConfig = parameterSchema[paramKey];
try {
const parseValue = paramConfig.parseFunction ?? paramConfig.codec?.parse ?? stringCodec.parse;
const rawValue = currentURLQuery[paramKey] ?? null;
const initialValue = typeof rawValue === "string" && rawValue.length > 0 ? parseValue(rawValue) : paramConfig.defaultValue;
reactiveState[paramKey] = initialValue;
} catch (error) {
console.warn(`Error initializing parameter "${paramKey}":`, error);
reactiveState[paramKey] = paramConfig.defaultValue;
}
});
function serializeStateSubset(stateSubset) {
const serializedQuery = {};
Object.keys(stateSubset).forEach((paramKey) => {
if (!(paramKey in parameterSchema)) {
return;
}
try {
const paramValue = stateSubset[paramKey];
const paramConfig = parameterSchema[paramKey];
const serializeValue = paramConfig.serializeFunction ?? paramConfig.codec?.serialize ?? stringCodec.serialize;
const isDefaultValue = paramConfig.defaultValue !== void 0 && areValuesEqual(paramValue, paramConfig.defaultValue, paramConfig.isEqual);
const shouldOmit = (paramConfig.shouldOmitDefault ?? true) && isDefaultValue;
if (shouldOmit) {
serializedQuery[paramKey] = void 0;
} else {
const serialized = serializeValue(paramValue);
serializedQuery[paramKey] = serialized ?? void 0;
}
} catch (error) {
console.warn(`Error serializing parameter "${paramKey}":`, error);
serializedQuery[paramKey] = void 0;
}
});
return serializedQuery;
}
function syncAllToURL() {
try {
const fullState = {};
Object.keys(parameterSchema).forEach((key) => {
fullState[key] = reactiveState[key];
});
const serializedQuery = serializeStateSubset(fullState);
selectedAdapter.updateQuery(serializedQuery, { historyStrategy });
} catch (error) {
console.warn("Error syncing all parameters to URL:", error);
}
}
let isSyncingFromURL = false;
let isBatchUpdating = false;
const stopWatcher = (0, import_vue4.watch)(
() => {
const stateSnapshot = {};
Object.keys(parameterSchema).forEach((key) => {
stateSnapshot[key] = reactiveState[key];
});
return stateSnapshot;
},
(changedState) => {
if (isSyncingFromURL || isBatchUpdating) {
return;
}
try {
const serializedQuery = serializeStateSubset(changedState);
selectedAdapter.updateQuery(serializedQuery, { historyStrategy });
} catch (error) {
console.warn("Error syncing state changes to URL:", error);
}
},
{
deep: true,
flush: "sync"
// Immediate updates to avoid batching delays
}
);
function updateBatch(updates, batchOptions) {
try {
isBatchUpdating = true;
Object.keys(updates).forEach((key) => {
if (key in parameterSchema) {
reactiveState[key] = updates[key];
}
});
const serializedQuery = serializeStateSubset(updates);
const finalHistoryStrategy = batchOptions?.historyStrategy ?? historyStrategy;
selectedAdapter.updateQuery(serializedQuery, { historyStrategy: finalHistoryStrategy });
} catch (error) {
console.warn("Error during batch update:", error);
} finally {
queueMicrotask(() => {
isBatchUpdating = false;
});
}
}
let unsubscribeFromURLChanges;
if (enableTwoWaySync) {
let syncFromURL2 = function() {
try {
const currentQuery = selectedAdapter.getCurrentQuery();
isSyncingFromURL = true;
try {
Object.keys(parameterSchema).forEach((paramKey) => {
const paramConfig = parameterSchema[paramKey];
const parseValue = paramConfig.parseFunction ?? paramConfig.codec?.parse ?? stringCodec.parse;
const rawValue = currentQuery[paramKey] ?? null;
const parsedValue = typeof rawValue === "string" && rawValue.length > 0 ? parseValue(rawValue) : paramConfig.defaultValue;
reactiveState[paramKey] = parsedValue;
});
} finally {
queueMicrotask(() => {
isSyncingFromURL = false;
});
}
} catch (error) {
console.warn("Error syncing from URL:", error);
}
};
var syncFromURL = syncFromURL2;
if (selectedAdapter.onQueryChange) {
unsubscribeFromURLChanges = selectedAdapter.onQueryChange(syncFromURL2);
} else if (typeof window !== "undefined") {
const handlePopState = () => syncFromURL2();
window.addEventListener("popstate", handlePopState);
unsubscribeFromURLChanges = () => {
window.removeEventListener("popstate", handlePopState);
};
}
}
if (componentInstance) {
(0, import_vue4.onBeforeUnmount)(() => {
try {
stopWatcher();
unsubscribeFromURLChanges?.();
} catch (error) {
console.warn("Error during useQueryReactive cleanup:", error);
}
});
}
return {
queryState: reactiveState,
updateBatch,
syncAllToUrl: syncAllToURL
};
}
// src/adapters/vue-router-adapter.ts
function createVueRouterAdapter(vueRouter, options = {}) {
const { warnOnArrayParams = true } = options;
function normalizeRouterQuery(routerQuery) {
const normalizedQuery = {};
try {
Object.entries(routerQuery).forEach(([key, value]) => {
if (Array.isArray(value)) {
const firstValue = value[0];
normalizedQuery[key] = typeof firstValue === "string" && firstValue.length > 0 ? String(firstValue) : void 0;
if (warnOnArrayParams && value.length > 1) {
console.warn(
`Query parameter "${key}" has multiple values. Only the first value will be used.`,
{ key, values: value }
);
}
} else if (typeof value === "string" && value.length > 0) {
normalizedQuery[key] = String(value);
} else {
normalizedQuery[key] = void 0;
}
});
return normalizedQuery;
} catch (error) {
console.warn("Error normalizing router query:", error);
return {};
}
}
function areQueriesEqual(queryA, queryB) {
try {
const normalizedA = normalizeRouterQuery(queryA);
const normalizedB = normalizeRouterQuery(queryB);
const keysA = Object.keys(normalizedA);
const keysB = Object.keys(normalizedB);
if (keysA.length !== keysB.length) {
return false;
}
return keysA.every((key) => normalizedA[key] === normalizedB[key]);
} catch (error) {
console.warn("Error comparing queries:", error);
return false;
}
}
const queryAdapter = {
getCurrentQuery() {
try {
const currentRoute = vueRouter.currentRoute.value;
return normalizeRouterQuery(currentRoute.query);
} catch (error) {
console.warn("Error getting current query from Vue Router:", error);
return {};
}
},
updateQuery(queryUpdates, updateOptions) {
try {
const currentRoute = vueRouter.currentRoute.value;
const currentQuery = { ...currentRoute.query };
Object.entries(queryUpdates).forEach(([key, value]) => {
if (value === void 0) {
delete currentQuery[key];
} else {
currentQuery[key] = value;
}
});
if (areQueriesEqual(currentRoute.query, currentQuery)) {
return;
}
const historyStrategy = updateOptions?.historyStrategy ?? "replace";
const navigationMethod = historyStrategy === "push" ? vueRouter.push : vueRouter.replace;
navigationMethod.call(vueRouter, {
query: currentQuery
}).catch((error) => {
if (error?.name !== "NavigationDuplicated") {
console.warn("Vue Router navigation error:", error);
}
});
} catch (error) {
console.warn("Error updating query in Vue Router:", error);
}
},
onQueryChange(callback) {
try {
const unsubscribeHook = vueRouter.afterEach(() => {
try {
callback();
} catch (error) {
console.warn("Error in Vue Router query change callback:", error);
}
});
return unsubscribeHook;
} catch (error) {
console.warn("Error setting up Vue Router query change listener:", error);
return () => {
};
}
}
};
return queryAdapter;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
areValuesEqual,
booleanCodec,
buildSearchString,
createArrayCodec,
createEnumCodec,
createHistoryAdapter,
createJsonCodec,
createRuntimeEnvironment,
createVueQsPlugin,
createVueRouterAdapter,
dateISOCodec,
isBrowserEnvironment,
mergeObjects,
numberCodec,
parseSearchString,
provideQueryAdapter,
removeUndefinedValues,
serializers,
stringCodec,
useQueryAdapter,
useQueryReactive,
useQueryRef
});