Class: Dommy::EventSource

Inherits:
Object
  • Object
show all
Includes:
EventTarget
Defined in:
lib/dommy/event_source.rb

Overview

‘EventSource` (Server-Sent Events). Like `WebSocket`, dommy provides simulation seams instead of network IO:

es.__simulate_open__
es.__simulate_message__(data, event: "msg", id: "1")
es.__simulate_error__

Auto-opens on a microtask after construction, mirroring real browser behavior.

Spec: html.spec.whatwg.org/multipage/server-sent-events.html

Constant Summary collapse

CONNECTING =
0
OPEN =
1
CLOSED =
2
INLINE_HANDLERS =
%w[open message error].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from EventTarget

#__deliver_event__, #add_event_listener, #dispatch_event, #invoke_listener, #remove_event_listener

Constructor Details

#initialize(window, url, options = nil) ⇒ EventSource

Returns a new instance of EventSource.



26
27
28
29
30
31
32
33
34
35
# File 'lib/dommy/event_source.rb', line 26

def initialize(window, url, options = nil)
  @window = window
  @url = url.to_s
  @ready_state = CONNECTING
  opts = options.is_a?(Hash) ? options : {}
  @with_credentials = !!(opts["withCredentials"] || opts[:withCredentials])
  @inline_handlers = {}

  @window.scheduler.queue_microtask(proc { __simulate_open__ })
end

Instance Attribute Details

#ready_stateObject (readonly)

Returns the value of attribute ready_state.



24
25
26
# File 'lib/dommy/event_source.rb', line 24

def ready_state
  @ready_state
end

#urlObject (readonly)

Returns the value of attribute url.



24
25
26
# File 'lib/dommy/event_source.rb', line 24

def url
  @url
end

#with_credentialsObject (readonly)

Returns the value of attribute with_credentials.



24
25
26
# File 'lib/dommy/event_source.rb', line 24

def with_credentials
  @with_credentials
end

Instance Method Details

#__event_parent__Object



104
105
106
# File 'lib/dommy/event_source.rb', line 104

def __event_parent__
  nil
end

#__js_call__(method, args) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/dommy/event_source.rb', line 91

def __js_call__(method, args)
  case method
  when "close"
    close
  when "addEventListener"
    add_event_listener(args[0], args[1], args[2])
  when "removeEventListener"
    remove_event_listener(args[0], args[1])
  when "dispatchEvent"
    dispatch_event(args[0])
  end
end

#__js_get__(key) ⇒ Object

— JS bridge ————————————————-



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/dommy/event_source.rb', line 66

def __js_get__(key)
  case key
  when "url"
    @url
  when "readyState"
    @ready_state
  when "withCredentials"
    @with_credentials
  when "CONNECTING"
    CONNECTING
  when "OPEN"
    OPEN
  when "CLOSED"
    CLOSED
  else
    @inline_handlers[inline_event_for(key)]
  end
end

#__js_set__(key, value) ⇒ Object



85
86
87
88
89
# File 'lib/dommy/event_source.rb', line 85

def __js_set__(key, value)
  event = inline_event_for(key)
  set_inline_handler(event, value) if event
  nil
end

#__simulate_error__Object



60
61
62
# File 'lib/dommy/event_source.rb', line 60

def __simulate_error__
  dispatch_event(Event.new("error"))
end

#__simulate_message__(data, event: "message", id: nil, retry_ms: nil) ⇒ Object



51
52
53
54
55
56
57
58
# File 'lib/dommy/event_source.rb', line 51

def __simulate_message__(data, event: "message", id: nil, retry_ms: nil)
  return if @ready_state != OPEN

  payload = {"data" => data.to_s}
  payload["lastEventId"] = id.to_s if id
  payload["retry"] = retry_ms.to_i if retry_ms
  dispatch_event(MessageEvent.new(event.to_s, payload))
end

#__simulate_open__Object

— Test seams ————————————————



44
45
46
47
48
49
# File 'lib/dommy/event_source.rb', line 44

def __simulate_open__
  return if @ready_state != CONNECTING

  @ready_state = OPEN
  dispatch_event(Event.new("open"))
end

#closeObject



37
38
39
40
# File 'lib/dommy/event_source.rb', line 37

def close
  @ready_state = CLOSED
  nil
end