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 +4 -4
- data/.travis.yml +3 -2
- data/FarMenu.ini +11 -10
- data/README.md +61 -11
- data/lib/execjs/wsh/repl.js +1 -1
- data/lib/execjs/xtrn.rb +1 -1
- data/lib/execjs/xtrn/engine.rb +18 -0
- data/lib/execjs/xtrn/rails.rb +2 -0
- data/lib/execjs/xtrn/routes.rb +3 -0
- data/lib/execjs/xtrn/routing.rb +45 -0
- data/lib/execjs/xtrn/version.rb +1 -1
- data/lib/execjs/xtrn/wsh.rb +1 -1
- data/test/engine.rb +31 -0
- data/test/load.js +5 -0
- metadata +10 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8754e3aa4bbca96de99f7b970259186ab5791bd0
|
4
|
+
data.tar.gz: 3cbcbdba3d22e45da939f7d52b94c449bd77a2d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d29c2822c4e601d959ab6330d605bfbd2af5633c75dd4af16c31ecb894e40b4231fdf9ff51f15ec80d270175fb70e916a1fff86259711e772b9cfe0b49ddc89
|
7
|
+
data.tar.gz: 2b08bbcb400b3da6a9376351ce54b5c04f9dd4ceb5b464df03e93d7bebbe4eaf34d5c75016791bdaeac7212b67b83c9f0303ca731d370e5d70617ee85fa0842f
|
data/.travis.yml
CHANGED
data/FarMenu.ini
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
|
2
|
-
bundle install
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
76
|
+
puts "10! = #{ctx.call 'fact', 10}"
|
75
77
|
```
|
76
|
-
Every execution context has
|
77
|
-
* exec(
|
78
|
-
*
|
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
|
-
|
82
|
-
|
83
|
-
|
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`
|
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
|
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
|
-
|
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
|
|
data/lib/execjs/wsh/repl.js
CHANGED
data/lib/execjs/xtrn.rb
CHANGED
data/lib/execjs/xtrn/engine.rb
CHANGED
@@ -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,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
|
data/lib/execjs/xtrn/version.rb
CHANGED
data/lib/execjs/xtrn/wsh.rb
CHANGED
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
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
|
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-
|
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.
|
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
|