@noego/beacon
v0.0.2
Published
Relay server for multi-device messaging
Maintainers
Readme
@noego/beacon
Relay server for multi-device messaging. Handles pairing, sessions, SSE streaming, and message routing.
Install
npm install @noego/beaconRequirements:
- Node.js 20+
- Native build support for
better-sqlite3
Quick Start
import { Beacon } from '@noego/beacon';
// Prebaked — SQLite + bcrypt + JWT, zero config
const beacon = Beacon.create({ dataDir: './data/beacon' });
// Mount in Express
app.use('/v1', (req, res) => beacon.expressHandle(req, res));
// Or run standalone
await beacon.listen(3080);
console.log(beacon.url); // http://127.0.0.1:3080Custom Stores
Beacon defines interfaces for all infrastructure concerns. Implement them to bring your own database, auth, or token strategy.
import { Beacon } from '@noego/beacon';
import type { DeviceStore, MessageStore, SessionStore, TokenSigner, PasswordHasher } from '@noego/beacon';
const beacon = new Beacon({
deviceStore: myPostgresDeviceStore,
messageStore: myRedisMessageStore,
sessionStore: mySessionStore,
tokenSigner: myCustomSigner,
passwordHasher: myArgon2Hasher,
});Interfaces
| Interface | Purpose | Methods |
|-----------|---------|---------|
| DeviceStore | Device CRUD + pairing code lookup | create, findById, findByPairingCode, findByUserId, findAll, clearPairingCode, updateLastSeen |
| MessageStore | Message persistence + visibility | create, findById, findByRequestId, findVisibleSince, getHighWaterMark |
| SessionStore | Session lifecycle | create, findById, findActiveByDeviceId, closeForDevice, close |
| TokenSigner | Stream token sign/verify | sign, verify |
| PasswordHasher | Auth token hashing | hash, compare |
Prebaked Implementations
Included for convenience — used by Beacon.create():
| Class | Backing |
|-------|---------|
| SqliteDeviceStore | better-sqlite3 |
| SqliteMessageStore | better-sqlite3 |
| SqliteSessionStore | better-sqlite3 |
| JwtTokenSigner | jsonwebtoken |
| BcryptHasher | bcryptjs |
Endpoints
Beacon handles these routes internally (paths relative to mount point):
| Method | Path | Purpose |
|--------|------|---------|
| POST | /pair/register | Register a new device, get credentials + pairing code |
| POST | /pair/claim | Claim a pairing code, create paired device |
| GET | /devices | List all devices for authenticated user |
| POST | /sessions | Create session, get stream token + bootstrap config |
| POST | /messages | Send a message to a device or user |
| GET | /events | SSE stream — replay + live message delivery |
expressHandle(req, res)
The primary integration point. Pass any Node.js IncomingMessage + ServerResponse — works with Express, dinner, raw http.createServer, or any framework.
// Express
app.use('/v1', (req, res) => beacon.expressHandle(req, res));
// dinner controller
async sendMessage({ req, res }) {
beacon.expressHandle(req, res);
}
// Raw http
http.createServer((req, res) => beacon.expressHandle(req, res));CLI
For subprocess spawning or local relay bootstrapping:
npx beacon --port 0
# Prints URL to stdout: http://127.0.0.1:12345You can also control the storage directory explicitly:
npx beacon --port 3080 --data-dir ./data/beaconTesting
npm testTests use Express + Beacon.create() with temp directories. No external dependencies.
