@@ -315,11 +315,6 @@ type FormDataOptions = Partial<{
315315 keepFiles : boolean ;
316316} > ;
317317
318- type FormUpdate = (
319- result : Exclude < ActionResult , { type : 'error' } > ,
320- untaint ?: boolean
321- ) => Promise < void > ;
322-
323318const formIds = new WeakMap < Page , Set < string | undefined > > ( ) ;
324319const initialForms = new WeakMap <
325320 object ,
@@ -870,7 +865,7 @@ export function superForm<
870865 Errors . set ( output as ValidationErrors < T > ) ;
871866 }
872867
873- function Form_set ( data : T , options : FormDataOptions = { } ) {
868+ function Form_set ( data : Partial < T > , options : FormDataOptions = { } ) {
874869 // Check if file fields should be kept, usually when the server returns them as undefined.
875870 // in that case remove the undefined field from the new data.
876871 if ( options . keepFiles ) {
@@ -886,7 +881,7 @@ export function superForm<
886881 }
887882 } ) ;
888883 }
889- return Form . set ( data , options ) ;
884+ return Form . update ( ( $form ) => ( { ... $form , ... data } ) , options ) ;
890885 }
891886
892887 function Form_shouldReset ( validForm : boolean , successActionResult : boolean ) {
@@ -902,7 +897,11 @@ export function superForm<
902897 if ( form . valid && successResult && Form_shouldReset ( form . valid , successResult ) ) {
903898 Form_reset ( { message : form . message , posted : true } ) ;
904899 } else {
905- rebind ( { form, untaint : successResult , keepFiles : true } ) ;
900+ rebind ( {
901+ form,
902+ untaint : successResult ,
903+ keepFiles : true
904+ } ) ;
906905 }
907906
908907 // onUpdated may check stores, so need to wait for them to update.
@@ -917,7 +916,12 @@ export function superForm<
917916 }
918917
919918 function Form_reset (
920- opts : { message ?: M ; data ?: Partial < T > ; id ?: string ; posted ?: boolean } = { }
919+ opts : {
920+ message ?: M ;
921+ data ?: Partial < T > ;
922+ id ?: string ;
923+ posted ?: boolean ;
924+ } = { }
921925 ) {
922926 const resetData = clone ( initialForm ) ;
923927 resetData . data = { ...resetData . data , ...opts . data } ;
@@ -932,7 +936,7 @@ export function superForm<
932936 } ) ;
933937 }
934938
935- const Form_updateFromActionResult : FormUpdate = async ( result ) => {
939+ async function Form_updateFromActionResult ( result : Exclude < ActionResult , { type : 'error' } > ) {
936940 if ( result . type == ( 'error' as string ) ) {
937941 throw new SuperFormError (
938942 `ActionResult of type "${ result . type } " cannot be passed to update function.`
@@ -964,7 +968,7 @@ export function superForm<
964968 result . status >= 200 && result . status < 300
965969 ) ;
966970 }
967- } ;
971+ }
968972
969973 //#endregion
970974
@@ -1188,25 +1192,39 @@ export function superForm<
11881192 // tainted dialog when a form doesn't use it or the browser doesn't use JS.
11891193 options . taintedMessage = undefined ;
11901194
1191- // Role rebinding
1192- function rebind ( opts : {
1195+ function rebindPage ( opts : {
11931196 form : SuperValidated < T , M , In > ;
11941197 untaint : TaintedFields < T > | boolean ;
1195- message ?: M ;
11961198 keepFiles ?: boolean ;
1197- posted ?: boolean ;
11981199 } ) {
1199- //console.log('🚀 ~ file: superForm.ts:721 ~ rebind ~ form:', form.data); //debug
12001200 const form = opts . form ;
1201- const message = opts . message ?? form . message ;
12021201
12031202 if ( opts . untaint ) {
12041203 Tainted_set ( typeof opts . untaint === 'boolean' ? undefined : opts . untaint , form . data ) ;
12051204 }
12061205
12071206 // Form data is not tainted when rebinding.
12081207 // Prevents object errors from being revalidated after rebind.
1208+ // Check if form was invalidated (usually with options.invalidateAll) to prevent data from being
1209+ // overwritten by the load function data
12091210 Form_set ( form . data , { taint : 'ignore' , keepFiles : opts . keepFiles } ) ;
1211+ }
1212+
1213+ // Role rebinding
1214+ function rebind ( opts : {
1215+ form : SuperValidated < T , M , In > ;
1216+ untaint : TaintedFields < T > | boolean ;
1217+ message ?: M ;
1218+ keepFiles ?: boolean ;
1219+ posted ?: boolean ;
1220+ } ) {
1221+ //console.log('🚀 ~ file: superForm.ts:721 ~ rebind ~ form:', form.data); //debug
1222+
1223+ rebindPage ( { ...opts } ) ;
1224+
1225+ const form = opts . form ;
1226+ const message = opts . message ?? form . message ;
1227+
12101228 Message . set ( message ) ;
12111229 Errors . set ( form . errors ) ;
12121230 FormId . set ( form . id ) ;
@@ -1283,13 +1301,6 @@ export function superForm<
12831301 // Need to subscribe to catch page invalidation.
12841302 Unsubscriptions_add (
12851303 page . subscribe ( async ( pageUpdate ) => {
1286- // Strange timing issue in SPA mode forces a wait here,
1287- // otherwise errors will appear even if the form is valid
1288- // when pressing enter to submit the form (not when clicking a submit button!)
1289- if ( options . SPA ) {
1290- await new Promise ( ( r ) => setTimeout ( r , 0 ) ) ;
1291- }
1292-
12931304 const successResult = pageUpdate . status >= 200 && pageUpdate . status < 300 ;
12941305
12951306 if ( options . applyAction && pageUpdate . form && typeof pageUpdate . form === 'object' ) {
@@ -1830,7 +1841,7 @@ export function superForm<
18301841 // This will trigger the page subscription in superForm,
18311842 // which will in turn call Data_update.
18321843 await applyAction ( result ) ;
1833- } else if ( result . type !== 'success' || ! options . invalidateAll ) {
1844+ } else {
18341845 // Call Data_update directly to trigger events
18351846 await Form_updateFromActionResult ( result ) ;
18361847 }
0 commit comments