trellis
Version:
Agentic State Engine — event-sourced causal graph with branching, decision traces, and realtime sync for AI-native applications
147 lines • 4.2 kB
TypeScript
/**
* EAV-based Datalog Engine with Path-Aware Ingestor
*
* Core types and fact storage for schema-agnostic data processing.
* Inlined from trellis-core for single-package publish.
*
* @module trellis/core
*/
export type Atom = string | number | boolean | Date | EntityRef;
export type EntityRef = string;
/**
* Where an asserted value came from (ADR 0021 §2).
*
* A deliberate subset of SemType's source shape — `authors`, `location.uri`,
* and the three timestamps. Every field is optional: a source that only knows
* its URI is still worth recording.
*/
export interface Source {
authors?: string[];
location?: {
uri: string;
};
loadedAt?: string;
firstPublished?: string;
lastUpdated?: string;
}
/**
* Value-level provenance (ADR 0021 §2).
*
* Carries only what cannot be derived from the op. Actor provenance
* (`actorType`/`origin`/`createdById`) is *not* denormalized here — a fact
* belongs to exactly one op, so its actor is the op's. `confidence` and
* `sources` genuinely vary per-fact within a single op, so they live here.
*/
export interface FactMeta {
/** [0,1], SemType-aligned. */
confidence?: number;
/** SemType value-node requirement. */
dataTypeId?: string;
sources?: Source[];
}
export interface Fact {
e: string;
a: string;
v: Atom;
/**
* Optional value-level provenance. Rides inside `facts[]`, which is inside
* the hash preimage — so it is tamper-evident for free.
*/
meta?: FactMeta;
}
export interface Link {
e1: string;
a: string;
e2: string;
}
export interface CatalogEntry {
attribute: string;
type: 'string' | 'number' | 'boolean' | 'date' | 'mixed';
cardinality: 'one' | 'many';
distinctCount: number;
examples: Atom[];
min?: number;
max?: number;
}
export interface QueryTraceEntry {
goal: string;
bindingsCount: number;
durationMs: number;
}
export interface QueryResult {
bindings: Record<string, Atom>[];
executionTime: number;
plan?: string;
trace?: QueryTraceEntry[];
}
/**
* Path-aware JSON flattener
* Converts nested JSON into attribute-value pairs with dot notation
*/
export declare function flatten(obj: any, base?: string): Generator<[string, any]>;
/**
* Convert JSON entity to EAV facts
*/
export declare function jsonEntityFacts(entityId: string, root: any, type: string): Fact[];
/**
* In-memory EAV triple store
*/
export declare class EAVStore {
private facts;
private links;
private catalog;
private eavIndex;
private aevIndex;
private aveIndex;
private linkIndex;
private linkReverseIndex;
private linkAttrIndex;
private distinct;
addFacts(facts: Fact[]): void;
/**
* Check if a fact already exists in the store.
*/
private hasFact;
addLinks(links: Link[]): void;
deleteFacts(factsToDelete: Fact[]): void;
deleteLinks(linksToDelete: Link[]): void;
private updateIndexes;
private updateLinkIndexes;
private valueKey;
private updateCatalog;
private inferType;
getFactsByEntity(entity: string): Fact[];
getFactsByAttribute(attribute: string): Fact[];
getFactsByValue(attribute: string, value: Atom): Fact[];
getCatalog(): CatalogEntry[];
getCatalogEntry(attribute: string): CatalogEntry | undefined;
getAllFacts(): Fact[];
getAllLinks(): Link[];
getLinksByEntity(entity: string): Link[];
getLinksByAttribute(attribute: string): Link[];
getLinksByEntityAndAttribute(entity: string, attribute: string): Link[];
getStats(): {
totalFacts: number;
totalLinks: number;
uniqueEntities: number;
uniqueAttributes: number;
catalogEntries: number;
};
/**
* Creates a serializable snapshot of the current store state.
*/
snapshot(): {
facts: Fact[];
links: Link[];
catalog: CatalogEntry[];
};
/**
* Restores the store state from a snapshot and rebuilds all indexes.
*/
restore(snapshot: {
facts: Fact[];
links: Link[];
catalog: CatalogEntry[];
}): void;
}
//# sourceMappingURL=eav-store.d.ts.map