Module: OpenLoam::EventStream
- Defined in:
- lib/open_loam/event_stream.rb
Overview
The real-time bridge: pushes selected OpenLoam events to a browser over Server-Sent Events, so the admin updates live instead of polling.
SECURITY POSTURE — default OFF. An event reaches a browser only if ALL hold:
* its name matches a declared OpenLoam.broadcast_events pattern (opt-in), AND
* its tenant matches the connected tenant (isolation), AND
* its audience includes the connected actor (a payload `user_id`, if any,
is the sole recipient; no `user_id` means tenant-wide).
FAN-OUT is behind a swappable broadcaster seam (OpenLoam::EventStream.broadcaster). The default in-process broadcaster only sees events published in THIS process — fine for the single-process prototype; a multi-process deploy swaps in a Redis/SolidCable-backed broadcaster with no controller change (see docs/_foundation/overview.md).
Defined Under Namespace
Classes: InProcessBroadcaster
Class Attribute Summary collapse
Class Method Summary collapse
-
.broadcastable?(event_name) ⇒ Boolean
Is this event name allowed to reach browsers at all? Empty allow-list → false, always (nothing leaks by default).
-
.deliverable?(event_name, payload, tenant:, actor:) ⇒ Boolean
Should a broadcastable event reach a stream connected as (tenant, actor)?.
-
.frame(event_name, payload) ⇒ Object
One SSE message: an
event:line (the OpenLoam event name) and adata:line (JSON), ended by a blank line.
Class Attribute Details
.broadcaster ⇒ Object
20 21 22 |
# File 'lib/open_loam/event_stream.rb', line 20 def broadcaster @broadcaster ||= InProcessBroadcaster.new end |
Class Method Details
.broadcastable?(event_name) ⇒ Boolean
Is this event name allowed to reach browsers at all? Empty allow-list → false, always (nothing leaks by default).
26 27 28 29 30 31 32 |
# File 'lib/open_loam/event_stream.rb', line 26 def broadcastable?(event_name) OpenLoam.broadcast_events.any? do |pattern| next false if OpenLoam::Overrides.disabled?(:broadcast_events, pattern) # an app can turn a default pattern off OpenLoam::Events.pattern_matches?(pattern, event_name) end end |
.deliverable?(event_name, payload, tenant:, actor:) ⇒ Boolean
Should a broadcastable event reach a stream connected as (tenant, actor)?
35 36 37 38 39 40 41 42 43 |
# File 'lib/open_loam/event_stream.rb', line 35 def deliverable?(event_name, payload, tenant:, actor:) return false unless broadcastable?(event_name) payload = payload.symbolize_keys return false unless payload[:tenant_id] == tenant&.id recipient = payload[:user_id] recipient.nil? || recipient == actor&.id end |
.frame(event_name, payload) ⇒ Object
One SSE message: an event: line (the OpenLoam event name) and a data:
line (JSON), ended by a blank line. Only small id-ish keys ride along —
OpenLoam events carry no attribute values, and this slices to a safe set as
belt-and-suspenders (tenant_id is dropped; it is implied by the connection).
49 50 51 |
# File 'lib/open_loam/event_stream.rb', line 49 def frame(event_name, payload) "event: #{event_name}\ndata: #{safe_payload(payload).to_json}\n\n" end |