// util — shared helpers (kind=module). import "util" as util; // Turn a title into a URL slug: lowercase, non-alnum -> hyphen, trim hyphens. fn slugify(s) { let out = s.to_lower(); out = regex::replace_all("[^a-z0-9]+", out, "-"); out = regex::replace_all("(^-+|-+$)", out, ""); if out == "" { out = "untitled"; } out } // Flatten a docs envelope { id, data, created_at, updated_at } into a single // map (data fields + id/timestamps) for JSON responses. fn shape_doc(doc) { let d = doc.data; d.id = doc.id; d.created_at = doc.created_at; d.updated_at = doc.updated_at; d } fn to_int_or(s, dflt) { if s == () { return dflt; } if type_of(s) == "i64" || type_of(s) == "int" { return s; } try { parse_int(s) } catch(e) { dflt } } // Atomic KV counter increment via set_if (CAS), bounded retries. fn incr(coll_name, key) { let c = kv::collection(coll_name); let i = 0; while i < 8 { let cur = c.get(key); let n = if cur == () { 0 } else { cur }; if c.set_if(key, cur, n + 1) { return n + 1; } i += 1; } // give up gracefully — a stale counter is not worth failing the request c.get(key) }