@@ -51,27 +51,32 @@ export function useSubmission<T extends Array<any>, U>(
5151}
5252
5353export function useAction < T extends Array < any > , U > ( action : Action < T , U > ) {
54- const router = useRouter ( ) ;
55- return ( ...args : Parameters < Action < T , U > > ) => action . apply ( router , args ) ;
54+ const r = useRouter ( ) ;
55+ return ( ...args : Parameters < Action < T , U > > ) => action . apply ( { r } , args ) ;
5656}
5757
5858export function action < T extends Array < any > , U = void > (
5959 fn : ( ...args : T ) => Promise < U > ,
6060 name ?: string
6161) : Action < T , U > {
62- function mutate ( this : RouterContext , ...variables : T ) {
63- const router = this ;
62+ function mutate ( this : { r : RouterContext , f ?: HTMLFormElement } , ...variables : T ) {
63+ const router = this . r ;
64+ const form = this . f ;
6465 const p = (
6566 router . singleFlight && ( fn as any ) . withOptions
6667 ? ( fn as any ) . withOptions ( { headers : { "X-Single-Flight" : "true" } } )
6768 : fn
6869 ) ( ...variables ) ;
69- const [ result , setResult ] = createSignal < { data ?: U } > ( ) ;
70+ const [ result , setResult ] = createSignal < { data ?: U , error ?: any } > ( ) ;
7071 let submission : Submission < T , U > ;
71- async function handler ( res : any ) {
72- const data = await handleResponse ( res as any , router . navigatorFactory ( ) ) ;
73- data ? setResult ( { data } ) : submission . clear ( ) ;
74- return data ;
72+ function handler ( error ?: boolean ) {
73+ return async ( res : any ) => {
74+ const result = await handleResponse ( res , error , router . navigatorFactory ( ) ) ;
75+ if ( ! result ) return submission . clear ( ) ;
76+ setResult ( result ) ;
77+ if ( result . error && ! form ) throw result . error ;
78+ return result . data ;
79+ } ;
7580 }
7681 router . submissions [ 1 ] ( s => [
7782 ...s ,
@@ -81,6 +86,9 @@ export function action<T extends Array<any>, U = void>(
8186 get result ( ) {
8287 return result ( ) ?. data ;
8388 } ,
89+ get error ( ) {
90+ return result ( ) ?. error ;
91+ } ,
8492 get pending ( ) {
8593 return ! result ( ) ;
8694 } ,
@@ -90,11 +98,11 @@ export function action<T extends Array<any>, U = void>(
9098 retry ( ) {
9199 setResult ( undefined ) ;
92100 const p = fn ( ...variables ) ;
93- return p . then ( handler , handler ) ;
101+ return p . then ( handler ( ) , handler ( true ) ) ;
94102 }
95103 } )
96104 ] ) ;
97- return p . then ( handler , handler ) ;
105+ return p . then ( handler ( ) , handler ( true ) ) ;
98106 }
99107
100108 const url : string =
@@ -134,7 +142,7 @@ function toAction<T extends Array<any>, U>(fn: Function, url: string): Action<T,
134142const hashString = ( s : string ) =>
135143 s . split ( "" ) . reduce ( ( a , b ) => ( ( a << 5 ) - a + b . charCodeAt ( 0 ) ) | 0 , 0 ) ;
136144
137- async function handleResponse ( response : Response , navigate : Navigator ) {
145+ async function handleResponse ( response : unknown , error : boolean | undefined , navigate : Navigator ) {
138146 let data : any ;
139147 let keys : string [ ] | undefined ;
140148 let invalidateKeys : string [ ] | undefined ;
@@ -162,10 +170,11 @@ async function handleResponse(response: Response, navigate: Navigator) {
162170 navigate ( locationUrl ) ;
163171 }
164172 }
165- } else data = response ;
173+ } else if ( error ) return { error : response } ;
174+ else data = response ;
166175 // invalidate
167176 cacheKeyOp ( invalidateKeys , entry => ( entry [ 0 ] = 0 ) ) ;
168177 // trigger revalidation
169178 await revalidate ( keys , false ) ;
170- return data ;
179+ return data != null ? { data } : undefined ;
171180}
0 commit comments