UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

189 lines (188 loc) • 7.67 kB
export const RECEIPT_FAULTS = Object.freeze(["proxy", "accessor", "hidden", "getter-threw", "prototype-moved", "not-data", "cycle", "too-deep", "uncopyable"]); export function isPlainRecord(v) { if (typeof v !== "object" || v === null || Array.isArray(v)) return false; const proto = Object.getPrototypeOf(v); return proto === Object.prototype || proto === null; } function isOrdinaryArray(v) { return Array.isArray(v) && Object.getPrototypeOf(v) === Array.prototype; } export function receive(value, mode, held) { const seen = new Map(); const path = []; const open = new Set(); const heights = new Map(); const faults = []; const refusedAt = new Map(); const stack = []; const refusals = new Set(); const refuse = (kind) => { const fault = Object.freeze({ kind, path: Object.freeze([...path]) }); refusals.add(fault); throw fault; }; const faultOf = (err) => typeof err === "object" && err !== null && refusals.has(err) ? err : Object.freeze({ kind: "uncopyable", path: Object.freeze([...path]) }); const other = (v, kind) => (mode.others === "as-is" ? v : refuse(kind)); const refuseContainer = (v, kind) => { if (mode.contain === true) { refusedAt.set(v, kind); open.delete(v); } return refuse(kind); }; const memberOf = (v, d) => { if (Object.hasOwn(d, "value")) { if (mode.accessors === "refuse" && d.enumerable !== true) refuse("hidden"); return d.value; } if (mode.accessors === "refuse") refuse("accessor"); const get = Object.hasOwn(d, "get") ? d.get : undefined; try { return get === undefined ? undefined : Reflect.apply(get, v, []); } catch { return refuse("getter-threw"); } }; const measured = mode.past === "refuse" || mode.others !== "as-is"; const heightOf = (v) => heights.get(v) ?? (open.has(v) || (held?.has(v) === true && mode.isProxy?.(v) !== true && (isOrdinaryArray(v) || isPlainRecord(v))) ? 1 : 0); const pastDepth = (v, level) => measured && level + heightOf(v) > mode.depth; const meet = (v, level) => { if (v === null || v === undefined || typeof v === "string" || typeof v === "number" || typeof v === "boolean") return v; if (typeof v !== "object") return other(v, "not-data"); if (held?.has(v) === true) return pastDepth(v, level) ? refuse("too-deep") : v; if (seen.has(v)) { if (refusedAt.has(v)) return refuse(refusedAt.get(v)); if (open.has(v) && mode.others !== "as-is") return refuse("cycle"); return pastDepth(v, level) ? refuse("too-deep") : seen.get(v); } if (level >= mode.depth && mode.past === "refuse") { if (mode.isProxy?.(v) === true) return refuse("proxy"); if (isOrdinaryArray(v) || isPlainRecord(v)) return refuse("too-deep"); } if (level >= mode.depth) return other(v, "too-deep"); if (mode.isProxy?.(v) === true) return refuse("proxy"); const list = isOrdinaryArray(v) || (mode.others === "copy" && Array.isArray(v)); if (!list && !isPlainRecord(v) && mode.others !== "copy") return other(v, "not-data"); const proto = Object.getPrototypeOf(v); const captured = Object.getOwnPropertyDescriptors(v); const out = list ? [] : {}; seen.set(v, out); open.add(v); if (mode.accessors === "refuse" && Object.getOwnPropertySymbols(captured).length > 0) refuseContainer(v, "hidden"); stack.push({ v, out, list, proto, captured, keys: Object.getOwnPropertyNames(captured), level, next: 0, height: 1, key: "", member: undefined }); return out; }; const land = (f, key, copy, member) => { if (measured && typeof member === "object" && member !== null) f.height = Math.max(f.height, heightOf(member) + 1); Object.defineProperty(f.out, key, { value: copy, enumerable: true, writable: true, configurable: true }); path.length = f.level; }; const finish = (f) => { heights.set(f.v, f.height); if (mode.accessors === "call-once" && mode.others !== "copy" && Object.getPrototypeOf(f.v) !== f.proto) refuseContainer(f.v, "prototype-moved"); if (Array.isArray(f.out)) { const length = f.captured["length"]?.value; if (typeof length === "number") f.out.length = length; } if (mode.freeze === true) Object.freeze(f.out); open.delete(f.v); return f.out; }; const received = (copy) => (mode.contain === true ? { ok: true, value: copy, faults: Object.freeze(faults) } : { ok: true, value: copy }); try { const copy = meet(value, 0); if (stack.length === 0) return received(copy); } catch (err) { return { ok: false, fault: faultOf(err) }; } for (;;) { const f = stack[stack.length - 1]; if (f.next < f.keys.length) { const key = f.keys[f.next++]; if (f.list && key === "length") continue; path.push(key); try { const member = memberOf(f.v, f.captured[key]); const frames = stack.length; const copy = meet(member, f.level + 1); if (stack.length > frames) { f.key = key; f.member = member; } else land(f, key, copy, member); } catch (err) { if (mode.contain !== true) return { ok: false, fault: faultOf(err) }; faults.push(faultOf(err)); path.length = f.level; } continue; } let copy; try { copy = finish(f); } catch (err) { stack.pop(); const holder = stack[stack.length - 1]; if (mode.contain !== true || holder === undefined) return { ok: false, fault: faultOf(err) }; faults.push(faultOf(err)); path.length = holder.level; continue; } stack.pop(); const holder = stack[stack.length - 1]; if (holder === undefined) return received(copy); land(holder, holder.key, copy, holder.member); } } export const MODS_PAYLOAD_MODE = Object.freeze({ accessors: "refuse", depth: Infinity, others: "as-is", freeze: true }); export function describeFault(fault) { const at = fault.path.length > 0 ? ` at ${fault.path.join(".")}` : ""; switch (fault.kind) { case "proxy": return `a Proxy${at}`; case "accessor": return `an accessor${at} (a getter is never run)`; case "hidden": return `a member that is not an enumerable data property${at}`; case "getter-threw": return `a getter that threw${at}`; case "prototype-moved": return `a prototype that moved while it was read${at}`; case "not-data": return `a value that is not data${at}`; case "cycle": return `a cycle${at}`; case "too-deep": return `a value nested too deep${at}`; case "uncopyable": return `a value that could not be copied whole${at}`; } }