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}