code wiki / (root) / nx_family_hub.nx

nx_family_hub.nx source

↩ module page · 118 lines · 7832 B

1// nx_family_hub.nx -- EMIT nishifamily.com/hub, AUTO-GENERATED from the sovereign 2// app registry (nx_app_store / seg_store). No hardcoded cards, no TSV: publish an 3// app into the store and it appears here automatically, grouped by category, with 4// CAD featured. Organ-authored; published via nx_aw_push to /hub/index.html. 5// license_tier: ORIGINAL 6import "nx_syscalls.nx" 7import "nx_app_store.nx" 8const HUB_MAGIC_8192: i64 = 8192 9const HUB_MAGIC_1024: i64 = 1024 10const HUB_MAGIC_65536: i64 = 65536 11 12const HUB_OUT: *u8 = "web_assets/hub.html" 13const HUB_CAP: i64 = 131072 14 15func cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){ dst[off+i]=s[i]; i=i+1 } return off+i } 16func catn(dst: *u8, off: i64, v: i64) -> i64 { 17 var o: i64=off; var n: i64=v; if n<0 { dst[o]=45 as u8; o=o+1; n=0-n } 18 let t: *u8=sys_mmap(32); var k: i64=0; if n==0{t[0]=48 as u8;k=1}; while n>0{t[k]=(48+(n%10)) as u8;n=n/10;k=k+1} 19 var j: i64=k-1; while j>=0{dst[o]=t[j];o=o+1;j=j-1} return o 20} 21// TAB-delimited field `fi` of rec[0..rl) into out (NUL-term); returns length 22func getfield(rec: *u8, rl: i64, fi: i64, out: *u8) -> i64 { 23 var f: i64=0; var i: i64=0 24 while f<fi { if i>=rl { out[0]=0 as u8; return 0 } if rec[i]==9 as u8 { f=f+1 } i=i+1 } 25 var o: i64=0 26 while i<rl { if rec[i]==9 as u8 { i=rl } else { out[o]=rec[i]; o=o+1; i=i+1 } } 27 out[o]=0 as u8; return o 28} 29// load app <name>'s fields; returns 0 ok / -1 missing 30func app_fields(name: *u8, path: *u8, title: *u8, blurb: *u8, cate: *u8) -> i64 { 31 let po: *i64=sys_mmap(16) as *i64; let lo: *i64=sys_mmap(16) as *i64 32 if nx_app_store_get(name, po, lo) < 0 { return 0 - 1 } 33 let rec: *u8=sys_mmap(HUB_MAGIC_8192); let src: *u8=po[0] as *u8; let rl: i64=lo[0] 34 var c: i64=0; while c<rl { rec[c]=src[c]; c=c+1 } 35 getfield(rec, rl, 0, path); getfield(rec, rl, 1, title); getfield(rec, rl, 2, blurb); getfield(rec, rl, 3, cate) 36 return 0 37} 38func streq(a: *u8, b: *u8) -> i64 { var i: i64=0; while a[i]!=(0 as u8){ if a[i]!=b[i]{return 0} i=i+1 } if b[i]!=(0 as u8){return 0} return 1 } 39 40// emit one category section: every app whose category == want 41func emit_cat(h: *u8, off: i64, idx: *u8, idxn: i64, want: *u8, header: *u8) -> i64 { 42 var o: i64=off 43 o=cat(h,o,"<h2>" as *u8); o=cat(h,o,header); o=cat(h,o,"</h2><div class=\"grid\">\n" as *u8) 44 let name: *u8=sys_mmap(256); let path: *u8=sys_mmap(256); let title: *u8=sys_mmap(256) 45 let blurb: *u8=sys_mmap(HUB_MAGIC_1024); let cate: *u8=sys_mmap(64) 46 var ls: i64=0; var i: i64=0 47 while i<=idxn { 48 var eol: i64=0 49 if i==idxn { eol=1 } else { if idx[i]==10 as u8 { eol=1 } } 50 if eol==1 { 51 if i>ls { 52 var c: i64=0; while c<i-ls { name[c]=idx[ls+c]; c=c+1 } name[i-ls]=0 as u8 53 if app_fields(name, path, title, blurb, cate)==0 { 54 if streq(cate, want)==1 { 55 o=cat(h,o,"<a class=\"card\" href=\"" as *u8); o=cat(h,o,path) 56 o=cat(h,o,"\"><h3>" as *u8); o=cat(h,o,title); o=cat(h,o,"</h3><p>" as *u8) 57 o=cat(h,o,blurb); o=cat(h,o,"</p></a>\n" as *u8) 58 } 59 } 60 } 61 ls=i+1 62 } 63 i=i+1 64 } 65 o=cat(h,o,"</div>\n" as *u8) 66 return o 67} 68 69func main() -> i64 { 70 let now: i64 = sys_now_realtime_sec() 71 let h: *u8 = sys_mmap(HUB_CAP) 72 var w: i64 = 0 73 let idx: *u8 = sys_mmap(HUB_MAGIC_65536) 74 let idxn: i64 = nx_app_store_index(idx) 75 76 w = cat(h, w, "<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\">\n" as *u8) 77 w = cat(h, w, "<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n" as *u8) 78 w = cat(h, w, "<title>Nishi Family &mdash; Hub</title>\n<style>\n" as *u8) 79 w = cat(h, w, ":root{--bg:#0b0f14;--panel:#131b24;--ink:#e6edf3;--mut:#8aa0b4;--acc:#4cc2ff;--good:#3fb950;--line:#243140}\n" as *u8) 80 w = cat(h, w, "*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:15px/1.55 system-ui,Segoe UI,Roboto,sans-serif}\n" as *u8) 81 w = cat(h, w, "header{padding:38px 20px 8px;max-width:1000px;margin:0 auto;text-align:center}h1{margin:0;font-size:32px}.sub{color:var(--mut);margin:.6em 0 0}.stamp{color:var(--mut);font-size:12px;margin:.5em 0 0}\n" as *u8) 82 w = cat(h, w, "main{max-width:1000px;margin:0 auto;padding:18px 20px 60px}\n" as *u8) 83 w = cat(h, w, ".grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:14px;margin-top:10px}\n" as *u8) 84 w = cat(h, w, "a.card{display:block;background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:16px 18px;text-decoration:none;color:var(--ink);transition:border-color .15s,transform .15s}\n" as *u8) 85 w = cat(h, w, "a.card:hover{border-color:var(--acc);transform:translateY(-2px)}a.card h3{margin:0 0 6px;font-size:17px;color:var(--acc)}a.card p{margin:0;color:var(--mut);font-size:13.5px}\n" as *u8) 86 w = cat(h, w, "a.feat{display:block;text-decoration:none;color:var(--ink);background:linear-gradient(135deg,#10212e,#13243a);border:1px solid #2c4a63;border-radius:12px;padding:16px 18px;margin-top:10px}a.feat h3{margin:.1em 0 6px;font-size:21px;color:var(--acc)}a.feat p{margin:0;color:var(--mut)}a.feat .tagx{color:var(--good);font-size:12px;font-weight:600;letter-spacing:.4px;text-transform:uppercase}\n" as *u8) 87 w = cat(h, w, "h2{font-size:13px;color:var(--mut);text-transform:uppercase;letter-spacing:.5px;margin:26px 0 2px}\n" as *u8) 88 w = cat(h, w, "footer{max-width:1000px;margin:0 auto;padding:8px 20px 40px;color:var(--mut);font-size:12px;text-align:center}\n" as *u8) 89 w = cat(h, w, "</style></head><body>\n" as *u8) 90 91 w = cat(h, w, "<header><h1>Nishi Family &mdash; Hub</h1>\n" as *u8) 92 w = cat(h, w, "<p class=\"sub\">Home of the Nishi sovereign ecosystem &mdash; every app below is built from the hardware rung up, served bits-up over our own TLS&nbsp;1.3.</p>\n" as *u8) 93 w = cat(h, w, "<p class=\"stamp\">Auto-generated by <code>nx_family_hub</code> from the sovereign app registry (<code>nx_app_store</code> on seg_store) at epoch " as *u8) 94 w = catn(h, w, now) 95 w = cat(h, w, "</p></header>\n<main>\n" as *u8) 96 97 // featured: CAD (read from the store) 98 let fpath: *u8=sys_mmap(256); let ftitle: *u8=sys_mmap(256); let fblurb: *u8=sys_mmap(HUB_MAGIC_1024); let fcate: *u8=sys_mmap(64) 99 if app_fields("cad" as *u8, fpath, ftitle, fblurb, fcate)==0 { 100 w=cat(h,w,"<a class=\"feat\" href=\"" as *u8); w=cat(h,w,fpath); w=cat(h,w,"\"><div class=\"tagx\">&#9733; Featured</div><h3>" as *u8) 101 w=cat(h,w,ftitle); w=cat(h,w," &rarr;</h3><p>" as *u8); w=cat(h,w,fblurb); w=cat(h,w,"</p></a>\n" as *u8) 102 } 103 104 w = emit_cat(h, w, idx, idxn, "make" as *u8, "Make &amp; build" as *u8) 105 w = emit_cat(h, w, idx, idxn, "play" as *u8, "Play" as *u8) 106 w = emit_cat(h, w, idx, idxn, "home" as *u8, "Home &amp; family" as *u8) 107 108 w = cat(h, w, "</main>\n<footer>Served bits-up by the Nishi stack &middot; TLS&nbsp;1.3, no third-party web server &middot; registry: <code>nx_app_store</code> (seg_store) &middot; hub: <code>nx_family_hub</code> &middot; nishifamily.com/hub</footer>\n</body></html>\n" as *u8) 109 110 let fd: i64 = sys_openat_wr(HUB_OUT, 0x1a4) 111 if fd < 0 { sys_write(2, "FATAL: hub.html open\n" as *u8, 21); sys_exit(2); return 2 } 112 sys_write(fd, h, w); sys_close(fd) 113 sys_write(1, "[nx_family_hub] hub.html auto-generated from registry, bytes=" as *u8, 60) 114 let nb: *u8 = sys_mmap(28); var k2: i64=0; var m2: i64=w; if m2==0{nb[0]=48 as u8;k2=1}; while m2>0{nb[k2]=(48+(m2%10)) as u8;m2=m2/10;k2=k2+1} 115 var qd: i64=k2-1; while qd>=0 { let o1: *u8=sys_mmap(1); o1[0]=nb[qd]; sys_write(1,o1,1); qd=qd-1 } 116 sys_write(1, "\n" as *u8, 1) 117 sys_exit(0); return 0 118}