4.2 KiB
SessionGraphNode
(no submodules)
Purpose
SessionGraphNode is the internal mutable graph node powering the
hierarchical session tree at the heart of @suaveplan/game-server. Every
node holds a stable id, a closed-vocabulary session type, a metadata bag,
the mutable bidirectional parent/children links that form the tree, and
the two timestamps that mark when the node was created and last touched.
The class is named SessionGraphNode deliberately — Wave A's public
SessionNode interface (in core/types) is a read-only structural view of
exactly this shape. exposes the read-only interface to consumers
and uses the mutable class internally, so callers cannot accidentally
mutate the tree by reaching into node.children.push(...) through the
public manager surface.
Features
- Implements Wave A's
SessionNodeinterface structurally (the class is the canonical implementation; the interface is the read-only view). - Injectable
Clock— noDate.now()calls; the entire tree is deterministic underFakeClock. - Bidirectional parent/children link maintenance via
addChild/removeChildwith idempotent attach/detach semantics. - Tree-walking helpers:
getDepth,getDescendants(DFS pre-order),getAncestors,getRoot,isAncestorOf,isDescendantOf. toJSON()returning aSerializedSessionNodeshape forSessionStorepersistence.
Usage: Basic
import { SessionGraphNode } from "../session-node/index.js";
const clock = () => 1700000000000;
const root = new SessionGraphNode(
"venue1",
"venue",
{ createdAt: 0, updatedAt: 0 },
clock
);
const table = new SessionGraphNode(
"table1",
"table",
{ createdAt: 0, updatedAt: 0 },
clock,
root
);
root.addChild(table);
console.log(table.getDepth()); // 1
console.log(table.getRoot().id); // "venue1"
Usage: Advanced
import { SessionGraphNode } from "../session-node/index.js";
// Persistence round-trip: serialise, then restore with original timestamps.
const node = new SessionGraphNode("s1", "game", meta, clock);
const json = node.toJSON();
const restored = new SessionGraphNode(
json.id,
json.type,
json.metadata,
clock,
null,
{ createdAt: json.createdAt, updatedAt: json.updatedAt }
);
// Removing a child clears the bidirectional link.
root.removeChild(table);
console.log(table.parent); // null
console.log(root.children.length); // 0
API Reference
Constructor
new SessionGraphNode(id, type, metadata, clock, parent?, timestamps?)
timestamps is optional — passed only when restoring from persistence to
preserve the original createdAt / updatedAt stamps.
Methods
addChild(child)— attach a child; idempotent (re-adding is a no-op).removeChild(child)— returnstrueif removed,falseif not a child.updateMetadata(patch)— shallow-merge patch; refreshesupdatedAt.getDepth()— 0 for a root, otherwise the distance to the root.getDescendants()— depth-first pre-order array, excludingthis.getAncestors()— parent-to-root array.getRoot()— the topmost ancestor (orthis).isAncestorOf(other)/isDescendantOf(other)— strict ancestry tests.toJSON()— serialised plain object suitable for storage adapters.
Read-only properties
id, type, createdAt, updatedAt.
Mutable properties
parent (managed by addChild/removeChild), children, metadata.
Implementation Notes
The bidirectional parent/children invariant is held by addChild and
removeChild. Direct mutation of node.children or node.parent is
discouraged — callers should always go through these methods so the
counterpart link stays in sync. The class is internal to the engine
package and is not part of the public re-export surface; consumers should
import SessionNode from core/types instead.
The constructor accepts an optional timestamps parameter solely for the
persistence round-trip path — without it, a freshly restored node would
have its createdAt set to the moment of restoration, losing the original
creation time. With it, SessionStore.restore produces nodes that are
byte-equivalent to the ones that were originally persisted.