@@ -364,6 +364,58 @@ <h2>
364364es.close();</ pre >
365365 </ div >
366366
367+ < h2 >
368+ 7. Native < code > fetch()</ code > — call & publish over HTTP
369+ < span class ="badge "> no SDK</ span >
370+ </ h2 >
371+ < p style ="font-size: 0.9em; color: #555 ">
372+ The < code > curl</ code > commands in section 5 translate one-to-one to the
373+ browser's < code > fetch()</ code > API — same method, URL, headers and JSON
374+ body. Because the runtime sends CORS headers
375+ (< code > new HttpTransport({ cors: true })</ code > ), these cross-origin
376+ requests succeed straight from the page (served on < code > :8080</ code > ,
377+ runtime on < code > :9001</ code > ). < code > call</ code > returns
378+ < code > 200</ code > + a JSON reply; < code > publish</ code > returns
379+ < code > 204 No Content</ code > . The publish lands on the same
380+ < code > /web_demo_chatter</ code > topic as panels 2 and 3, so it also shows
381+ up in their logs.
382+ </ p >
383+ < div class ="panel ">
384+ < div class ="controls ">
385+ < div class ="row ">
386+ < button id ="fetchCallBtn "> fetch call < code > /add_two_ints</ code > </ button >
387+ < button id ="fetchPubBtn ">
388+ fetch publish < code > /web_demo_chatter</ code >
389+ </ button >
390+ </ div >
391+ < div class ="log " id ="fetchLog "> </ div >
392+ </ div >
393+ < pre
394+ class ="code "
395+ > < span class ="com "> // No import — fetch() is built into every browser.</ span >
396+ < span class ="com "> // Service call → 200 + JSON reply:</ span >
397+ < span class ="kw "> const</ span > res = < span class ="kw "> await</ span > fetch(
398+ < span class ="str "> 'http://localhost:9001/capability/call/add_two_ints'</ span > ,
399+ {
400+ method: < span class ="str "> 'POST'</ span > ,
401+ headers: { < span class ="str "> 'content-type'</ span > : < span class ="str "> 'application/json'</ span > },
402+ body: JSON.stringify({ a: < span class ="str "> '7n'</ span > , b: < span class ="str "> '35n'</ span > }),
403+ },
404+ );
405+ < span class ="kw "> const</ span > reply = < span class ="kw "> await</ span > res.json();
406+ console.log(reply.sum); < span class ="com "> // '42n'</ span >
407+
408+ < span class ="com "> // Topic publish → 204 No Content (no body):</ span >
409+ < span class ="kw "> await</ span > fetch(
410+ < span class ="str "> 'http://localhost:9001/capability/publish/web_demo_chatter'</ span > ,
411+ {
412+ method: < span class ="str "> 'POST'</ span > ,
413+ headers: { < span class ="str "> 'content-type'</ span > : < span class ="str "> 'application/json'</ span > },
414+ body: JSON.stringify({ data: < span class ="str "> 'hello from fetch()'</ span > }),
415+ },
416+ );</ pre >
417+ </ div >
418+
367419 < script type ="module ">
368420 import { connect } from '/sdk/index.js' ;
369421
@@ -570,6 +622,47 @@ <h2>
570622 log ( 'sseLog' , 'closed' , 'ok' ) ;
571623 } ;
572624
625+ // Native fetch() — call/publish straight to the HTTP transport,
626+ // no SDK and no WebSocket. CORS on the runtime lets these
627+ // cross-origin requests (page on :8080 → runtime on :9001)
628+ // succeed. Independent of the WS/HTTP transport toggle above.
629+ document . getElementById ( 'fetchCallBtn' ) . onclick = async ( ) => {
630+ try {
631+ const res = await fetch (
632+ `${ ENDPOINTS . http } /capability/call/add_two_ints` ,
633+ {
634+ method : 'POST' ,
635+ headers : { 'content-type' : 'application/json' } ,
636+ body : JSON . stringify ( { a : '7n' , b : '35n' } ) ,
637+ }
638+ ) ;
639+ const reply = await res . json ( ) ;
640+ log ( 'fetchLog' , `7 + 35 = ${ reply . sum } (HTTP ${ res . status } )` , 'ok' ) ;
641+ } catch ( e ) {
642+ log ( 'fetchLog' , `call error: ${ e . message } ` , 'err' ) ;
643+ }
644+ } ;
645+ document . getElementById ( 'fetchPubBtn' ) . onclick = async ( ) => {
646+ try {
647+ const res = await fetch (
648+ `${ ENDPOINTS . http } /capability/publish/web_demo_chatter` ,
649+ {
650+ method : 'POST' ,
651+ headers : { 'content-type' : 'application/json' } ,
652+ body : JSON . stringify ( { data : 'hello from fetch()' } ) ,
653+ }
654+ ) ;
655+ // publish replies 204 No Content on success.
656+ log (
657+ 'fetchLog' ,
658+ `published 'hello from fetch()' (HTTP ${ res . status } )` ,
659+ res . ok ? 'ok' : 'err'
660+ ) ;
661+ } catch ( e ) {
662+ log ( 'fetchLog' , `publish error: ${ e . message } ` , 'err' ) ;
663+ }
664+ } ;
665+
573666 for ( const radio of document . querySelectorAll (
574667 'input[name="transport"]'
575668 ) ) {
0 commit comments