code wiki / _hdl_build / nx_js_pending_fetch_gate.nx

nx_js_pending_fetch_gate.nx source

↩ module page · 77 lines · 4294 B

1import "nx_gate_gn.nx" 2import "nx_gate_base.nx" 3// nx_js_pending_fetch_gate.nx -- proves the PENDING-FETCH loop mechanism (the real-web unlock): a fetch to 4// a NON-data (https) URL becomes a PENDING request + a pending promise; after run+drain the page is NOT yet 5// hydrated; the consumer enumerates pending (js_pending_count/url), SERVICES it (js_pending_service, as a 6// real TLS consumer would), el_drains, and the promise chain hydrates. Hermetic (the gate plays consumer). 7// license_tier: ORIGINAL 8import "nx_js_eval.nx" 9 10func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 11" as *u8); return ok } 12func gsl(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 13 14// read the global string `name` from genv; 1 if it equals `want`, else 0 (prints). 15func expect_g(label: *u8, genv: *i64, name: *u8, want: *u8, pp: *i64, tp: *i64) -> i64 { 16 tp[0] = tp[0] + 1 17 let out: *i64 = sys_mmap(16) as *i64 18 gw(" "); gw(label); gw(": " as *u8) 19 if env_get(genv, name, 0, gsl(name), out) != 0 { gw("FAIL (undeclared)\n" as *u8); return 0 } 20 if out[0] != VAL_STR { gw("FAIL (not a string)\n" as *u8); return 0 } 21 let rec: *i64 = (out[1]) as *i64 22 let wl: i64 = gsl(want) 23 if ev_str_len(rec) != wl { gw("FAIL (got '" as *u8); sys_write(1, ev_str_bytes(rec), ev_str_len(rec)); gw("')\n" as *u8); return 0 } 24 let rb: *u8 = ev_str_bytes(rec) 25 var i: i64 = 0 26 while i < wl { if (rb[i] & 0xff) != (want[i] & 0xff) { gw("FAIL (mismatch)\n" as *u8); return 0 } i = i + 1 } 27 pp[0] = pp[0] + 1; gw("ok ('" as *u8); gw(want); gw("')\n" as *u8); return 1 28} 29func chk(cond: i64, label: *u8, pp: *i64, tp: *i64) -> i64 { 30 tp[0] = tp[0] + 1; gw(" "); gw(label) 31 if cond == 1 { pp[0] = pp[0] + 1; gw(": ok\n" as *u8) } else { gw(": FAIL\n" as *u8) } 32 return 0 33} 34 35func main(argc: i64, argv: *i64) -> i64 { 36 gw("=== nx_js_pending_fetch_gate: fetch(https) -> PEND -> service -> hydrate ===\n" as *u8) 37 let pp: *i64 = sys_mmap(8) as *i64; pp[0] = 0 38 let tp: *i64 = sys_mmap(8) as *i64; tp[0] = 0 39 40 let ob: *i64 = sys_mmap(16) as *i64 41 let src1: *u8 = "var log='waiting';fetch('https://api/d').then(function(r){return r.text();}).then(function(t){log=t;});" as *u8 42 js_run_source_keep(src1, gsl(src1), ob) 43 let ctx: *i64 = (ob[0]) as *i64 44 let genv: *i64 = (ob[1]) as *i64 45 46 // T1: fetch(https) is PENDING -- after the initial drain the page is NOT hydrated yet. 47 expect_g("T1 unhydrated after drain" as *u8, genv, "log\x00" as *u8, "waiting" as *u8, pp, tp) 48 // T2: exactly one pending request enumerated. 49 chk(js_pending_count(genv) == 1, "T2 pending count == 1\x00" as *u8, pp, tp) 50 // T3: the consumer can read the pending URL. 51 let urlbuf: *u8 = sys_mmap(256) 52 let ul: i64 = js_pending_url(genv, 0, urlbuf, 256) 53 var urlok: i64 = 0 54 if ul == 13 { var i: i64 = 0; var m: i64 = 1; let want: *u8 = "https://api/d\x00" as *u8 55 while i < 13 { if (urlbuf[i] & 0xff) != (want[i] & 0xff) { m = 0 } i = i + 1 } urlok = m } 56 chk(urlok == 1, "T3 pending url == https://api/d\x00" as *u8, pp, tp) 57 58 // SERVICE it (as a TLS consumer would), then drain -> the promise chain hydrates. 59 js_pending_service(ctx, genv, 0, 200, "HYDRATED42" as *u8, 10) 60 el_drain(ctx, genv) 61 // T4: THE UNLOCK -- serviced fetch hydrated the page. 62 expect_g("T4 serviced -> hydrated" as *u8, genv, "log\x00" as *u8, "HYDRATED42" as *u8, pp, tp) 63 // T5: no pending left. 64 chk(js_pending_count(genv) == 0, "T5 pending drained to 0\x00" as *u8, pp, tp) 65 66 // T6: a data: fetch does NOT pend (resolves inline in the first drain). 67 let ob2: *i64 = sys_mmap(16) as *i64 68 let src2: *u8 = "var x='';fetch('data:,inline').then(function(r){return r.text();}).then(function(t){x=t;});" as *u8 69 js_run_source_keep(src2, gsl(src2), ob2) 70 let genv2: *i64 = (ob2[1]) as *i64 71 chk(js_pending_count(genv2) == 0, "T6 data: fetch does NOT pend\x00" as *u8, pp, tp) 72 expect_g("T6b data: hydrated inline" as *u8, genv2, "x\x00" as *u8, "inline" as *u8, pp, tp) 73 74 gw("=== "); gn(pp[0]); gw("/"); gn(tp[0]); gw(" "); if pp[0] == tp[0] { gw("GREEN ===\n" as *u8) } else { gw("RED ===\n" as *u8) } 75 if pp[0] == tp[0] { return 0 } 76 return 1 77}