isorun 0.1.0.pre-arm64-darwin

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Isorun
4
+ class Config
5
+ # Isorun configuration option DSL
6
+ module Option
7
+ # Defines configuration option
8
+ #
9
+ # When you call option, it defines two methods. One method will take place
10
+ # in the +Config+ class and the other method will take place in the
11
+ # +Builder+ class.
12
+ #
13
+ # The +name+ parameter will set both builder method and config attribute.
14
+ # If the +:as+ option is defined, the builder method will be the specified
15
+ # option while the config attribute will be the +name+ parameter.
16
+ #
17
+ # If you want to introduce another level of config DSL you can
18
+ # define +builder_class+ parameter.
19
+ # Builder should take a block as the initializer parameter and respond to function +build+
20
+ # that returns the value of the config attribute.
21
+ #
22
+ # ==== Options
23
+ #
24
+ # * [:+as+] Set the builder method that goes inside +configure+ block
25
+ # * [+:default+] The default value in case no option was set
26
+ # * [+:builder_class+] Configuration option builder class
27
+ #
28
+ # ==== Examples
29
+ #
30
+ # option :name
31
+ # option :name, as: :set_name
32
+ # option :name, default: 'My Name'
33
+ # option :scopes builder_class: ScopesBuilder
34
+ #
35
+ def option(name, options = {})
36
+ attribute = options[:as] || name
37
+ attribute_builder = options[:builder_class]
38
+
39
+ builder_class.instance_eval do
40
+ if method_defined?(name)
41
+ Kernel.warn "[ISORUN] Option #{name} already defined and will be overridden"
42
+ remove_method name
43
+ end
44
+
45
+ define_method name do |*args, &block|
46
+ if (deprecation_opts = options[:deprecated])
47
+ warning = "[ISORUN] #{name} has been deprecated and will soon be removed"
48
+ warning = "#{warning}\n#{deprecation_opts.fetch(:message)}" if deprecation_opts.is_a?(Hash)
49
+
50
+ Kernel.warn(warning)
51
+ end
52
+
53
+ value = if attribute_builder
54
+ attribute_builder.new(&block).build
55
+ else
56
+ block || args.first
57
+ end
58
+
59
+ @config.instance_variable_set(:"@#{attribute}", value)
60
+ end
61
+ end
62
+
63
+ define_method attribute do |*_args|
64
+ if instance_variable_defined?(:"@#{attribute}")
65
+ instance_variable_get(:"@#{attribute}")
66
+ else
67
+ options[:default]
68
+ end
69
+ end
70
+
71
+ public attribute
72
+ end
73
+
74
+ def self.extended(base)
75
+ return if base.respond_to?(:builder_class)
76
+
77
+ raise Isorun::MissingConfigurationBuilderClass, "Define `self.builder_class` method " \
78
+ "for #{base} that returns your custom Builder class to use options DSL!"
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Isorun
4
+ class Config
5
+ # Isorun configuration validator.
6
+ #
7
+ module Validations
8
+ # Validates configuration options to be set properly.
9
+ def validate!; end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "isorun/config/abstract_builder"
4
+ require "isorun/config/option"
5
+ require "isorun/config/validations"
6
+ require "isorun/resolver"
7
+
8
+ # taken from https://github.com/doorkeeper-gem/doorkeeper/blob/main/lib/doorkeeper/config.rb
9
+ module Isorun
10
+ class MissingConfiguration < StandardError
11
+ def initialize
12
+ super("Configuration for isorun is missing. Do you have a isorun initializer?")
13
+ end
14
+ end
15
+
16
+ class MissingConfigurationBuilderClass < StandardError; end
17
+
18
+ class << self
19
+ def configure(&block)
20
+ @config = Config::Builder.new(&block).build
21
+ end
22
+
23
+ def configuration
24
+ @config || (raise MissingConfiguration)
25
+ end
26
+
27
+ alias config configuration
28
+ end
29
+
30
+ class Config
31
+ class Builder < AbstractBuilder
32
+ end
33
+
34
+ # Replace with `default: Builder` when we drop support of Rails < 5.2
35
+ mattr_reader(:builder_class) { Builder }
36
+
37
+ extend Option
38
+ include Validations
39
+
40
+ option :module_resolver, default: Isorun::Resolver::SSR_APP_RESOLVER
41
+ option :receiver, default: ->(*_args, **_kwargs) {}
42
+ end
43
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Isorun
4
+ class Context
5
+ class Import
6
+ attr_reader :context, :export_names
7
+
8
+ def initialize(context, export_names)
9
+ @context = context
10
+ @export_names = export_names
11
+ end
12
+
13
+ def from(module_path)
14
+ mod = load(module_path)
15
+ imports = export_names.map { |export_name| mod.import(export_name) }
16
+ return imports.first if imports.size == 1
17
+
18
+ imports
19
+ end
20
+
21
+ private
22
+
23
+ CACHE_KEY = "isorun_module_path_mtime"
24
+ private_constant :CACHE_KEY
25
+
26
+ def load(module_path)
27
+ return context.load(module_path) if Rails.env.production?
28
+
29
+ key = module_path.parameterize
30
+
31
+ file = File.open(module_path)
32
+ mtime = file.mtime.to_i
33
+
34
+ cache_miss = false
35
+
36
+ prev_mtime = Rails.cache.fetch("#{CACHE_KEY}:#{key}") do
37
+ cache_miss = true
38
+ mtime
39
+ end
40
+
41
+ # map to URI scheme to allow adding a timestamp to bust module cache
42
+ module_path = "file://#{module_path}?t=#{mtime}"
43
+
44
+ return context.load(module_path) if cache_miss
45
+
46
+ Rails.cache.write("#{CACHE_KEY}:#{key}", mtime) if prev_mtime < mtime
47
+
48
+ context.load(module_path)
49
+ end
50
+ end
51
+
52
+ private_constant :Import
53
+
54
+ class << self
55
+ def create(&block)
56
+ raise "[Isorun::Context] block missing when creating context" unless block
57
+
58
+ context = Isorun::Context.new
59
+ yield(context)
60
+ end
61
+
62
+ # @!method new()
63
+ # @return [Isorun::Context] the newly created context
64
+
65
+ private
66
+
67
+ def default_options
68
+ {
69
+ receiver: Isorun.configuration.receiver
70
+ }
71
+ end
72
+ end
73
+
74
+ def import(*export_names)
75
+ export_names = [*export_names].map(&:to_s)
76
+ export_names = [:default.to_s] if export_names.empty?
77
+ Import.new(self, export_names)
78
+ end
79
+ end
80
+
81
+ # @!method receiver=(receiver)
82
+ # @param receiver [Proc]
83
+ # @return [Isorun::Context] the newly created context
84
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/engine"
4
+
5
+ module Isorun
6
+ class Engine < Rails::Engine
7
+ isolate_namespace Isorun
8
+ config.eager_load_namespaces << Isorun
9
+ config.autoload_once_paths = %W[
10
+ #{root}/app/helpers
11
+ ]
12
+
13
+ initializer "isorun.helpers", before: :load_config_initializers do
14
+ ActiveSupport.on_load(:action_controller_base) do
15
+ Rails.logger.debug Isorun::Engine.helpers
16
+ helper Isorun::Engine.helpers
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Isorun
4
+ class Function # rubocop:disable Lint/EmptyClass
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Isorun
4
+ class Module # rubocop:disable Lint/EmptyClass
5
+ end
6
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Isorun
4
+ module Resolver
5
+ SSR_APP_RESOLVER = lambda { |bundle_id|
6
+ if Rails.env.development?
7
+ Rails.root.join("app", "assets", "builds", "#{bundle_id}-server.js").to_s
8
+ else
9
+ javascript_path("#{bundle_id}-server")
10
+ end
11
+ }
12
+
13
+ SIMPLE_RESOLVER = lambda { |bundle_id|
14
+ if Rails.env.development?
15
+ Rails.root.join("app", "assets", "builds", "#{bundle_id}.js").to_s
16
+ else
17
+ javascript_path(bundle_id)
18
+ end
19
+ }
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Isorun
4
+ VERSION = "0.1.0.pre"
5
+ end
data/lib/isorun.rb ADDED
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # load native extension
4
+ begin
5
+ ruby_version = /(\d+\.\d+)/.match(::RUBY_VERSION)
6
+ require "isorun/#{ruby_version}/isorun"
7
+ rescue LoadError
8
+ require "isorun/isorun"
9
+ end
10
+
11
+ require "isorun/config"
12
+ require "isorun/context"
13
+ require "isorun/engine"
14
+ require "isorun/function"
15
+ require "isorun/module"
16
+ require "isorun/version"
17
+
18
+ module Isorun
19
+ extend ActiveSupport::Autoload
20
+
21
+ class Error < StandardError; end
22
+
23
+ def self.with_receiver(receiver)
24
+ self.receiver = receiver
25
+ result = yield
26
+ self.receiver = nil
27
+ result
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,172 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: isorun
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.pre
5
+ platform: arm64-darwin
6
+ authors:
7
+ - Hannes Moser
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-12-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: railties
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 6.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 6.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '13.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '13.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rb_sys
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.9.46
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.9.46
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake-compiler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake-compiler-dock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec-rails
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: "Import ECMAScript modules into Ruby and use values and functions like
98
+ \nJavaScript is part of Ruby. Enables easy to set up server-side rendering for\nmodern
99
+ frontend stacks.\n\nIsorun embeds v8 into Ruby via a native extension built with
100
+ Rust and\ndeno_core.\n"
101
+ email:
102
+ - box@hannesmoser.at
103
+ executables: []
104
+ extensions: []
105
+ extra_rdoc_files: []
106
+ files:
107
+ - LICENSE
108
+ - README.md
109
+ - Rakefile
110
+ - app/helpers/isorun/app_helper.rb
111
+ - ext/isorun/Cargo.lock
112
+ - ext/isorun/Cargo.toml
113
+ - ext/isorun/extconf.rb
114
+ - ext/isorun/src/call.js
115
+ - ext/isorun/src/isorun/configure.rs
116
+ - ext/isorun/src/isorun/context.rs
117
+ - ext/isorun/src/isorun/function.rs
118
+ - ext/isorun/src/isorun/mod.rs
119
+ - ext/isorun/src/isorun/module.rs
120
+ - ext/isorun/src/isorun/utils.rs
121
+ - ext/isorun/src/js/mod.rs
122
+ - ext/isorun/src/js/module.rs
123
+ - ext/isorun/src/js/module_item.rs
124
+ - ext/isorun/src/js/worker.rs
125
+ - ext/isorun/src/lib.rs
126
+ - lib/isorun.rb
127
+ - lib/isorun/2.7/isorun.bundle
128
+ - lib/isorun/3.0/isorun.bundle
129
+ - lib/isorun/3.1/isorun.bundle
130
+ - lib/isorun/config.rb
131
+ - lib/isorun/config/abstract_builder.rb
132
+ - lib/isorun/config/option.rb
133
+ - lib/isorun/config/validations.rb
134
+ - lib/isorun/context.rb
135
+ - lib/isorun/engine.rb
136
+ - lib/isorun/function.rb
137
+ - lib/isorun/module.rb
138
+ - lib/isorun/resolver.rb
139
+ - lib/isorun/version.rb
140
+ homepage: https://github.com/eliias/isorun
141
+ licenses:
142
+ - MIT
143
+ metadata:
144
+ allowed_push_host: https://rubygems.org
145
+ homepage_uri: https://github.com/eliias/isorun
146
+ source_code_uri: https://github.com/eliias/isorun
147
+ changelog_uri: https://github.com/eliias/isorun
148
+ documentation_uri: https://eliias.github.io/isorun
149
+ rubygems_mfa_required: 'true'
150
+ post_install_message:
151
+ rdoc_options: []
152
+ require_paths:
153
+ - lib
154
+ required_ruby_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '2.7'
159
+ - - "<"
160
+ - !ruby/object:Gem::Version
161
+ version: 3.2.dev
162
+ required_rubygems_version: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">"
165
+ - !ruby/object:Gem::Version
166
+ version: 1.3.1
167
+ requirements: []
168
+ rubygems_version: 3.3.22
169
+ signing_key:
170
+ specification_version: 4
171
+ summary: Run JavaScript applications in your Rails application.
172
+ test_files: []