Class: InstantRecord::Client::Transport::JsFetch

Inherits:
Object
  • Object
show all
Defined in:
lib/instant_record/client/transport.rb

Overview

Browser implementation over the JS fetch API via ruby.wasm's js gem. Every .await is an asyncify suspension point, so this class must only run under evalAsync.

Instance Method Summary collapse

Constructor Details

#initializeJsFetch

Returns a new instance of JsFetch.



38
39
40
# File 'lib/instant_record/client/transport.rb', line 38

def initialize
  require "js"
end

Instance Method Details

#each_event(path, &block) ⇒ Object

Streams an SSE response, yielding one parsed event hash at a time. The server closes its bounded window; we return when the body ends.

Raises:



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/instant_record/client/transport.rb', line 65

def each_event(path, &block)
  response = JS.global.fetch(url(path)).await
  raise Error, "GET #{path} -> #{response[:status]}" unless response[:ok] == JS::True

  parser = SseParser.new(&block)
  reader = response[:body].getReader
  decoder = JS.global[:TextDecoder].new
  @stream_options ||= JS.eval("return {stream: true}")

  loop do
    result = reader.read.await
    break if result[:done] == JS::True

    parser.feed(decoder.decode(result[:value], @stream_options).to_s)
  end
end

#get_json(path) ⇒ Object

Raises:



42
43
44
45
46
47
# File 'lib/instant_record/client/transport.rb', line 42

def get_json(path)
  response = JS.global.fetch(url(path)).await
  raise Error, "GET #{path} -> #{response[:status]}" unless response[:ok] == JS::True

  JSON.parse(response.text.await.to_s)
end

#post_json(path, payload) ⇒ Object

Raises:



49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/instant_record/client/transport.rb', line 49

def post_json(path, payload)
  options = JS.eval("return {}")
  options[:method] = "POST"
  headers = JS.eval("return {}")
  headers["Content-Type"] = "application/json"
  options[:headers] = headers
  options[:body] = JSON.generate(payload)

  response = JS.global.fetch(url(path), options).await
  raise Error, "POST #{path} -> #{response[:status]}" unless response[:ok] == JS::True

  JSON.parse(response.text.await.to_s)
end