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

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.



45
46
47
48
49
50
# File 'lib/js/require_remote.rb', line 45

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.


61
62
63
64
65
# File 'lib/js/require_remote.rb', line 61

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.



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/js/require_remote.rb', line 68

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