rspace-online/shared/markwhen/types.ts

77 lines
2.5 KiB
TypeScript

/**
* Universal markwhen projection types for rSpace.
*
* Any rApp can expose date-bearing Automerge records as a MwSource.
* The renderer unions sources into a single `.mw` document that feeds
* timeline / calendar / gantt views.
*
* Storage model: `.mw` is NEVER the source of truth. It is a pure
* projection over canonical CRDT state. Do not round-trip edits through it.
*/
/** Hex color or markwhen named color (e.g. "blue"). */
export type MwColor = string;
/** A single event in markwhen's mental model. */
export interface MwEvent {
/** UTC epoch ms. For all-day events, the renderer normalizes to date-only. */
start: number;
/** UTC epoch ms. Omit for a point event. */
end?: number;
/** Single-line headline (truncated at ~90 chars when serialized). */
title: string;
/** Optional body — becomes indented description under the event. */
description?: string;
/** Freeform tags. Prefixed with `#` on serialize. Used for coloring + filtering. */
tags?: string[];
/** Optional deep-link back into the canonical module (e.g. rspace:/cal/ev/123). */
href?: string;
/** Treat date as wall-clock in the named IANA zone, not UTC. */
timezone?: string;
/** Stable ID for dedup across projections (e.g. module:collection:recordId). */
sourceId: string;
}
/** A module's contribution to a composite timeline. */
export interface MwSource {
/** Short section slug, e.g. "rcal", "rnotes", "rvote". */
id: string;
/** Display label for the markwhen `section` header. */
label: string;
/** Section-level tag; applied to every event from this source. */
tag: string;
/** Optional color for the tag in frontmatter. */
color?: MwColor;
/** The events themselves. */
events: MwEvent[];
}
/** Result of projecting + rendering. */
export interface MwProjection {
/** Serialized `.mw` text. */
text: string;
/** Flat list of all events across sources (post-dedup). */
events: MwEvent[];
/** Total event count. */
count: number;
}
/**
* A module registers a factory that builds its MwSource on demand.
* The composite rApp (rSaga) calls these at projection time.
*/
export interface MarkwhenSourceFactory {
/** Module id, e.g. "rcal". */
module: string;
/** Human label for picker UI. */
label: string;
/** Emoji for picker UI. */
icon: string;
/**
* Build the source. Receives the current space slug and an optional
* date window — implementations should filter events to the window
* to keep DOM render sizes bounded (~5k event ceiling for smooth UX).
*/
build(ctx: { space: string; from?: number; to?: number }): Promise<MwSource | null>;
}