alaska 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 838fe0565db0f27a2c6f91f1cc16af4104401a05
4
+ data.tar.gz: cbc675b45795d1fd7145066f0fe711c454cc71d6
5
+ SHA512:
6
+ metadata.gz: b7ac32056cfafd5da0fa134eadf37137ec5172c257566863e70aea3146f84869beb0ece8f1bdc5effec520c3d6a5df10703c5bb00812a925d2c5fa817dca78d7
7
+ data.tar.gz: caf187b1da186e80c3cc86498746a49ac749d07de9ba0d8ee305148158753328c2e3b35c451914a9d80677866c4e0d0a5852f7ec158efdbace151cbb9e5e1c9c
@@ -0,0 +1,52 @@
1
+ var vm = require('vm');
2
+ var http = require("http");
3
+ var sandbox = vm.createContext({ console: {log: console.log}});
4
+
5
+ var contextOptions = {displayErrors: true};
6
+ var debugOpt = '--debug true';
7
+ var debug = false;
8
+
9
+ process.argv.forEach(function (val, index, array) {
10
+ if (debugOpt === val) {
11
+ debug = true;
12
+ }
13
+ });
14
+
15
+ var webPrint = function(res, respBody) {
16
+ res.writeHead(200, {'Connection': 'keep-alive'});
17
+ res.write(respBody);
18
+ res.end();
19
+ };
20
+
21
+ var server = http.createServer(function(req, res) {
22
+ var contents = '';
23
+
24
+ req.on('data', function (dataIn) {
25
+ contents += dataIn;
26
+ });
27
+
28
+ req.on('end', function () {
29
+ try {
30
+ var result = vm.runInContext(contents, sandbox, contextOptions);
31
+ if (typeof(result) == 'undefined' && result !== null) {
32
+ webPrint(res, '["ok"]');
33
+ } else {
34
+ try {
35
+ webPrint(res, JSON.stringify(['ok', result]));
36
+ } catch (err) {
37
+ webPrint(res, '["err"]');
38
+ }
39
+ }
40
+ } catch(err) {
41
+ webPrint(res, JSON.stringify(["err", err.toString()]));
42
+ }
43
+ });
44
+ });
45
+
46
+ var port = process.env.PORT || 3001;
47
+ server.listen(port);
48
+
49
+ if (debug) {
50
+ console.log('Listening on port:', port);
51
+ console.error('Alaska.js started. Piping coffee to warmer climates.');
52
+ }
@@ -0,0 +1,72 @@
1
+ require 'net/http'
2
+ require 'socket'
3
+ require 'tempfile'
4
+ require 'json'
5
+
6
+ require 'execjs/runtime'
7
+ require 'execjs/module'
8
+
9
+ module Alaska
10
+ class Context < ExecJS::Runtime::Context
11
+ # runtime is an instance of Alaska
12
+ # src is the js code to be eval()'d in the nodejs context
13
+ def initialize(runtime, src = "") # third step, repeated .. yes, at least twice for common.css
14
+ @runtime = runtime
15
+
16
+ # compile context source, in most cases
17
+ # this is something like the CoffeeScript compiler
18
+ # or the SASS compiler
19
+ eval(src)
20
+ end
21
+
22
+ def eval(src)
23
+ if /\S/ =~ src #IMPORTANT! /\S/ =~ "()" => 0
24
+ exec(src)
25
+ end
26
+ end
27
+
28
+ def exec(src)
29
+ return "" unless src.length > 0
30
+
31
+ src = src.encode('UTF-8', :undef => :replace, :replace => '')
32
+ src = compile_source(src)
33
+
34
+ # src is either an empty object
35
+ # OR a valid JSON string in the form
36
+ # ['ok', 'result-of-coffeescript-or-sass-compiler']
37
+ # OR if an error occured
38
+ # ['err', 'some sort of error to be presented to the developer as a sprockets error']
39
+ #
40
+ status, value = src.empty? ? [] : ::JSON.parse(src, create_additions: false)
41
+ if status == "ok"
42
+ value
43
+ elsif value =~ /SyntaxError:/
44
+ raise ExecJS::RuntimeError, value
45
+ else
46
+ raise ExecJS::ProgramError, value
47
+ end
48
+ end
49
+
50
+ def call(identifier, *args)
51
+ eval "#{identifier}.apply(this, #{::JSON.generate(args)})"
52
+ end
53
+
54
+ private
55
+
56
+ def compile_source(contents)
57
+ sock = Net::BufferedIO.new(@runtime.provision_socket)
58
+ request = Net::HTTP::Post.new("/")
59
+ request['Connection'] = 'close'
60
+ request.body = contents
61
+ request.exec(sock, "1.1", "/")
62
+
63
+ begin
64
+ response = Net::HTTPResponse.read_new(sock)
65
+ end while response.kind_of?(Net::HTTPContinue)
66
+
67
+ response.reading_body(sock, request.response_body_permitted?) { }
68
+ sock.close
69
+ response.body
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,100 @@
1
+ require 'tempfile'
2
+
3
+ require 'execjs/runtime'
4
+ require 'execjs/module'
5
+
6
+ require 'alaska/context'
7
+
8
+ module Alaska
9
+ class Runtime < ExecJS::Runtime
10
+ attr_accessor :debug, :nodejs_cmd, :port, :pid, :semaphore
11
+
12
+ def initialize(opts = {})
13
+ srand
14
+
15
+ @debug = opts[:debug]
16
+ @nodejs_cmd = "node"
17
+ @pid = nil
18
+ @semaphore = Mutex.new
19
+ end
20
+
21
+ def name
22
+ "Alaska"
23
+ end
24
+
25
+ def available?
26
+ #NOTE: this is brittle in terms of cross platform detection of node executable
27
+ `which #{@nodejs_cmd}`.strip.length > 0 # this must return true to be enabled
28
+ end
29
+
30
+ def deprecated?
31
+ false
32
+ end
33
+
34
+ def context_class
35
+ Alaska::Context
36
+ end
37
+
38
+ #NOTE: this should be thread-safe
39
+ def provision_socket
40
+ ensure_startup unless @pid
41
+
42
+ wait_socket = nil
43
+ checks = 0
44
+ max_retries = 12
45
+
46
+ while checks < max_retries
47
+ begin
48
+ checks += 1
49
+ wait_socket = UNIXSocket.new(@port)
50
+ break
51
+ rescue Errno::ENOENT, Errno::ECONNREFUSED, Errno::ENOTDIR
52
+ wait_socket = nil
53
+ sleep 0.5
54
+ end
55
+ end
56
+
57
+ if checks >= max_retries
58
+ ensure_shutdown
59
+ raise ExecJS::RuntimeError, "unable to connect to alaska.js server"
60
+ end
61
+
62
+ wait_socket
63
+ end
64
+
65
+ private
66
+
67
+ def ensure_startup
68
+ @semaphore.synchronize {
69
+ return if @pid
70
+
71
+ @port = begin
72
+ tmpfile = Tempfile.new("alaska")
73
+ path = tmpfile.path
74
+ tmpfile.close
75
+ tmpfile.unlink
76
+ path
77
+ end
78
+
79
+ alaska_js_path = File.join(File.dirname(File.expand_path(__FILE__)), '../../alaska.js')
80
+ command_options = [alaska_js_path, "--debug #{!!@debug}"] # --other --command-line --options --go --here
81
+
82
+ @pid = Process.spawn({"PORT" => @port.to_s}, @nodejs_cmd, *command_options, {:err => :out})
83
+
84
+ at_exit do
85
+ ensure_shutdown
86
+ end
87
+ }
88
+ end
89
+
90
+ def ensure_shutdown
91
+ return unless @pid
92
+
93
+ Process.kill("TERM", @pid) rescue Errno::ECHILD
94
+ Process.wait(@pid) rescue Errno::ECHILD
95
+
96
+ @port = nil
97
+ @pid = nil
98
+ end
99
+ end
100
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: alaska
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Jon Bardin
8
+ - Stephen Grider
9
+ - Ville Lautanala
10
+ - Giovanni Bonetti
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2015-02-10 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: execjs
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '2.6'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.6'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - "~>"
35
+ - !ruby/object:Gem::Version
36
+ version: '10.4'
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '10.4'
44
+ - !ruby/object:Gem::Dependency
45
+ name: minitest
46
+ requirement: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - "~>"
49
+ - !ruby/object:Gem::Version
50
+ version: '5.5'
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '5.5'
58
+ description: uses a single shared nodejs process to handle ExecJS::Runtime evaluation
59
+ email: diclophis@gmail.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - alaska.js
65
+ - lib/alaska/context.rb
66
+ - lib/alaska/runtime.rb
67
+ homepage: https://github.com/mavenlink/alaska
68
+ licenses:
69
+ - MIT
70
+ metadata: {}
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubyforge_project:
87
+ rubygems_version: 2.4.8
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: persistent ExecJS runtime
91
+ test_files: []