hyperloop-config 0.9.11 → 0.99.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +7 -1
- data/.travis.yml +29 -0
- data/DOCS.md +45 -0
- data/Gemfile +1 -2
- data/Gemfile.lock +299 -0
- data/README.md +58 -30
- data/Rakefile +9 -0
- data/hyperloop-config.gemspec +32 -26
- data/lib/hyperloop/active_support_string_inquirer.rb +32 -0
- data/lib/hyperloop/autoloader.rb +138 -0
- data/lib/hyperloop/autoloader_starter.rb +15 -0
- data/lib/hyperloop/config/version.rb +5 -0
- data/lib/hyperloop/env.rb +10 -0
- data/lib/hyperloop/environment/development/hyperloop_env.rb +5 -0
- data/lib/hyperloop/environment/production/hyperloop_env.rb +5 -0
- data/lib/hyperloop/environment/staging/hyperloop_env.rb +5 -0
- data/lib/hyperloop/environment/test/hyperloop_env.rb +5 -0
- data/lib/hyperloop/imports.rb +35 -50
- data/lib/hyperloop/js_imports.rb +18 -0
- data/lib/hyperloop/on_error.rb +5 -0
- data/lib/hyperloop/rail_tie.rb +35 -12
- data/lib/hyperloop/string.rb +6 -0
- data/lib/hyperloop-config.rb +18 -0
- data/lib/hyperloop-loader.js +1 -1
- data/lib/hyperloop-prerender-loader.js +1 -1
- metadata +127 -38
- data/CODE_OF_CONDUCT.md +0 -49
- data/LICENSE.txt +0 -21
- data/lib/hyperloop-loader-system.js.erb +0 -1
- data/lib/hyperloop-prerender-loader-system.js.erb +0 -1
data/Rakefile
CHANGED
data/hyperloop-config.gemspec
CHANGED
@@ -1,37 +1,43 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'hyperloop/config/version'
|
4
5
|
|
5
6
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
7
|
-
spec.version =
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
10
|
-
|
7
|
+
spec.name = 'hyperloop-config'
|
8
|
+
spec.version = Hyperloop::Config::VERSION
|
9
|
+
spec.authors = ['Mitch VanDuyn', 'Jan Biedermann']
|
10
|
+
spec.email = ['mitch@catprint.com', 'jan@kursator.com']
|
11
11
|
spec.summary = %q{Provides a single point configuration module for hyperloop gems}
|
12
|
-
spec.homepage =
|
13
|
-
spec.license =
|
12
|
+
spec.homepage = 'http://ruby-hyperloop.org'
|
13
|
+
spec.license = 'MIT'
|
14
|
+
# spec.metadata = {
|
15
|
+
# "homepage_uri" => 'http://ruby-hyperloop.org',
|
16
|
+
# "source_code_uri" => 'https://github.com/ruby-hyperloop/hyper-component'
|
17
|
+
# }
|
14
18
|
|
15
19
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
16
|
-
spec.bindir =
|
20
|
+
spec.bindir = 'exe'
|
17
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
|
-
spec.require_paths = [
|
19
|
-
|
20
|
-
spec.add_dependency '
|
21
|
-
spec.add_dependency '
|
22
|
-
|
23
|
-
spec.
|
24
|
-
spec.
|
25
|
-
|
26
|
-
|
27
|
-
spec.add_development_dependency '
|
28
|
-
spec.add_development_dependency '
|
29
|
-
spec.add_development_dependency '
|
22
|
+
spec.require_paths = ['lib']
|
23
|
+
|
24
|
+
spec.add_dependency 'libv8', '~> 6.3.0' # see https://github.com/discourse/mini_racer/issues/92
|
25
|
+
spec.add_dependency 'mini_racer', '~> 0.1.15'
|
26
|
+
spec.add_dependency 'opal', '>= 0.11.0', '< 0.12.0'
|
27
|
+
spec.add_dependency 'opal-browser', '~> 0.2.0'
|
28
|
+
spec.add_dependency 'uglifier'
|
29
|
+
|
30
|
+
|
31
|
+
spec.add_development_dependency 'bundler', '~> 1.16.0'
|
32
|
+
spec.add_development_dependency 'chromedriver-helper'
|
33
|
+
spec.add_development_dependency 'hyper-spec', Hyperloop::Config::VERSION
|
34
|
+
spec.add_development_dependency 'opal-rails', '~> 0.9.4'
|
35
|
+
spec.add_development_dependency 'pry'
|
36
|
+
spec.add_development_dependency 'puma'
|
37
|
+
spec.add_development_dependency 'rails', '>= 4.0.0'
|
38
|
+
spec.add_development_dependency 'rake'
|
39
|
+
spec.add_development_dependency 'rspec', '~> 3.7.0'
|
40
|
+
spec.add_development_dependency 'rubocop', '~> 0.51.0'
|
30
41
|
spec.add_development_dependency 'sqlite3'
|
31
|
-
spec.add_development_dependency '
|
32
|
-
spec.add_development_dependency 'jquery-rails'
|
33
|
-
|
34
|
-
# Keep linter-rubocop happy
|
35
|
-
spec.add_development_dependency 'rubocop'
|
36
|
-
|
42
|
+
spec.add_development_dependency 'timecop', '~> 0.8.1'
|
37
43
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module ActiveSupport
|
2
|
+
# Wrapping a string in this class gives you a prettier way to test
|
3
|
+
# for equality. The value returned by <tt>Rails.env</tt> is wrapped
|
4
|
+
# in a StringInquirer object, so instead of calling this:
|
5
|
+
#
|
6
|
+
# Rails.env == 'production'
|
7
|
+
#
|
8
|
+
# you can call this:
|
9
|
+
#
|
10
|
+
# Rails.env.production?
|
11
|
+
#
|
12
|
+
# == Instantiating a new StringInquirer
|
13
|
+
#
|
14
|
+
# vehicle = ActiveSupport::StringInquirer.new('car')
|
15
|
+
# vehicle.car? # => true
|
16
|
+
# vehicle.bike? # => false
|
17
|
+
class StringInquirer < String
|
18
|
+
private
|
19
|
+
|
20
|
+
def respond_to_missing?(method_name, include_private = false)
|
21
|
+
(method_name[-1] == "?") || super
|
22
|
+
end
|
23
|
+
|
24
|
+
def method_missing(method_name, *arguments)
|
25
|
+
if method_name[-1] == "?"
|
26
|
+
self == method_name[0..-2]
|
27
|
+
else
|
28
|
+
super
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Hyperloop
|
4
|
+
class Autoloader
|
5
|
+
# All files ever loaded.
|
6
|
+
def self.history=(a)
|
7
|
+
@@history = a
|
8
|
+
end
|
9
|
+
def self.history
|
10
|
+
@@history
|
11
|
+
end
|
12
|
+
self.history = Set.new
|
13
|
+
|
14
|
+
def self.load_paths=(a)
|
15
|
+
@@load_paths = a
|
16
|
+
end
|
17
|
+
def self.load_paths
|
18
|
+
@@load_paths
|
19
|
+
end
|
20
|
+
self.load_paths = []
|
21
|
+
|
22
|
+
def self.loaded=(a)
|
23
|
+
@@loaded = a
|
24
|
+
end
|
25
|
+
def self.loaded
|
26
|
+
@@loaded
|
27
|
+
end
|
28
|
+
self.loaded = Set.new
|
29
|
+
|
30
|
+
def self.loading=(a)
|
31
|
+
@@loading = a
|
32
|
+
end
|
33
|
+
def self.loading
|
34
|
+
@@loading
|
35
|
+
end
|
36
|
+
self.loading = []
|
37
|
+
|
38
|
+
def self.const_missing(const_name, mod)
|
39
|
+
# name.nil? is testing for anonymous
|
40
|
+
from_mod = mod.name.nil? ? guess_for_anonymous(const_name) : mod
|
41
|
+
load_missing_constant(from_mod, const_name)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.guess_for_anonymous(const_name)
|
45
|
+
if Object.const_defined?(const_name)
|
46
|
+
raise NameError.new "#{const_name} cannot be autoloaded from an anonymous class or module", const_name
|
47
|
+
else
|
48
|
+
Object
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.load_missing_constant(from_mod, const_name)
|
53
|
+
# see active_support/dependencies.rb in case of reloading on how to handle
|
54
|
+
qualified_name = qualified_name_for(from_mod, const_name)
|
55
|
+
qualified_path = underscore(qualified_name)
|
56
|
+
|
57
|
+
module_path = search_for_module(qualified_path)
|
58
|
+
if module_path
|
59
|
+
if loading.include?(module_path)
|
60
|
+
raise "Circular dependency detected while autoloading constant #{qualified_name}"
|
61
|
+
else
|
62
|
+
require_or_load(from_mod, module_path)
|
63
|
+
raise LoadError, "Unable to autoload constant #{qualified_name}, expected #{module_path} to define it" unless from_mod.const_defined?(const_name, false)
|
64
|
+
return from_mod.const_get(const_name)
|
65
|
+
end
|
66
|
+
elsif (parent = from_mod.parent) && parent != from_mod &&
|
67
|
+
! from_mod.parents.any? { |p| p.const_defined?(const_name, false) }
|
68
|
+
begin
|
69
|
+
return parent.const_missing(const_name)
|
70
|
+
rescue NameError => e
|
71
|
+
raise unless missing_name?(e, qualified_name_for(parent, const_name))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.missing_name?(e, name)
|
77
|
+
mn = if /undefined/ !~ e.message
|
78
|
+
$1 if /((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/ =~ e.message
|
79
|
+
end
|
80
|
+
mn == name
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns the constant path for the provided parent and constant name.
|
84
|
+
def self.qualified_name_for(mod, name)
|
85
|
+
mod_name = to_constant_name(mod)
|
86
|
+
mod_name == 'Object' ? name.to_s : "#{mod_name}::#{name}"
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.require_or_load(from_mod, module_path)
|
90
|
+
return if loaded.include?(module_path)
|
91
|
+
loaded << module_path
|
92
|
+
loading << module_path
|
93
|
+
|
94
|
+
begin
|
95
|
+
result = require module_path
|
96
|
+
rescue Exception
|
97
|
+
loaded.delete module_path
|
98
|
+
raise LoadError, "Unable to autoload: require_or_load #{module_path} failed"
|
99
|
+
ensure
|
100
|
+
loading.pop
|
101
|
+
end
|
102
|
+
|
103
|
+
# Record history *after* loading so first load gets warnings.
|
104
|
+
history << module_path
|
105
|
+
result
|
106
|
+
# end
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.search_for_module(path)
|
110
|
+
# oh my! imagine Bart Simpson, writing on the board:
|
111
|
+
# "javascript is not ruby, javascript is not ruby, javascript is not ruby, ..."
|
112
|
+
# then running home, starting irb, on the fly developing a chat client and opening a session with Homer at his workplace: "Hi Dad ..."
|
113
|
+
load_paths.each do |load_path|
|
114
|
+
mod_path = load_path + '/' + path
|
115
|
+
return mod_path if `Opal.modules.hasOwnProperty(#{mod_path})`
|
116
|
+
end
|
117
|
+
return path if `Opal.modules.hasOwnProperty(#{path})`
|
118
|
+
nil # Gee, I sure wish we had first_match ;-)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Convert the provided const desc to a qualified constant name (as a string).
|
122
|
+
# A module, class, symbol, or string may be provided.
|
123
|
+
def self.to_constant_name(desc) #:nodoc:
|
124
|
+
case desc
|
125
|
+
when String then desc.sub(/^::/, '')
|
126
|
+
when Symbol then desc.to_s
|
127
|
+
when Module
|
128
|
+
desc.name ||
|
129
|
+
raise(ArgumentError, 'Anonymous modules have no name to be referenced by')
|
130
|
+
else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.underscore(string)
|
135
|
+
string.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').tr("-", "_").downcase
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Hyperloop::Autoloader.load_paths = %w[components models operations stores]
|
2
|
+
|
3
|
+
class Object
|
4
|
+
class << self
|
5
|
+
alias _autoloader_original_const_missing const_missing
|
6
|
+
|
7
|
+
def const_missing(const_name)
|
8
|
+
# need to call original code because some things are set up there
|
9
|
+
# original code may also be overloaded by reactrb, for example
|
10
|
+
_autoloader_original_const_missing(const_name)
|
11
|
+
rescue StandardError => e
|
12
|
+
Hyperloop::Autoloader.const_missing(const_name, self) || raise(e)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/hyperloop/imports.rb
CHANGED
@@ -5,41 +5,49 @@ module Hyperloop
|
|
5
5
|
@import_list ||= []
|
6
6
|
end
|
7
7
|
|
8
|
-
def import(value, gem: nil,
|
9
|
-
if
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
raise [
|
15
|
-
"Could not substitute import '#{instead_of}' with '#{value}'. '#{instead_of}' not found.",
|
16
|
-
'The following files are currently being imported:',
|
17
|
-
*import_list.collect { |old_value, *_rest| old_value }
|
18
|
-
].join("\n")
|
19
|
-
end
|
20
|
-
elsif !import_list.detect { |current_value, *_rest| value == current_value }
|
21
|
-
kind = if tree
|
22
|
-
:tree
|
23
|
-
else
|
24
|
-
:gem
|
25
|
-
end
|
26
|
-
import_list << [value, !client_only, !server_only, kind]
|
27
|
-
end
|
8
|
+
def import(value, gem: nil, cancelled: nil, client_only: nil, server_only: nil, tree: nil, js_import: nil, at_head: nil)
|
9
|
+
return if import_list.detect { |current_value, *_rest| value == current_value }
|
10
|
+
new_element = [
|
11
|
+
value, cancelled, !client_only, !server_only, (tree ? :tree : :gem), js_import
|
12
|
+
]
|
13
|
+
import_list.send(at_head ? :unshift : :push, new_element)
|
28
14
|
end
|
29
15
|
|
30
16
|
alias imports import
|
31
17
|
|
32
|
-
def import_tree(value,
|
33
|
-
import(value,
|
18
|
+
def import_tree(value, cancelled: nil, client_only: nil, server_only: nil)
|
19
|
+
import(value, cancelled: cancelled, client_only: client_only, server_only: server_only, tree: true)
|
34
20
|
end
|
35
21
|
|
36
22
|
def cancel_import(value)
|
37
|
-
|
23
|
+
return unless value
|
24
|
+
current_spec = import_list.detect { |old_value, *_rest| value == old_value }
|
25
|
+
if current_spec
|
26
|
+
current_spec[1] = true
|
27
|
+
else
|
28
|
+
import_list << [value, true, true, true, false]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def cancel_webpack_imports
|
33
|
+
import_list.collect { |name, _c, _co, _so, _t, js_import, *_rest| js_import && name }
|
34
|
+
.each { |name| cancel_import name }
|
35
|
+
end
|
36
|
+
|
37
|
+
def handle_webpack
|
38
|
+
return unless defined? Webpacker
|
39
|
+
client_only_manifest = Webpacker.manifest.lookup("client_only.js")
|
40
|
+
client_and_server_manifest = Webpacker.manifest.lookup("client_and_server.js")
|
41
|
+
return unless client_only_manifest || client_and_server_manifest
|
42
|
+
cancel_webpack_imports
|
43
|
+
import client_only_manifest.split("/").last, client_only: true, at_head: true if client_only_manifest
|
44
|
+
import client_and_server_manifest.split("/").last, at_head: true if client_and_server_manifest
|
38
45
|
end
|
39
46
|
|
40
47
|
def generate_requires(mode, sys, file)
|
41
|
-
|
42
|
-
|
48
|
+
handle_webpack
|
49
|
+
import_list.collect do |value, cancelled, render_on_server, render_on_client, kind|
|
50
|
+
next if cancelled
|
43
51
|
next if (sys && kind == :tree) || (!sys && kind != :tree)
|
44
52
|
next if mode == :client && !render_on_client
|
45
53
|
next if mode == :server && !render_on_server
|
@@ -89,31 +97,8 @@ module Hyperloop
|
|
89
97
|
end
|
90
98
|
end
|
91
99
|
|
92
|
-
Hyperloop.define_setting
|
93
|
-
|
94
|
-
def compile_and_compress(name, never_compress: false)
|
95
|
-
start_time = Time.now
|
96
|
-
|
97
|
-
puts "\n\n##########################################################################\n"
|
98
|
-
puts " HYPERLOOP LIBRARIES PRECOMPILING AND MINIFYING\n"
|
99
|
-
puts " FIRST TIME BOOTING YOUR APP IT CAN TAKE 1 OR 2 MINUTES\n"
|
100
|
-
puts " NB: You can force precompiling again by cleaning cache: rm -rf tmp/cache \n"
|
101
|
-
puts "##########################################################################\n\n"
|
102
|
-
|
103
|
-
puts "Compiling the system assets for #{name}"
|
104
|
-
|
105
|
-
compiled_code = Rails.application.assets[name].to_s
|
106
|
-
compilation_time = Time.now
|
107
|
-
compiled_code_length = compiled_code.length
|
108
|
-
puts " compiled - length: #{compiled_code_length}"
|
109
|
-
if Hyperloop.compress_system_assets && !never_compress
|
110
|
-
compiled_code = Uglifier.new.compile(compiled_code)
|
111
|
-
puts " minimized - length: #{compiled_code.length}"
|
112
|
-
puts " minification ratio #{(compiled_code.length*100.0/compiled_code_length).round}%"
|
113
|
-
end
|
114
|
-
puts " total time: #{(Time.now-start_time).to_f.round(2)} seconds"
|
115
|
-
compiled_code
|
100
|
+
Hyperloop.define_setting(:compress_system_assets, true) do
|
101
|
+
puts "INFO: The configuration option 'compress_system_assets' is no longer used."
|
116
102
|
end
|
117
|
-
|
118
103
|
end
|
119
104
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Hyperloop
|
2
|
+
class << self
|
3
|
+
def js_import(value, client_only: nil, server_only: nil, defines:)
|
4
|
+
defines = [*defines]
|
5
|
+
if RUBY_ENGINE != 'opal'
|
6
|
+
import(value, client_only: client_only, server_only: server_only, js_import: true)
|
7
|
+
else
|
8
|
+
on_server = `typeof Opal.global.document === 'undefined'`
|
9
|
+
return if (server_only && !on_server) || (client_only && on_server)
|
10
|
+
defines.each do |name|
|
11
|
+
next unless `Opal.global[#{name}] === undefined`
|
12
|
+
raise "The package #{name} was not found. Add it to the webpack "\
|
13
|
+
"#{client_only ? 'client_only.js' : 'client_and_server.js'} manifest."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|