temporal97
Concepts

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(), and seekTo() 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.

On this page