-- TrapOS router state machine: (label -> id) map with TTL. -- -- Pure logic so it can be unit-tested without a modem or eventloop. -- The wire glue lives in /programs/router.lua. local DEFAULT_TTL = 90; local function createRouter(options) options = options or {}; local ttl = options.ttl or DEFAULT_TTL; local nowFn = options.now or os.clock; local labelMap = {}; local function isExpired(entry) return entry.expiresAt < nowFn(); end local function register(label, id) local existing = labelMap[label]; if existing and existing.id ~= id and not isExpired(existing) then return false, 'duplicate label'; end labelMap[label] = { id = id, expiresAt = nowFn() + ttl }; return true; end local function resolve(label) local entry = labelMap[label]; if not entry then return nil end if isExpired(entry) then labelMap[label] = nil; return nil; end return entry.id; end local function forget(label) labelMap[label] = nil; end return { register = register, resolve = resolve, forget = forget, ttl = ttl, }; end return createRouter;