push

package
v0.8.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2026 License: MIT Imports: 27 Imported by: 0

Documentation

Overview

Package push delivers browser Web Push notifications for usher: a turn finishing or a permission prompt arriving while the web UI is closed or backgrounded. It is a second consumer of the same event seams the web SSE layer uses — broker.SubscribeAll for turn-end, hook.SubscribePending for permission requests — and fans those out to subscribed browsers.

The protocol is implemented from the stdlib only (RFC 8291 message encryption, RFC 8292 VAPID), so usher gains push without a new dependency.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	KeyPath   string // VAPID keypair JSON
	StorePath string // subscriptions JSON
	Lookup    Lookup
	Events    EventSource
	Pending   PendingSource
	Logger    *slog.Logger
}

Config wires a Manager. StorePath/KeyPath live under the usher data dir.

type EventSource

type EventSource interface {
	SubscribeAll() (<-chan broker.Event, func())
	HasViewers(sessionID string) bool
}

EventSource and PendingSource are the two broker/hook seams push consumes. Declared as interfaces so the Manager is testable without the real ones and so they document exactly what push needs from each: every session's events, plus whether a session is being watched live (to suppress its notifications).

type Lookup

type Lookup func(sessionID string) (info SessionInfo, ok bool)

Lookup resolves a session id to display metadata; ok is false when the session is no longer discoverable.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager owns the VAPID identity, the subscription store, and the dispatch loop. It is always constructed (keys are cheap); it simply does nothing while no browser has subscribed.

func New

func New(cfg Config) (*Manager, error)

New loads or creates the VAPID keys and subscription store. A failure to set up keys is fatal to push but the caller may choose to continue without it.

func (*Manager) Run

func (m *Manager) Run(ctx context.Context)

Run consumes turn-end and permission events until ctx is cancelled, fanning each out to all current subscriptions. Safe to call when Events/Pending are nil (it just blocks on ctx).

func (*Manager) Subscribe

func (m *Manager) Subscribe(sub Subscription) error

Subscribe records a browser subscription (idempotent by endpoint).

func (*Manager) Unsubscribe

func (m *Manager) Unsubscribe(endpoint string)

Unsubscribe drops a subscription by endpoint (no error if unknown).

func (*Manager) VAPIDPublicKey

func (m *Manager) VAPIDPublicKey() string

VAPIDPublicKey returns the applicationServerKey the browser needs to subscribe.

type PendingSource

type PendingSource interface {
	SubscribePending() (<-chan hook.Pending, func())
}

type SessionInfo

type SessionInfo struct {
	Title string
	Cwd   string
}

SessionInfo is the slice of session metadata a notification needs; supplied by a Lookup so push doesn't depend on the router.

type Subscription

type Subscription struct {
	Endpoint string `json:"endpoint"`
	Keys     struct {
		P256dh string `json:"p256dh"`
		Auth   string `json:"auth"`
	} `json:"keys"`
}

Subscription is a browser PushSubscription as serialized by PushSubscription.toJSON() and POSTed by the web client.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL