lithium.js is a miniature Negentropy (NIP-77) client, the replication layer for argon.js. It reconciles argon's local events for a filter with each relay's, then fetches only what is missing locally and publishes only what the relay lacks. Apps work fully offline and catch up both ways when a connection returns.
<script src="argon.js"></script>
<script src="lithium.js"></script>
<main nhy-relay="wss://relay.example" nli-sync='{"authors":["<your pubkey>"]}'></main>
On load and whenever the browser comes back online, the author's events are reconciled with every relay in both directions.
| attribute | default | description |
|---|---|---|
nli-sync |
JSON filter to reconcile. Runs on page load and on online |
|
nli-mode |
both ways | pull only fetches, push only publishes |
Relays come from the closest nhy-relay, else nhyCfg.relays. Leave limit out of the filter: relays ignore it for sync.
| event | cancel to | detail |
|---|---|---|
nli:sync |
skip this run | cfg (filter, relays, mode), editable |
nli:synced |
cfg, result per relay |
|
nli:error |
cfg, relay, error (for example the relay's NEG-ERR reason) |
result is {relay, have, need, pulled, pushed}: have and need are the ids only this side or only the relay held.
let result = await lithium.sync({authors:[pk]}, "wss://relay.example", "pull")
lithium.run(element) // run an nli-sync element now
NEG-CLOSE (tinyrelay does when the sets already match) counts as done.rate-limited: ... retry in Ns reply waits that long and retries, so a large backlog trickles in at the relay's pace.nli:error.Requires argon.js, and hydrogen.js for the nli-sync attribute. Tested against bindws (bind.ws) and tinyrelay.
lithium.js (5.0/2.0kb raw/brotli), prefix nli-, needs hydrogen, argon