@slan-health/taro-vueuse
Version:
taro vue版本hooks
139 lines (138 loc) • 3.88 kB
JavaScript
import { ref, shallowRef } from "vue";
import { resolvedPromise, isFunction, shallowCopy } from "./utils/index.js";
const setStateBind = (oldState, publicCb) => {
return (newState) => {
Object.keys(newState).forEach((key) => {
oldState[key].value = newState[key];
});
publicCb.forEach((fun) => fun(oldState));
};
};
const composeMiddleware = (middleArray, hook) => {
return () => {
let next = hook;
for (let i = middleArray.length; i-- > 0; ) {
next = middleArray[i](next);
}
return next();
};
};
const createQuery = (service, config, initialState) => {
const { initialData, onSuccess, onError, onBefore, onAfter } = config;
const loading = ref(false);
const data = ref(initialData);
const error = shallowRef(initialState == null ? void 0 : initialState.error);
const params = ref(initialState == null ? void 0 : initialState.params);
const plugins = ref([]);
const status = shallowRef("pending");
const context = {};
const setState = setStateBind(
{
status,
loading,
data,
error,
params
},
[]
);
const emit = (event, ...args) => {
if (event === "onQuery") {
const queryFn = plugins.value.map((i) => i.onQuery).filter(Boolean);
return { servicePromise: composeMiddleware(queryFn, args[0])() };
} else {
const res = plugins.value.map((i) => {
var _a;
return (_a = i[event]) == null ? void 0 : _a.call(i, ...args);
});
return Object.assign({}, ...res);
}
};
const count = ref(0);
context.runAsync = async (...args) => {
setState({
loading: true,
params: args,
status: "pending"
});
count.value += 1;
const currentCount = count.value;
const { isBreak, breakResult = resolvedPromise() } = emit("onBefore", args);
if (isBreak) {
setState({ status: "settled" });
return breakResult;
}
onBefore == null ? void 0 : onBefore(args);
try {
const serviceWrapper = () => new Promise((resolve) => resolve(service(...params.value)));
let { servicePromise } = emit("onQuery", serviceWrapper);
if (!servicePromise) {
servicePromise = serviceWrapper();
}
const res = await servicePromise;
if (currentCount !== count.value) return resolvedPromise();
setState({
data: res,
loading: false,
error: void 0,
status: "settled"
});
emit("onSuccess", res, args);
onSuccess == null ? void 0 : onSuccess(res, args);
emit("onAfter", args, res, void 0);
onAfter == null ? void 0 : onAfter(args);
return res;
} catch (error2) {
if (currentCount !== count.value) return resolvedPromise();
setState({
loading: false,
error: error2,
status: "settled"
});
emit("onError", error2, args);
onError == null ? void 0 : onError(error2, args);
emit("onAfter", args, void 0, error2);
onAfter == null ? void 0 : onAfter(args);
throw error2;
}
};
context.run = async (...args) => {
context.runAsync(...args).catch((error2) => {
if (!onError) {
console.error(error2);
}
});
};
context.cancel = () => {
count.value += 1;
setState({ loading: false });
emit("onCancel");
};
context.refresh = () => {
context.run(...params.value || []);
};
context.refreshAsync = () => {
return context.runAsync(...params.value || []);
};
context.mutate = (x) => {
const mutateData = isFunction(x) ? x(data.value) : x;
const _mutateData = shallowCopy(mutateData);
setState({
data: _mutateData
});
emit("onMutate", _mutateData);
};
return {
status,
loading,
data,
error,
params,
plugins,
context
};
};
export {
createQuery as default
};
//# sourceMappingURL=createQuery.js.map