Skip to main content

Crate heatsync_core

Crate heatsync_core 

Source
Expand description

heatsync-core — the brain. protocol types, heat ramp, emote resolution, ws parsing, mock feed, and the editing model. no terminal, no async, no i/o (clocks and keystrokes are passed in). every client is a thin face over this.

The editing half (key, edit, vi, slash, clip) lived in the tui until a second face needed it. None of it ever touched the terminal except for crossterm’s key type, which key now replaces — a face maps its own keystrokes into key::KeyEvent and gets the same editor.

Modules§

clip
yank target. tries the system clipboard first, then falls back to OSC 52 so a yank still lands over ssh, where there is no local clipboard daemon to talk to. returns a short label naming which path worked, for the status line.
edit
a vi line editor for the composer. insert and normal sub-modes, motions, operators, registers and history — the same muscle memory as everywhere else, rather than a handful of emacs control chords.
emote
emote resolution. mirrors the server: /api/channel/:c/emotes returns a precedence-ordered (7tv > bttv > ffz > twitch > kick) deduped list, so we insert first-wins into a name→emote map and word-match message text against it. modifiers (BTTV w!-style prefixes / FFZ ffzX-style effect words) are parsed here into per-stack Effect lists; the pixel work happens at render.
heat
the heat ramp — one decaying scalar → a stepped temperature color. mirrors client/config/colors.js (the ONE source of truth). terminal-native: we return the xterm-256 index, not css. the tui maps that to a cell color.
key
Face-independent key events.
mock
deterministic mock feed — proves the aesthetic before the relay WS exists. no rand crate, no real clock: a seeded xorshift + a synthetic ms clock advanced each tick. heat emerges from the same decaying-counter model the live feed uses, so the mock and the real thing behave identically.
proto
HeatSync /ws relay protocol — parse inbound frames, build outbound ones. anon read is allowed, so no auth is required to consume chat. content and usernames are sanitized HERE, at the trust boundary, before anything else touches them (terminal-injection defense).
sanitize
terminal-injection defense. chat text is UNTRUSTED — a raw escape sequence in a message could retitle the terminal, poke the clipboard, or worse on some emulators. we render into a terminal, so we strip every control byte before a message is ever handed to the tui. this is the one risk chatterino never has.
slash
slash commands typed in the composer, the way every chat client does it.
vi
vi navigation over the chat ring: a cursor, a linewise visual selection, counts, and search. no rendering and no I/O — main.rs owns the keymap and the drawing, this owns the model, which is what makes the motions testable.

Structs§

Channel
live state for a single channel. bounded ring buffer — a raid can flood forever and we never grow past cap (mele is 8GB; resource-conscious). heat is a decaying counter driven by message arrivals.
Message
one chat line. heat is the channel’s heat snapshotted at arrival, so a message sent during a spike stays warm in scrollback. color is the user’s chat color (hex) if the platform sent one.

Enums§

Platform
where a channel’s chat comes from.