Class: Cloudflare::DurableObjectStub
- Inherits:
-
Object
- Object
- Cloudflare::DurableObjectStub
- Defined in:
- lib/homura/runtime/durable_object.rb
Overview
Wraps a stub (the object returned by ‘namespace.get(id)`). Its only callable method is `fetch(request)`, which submits an HTTP request to the DO instance and returns a `Response`. We return the same `Cloudflare::HTTPResponse` shape as Phase 6 so routes don’t need to learn a second API.
Instance Attribute Summary collapse
-
#js ⇒ Object
readonly
Returns the value of attribute js.
Instance Method Summary collapse
- #delete(path, headers: nil) ⇒ Object
-
#fetch(url_or_request, method: "GET", headers: nil, body: nil) ⇒ Object
Call the DO with a plain URL (String) and optional init-Hash.
-
#fetch_raw(url_or_request, method: "GET", headers: nil, body: nil) ⇒ Object
Same as ‘fetch` but returns the raw JS Response (a JS Promise resolving to it) instead of wrapping it in a `Cloudflare::HTTPResponse`.
- #get(path, headers: nil) ⇒ Object
-
#initialize(js) ⇒ DurableObjectStub
constructor
A new instance of DurableObjectStub.
- #post(path, body = nil, headers: nil) ⇒ Object
- #put(path, body = nil, headers: nil) ⇒ Object
- #request(path, method: "GET", headers: nil, body: nil) ⇒ Object
Constructor Details
#initialize(js) ⇒ DurableObjectStub
Returns a new instance of DurableObjectStub.
131 132 133 |
# File 'lib/homura/runtime/durable_object.rb', line 131 def initialize(js) @js = js end |
Instance Attribute Details
#js ⇒ Object (readonly)
Returns the value of attribute js.
129 130 131 |
# File 'lib/homura/runtime/durable_object.rb', line 129 def js @js end |
Instance Method Details
#delete(path, headers: nil) ⇒ Object
216 217 218 |
# File 'lib/homura/runtime/durable_object.rb', line 216 def delete(path, headers: nil) request(path, method: "DELETE", headers: headers) end |
#fetch(url_or_request, method: "GET", headers: nil, body: nil) ⇒ Object
Call the DO with a plain URL (String) and optional init-Hash. The DO’s fetch handler sees the URL as-is (no routing layer strips the prefix), so user code can use any pathname it wants as its internal DO command channel. Returns a JS Promise the caller ‘__await__`s to get a `Cloudflare::HTTPResponse`.
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/homura/runtime/durable_object.rb', line 157 def fetch(url_or_request, method: "GET", headers: nil, body: nil) js_stub = @js hdrs = headers || {} method_str = method.to_s.upcase js_headers = Cloudflare::HTTP.ruby_headers_to_js(hdrs) js_body = body.nil? ? nil : body.to_s url_str = url_or_request.to_s err_klass = Cloudflare::DurableObjectError response_klass = Cloudflare::HTTPResponse do_class_label = "DurableObjectStub" # Single-line IIFE — see `lib/homura/runtime/cache.rb#put` # for why Opal can silently drop a multi-line x-string Promise. js_promise = `(async function(stub, url_str, method_str, js_headers, js_body, Kernel, err_klass, do_class_label) { var init = { method: method_str, headers: js_headers }; if (js_body !== null && js_body !== undefined && js_body !== Opal.nil) { init.body = js_body; } var resp; try { resp = await stub.fetch(url_str, init); } catch (e) { Kernel.$raise(err_klass.$new(e && e.message ? e.message : String(e), Opal.hash({ operation: 'stub.fetch', do_class: do_class_label }))); } var text = ''; try { text = await resp.text(); } catch (_) { text = ''; } var hk = []; var hv = []; if (resp.headers && typeof resp.headers.forEach === 'function') { resp.headers.forEach(function(v, k) { hk.push(String(k).toLowerCase()); hv.push(String(v)); }); } return { status: resp.status|0, text: text, hkeys: hk, hvals: hv }; })(#{js_stub}, #{url_str}, #{method_str}, #{js_headers}, #{js_body}, #{Kernel}, #{err_klass}, #{do_class_label})` js_result = js_promise.__await__ hkeys = `#{js_result}.hkeys` hvals = `#{js_result}.hvals` h = {} i = 0 len = `#{hkeys}.length` while i < len h[`#{hkeys}[#{i}]`] = `#{hvals}[#{i}]` i += 1 end response_klass.new( status: `#{js_result}.status`, headers: h, body: `#{js_result}.text`, url: url_str ) end |
#fetch_raw(url_or_request, method: "GET", headers: nil, body: nil) ⇒ Object
Same as ‘fetch` but returns the raw JS Response (a JS Promise resolving to it) instead of wrapping it in a `Cloudflare::HTTPResponse`. Needed for WebSocket-upgrade responses — the 101 Response carries its WebSocket in a `.webSocket` property that disappears if we reconstruct the Response via the HTTPResponse wrapper.
141 142 143 144 145 146 147 148 149 150 |
# File 'lib/homura/runtime/durable_object.rb', line 141 def fetch_raw(url_or_request, method: "GET", headers: nil, body: nil) hdrs = headers || {} method_str = method.to_s.upcase js_headers = Cloudflare::HTTP.ruby_headers_to_js(hdrs) js_body = body.nil? ? nil : body.to_s url_str = url_or_request.to_s js_stub = @js err_klass = Cloudflare::DurableObjectError `(async function(stub, url_str, method_str, js_headers, js_body, Kernel, err_klass) { var init = { method: method_str, headers: js_headers }; if (js_body !== null && js_body !== undefined && js_body !== Opal.nil) { init.body = js_body; } try { return await stub.fetch(url_str, init); } catch (e) { Kernel.$raise(err_klass.$new(e && e.message ? e.message : String(e), Opal.hash({ operation: 'stub.fetch_raw' }))); } })(#{js_stub}, #{url_str}, #{method_str}, #{js_headers}, #{js_body}, #{Kernel}, #{err_klass})` end |
#get(path, headers: nil) ⇒ Object
204 205 206 |
# File 'lib/homura/runtime/durable_object.rb', line 204 def get(path, headers: nil) request(path, method: "GET", headers: headers) end |
#post(path, body = nil, headers: nil) ⇒ Object
208 209 210 |
# File 'lib/homura/runtime/durable_object.rb', line 208 def post(path, body = nil, headers: nil) request(path, method: "POST", headers: headers, body: body) end |
#put(path, body = nil, headers: nil) ⇒ Object
212 213 214 |
# File 'lib/homura/runtime/durable_object.rb', line 212 def put(path, body = nil, headers: nil) request(path, method: "PUT", headers: headers, body: body) end |
#request(path, method: "GET", headers: nil, body: nil) ⇒ Object
192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/homura/runtime/durable_object.rb', line 192 def request(path, method: "GET", headers: nil, body: nil) hdrs = headers ? headers.dup : {} request_body = body if body.is_a?(Hash) || body.is_a?(Array) request_body = body.to_json unless hdrs.key?("content-type") || hdrs.key?("Content-Type") hdrs["content-type"] = "application/json" end end fetch(path, method: method, headers: hdrs, body: request_body) end |