execjs-xtrn 1.0.1 → 1.1.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 +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
|