@trpc/next
Version:
109 lines (105 loc) • 3.9 kB
JavaScript
var client = require('@trpc/client');
var unstableInternals = require('@trpc/client/unstable-internals');
var observable = require('@trpc/server/observable');
var unstableCoreDoNotImport = require('@trpc/server/unstable-core-do-not-import');
var React = require('react');
var shared = require('./shared.js');
// ts-prune-ignore-next
function experimental_serverActionLink(...args) {
const [opts] = args;
const transformer = unstableInternals.getTransformer(opts?.transformer);
return ()=>({ op })=>observable.observable((observer)=>{
const context = op.context;
context._action(shared.isFormData(op.input) ? op.input : transformer.input.serialize(op.input)).then((data)=>{
const transformed = unstableCoreDoNotImport.transformResult(data, transformer.output);
if (!transformed.ok) {
observer.error(client.TRPCClientError.from(transformed.error, {}));
return;
}
observer.next({
context: op.context,
result: transformed.result
});
observer.complete();
}).catch((cause)=>{
observer.error(client.TRPCClientError.from(cause));
});
});
}
// ts-prune-ignore-next
function experimental_createActionHook(opts) {
const client$1 = client.createTRPCUntypedClient(opts);
return function useAction(handler, useActionOpts) {
const count = React.useRef(0);
const [state, setState] = React.useState({
status: 'idle'
});
const actionOptsRef = React.useRef(useActionOpts);
actionOptsRef.current = useActionOpts;
React.useEffect(()=>{
return ()=>{
// cleanup after unmount to prevent calling hook opts after unmount
count.current = -1;
actionOptsRef.current = undefined;
};
}, []);
const mutateAsync = React.useCallback((input, requestOptions)=>{
const idx = ++count.current;
const context = {
...requestOptions?.context,
_action (innerInput) {
return handler(innerInput);
}
};
setState({
status: 'loading'
});
return client$1.mutation('serverAction', input, {
...requestOptions,
context
}).then(async (data)=>{
await actionOptsRef.current?.onSuccess?.(data);
if (idx !== count.current) {
return;
}
setState({
status: 'success',
data: data
});
}).catch(async (error)=>{
await actionOptsRef.current?.onError?.(error);
throw error;
}).catch((error)=>{
if (idx !== count.current) {
return;
}
setState({
status: 'error',
error: client.TRPCClientError.from(error, {})
});
throw error;
});
}, [
handler
]);
const mutate = React.useCallback((...args)=>{
void mutateAsync(...args).catch(()=>{
// ignored
});
}, [
mutateAsync
]);
return React.useMemo(()=>({
...state,
mutate,
mutateAsync
}), [
mutate,
mutateAsync,
state
]);
};
}
exports.experimental_createActionHook = experimental_createActionHook;
exports.experimental_serverActionLink = experimental_serverActionLink;
;