export type MarkerPosition = readonly [number, number, number]; /** * Small, display-only marker shape consumed by map renderers. Existing games * can project their own entities to this view without adopting marker * lifecycle storage or duplicating them into a {@link MarkerSet}. */ export interface MarkerView { id: string; position: MarkerPosition; kind?: string; label?: string; /** Optional world heading in radians for presentations that draw directional markers. */ heading?: number; meta?: TMeta; } /** A marker owned by {@link MarkerSet}, including its lifecycle and query fields. */ export interface MapMarker extends MarkerView { kind: string; owner?: string; createdAt: number; expiresAt?: number; } export interface MarkerInput { id?: string; kind: string; position: MarkerPosition; label?: string; /** Optional world heading in radians for directional map presentations. */ heading?: number; owner?: string; createdAt?: number; expiresAt?: number; meta?: TMeta; } export interface MarkerQuery { kind?: string; owner?: string; near?: MarkerPosition; radius?: number; } /** * Visual descriptor for a marker kind. Games supply their own palette; the * engine ships `DEFAULT_MARKER_KINDS` as a content-agnostic starting set that * the react minimap/compass read for colors and glyphs. */ export interface MarkerKindStyle { id: string; color: string; glyph: string; priority: number; } export declare const DEFAULT_MARKER_KINDS: Record; export declare function markerKindStyle(kind: string | undefined, styles?: Record): MarkerKindStyle; export interface MarkerSet { add(marker: MarkerInput): string; remove(id: string): boolean; get(id: string): MapMarker | null; list(): readonly MapMarker[]; query(query: MarkerQuery): MapMarker[]; prune(now: number): number; clear(): void; subscribe(listener: () => void): () => void; snapshot(): readonly MapMarker[]; } /** * Observable marker snapshots owned by an external project. `getSnapshot` * must return the same array identity until the source changes and calls its * subscribers, matching React's external-store contract. */ export interface MarkerSource { subscribe(listener: () => void): () => void; getSnapshot(): readonly TMarker[]; /** Optional hydration snapshot; omit when the client snapshot is also valid during SSR. */ getServerSnapshot?: () => readonly TMarker[]; } /** Marker data accepted by portable consumers: static views, an external source, or a native set. */ export type MarkerCollection = readonly TMarker[] | MarkerSource | MarkerSet; /** Configuration for projecting a caller-owned collection into display-only markers. */ export interface MarkerSourceOptions { /** Subscribe to changes in the caller-owned collection. Static collections may omit this. */ subscribe?: (listener: () => void) => () => void; /** Read the current caller-owned collection. Keep its identity stable between changes. */ getSnapshot: () => readonly TEntity[]; /** Optional server collection used to keep hydration output deterministic. */ getServerSnapshot?: () => readonly TEntity[]; /** Project one caller-owned record into the minimal marker view. */ project: (value: TEntity, index: number) => TMarker; } /** * Adapt a caller-owned array/store to an observable marker source. Projection * is cached between source changes, so React reads do not copy the collection * per frame. The caller retains ownership of entities, updates, persistence, * and subscription scheduling. * * @capability portable-marker-source project caller-owned arrays or subscribable stores into cached minimap marker snapshots without a MarkerSet */ export declare function createMarkerSource(options: MarkerSourceOptions): MarkerSource; export declare function createMarkerSet(now?: () => number): MarkerSet;