execjs-xtrn 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4abcfd3f47329826a53b863835a51592f1dc1030
4
- data.tar.gz: e96571ef15e4fe0b91a86a2e461cbdef62e42f29
3
+ metadata.gz: 8754e3aa4bbca96de99f7b970259186ab5791bd0
4
+ data.tar.gz: 3cbcbdba3d22e45da939f7d52b94c449bd77a2d1
5
5
  SHA512:
6
- metadata.gz: 2842042b3e8091e0caa59f5943635579c673c291d11cd831afb42e08797b26b8a55045c79c72a5e7b886a8ba3037fcf10b42b92c5a37b1faaadcbea8d08cb672
7
- data.tar.gz: 6328d3e668706b3282a4050ff614050254a0c20f9923219a8d56ff53631f17fdf6776bb4f7496b0e9585f5c819848a234087344353cf99b071ba6cac8f404f4c
6
+ metadata.gz: 0d29c2822c4e601d959ab6330d605bfbd2af5633c75dd4af16c31ecb894e40b4231fdf9ff51f15ec80d270175fb70e916a1fff86259711e772b9cfe0b49ddc89
7
+ data.tar.gz: 2b08bbcb400b3da6a9376351ce54b5c04f9dd4ceb5b464df03e93d7bebbe4eaf34d5c75016791bdaeac7212b67b83c9f0303ca731d370e5d70617ee85fa0842f
data/.travis.yml CHANGED
@@ -1,7 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.1
4
- - 2.0.0
3
+ - '2.2'
4
+ - '2.1'
5
+ - '2.0'
5
6
  - 1.9.3
6
7
  - 1.9.2
7
8
  before_install:
data/FarMenu.ini CHANGED
@@ -1,10 +1,11 @@
1
- i: Bundle install
2
- bundle install -new_console:c
3
- n: Npm install
4
- bundle exec rake npm -new_console:c
5
- --:
6
- t: Run tests
7
- bundle exec rake -new_console:c
8
- --:
9
- b: Build
10
- bundle exec rake build -new_console:c
1
+ I: Install dependencies
2
+ bundle install
3
+ bundle exec rake npm
4
+ --:
5
+ T: Run tests
6
+ bundle exec rake -new_console:c
7
+ C: Console
8
+ bundle console -new_console
9
+ --:
10
+ B: Build
11
+ bundle exec rake build -new_console:c
data/README.md CHANGED
@@ -39,6 +39,8 @@ ExecJS::Xtrn uses two external JavaScript runners:
39
39
  - Simple (1 execution context = 1 external process)
40
40
  - Nvm (all execution contexts share single external process using [vm API](http://nodejs.org/api/vm.html))
41
41
 
42
+ Nvm engine has nothing common with [nvm](https://github.com/creationix/nvm).
43
+
42
44
  So, there exist *four* engines:
43
45
 
44
46
  * Engine - absctract engine (smart enough to execute blank lines)
@@ -71,28 +73,66 @@ In general one should create instance of an Engine and then feed it with JavaScr
71
73
  ```ruby
72
74
  ctx=ExecJS::Xtrn::Wsh.new
73
75
  ctx.exec 'fact = function(n){return n>1 ? n*fact(n-1) : 1}'
74
- puts "10!=#{ctx.call 'fact', 10}"
76
+ puts "10! = #{ctx.call 'fact', 10}"
75
77
  ```
76
- Every execution context has three methods:
77
- * exec('`code`') - executes arbitrary JavaScript code. To get result `return` must be called.
78
- * eval('`expression`') - evaluate JavaScript expression. `return` is not needed
78
+ Every execution context has four methods:
79
+ * exec(`code`) - executes arbitrary JavaScript code. To get result `return` must be called
80
+ * load(`code`) or load(`path`) - exec that can load its code from file
81
+ * eval(`expression`) - evaluate JavaScript expression. `return` is not needed
79
82
  * call(`function`, arguments...) - special form of eval for function call
80
83
 
81
- Engine class also has exec and eval methods, they just create brand new execution context,
82
- pass argument to it, destroy that context and return its result. Using these class methods
83
- is not recommended, since it's just what ExecJS does (except for Nvm engine).
84
+ There are `exec` and `eval` methods in Engine class,
85
+ they just create brand new execution context,
86
+ pass argument to it, destroy that context and return its result.
87
+ Using these class methods is not recommended, since it's just what ExecJS does
88
+ (except for Nvm engine).
84
89
 
85
- Engine class also has compile method that combines `new` and `exec` and returns execution context.
90
+ Engine class also has `compile` method that combines `new` and `exec`
91
+ and returns execution context.
86
92
  This is how ExecJS is used in most cases.
87
93
 
88
94
  ```ruby
89
95
  ctx=ExecJS::Xtrn::Wsh.compile 'fact = function(n){return n>1 ? n*fact(n-1) : 1}'
90
- puts "10!=#{ctx.call 'fact', 10}"
96
+ puts "10! = #{ctx.call 'fact', 10}"
91
97
  ```
98
+ And `load` methods is likewise combination of `new`+`load`,
99
+ it is `compile` that can load its code from file.
100
+
101
+ `load` method (class' or instance's) detects whether its argument
102
+ is code or path by first symbols of it. So, start path with `/`, `./`
103
+ or `../` (but not from `//`). On Windows `\` and `C:` can be also used.
92
104
 
93
- And finally ExecJS::Xtrn patches ExecJS and installs those 3 class methods (exec, eval, compile) in it.
105
+ Finally ExecJS::Xtrn patches ExecJS and installs those 4 class methods
106
+ (`exec`, `eval`, `compile` and `load`) in it.
94
107
  So, `ExecJS.compile` is `ExecJS::Xtrn::Nvm.compile` if Nvm engine is available.
95
108
 
109
+ ## Preloading
110
+
111
+ Sometimes it's neccesary to initialize all execution contexts before passing
112
+ code to them.
113
+ For instance, add some standard JavaScript methods missing in Wsh engine.
114
+
115
+ It can be done by setting Preload constant on engine class.
116
+
117
+ ```ruby
118
+ ExecJS::Xtrn::Wsh::Preload='./lib/js/map.js'
119
+ ```
120
+ or maybe
121
+
122
+ ```ruby
123
+ ExecJS::Xtrn::Wsh::Preload=[
124
+ './lib/js/map.js',
125
+ './lib/js/keys.js',
126
+ 'console={log: function(){WScript.Echo([].slice.call(arguments).join(" "))}}'
127
+ ]
128
+ # Yes, console.log is avaialable in Wsh now!
129
+ # And yes, console.log can be used in ExecJS::Xtrn!
130
+ ```
131
+ You can add preload scripts to any engine or to Engine base class.
132
+ They will be loaded according to inheritance:
133
+ Engine::Preload will be used by all engines,
134
+ Node::Preload is for Node and Nvm, while Nvm::Preload is for Nvm only.
135
+
96
136
  ## Overriding ExecJS
97
137
 
98
138
  Sometimes ExecJS is required after ExecJS::Xtrn. In that case you can call ExecJS::Xtrn.init and
@@ -130,6 +170,15 @@ s.stats
130
170
  ```
131
171
  but c (and m, x) fields are omitted there.
132
172
 
173
+ If ExecJS::Xtrn detects it is run under Ruby on Rails,
174
+ it installs additional path `/rails/jsx' to display its statistics
175
+ (you can see that route in sextant, for example).
176
+
177
+ It is one more reason not to use ExecJS::Xtrn in production mode ;-)
178
+
179
+ By default statistics is output in YAML format, but you can
180
+ get `/rails/jsx.json` or `/rails/jsx.html`.
181
+
133
182
  ## Compatibilty
134
183
 
135
184
  Not every JavaScript code behaves identically in ExecJS and ExecJS::Xtrn. In most cases it depends on how
@@ -148,7 +197,8 @@ The following packages have been tested to run under ExecJS::Xtrn out-of-box:
148
197
 
149
198
  CoffeeScript since v1.9.0 introduces new incompatibility:
150
199
  it uses `Object.create` that is missing from WSH.
151
- To fix it, `Object.create` was manually defined in ExecJS::Xtrn::Wsh.
200
+ To fix it, `Object.create` was manually defined in ExecJS::Xtrn::Wsh
201
+ (sort of [ExecJS::Xtrn::Wsh::Preload](#preloading))
152
202
 
153
203
  ## Testing
154
204
 
@@ -48,7 +48,7 @@ function oCreate()
48
48
  if(Object.create) return
49
49
  Object.create=function(proto)
50
50
  {
51
- f=function(){}
51
+ function f(){}
52
52
  f.prototype=proto
53
53
  return new f
54
54
  }
data/lib/execjs/xtrn.rb CHANGED
@@ -1,4 +1,4 @@
1
- %w(wsh nvm).each{|x| require_relative "xtrn/#{x}"}
1
+ require_relative "xtrn/rails"
2
2
 
3
3
  module ExecJS::Xtrn
4
4
 
@@ -19,6 +19,13 @@ class ExecJS::Xtrn::Engine
19
19
  result['ok']
20
20
  end
21
21
 
22
+ PathX=[/^[.]{1,2}\/|^\/(?![\/*])/]
23
+ PathX << /^[.]{0,2}\\|^\w:./ if Gem.win_platform?
24
+
25
+ def load code
26
+ exec PathX.find{|re| re.match code} ? File.read(code) : code
27
+ end
28
+
22
29
  def eval(code)
23
30
  return if (code=code.to_s.strip).length==0
24
31
  exec "return eval(#{JSON.generate([code])[1...-1]})"
@@ -40,6 +47,10 @@ class ExecJS::Xtrn::Engine
40
47
  new.tap{|ctx| ctx.exec code}
41
48
  end
42
49
 
50
+ def self.load code
51
+ new.tap{|ctx| ctx.load code}
52
+ end
53
+
43
54
  def self.stats
44
55
  (@stats||{}).dup
45
56
  end
@@ -60,4 +71,11 @@ class ExecJS::Xtrn::Engine
60
71
  child
61
72
  end
62
73
 
74
+ def initialize
75
+ self.class.ancestors.reverse.map do |m|
76
+ list=m.const_get 'Preload', false rescue nil
77
+ list ? Array===list ? list : [list] : []
78
+ end
79
+ .flatten.uniq.each{|code| load code}
80
+ end
63
81
  end
@@ -0,0 +1,2 @@
1
+ require_relative 'wsh'
2
+ require_relative 'routing' if defined? Rails::Application
@@ -0,0 +1,3 @@
1
+ Rails::application.routes.draw do
2
+ get "/rails/jsx" => ExecJS::Xtrn::Rack
3
+ end
@@ -0,0 +1,45 @@
1
+ module ExecJS::Xtrn::Rack
2
+ Formats=YAML.load <<-EOY
3
+ -:
4
+ mime: text/x-yaml
5
+ dump: YAML
6
+ json:
7
+ mime: appication/json
8
+ dump: JSON
9
+ html:
10
+ mime: text/html
11
+ dump: self
12
+ EOY
13
+
14
+ Formats.each {|k, v| v['dump']=instance_eval v['dump']}
15
+
16
+ def self.stats
17
+ ExecJS::Xtrn.stats.as_json
18
+ end
19
+
20
+ def self.call req
21
+ f=Formats[req['action_dispatch.request.path_parameters'][:format]] ||
22
+ Formats['-']
23
+ [
24
+ 200,
25
+ {"Content-Type"=> f['mime']},
26
+ [f['dump'].dump(stats)],
27
+ ]
28
+ end
29
+
30
+ # Dump as HTML
31
+ def self.dump s
32
+ '<ul>'+
33
+ s.map do |k, v|
34
+ "<li><b>#{k}</b>#{Hash===v ? dump(v) : ": #{v}"}</li>"
35
+ end
36
+ .join('')+'</ul>'
37
+ end
38
+ end
39
+
40
+ class Rails::Application
41
+ initializer :execjs_xtrn_stats do
42
+ Rails.application.routes_reloader.paths <<
43
+ File.expand_path('../routes.rb', __FILE__)
44
+ end
45
+ end
@@ -1,5 +1,5 @@
1
1
  module ExecJS
2
2
  module Xtrn
3
- VERSION = "1.0.1"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  end
@@ -1,4 +1,4 @@
1
- require_relative 'engine'
1
+ require_relative 'nvm'
2
2
 
3
3
  class ExecJS::Xtrn::Wsh < ExecJS::Xtrn::Engine
4
4
 
data/test/engine.rb CHANGED
@@ -6,6 +6,8 @@ class TestEngine < Minitest::Test
6
6
 
7
7
  Spawn=5
8
8
  Engines=M::Engines
9
+ Engines.each{|e| e::Preload=[]}
10
+ M::Engine::Preload=[]
9
11
 
10
12
  def shag_methods
11
13
  refute @engine.exec <<-EOJ
@@ -17,6 +19,12 @@ class TestEngine < Minitest::Test
17
19
  assert_equal 89, @engine.eval('fib(10)')
18
20
  assert_equal 8, @engine.call('fib', 5)
19
21
  assert_equal 79, @engine.call('Math.max', 44, 27, 79, 73, 42, 4, 23, 24, 36, 13)
22
+
23
+ assert_raises(M::Error){ @engine.eval '_load' }
24
+ @engine.load File.expand_path '../load.js', __FILE__
25
+ assert_equal ({}), @engine.eval('_load')
26
+ @engine.load '_load.a=108'
27
+ assert_equal ({"a"=>108}), @engine.eval('_load')
20
28
  end
21
29
 
22
30
  def shag_vars
@@ -62,6 +70,29 @@ class TestEngine < Minitest::Test
62
70
  assert_equal 6, x.call('inc', 5)
63
71
  end
64
72
 
73
+ def klas_load
74
+ z=@class.load File.expand_path '../load.js', __FILE__
75
+ assert_equal ({}), z.eval('_load')
76
+ end
77
+
78
+ def klas_preload
79
+ res=@class.name[-1]
80
+ res='em' if 'm'==res
81
+
82
+ Spawn.times do
83
+ begin
84
+ Engines.shuffle.each{|e| e::Preload << "_preload.#{e.name[-1]}=1"}
85
+ M::Engine::Preload << '!function(){this._preload={}}()'
86
+
87
+ assert_equal res, @class.eval('_preload').keys*''
88
+
89
+ ensure
90
+ Engines.each{|e| e::Preload.clear}
91
+ M::Engine::Preload.clear
92
+ end
93
+ end
94
+ end
95
+
65
96
  def engines
66
97
  (1..Spawn).map do
67
98
  Engines.map{|k| k::Valid ? k.compile : nil }
data/test/load.js ADDED
@@ -0,0 +1,5 @@
1
+ // Test .load method
2
+ !function()
3
+ {
4
+ this._load={}
5
+ }()
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: execjs-xtrn
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stas Ukolov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-20 00:00:00.000000000 Z
11
+ date: 2015-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -96,6 +96,8 @@ files:
96
96
  - Rakefile
97
97
  - execjs-xtrn.gemspec
98
98
  - lib/execjs/node/index.js
99
+ - lib/execjs/node/node_modules/split/index.js
100
+ - lib/execjs/node/node_modules/through/index.js
99
101
  - lib/execjs/node/package.json
100
102
  - lib/execjs/wsh/json2.js
101
103
  - lib/execjs/wsh/repl.js
@@ -104,15 +106,17 @@ files:
104
106
  - lib/execjs/xtrn/engine.rb
105
107
  - lib/execjs/xtrn/node.rb
106
108
  - lib/execjs/xtrn/nvm.rb
109
+ - lib/execjs/xtrn/rails.rb
110
+ - lib/execjs/xtrn/routes.rb
111
+ - lib/execjs/xtrn/routing.rb
107
112
  - lib/execjs/xtrn/version.rb
108
113
  - lib/execjs/xtrn/wsh.rb
109
114
  - test/child.rb
110
115
  - test/engine.rb
116
+ - test/load.js
111
117
  - test/nvm.rb
112
118
  - test/shagi.rb
113
119
  - test/top.rb
114
- - lib/execjs/node/node_modules/split/index.js
115
- - lib/execjs/node/node_modules/through/index.js
116
120
  homepage: https://github.com/ukoloff/execjs-xtrn
117
121
  licenses:
118
122
  - MIT
@@ -133,13 +137,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
137
  version: '0'
134
138
  requirements: []
135
139
  rubyforge_project:
136
- rubygems_version: 2.0.14
140
+ rubygems_version: 2.4.6
137
141
  signing_key:
138
142
  specification_version: 4
139
143
  summary: 'Proof-of-concept: make ExecJS fast even without therubyracer'
140
144
  test_files:
141
145
  - test/child.rb
142
146
  - test/engine.rb
147
+ - test/load.js
143
148
  - test/nvm.rb
144
149
  - test/shagi.rb
145
150
  - test/top.rb