ecs-observable/src/relationship.ts

56 lines
1.7 KiB
TypeScript

// ── Relationship ─────────────────────────────────────
/**
* A relationship definition — like a component, but represents a directed
* link between two entities. Every relationship carries an optional data
* payload (defaults to `{}` for bare edges).
*
* @example
* ```ts
* const ChildOf = defineRelationship('childOf');
* const Health = defineRelationship('health', { hp: 100 });
* ```
*/
export interface RelationshipDef<T extends Record<string, any> = {}> {
/** Unique symbol used as the storage key. */
readonly _key: symbol;
/** Human-readable name, used for serialization. */
readonly name: string;
/** Default values used when no data override is provided. */
readonly defaults: T;
/** Phantom type for inference. */
readonly type: T;
}
/**
* Define a named relationship between entities.
*
* When `defaults` is omitted the relationship is a bare edge (no data).
* When `defaults` is provided the relationship carries data accessible
* via `world.getRelData()` / `world.setRelData()`.
*
* @example
* ```ts
* // Bare edge
* const ChildOf = defineRelationship('childOf');
*
* // With data
* const Health = defineRelationship('health', { hp: 100 });
* ```
*/
export function defineRelationship(name: string): RelationshipDef<{}>;
export function defineRelationship<T extends Record<string, any>>(
name: string,
defaults: T,
): RelationshipDef<T>;
export function defineRelationship<T extends Record<string, any>>(
name: string,
defaults?: T,
): RelationshipDef<{}> | RelationshipDef<T> {
return {
_key: Symbol(),
name,
defaults: (defaults ?? {}) as any,
type: undefined as unknown as any,
};
}