diff --git a/lib/hyperscript/compiler.sx b/lib/hyperscript/compiler.sx index 7d296f3e..7fd27959 100644 --- a/lib/hyperscript/compiler.sx +++ b/lib/hyperscript/compiler.sx @@ -1832,7 +1832,7 @@ (list (quote fn) (list) (hs-to-sx (nth ast 1))) (list (quote fn) (list) (hs-to-sx (nth ast 2))))) ((= head (quote fetch)) - (list (quote hs-fetch) (hs-to-sx (nth ast 1)) (nth ast 2) (nth ast 3))) + (list (quote hs-fetch) (hs-to-sx (nth ast 1)) (nth ast 2) (nth ast 3) (quote me))) ((= head (quote fetch-gql)) (list (quote hs-fetch-gql) diff --git a/lib/hyperscript/runtime.sx b/lib/hyperscript/runtime.sx index 7a749487..c8f3a4cc 100644 --- a/lib/hyperscript/runtime.sx +++ b/lib/hyperscript/runtime.sx @@ -874,12 +874,15 @@ (define hs-fetch (fn - (url format do-not-throw) + (url format do-not-throw target) (let ((fmt (cond ((nil? format) "text") ((or (= format "json") (= format "JSON") (= format "Object")) "json") ((or (= format "html") (= format "HTML")) "html") ((or (= format "response") (= format "Response")) "response") ((or (= format "text") (= format "Text")) "text") ((or (= format "number") (= format "Number")) "number") (true format)))) - (let - ((raw (perform (list "io-fetch" url "response" (dict))))) - (do + (do + (when (not (nil? target)) + (dom-dispatch target "hyperscript:beforeFetch" nil)) + (let + ((raw (perform (list "io-fetch" url "response" (dict))))) + (do (when (get raw :_network-error) (raise {:response raw :message "Network error" :_hs-error "FetchError"})) (when (and (not (get raw :ok)) (not (= fmt "response")) (not do-not-throw)) @@ -897,7 +900,7 @@ (parse-number (get raw :_number)) (parse-number (get raw :_body)) 0)) - (true (get raw :_body)))))))) + (true (get raw :_body))))))))) (define hs-json-escape diff --git a/shared/static/wasm/sx/hs-compiler.sx b/shared/static/wasm/sx/hs-compiler.sx index 7d296f3e..7fd27959 100644 --- a/shared/static/wasm/sx/hs-compiler.sx +++ b/shared/static/wasm/sx/hs-compiler.sx @@ -1832,7 +1832,7 @@ (list (quote fn) (list) (hs-to-sx (nth ast 1))) (list (quote fn) (list) (hs-to-sx (nth ast 2))))) ((= head (quote fetch)) - (list (quote hs-fetch) (hs-to-sx (nth ast 1)) (nth ast 2) (nth ast 3))) + (list (quote hs-fetch) (hs-to-sx (nth ast 1)) (nth ast 2) (nth ast 3) (quote me))) ((= head (quote fetch-gql)) (list (quote hs-fetch-gql) diff --git a/shared/static/wasm/sx/hs-runtime.sx b/shared/static/wasm/sx/hs-runtime.sx index 7a749487..c8f3a4cc 100644 --- a/shared/static/wasm/sx/hs-runtime.sx +++ b/shared/static/wasm/sx/hs-runtime.sx @@ -874,12 +874,15 @@ (define hs-fetch (fn - (url format do-not-throw) + (url format do-not-throw target) (let ((fmt (cond ((nil? format) "text") ((or (= format "json") (= format "JSON") (= format "Object")) "json") ((or (= format "html") (= format "HTML")) "html") ((or (= format "response") (= format "Response")) "response") ((or (= format "text") (= format "Text")) "text") ((or (= format "number") (= format "Number")) "number") (true format)))) - (let - ((raw (perform (list "io-fetch" url "response" (dict))))) - (do + (do + (when (not (nil? target)) + (dom-dispatch target "hyperscript:beforeFetch" nil)) + (let + ((raw (perform (list "io-fetch" url "response" (dict))))) + (do (when (get raw :_network-error) (raise {:response raw :message "Network error" :_hs-error "FetchError"})) (when (and (not (get raw :ok)) (not (= fmt "response")) (not do-not-throw)) @@ -897,7 +900,7 @@ (parse-number (get raw :_number)) (parse-number (get raw :_body)) 0)) - (true (get raw :_body)))))))) + (true (get raw :_body))))))))) (define hs-json-escape diff --git a/tests/hs-run-filtered.js b/tests/hs-run-filtered.js index 1495788d..ba38cacd 100755 --- a/tests/hs-run-filtered.js +++ b/tests/hs-run-filtered.js @@ -603,15 +603,10 @@ globalThis._driveAsync=function driveAsync(r,d){d=d||0;if(d>500||!r||!r.suspende if(opName==='io-sleep'||opName==='wait')doResume(null); else if(opName==='io-fetch'){ const url=typeof items[1]==='string'?items[1]:'/test'; - const fmt=typeof items[2]==='string'?items[2]:'text'; const scriptRoutes=_fetchScripts[globalThis.__currentHsTestName]; const route=(scriptRoutes&&scriptRoutes[url])||_fetchRoutes[url]||_fetchRoutes['/test']; - if(route&&route.networkError){doResume({_network_error:true,message:'aborted'});} - else if(fmt==='json'){try{doResume(JSON.parse(route.json||route.body||'{}'));}catch(e){doResume(null);}} - else if(fmt==='html'){const frag=new El('fragment');frag.nodeType=11;frag.innerHTML=route.html||route.body||'';frag.textContent=frag.innerHTML.replace(/<[^>]*>/g,'');doResume(frag);} - else if(fmt==='response')doResume({ok:(route.status||200)<400,status:route.status||200,url}); - else if(fmt.toLowerCase()==='number')doResume(parseFloat(route.number||route.body||'0')); - else doResume(route.body||''); + if(route&&route.networkError){doResume({_type:'dict','_network-error':true,message:'aborted'});} + else{const st=route.status||200;doResume({_type:'dict',ok:st<400,status:st,url,_body:route.body||'',_json:route.json||route.body||'',_html:route.html||route.body||'',_number:route.number||route.body||''});} } else if(opName==='io-parse-text'){const resp=items&&items[1];doResume(resp&&resp._body?resp._body:typeof resp==='string'?resp:'');} else if(opName==='io-parse-json'){const resp=items&&items[1];try{doResume(JSON.parse(typeof resp==='string'?resp:resp&&resp._json?resp._json:'{}'));}catch(e){doResume(null);}}