alaska 1.0.4

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.
@@ -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: []