Files
noise/noise-sse.el
T

55 lines
1.7 KiB
EmacsLisp

;;; noise-sse.el --- SSE client for signal-cli -*- lexical-binding: t; -*-
;;; Commentary:
;; Implements Server-Sent Events client for receiving real-time messages
;; from signal-cli daemon's /api/v1/events endpoint.
;;; Code:
(require 'url)
(require 'json)
(require 'cl-lib)
(defvar noise-sse--process nil
"Active SSE network process, or nil.")
(defvar noise-sse--reconnect-timer nil
"Timer for reconnection attempts, or nil.")
(defvar noise-sse--reconnect-delay 1
"Current delay in seconds before next reconnection attempt.")
(defcustom noise-sse-max-reconnect-delay 60
"Maximum delay in seconds between reconnection attempts."
:type 'integer
:group 'noise)
(defun noise-sse--increase-reconnect-delay ()
"Increase reconnect delay with exponential backoff, capped at max."
(setq noise-sse--reconnect-delay
(min (* noise-sse--reconnect-delay 2)
noise-sse-max-reconnect-delay)))
(defun noise-sse--reset-reconnect-delay ()
"Reset reconnect delay to initial value after successful connection."
(setq noise-sse--reconnect-delay 1))
(defun noise-sse--parse-event (event-string)
"Parse an SSE EVENT-STRING into a hash table.
Returns nil for empty or invalid events."
(when (and event-string (not (string-empty-p event-string)))
(let ((lines (split-string event-string "\n"))
(data-lines '()))
(dolist (line lines)
(when (string-prefix-p "data: " line)
(push (substring line 6) data-lines)))
(when data-lines
(let ((json-str (mapconcat #'identity (nreverse data-lines) "")))
(condition-case nil
(json-parse-string json-str)
(error nil)))))))
(provide 'noise-sse)
;;; noise-sse.el ends here