Core Concepts
The five building blocks behind temporal97.
Snapshot
A SnapshotId is a plain number used as a logical timestamp. Snapshots must always increase — you can use integers, Unix timestamps, or sequence numbers. Multiple entries can share the same snapshot, representing a batch of changes that happened "at the same time."
Mutation
A single set or delete operation targeting one node or one edge:
{ kind: "node", op: "set", id: "a", value: { label: "Alice" } }
{ kind: "edge", op: "delete", id: "a->b" }Mutations are always grouped inside an Entry — they are never written to the log on their own.
Entry
The unit written to the log. An entry bundles a snapshot ID, an optional typed event payload, and an array of mutations:
graph.append({
snapshot: 42,
event: { type: "user-joined", userId: "u1" }, // optional
mutations: [
{ kind: "node", op: "set", id: "u1", value: { name: "Alice" } },
],
});The generic type parameter TEvent on TemporalGraph<TNode, TEdge, TEvent> types the event payload.
Cursor
The cursor marks the graph's current position in the log. Every read method (getNode, liveNodes, etc.) reflects the state at the cursor.
- Writing requires the cursor to be at the head of the log.
advance(),rewind(), andseekTo()move the cursor and update all live state.
Delta
Every write and every cursor movement returns a Delta — a plain description of what changed:
interface Delta {
nodes: { added: Set<EntityId>; updated: Set<EntityId>; removed: Set<EntityId> };
edges: { added: Set<EntityId>; updated: Set<EntityId>; removed: Set<EntityId> };
}Use it to drive incremental re-renders or sync a downstream library without re-scanning the whole graph.