| .. | ||
| oganesson.js | 4.8K | |
| README.md | 4.4K |
👻 oganesson.js - live and ephemeral
oganesson.js is a miniature of the live layer of a big chat app: who's here, who's typing, where their cursor is. Any element can send an ephemeral event (kinds 20000-29999) on a heartbeat or on input, and any element can show the latest one per person from a template, removing it when it goes stale or its author leaves. It publishes and subscribes through xenon.js, signs through the same nhy:config hook (so helium.js or any other signer applies), and argon.js keeps none of it: argon keeps what lasts, oganesson handles what vanishes.
<main nog-room="lobby">
<ul nog-send="presence" nog-show="presence">
<template><li><b nrn-profile="{pubkey}" nrn-field="name">{npub}</b> {status}</li></template>
</ul>
<textarea nog-send="typing"></textarea>
<p nog-show="typing"><template><span><b nrn-profile="{pubkey}" nrn-field="name">someone</b> is typing</span></template></p>
</main>
The list announces you every minute and shows everyone else in the room, each once, until they go quiet or hide the page; the paragraph shows who is typing for five seconds after each keystroke.
Attributes
| attribute | default | description |
|---|---|---|
nog-room |
none | Room id, sent as ["h", room] and filtered with #h. Inherited from the closest ancestor. Without it events have no h tag and shows are not filtered by room |
nog-send |
Topic this element publishes | |
nog-on |
input on inputs, textareas and selects |
Space-separated DOM events that publish. Pointer events send {"x","y"} as fractions of the element box. Without it (and not an input) the element sends a heartbeat every ttl/3 while the page is visible |
nog-status |
online |
Content of heartbeats, such as away |
nog-show |
Topic to show: one child per pubkey from the first element of the inner <template> (default <span>{pubkey}</), replaced on refresh, removed after the ttl |
|
nog-ttl |
per topic | Seconds an event stays shown, and the heartbeat period (ttl/3) |
nog-rate |
per topic | Minimum ms between sends. The latest throttled value is sent when the window ends |
nog-self |
Also show your own events (hidden by default; own pubkeys are learned from events you sign) | |
nog-ignore |
oganesson skips this element and its descendants |
Templates get xenon's fields (with neon.js {npub}, {ago}; with radon.js nrn-profile names), plus {status} and every key of JSON content, such as {x} and {y}, HTML-escaped. A cursor is <i style="left:calc({x} * 100%); top:calc({y} * 100%)">.
Topics
| topic | kind | ttl | rate | content |
|---|---|---|---|---|
presence |
20001 | 180 | 1000 | online, away, ... or offline |
typing |
20002 | 5 | 3000 | typing or stopped |
| anything else | nogCfg.kind (20078) |
30 | 1000 | the status, or JSON such as {"x":0.5,"y":0.25}; tagged ["t", topic] |
Presence and typing follow the convention shared by Block's Buzz and tinyrelay. Other topics, such as cursors, are only a convention of ours, on one configurable kind (window.nogCfg = {kind}).
Events
| event | cancel to | detail |
|---|---|---|
nog:send |
skip sending | cfg (unsigned cfg.event) |
nog:shown |
event, fields, elt |
|
nog:expired |
keep the element | pubkey, elt |
nog:error |
cfg, error |
|
nog:process |
dispatch on an element to initialize new content |
Behavior
- Readers drop events more than 5s in the future or older than their ttl, and events older than the one shown for that pubkey.
offlineandstoppedremove the entry at once. Reading also accepts JSON{"status"}and{"typing":bool}, andfalse,idle,offlineas stopped typing.- Typing sends
stoppedwhen the field is emptied or blurred. Hiding the page sendsofflinefor heartbeats andstoppedfor active typing; showing it sends a heartbeat. - Seeing a new pubkey makes this page's heartbeats in the same room and topic send right away, so newcomers don't wait a minute.
oganesson.send(el, content)publishes throughel's throttle,oganesson.leave()sends the goodbyes,oganesson.mineholds your pubkeys.
Caveats
- Every heartbeat, keystroke burst and cursor move is a signature. A NIP-07 extension may prompt each time, so this works best with helium.js's local key or an extension set to auto-approve these kinds.
- Buzz and tinyrelay members-only rooms may require NIP-42 AUTH, which a future family library will handle.
Requires xenon.js.