Class: JS::RequireRemote

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/js/require_remote.rb,
lib/js/require_remote/evaluator.rb,
lib/js/require_remote/url_resolver.rb

Overview

This class is used to load remote Ruby scripts.

Example

require 'js/require_remote'
JS::RequireRemote.instance.load("foo")

This class is intended to be used to replace Kernel#require_relative.

Example

require 'js/require_remote'
module Kernel
  def require_relative(path) = JS::RequireRemote.instance.load(path)
end

If you want to load the bundled gem

Example

require 'js/require_remote'
module Kernel
  alias original_require_relative require_relative

  def require_relative(path)
    caller_path = caller_locations(1, 1).first.absolute_path || ''
    dir = File.dirname(caller_path)
    file = File.absolute_path(path, dir)

    original_require_relative(file)
  rescue LoadError
    JS::RequireRemote.instance.load(path)
  end
end

You can also load included shim to achieve the same.

Example

require 'js/require_remote/relative_shim'

Defined Under Namespace

Classes: Evaluator, URLResolver

Constant Summary collapse

ScriptLocation =
Data.define(:url, :filename)

Instance Method Summary collapse

Constructor Details

#initializeRequireRemote

Returns a new instance of RequireRemote.



51
52
53
54
55
56
# File 'lib/js/require_remote.rb', line 51

def initialize
  # By default, the base_url is the URL of the HTML file that invoked ruby.wasm vm.
  base_url = JS.global[:URL].new(JS.global[:location][:href])
  @resolver = URLResolver.new(base_url)
  @evaluator = Evaluator.new
end

Instance Method Details

#base_url=(base_url) ⇒ Object

If you want to resolve relative paths to a starting point other than the HTML file that executes ruby.wasm, you can set the base_url property. For example, if you want to use the ‘lib` directory as the starting point, specify base_url as follows

Example

require 'js/require_remote'
JS::RequireRemote.instance.base_url = "lib"
JS::RequireRemote.instance.load("foo") # => 'lib/foo.rb' will be loaded.


67
68
69
70
71
# File 'lib/js/require_remote.rb', line 67

def base_url=(base_url)
  base_url = base_url.end_with?("/") ? base_url : "#{base_url}/"
  url = JS.global[:URL].new(base_url, JS.global[:location][:href])
  @resolver = URLResolver.new(url)
end

#load(relative_feature) ⇒ Object

Load the given feature from remote.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/js/require_remote.rb', line 74

def load(relative_feature)
  location = @resolver.get_location(relative_feature)

  # Do not load the same URL twice.
  return false if @evaluator.evaluated?(location.url[:href].to_s)

  response = JS.global.fetch(location.url).await
  unless response[:status].to_i == 200
    raise LoadError.new "cannot load such url -- #{response[:status]} #{location.url}"
  end

  # The fetch API may have responded to a redirect response
  # and fetched the script from a different URL than the original URL.
  # Retrieve the final URL again from the response object.
  final_url = response[:url].to_s

  # Do not evaluate the same URL twice.
  return false if @evaluator.evaluated?(final_url)

  code = response.text().await.to_s

  evaluate(code, location.filename, final_url)
end