vue-use-route-query
Version:
197 lines (196 loc) • 5.81 kB
JavaScript
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
import { computed, getCurrentInstance, reactive, watch } from "vue-demi";
import { createAsyncQueue } from "async-queue-chain";
const stringTransformer = {
fromQuery(value) {
return value || void 0;
},
toQuery(value) {
return value;
}
};
const integerTransformer = {
fromQuery(value) {
const numberValue = Number.parseInt(value, 10);
if (!Number.isInteger(numberValue)) {
return void 0;
}
return numberValue;
},
toQuery(value) {
return value == null ? void 0 : value.toString();
}
};
const floatTransformer = {
fromQuery(value) {
const numberValue = Number.parseFloat(value);
if (Number.isNaN(numberValue)) {
return void 0;
}
return numberValue;
},
toQuery(value) {
return value == null ? void 0 : value.toString();
}
};
const booleanTransformer = {
fromQuery(value) {
if (value === "true") {
return true;
}
if (value === "false") {
return false;
}
return void 0;
},
toQuery(value) {
return value == null ? void 0 : value.toString();
}
};
function enumTransformer(enumObject) {
return {
fromQuery(key) {
return enumObject[key];
},
toQuery(value) {
const entry = Object.entries(enumObject).find(([, val]) => val === value);
return entry ? entry[0] : void 0;
}
};
}
function useRouter() {
const vm = getCurrentInstance();
if (!vm) {
throw new ReferenceError("Not found vue instance.");
}
return vm.proxy.$router;
}
function useRoute() {
const vm = getCurrentInstance();
if (!vm) {
throw new ReferenceError("Not found vue instance.");
}
return computed(() => vm.proxy.$route);
}
function removeEmptyValues(object) {
return Object.fromEntries(Object.entries(object).filter(([, value]) => !isEmpty(value)));
}
function isEmpty(value) {
return value === null || value === void 0 || value === "";
}
function isObject(value) {
return typeof value === "object" && value !== null;
}
let queryReplaceQueue;
function queueQueryUpdate(router, currentQuery, key, newValue, mode) {
if (!queryReplaceQueue) {
queryReplaceQueue = createAsyncQueue();
}
queryReplaceQueue.add((previousQuery) => {
const newQuery = removeEmptyValues(__spreadProps(__spreadValues({}, previousQuery), {
[key]: newValue
}));
return updateQuery(router, previousQuery, newQuery, mode);
});
void queryReplaceQueue.run(currentQuery);
}
async function waitForQueryUpdate() {
if (queryReplaceQueue) {
await queryReplaceQueue.waitForFinish();
}
}
async function updateQuery(router, previousQuery, query, mode) {
try {
await router[mode]({
query
});
return query;
} catch (e) {
return previousQuery;
}
}
function useRouteQuery(key, defaultValue, transformerOrOptions, optionsParam) {
const route = useRoute();
const router = useRouter();
const [transformer, options] = extractTransformerAndOptions(transformerOrOptions, optionsParam);
const navigationMode = (options == null ? void 0 : options.mode) || "replace";
function updateQueryParam(newValue) {
queueQueryUpdate(router, route.value.query, key, newValue, navigationMode);
}
function get() {
if (!(key in route.value.query)) {
return defaultValue;
}
const value = getQueryValue(route.value.query, key);
if (!value) {
return defaultValue;
}
if (!transformer) {
return value;
}
const transformedValue = transformer.fromQuery(value);
if (transformedValue === void 0) {
return defaultValue;
}
return transformedValue;
}
function set(value) {
if (!transformer) {
updateQueryParam(value);
return;
}
const transformedValue = transformer.toQuery(value != null ? value : void 0);
updateQueryParam(transformedValue);
}
let valueWatchStopHandle;
return computed({
get() {
const value = get();
if (isObject(value)) {
const reactiveValue = reactive(value);
valueWatchStopHandle == null ? void 0 : valueWatchStopHandle();
valueWatchStopHandle = watch(reactiveValue, (newValue) => {
set(newValue);
});
return reactiveValue;
}
return value;
},
set(value) {
valueWatchStopHandle == null ? void 0 : valueWatchStopHandle();
set(value);
}
});
}
function getQueryValue(query, key) {
const value = query[key];
if (Array.isArray(value)) {
return value[0];
}
return value;
}
function extractTransformerAndOptions(transformerOrOptions, options) {
return isTransformer(transformerOrOptions) ? [transformerOrOptions, options] : [void 0, transformerOrOptions || options];
}
function isTransformer(transformerOrOptions) {
return !!transformerOrOptions && "fromQuery" in transformerOrOptions && "toQuery" in transformerOrOptions;
}
export { booleanTransformer, enumTransformer, floatTransformer, integerTransformer, stringTransformer, useRouteQuery, waitForQueryUpdate };