swr
Version:
React Hooks library for remote data fetching
132 lines (126 loc) • 5.23 kB
JavaScript
Object.defineProperty(exports, '__esModule', { value: true });
var react = require('react');
var useSWR = require('swr');
var _internal = require('swr/_internal');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var useSWR__default = /*#__PURE__*/_interopDefaultLegacy(useSWR);
const mutation = ()=>{
return (key, fetcher, config = {})=>{
const { mutate } = useSWR.useSWRConfig();
const keyRef = react.useRef(key);
const fetcherRef = react.useRef(fetcher);
const configRef = react.useRef(config);
// Ditch all mutation results that happened earlier than this timestamp.
const ditchMutationsUntilRef = react.useRef(0);
const [stateRef, stateDependencies, setState] = _internal.useStateWithDeps({
data: _internal.UNDEFINED,
error: _internal.UNDEFINED,
isMutating: false
});
const currentState = stateRef.current;
const trigger = react.useCallback(async (arg, opts)=>{
const [serializedKey, resolvedKey] = _internal.serialize(keyRef.current);
if (!fetcherRef.current) {
throw new Error('Can’t trigger the mutation: missing fetcher.');
}
if (!serializedKey) {
throw new Error('Can’t trigger the mutation: missing key.');
}
// Disable cache population by default.
const options = _internal.mergeObjects(_internal.mergeObjects({
populateCache: false,
throwOnError: true
}, configRef.current), opts);
// Trigger a mutation, and also track the timestamp. Any mutation that happened
// earlier this timestamp should be ignored.
const mutationStartedAt = _internal.getTimestamp();
ditchMutationsUntilRef.current = mutationStartedAt;
setState({
isMutating: true
});
try {
const data = await mutate(serializedKey, fetcherRef.current(resolvedKey, {
arg
}), // We must throw the error here so we can catch and update the states.
_internal.mergeObjects(options, {
throwOnError: true
}));
// If it's reset after the mutation, we don't broadcast any state change.
if (ditchMutationsUntilRef.current <= mutationStartedAt) {
setState({
data,
isMutating: false,
error: undefined
});
options.onSuccess == null ? void 0 : options.onSuccess(data, serializedKey, options);
}
return data;
} catch (error) {
// If it's reset after the mutation, we don't broadcast any state change
// or throw because it's discarded.
if (ditchMutationsUntilRef.current <= mutationStartedAt) {
setState({
error: error,
isMutating: false
});
options.onError == null ? void 0 : options.onError(error, serializedKey, options);
if (options.throwOnError) {
throw error;
}
}
}
}, // eslint-disable-next-line react-hooks/exhaustive-deps
[]);
const reset = react.useCallback(()=>{
ditchMutationsUntilRef.current = _internal.getTimestamp();
setState({
data: _internal.UNDEFINED,
error: _internal.UNDEFINED,
isMutating: false
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
_internal.useIsomorphicLayoutEffect(()=>{
keyRef.current = key;
fetcherRef.current = fetcher;
configRef.current = config;
});
// We don't return `mutate` here as it can be pretty confusing (e.g. people
// calling `mutate` but they actually mean `trigger`).
// And also, `mutate` relies on the useSWR hook to exist too.
return {
trigger,
reset,
get data () {
stateDependencies.data = true;
return currentState.data;
},
get error () {
stateDependencies.error = true;
return currentState.error;
},
get isMutating () {
stateDependencies.isMutating = true;
return currentState.isMutating;
}
};
};
};
/**
* A hook to define and manually trigger remote mutations like POST, PUT, DELETE and PATCH use cases.
*
* @link https://swr.vercel.app/docs/mutation
* @example
* ```jsx
* import useSWRMutation from 'swr/mutation'
*
* const {
* data,
* error,
* trigger,
* reset,
* isMutating
* } = useSWRMutation(key, fetcher, options?)
* ```
*/ var index = _internal.withMiddleware(useSWR__default["default"], mutation);
exports["default"] = index;