@blipr/js
v0.1.0
Published
Tiny, zero-dependency client for Blipr — publish and subscribe to notifications. curl your phone.
Maintainers
Readme
@blipr/js
Tiny, zero-dependency client for Blipr — publish and subscribe to notifications from anywhere. curl your phone.
- Zero runtime dependencies. Runs on Node ≥ 18, browsers, and edge runtimes (anywhere
fetchstreams). - Publish with title, priority, tags, click, markdown, and the reply/ask loop.
- Subscribe over SSE with auto-reconnect and resume-from-last-message.
- Token-ready from v1 — pass a token and it's forwarded for protected topics; a no-op until the server enforces them.
Install
npm install @blipr/jsPublish
import { BliprClient } from '@blipr/js';
const blipr = new BliprClient(); // defaults to https://blipr.dev
await blipr.publish('my-alerts', 'Build finished', {
title: 'CI',
priority: 4, // 1–5, or 'min'|'low'|'default'|'high'|'max'|'urgent'
tags: ['rocket'], // string or string[]
click: 'https://ci.example.com/run/42',
});publish() resolves with the stored message (including its id).
Subscribe
Callback style, with automatic reconnect:
const sub = blipr.subscribe('my-alerts', (msg) => {
console.log(msg.title, msg.message);
});
// later
sub.close();Async-iterator style:
for await (const msg of blipr.messages('my-alerts')) {
console.log(msg.message);
if (done) break; // breaking closes the connection
}Catch up on history, then stream — or just poll and stop:
blipr.subscribe('my-alerts', onMessage, { since: '10m' }); // last 10 minutes, then live
const backlog = [];
for await (const m of blipr.messages('my-alerts', { poll: true })) backlog.push(m); // one-shotSubscribe to multiple topics at once with a comma-separated list: blipr.subscribe('a,b,c', ...).
Protected topics (tokens)
Set a token on the client (or per call) and it's sent as Authorization: Bearer …:
const blipr = new BliprClient({ token: process.env.BLIPR_TOKEN });
await blipr.publish('deploys', 'Promoting to prod'); // authenticated
// per-call override
await blipr.publish('deploys', 'hi', { token: 'another-token' });Until protected topics land on the server this is simply forwarded and ignored — your code won't change when they do.
Ask for a reply
await blipr.publish('deploys', 'Promote to prod?', {
reply: 'choice',
options: ['Promote', 'Hold', 'Rollback'],
callback: 'https://ci.example.com/blipr-hook', // the reply is POSTed here
});reply: 'binary' gives Yes/No, reply: 'ack' a single Acknowledge. The first reply wins and locks the answer.
Self-hosting
Point the client at your own notify server:
const blipr = new BliprClient({ server: 'https://notify.mycompany.internal' });API
| Method | Description |
|---|---|
| new BliprClient({ server?, token?, fetch? }) | Create a client. |
| publish(topic, message, options?) | Publish; resolves with the message. |
| subscribe(topic, onMessage, options?) | Stream messages via a callback; returns { close(), done }. |
| messages(topic, options?) | Async-iterable of messages. |
PublishOptions: title, priority, tags, click, icon, markdown, reply, options, callback, token, signal.
SubscribeOptions: since, poll, filter, token, signal, onOpen, onError.
Errors throw a BliprError (with .status and .body for HTTP failures).
Environment notes
- Node ≥ 18, Deno, Bun, edge runtimes — work out of the box (global
fetchwith streaming). On older Node, pass afetch(e.g.undici). This is the primary use case: CI, scripts, servers, integrations. - Browser — the client is browser-safe (no Node-only imports). Cross-origin browser requests require the notify server to allow your origin via CORS (a standard browser requirement); pages served same-origin as the server need no extra setup. For browser publishing, also remember topic names are public unless protected.
License
MIT © Applogico
