import { AssertFact, Assertion, CauseString, Changes, ClaimFact, Fact, RetractFact, Statement, } from "./interface.ts"; export const from = (statements: Iterable) => { const changes = {} as Changes; for (const statement of statements) { const at = [statement.of, statement.the]; if (statement.cause) { const { cause, is } = statement; set(changes, at, cause.toString(), is === undefined ? {} : { is }); } else { set(changes, at, statement.fact.toString(), true); } } return changes as T extends Assertion ? { [of in Of]: { [the in The]: { [cause in CauseString]: { is: Is } } } } : T extends Fact ? Changes : T extends Statement ? Changes : never; }; export const set = ( target: Record, path: string[], key: string, value: RetractFact | AssertFact | ClaimFact | unknown, ) => { let cursor = target; for (const at of path) { let target = cursor[at]; if (!target) { target = {}; cursor[at] = target; } // FIXME: typing cursor = target as Record; } cursor[key] = value; };