code wiki / (root) / nx_app_store.nx

nx_app_store.nx source

↩ module page · 92 lines · 3621 B

1// nx_app_store.nx -- the Nishi-native app registry, on the sovereign seg_store 2// (append-only, additive, crash-safe rename-commit). REPLACES the flat TSV -- 3// "migrate to the nishi ecosystem everywhere". Each app is a record: 4// key = "app:<name>" 5// val = path<TAB>title<TAB>blurb<TAB>category<TAB>marker 6// plus an "__apps__" record (newline-separated names) maintained IN THE SAME COMMIT 7// so the hub + monitor can enumerate the whole registry atomically (no torn state). 8// Durable on disk under APP_PREFIX; history is never destroyed (additive law). 9// license_tier: ORIGINAL 10import "nx_syscalls.nx" 11import "nx_seg_store.nx" 12const APP_MAGIC_65536: i64 = 65536 13 14const APP_PREFIX: *u8 = "knowledge/appstore-" as *u8 15 16func aps_strlen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 17func aps_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 } 18 19// key "app:<name>" (NUL-terminated) into kbuf 20func aps_key(kbuf: *u8, name: *u8) -> i64 { 21 var o: i64 = aps_cat(kbuf, 0, "app:" as *u8) 22 o = aps_cat(kbuf, o, name) 23 kbuf[o] = 0 as u8 24 return o 25} 26 27// is `name` (namelen bytes) already a line in the newline-separated index buf[0..n)? 28func aps_name_present(buf: *u8, n: i64, name: *u8, namelen: i64) -> i64 { 29 var ls: i64 = 0 30 var i: i64 = 0 31 while i <= n { 32 var eol: i64 = 0 33 if i == n { eol = 1 } else { if buf[i] == 10 as u8 { eol = 1 } } 34 if eol == 1 { 35 if i - ls == namelen { 36 var m: i64 = 1 37 var c: i64 = 0 38 while c < namelen { if buf[ls + c] != name[c] { m = 0 } c = c + 1 } 39 if m == 1 { return 1 } 40 } 41 ls = i + 1 42 } 43 i = i + 1 44 } 45 return 0 46} 47 48// register/update an app (additive new version; __apps__ index advanced same commit) 49func nx_app_store_put(name: *u8, record: *u8, reclen: i64) -> i64 { 50 let kbuf: *u8 = sys_mmap(256) 51 aps_key(kbuf, name) 52 // fresh max+1 segid (ss_next_segid, uncapped) -- the capped ss_manifest count clobbers past the cap 53 let segid: i64 = ss_next_segid(APP_PREFIX) 54 let w: *i64 = ss_begin() 55 ss_add(w, 1, kbuf, record, reclen) 56 let ipo: *i64 = sys_mmap(16) as *i64 57 let ilo: *i64 = sys_mmap(16) as *i64 58 let idxbuf: *u8 = sys_mmap(APP_MAGIC_65536) 59 var ilen: i64 = 0 60 if ss_get(APP_PREFIX, "__apps__" as *u8, ipo, ilo) >= 0 { 61 let src: *u8 = ipo[0] as *u8 62 var c: i64 = 0 63 while c < ilo[0] { idxbuf[ilen] = src[c]; ilen = ilen + 1; c = c + 1 } 64 } 65 let nl: i64 = aps_strlen(name) 66 if aps_name_present(idxbuf, ilen, name, nl) == 0 { 67 var c2: i64 = 0 68 while c2 < nl { idxbuf[ilen] = name[c2]; ilen = ilen + 1; c2 = c2 + 1 } 69 idxbuf[ilen] = 10 as u8 70 ilen = ilen + 1 71 } 72 ss_add(w, 1, "__apps__" as *u8, idxbuf, ilen) 73 return ss_commit(APP_PREFIX, w, segid) 74} 75 76// copy the newline-separated app-name index into idxbuf; returns its length (0 if empty) 77func nx_app_store_index(idxbuf: *u8) -> i64 { 78 let ipo: *i64 = sys_mmap(16) as *i64 79 let ilo: *i64 = sys_mmap(16) as *i64 80 if ss_get(APP_PREFIX, "__apps__" as *u8, ipo, ilo) < 0 { return 0 } 81 let src: *u8 = ipo[0] as *u8 82 var i: i64 = 0 83 while i < ilo[0] { idxbuf[i] = src[i]; i = i + 1 } 84 return ilo[0] 85} 86 87// get app <name>'s current record -> ptrout[0]/lenout[0]; rc<0 if not found 88func nx_app_store_get(name: *u8, ptrout: *i64, lenout: *i64) -> i64 { 89 let kbuf: *u8 = sys_mmap(256) 90 aps_key(kbuf, name) 91 return ss_get(APP_PREFIX, kbuf, ptrout, lenout) 92}