opal-up 0.0.1 → 0.0.2

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,25 @@
1
+ require 'up/node/cluster'
2
+
3
+ module Up
4
+ module Node
5
+ module RackCluster
6
+ def self.run(app, options = {})
7
+ raise "already running" if @server
8
+ @server = Up::Node::Cluster.new(app: app, **options).listen
9
+ true
10
+ end
11
+
12
+ def self.shutdown
13
+ @server&.stop
14
+ @server = nil
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ ENV['RACK_HANDLER'] ||= 'up'
21
+
22
+ begin
23
+ ::Rackup::Handler.register('up', Up::Node::RackCluster) if defined?(::Rackup::Handler)
24
+ rescue StandardError
25
+ end
@@ -0,0 +1,106 @@
1
+ # backtick_javascript: true
2
+
3
+ require 'logger'
4
+ require 'up/version'
5
+
6
+ module Up
7
+ module Node
8
+ class RackEnv < ::Hash
9
+ RACK_VARS = %w[rack.errors rack.hijack rack.hijack? rack.input rack.logger
10
+ rack.multipart.buffer_size rack.multipart.tempfile_factory
11
+ rack.response_finished
12
+ rack.session rack.upgrade rack.upgrade? rack.url_scheme
13
+ HTTP_ACCEPT HTTP_ACCEPT_ENCODING HTTP_ACCEPT_LANGUAGE
14
+ HTTP_CONNECTION HTTP_HOST HTTP_USER_AGENT HTTP_VERSION PATH_INFO QUERY_STRING REQUEST_METHOD
15
+ SCRIPT_NAME SERVER_NAME SERVER_PROTOCOL SERVER_SOFTWARE]
16
+ def initialize(req, config)
17
+ @req = req
18
+ @config = config
19
+ end
20
+
21
+ def [](key)
22
+ return super(key) if key?(key)
23
+ self[key] = case key
24
+ when 'rack.errors'
25
+ STDERR
26
+ when 'rack.hijack'
27
+ nil
28
+ when 'rack.hijack?'
29
+ false
30
+ when 'rack.input'
31
+ ::IO.new
32
+ when 'rack.logger'
33
+ ::Logger.new(self['rack.errors'])
34
+ when 'rack.multipart.buffer_size'
35
+ 4096
36
+ when 'rack.multipart.tempfile_factory'
37
+ proc { |_filename, _content_type| File.new }
38
+ when 'rack.response_finished'
39
+ []
40
+ when 'rack.session'
41
+ {}
42
+ when 'rack.upgrade'
43
+ nil
44
+ when 'rack.upgrade?'
45
+ nil
46
+ when 'rack.url_scheme'
47
+ @config[:scheme]
48
+ when 'HTTP_VERSION'
49
+ `#@reg.httpVersion`
50
+ when 'PATH_INFO'
51
+ `#@req.url`
52
+ when 'QUERY_STRING'
53
+ ""
54
+ when 'RACK_ERRORS'
55
+ self['rack.errors']
56
+ when 'RACK_LOGGER'
57
+ self['rack.logger']
58
+ when 'REQUEST_METHOD'
59
+ `#@req.method`
60
+ when 'SCRIPT_NAME'
61
+ ""
62
+ when 'SERVER_NAME'
63
+ @config[:host]
64
+ when 'SERVER_PORT'
65
+ @config[:port].to_s
66
+ when 'SERVER_PROTOCOL'
67
+ ""
68
+ when 'SERVER_SOFTWARE'
69
+ "#{@config[:handler]}/#{Up::VERSION} #{@config[:engine]}"
70
+ else
71
+ if key.start_with?('HTTP_')
72
+ key = key[5..].gsub(/_/, '-')
73
+ `#@req.headers[key.toLowerCase()]`
74
+ else
75
+ nil
76
+ end
77
+ end
78
+ end
79
+
80
+ def req_headers
81
+ h = {}
82
+ %x{
83
+ var hdr, hds = #@req.headers;
84
+ for (hdr in hds) { h.set(hdr, hdrs[hdr]); }
85
+ }
86
+ h
87
+ end
88
+
89
+ def each
90
+ unless @got_them_all
91
+ RACK_VARS.each { |k| self[k] unless self.key?(k) }
92
+ @got_them_all = true
93
+ end
94
+ super
95
+ end
96
+
97
+ def to_s
98
+ unless @got_them_all
99
+ RACK_VARS.each { |k| self[k] unless self.key?(k) }
100
+ @got_them_all = true
101
+ end
102
+ super
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,25 @@
1
+ require 'up/node/server'
2
+
3
+ module Up
4
+ module Node
5
+ module RackServer
6
+ def self.run(app, options = {})
7
+ raise "already running" if @server
8
+ @server = Up::Node::Server.new(app: app, **options).listen
9
+ true
10
+ end
11
+
12
+ def self.shutdown
13
+ @server&.stop
14
+ @server = nil
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ ENV['RACK_HANDLER'] ||= 'up'
21
+
22
+ begin
23
+ ::Rackup::Handler.register('up', Up::Node::RackServer) if defined?(::Rackup::Handler)
24
+ rescue StandardError
25
+ end
@@ -0,0 +1,84 @@
1
+ # backtick_javascript: true
2
+ require 'up/cli'
3
+ require 'up/node/rack_env'
4
+
5
+ %x{
6
+ module.paths.push(process.cwd() + '/node_modules');
7
+ const http = require('node:http');
8
+ const https = require('node:https');
9
+ const fs = require('node:fs');
10
+ }
11
+
12
+ module Up
13
+ module Node
14
+ class Server
15
+ def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil)
16
+ @app = app
17
+ @scheme = scheme || 'http'
18
+ raise "unsupported scheme #{@scheme}" unless %w[http https].include?(@scheme)
19
+ @host = host || 'localhost'
20
+ @port = port&.to_i || 3000
21
+ @config = { handler: self.class.name, engine: "node/#{`process.version`}", port: port, scheme: scheme, host: host }.freeze
22
+ @ca_file = ca_file
23
+ @cert_file = cert_file
24
+ @key_file = key_file
25
+ @server = nil
26
+ end
27
+
28
+ %x{
29
+ self.handle_headers = function(rack_headers, srv_res) {
30
+ if (rack_headers.$$is_hash) {
31
+ var header, k, v;
32
+ for(header of rack_headers) {
33
+ k = header[0];
34
+ if (!k.startsWith('rack.')) {
35
+ v = header[1];
36
+ if (v.$$is_array) {
37
+ v = v.join("\n");
38
+ }
39
+ srv_res.setHeader(k, v);
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ self.handle_response = function(parts, srv_res) {
46
+ if (parts["$respond_to?"]('each')) {
47
+ #{`parts`.each { |part| `srv_res.write(part)` }}
48
+ } else if (parts["$respond_to?"]('call')) {
49
+ srv_res.write(parts.$call());
50
+ }
51
+ #{`parts`.close if `parts`.respond_to?(:close)}
52
+ }
53
+ }
54
+
55
+ def listen
56
+ raise "already running" if @server
57
+ %x{
58
+ const ounr = Opal.Up.Node.RackEnv;
59
+ const ouns = Opal.Up.Node.Server;
60
+ function handler(req, res) {
61
+ const rack_res = #@app.$call(ounr.$new(req, #@config));
62
+ res.statusCode = rack_res[0];
63
+ ouns.handle_headers(rack_res[1], res);
64
+ ouns.handle_response(rack_res[2], res);
65
+ res.end();
66
+ }
67
+ if (#@scheme == 'https') {
68
+ #@server = https.createServer({ ca: fs.readFileSync(#@ca_file), cert: fs.readFileSync(#@cert_file), key: fs.readFileSync(#@key_file) }, handler);
69
+ } else {
70
+ #@server = http.createServer(handler);
71
+ }
72
+ #@server.listen(#@port, #@host, () => { console.log(`Server is running on ${#@scheme}://${#@host}:${#@port}`)});
73
+ }
74
+ end
75
+
76
+ def stop
77
+ if Up::CLI::stoppable?
78
+ `#@server.close()`
79
+ @server = nil
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,15 @@
1
+ require 'opal/platform'
2
+ require 'nodejs/file'
3
+ require 'nodejs/require'
4
+ require 'opal-parser'
5
+ require 'rack/builder'
6
+ require 'up/rack_builder_patch'
7
+ require 'up/node/rack_server'
8
+
9
+ module Up
10
+ module CLI
11
+ def self.call
12
+ Up::Node::RackServer.run(get_app, get_options)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,39 @@
1
+ # backtick_javascript: true
2
+ require 'up/u_web_socket/server'
3
+
4
+ %x{
5
+ const cluster = require('node:cluster');
6
+ const num_workers = require('node:os').availableParallelism();
7
+ }
8
+
9
+ module Up
10
+ module UWebSocket
11
+ class Cluster < Up::UWebSocket::Server
12
+ def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil, workers: nil)
13
+ super(app: app, host: host, port: port, scheme: scheme, ca_file: ca_file, cert_file: cert_file, key_file: key_file)
14
+ @workers = workers || `num_workers`
15
+ @members = []
16
+ end
17
+
18
+ def listen
19
+ raise "already running" unless @members.empty?
20
+ %x{
21
+ if (cluster.isPrimary) {
22
+ for (let i = 0; i < #@workers; i++) {
23
+ #@members.push(cluster.fork());
24
+ }
25
+ } else {
26
+ #{super}
27
+ }
28
+ }
29
+ end
30
+
31
+ def stop
32
+ if Up::CLI::stoppable?
33
+ @members.each { |m| `m.kill()` }
34
+ @members.clear
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,15 @@
1
+ require 'opal/platform'
2
+ require 'nodejs/file'
3
+ require 'nodejs/require'
4
+ require 'opal-parser'
5
+ require 'rack/builder'
6
+ require 'up/rack_builder_patch'
7
+ require 'up/u_web_socket/rack_cluster'
8
+
9
+ module Up
10
+ module CLI
11
+ def self.call
12
+ Up::UWebSocket::RackCluster.run(get_app, get_options)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ require 'up/u_web_socket/cluster'
2
+
3
+ module Up
4
+ module UWebSocket
5
+ module RackCluster
6
+ def self.run(app, options = {})
7
+ raise "already running" if @server
8
+ @server = Up::UWebSocket::Cluster.new(app: app, **options).listen
9
+ true
10
+ end
11
+
12
+ def self.shutdown
13
+ @server&.stop
14
+ @server = nil
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ ENV['RACK_HANDLER'] ||= 'up'
21
+
22
+ begin
23
+ ::Rackup::Handler.register('up', Up::UWebSocket::RackCluster) if defined?(::Rackup::Handler)
24
+ rescue StandardError
25
+ end
@@ -0,0 +1,101 @@
1
+ # backtick_javascript: true
2
+
3
+ require 'logger'
4
+ require 'up/version'
5
+
6
+ module Up
7
+ module UWebSocket
8
+ class RackEnv < ::Hash
9
+ RACK_VARS = %w[rack.errors rack.hijack rack.hijack? rack.input rack.logger
10
+ rack.multipart.buffer_size rack.multipart.tempfile_factory
11
+ rack.response_finished
12
+ rack.session rack.upgrade rack.upgrade? rack.url_scheme
13
+ HTTP_ACCEPT HTTP_ACCEPT_ENCODING HTTP_ACCEPT_LANGUAGE
14
+ HTTP_CONNECTION HTTP_HOST HTTP_USER_AGENT PATH_INFO QUERY_STRING REQUEST_METHOD
15
+ SCRIPT_NAME SERVER_NAME SERVER_PROTOCOL SERVER_SOFTWARE]
16
+ def initialize(req, config)
17
+ @req = req
18
+ @config = config
19
+ end
20
+
21
+ def [](key)
22
+ return super(key) if key?(key)
23
+ self[key] = case key
24
+ when 'rack.errors'
25
+ STDERR
26
+ when 'rack.hijack'
27
+ nil
28
+ when 'rack.hijack?'
29
+ false
30
+ when 'rack.input'
31
+ ::IO.new
32
+ when 'rack.logger'
33
+ ::Logger.new(self['rack.errors'])
34
+ when 'rack.multipart.buffer_size'
35
+ 4096
36
+ when 'rack.multipart.tempfile_factory'
37
+ proc { |_filename, _content_type| File.new }
38
+ when 'rack.response_finished'
39
+ []
40
+ when 'rack.session'
41
+ {}
42
+ when 'rack.upgrade'
43
+ nil
44
+ when 'rack.upgrade?'
45
+ nil
46
+ when 'rack.url_scheme'
47
+ @config[:scheme]
48
+ when 'PATH_INFO'
49
+ `#@req.getUrl()`
50
+ when 'QUERY_STRING'
51
+ `#@req.getQuery()`
52
+ when 'RACK_ERRORS'
53
+ self['rack.errors']
54
+ when 'RACK_LOGGER'
55
+ self['rack.logger']
56
+ when 'REQUEST_METHOD'
57
+ `#@req.getMethod().toUpperCase()`
58
+ when 'SCRIPT_NAME'
59
+ ""
60
+ when 'SERVER_NAME'
61
+ @config[:host]
62
+ when 'SERVER_PORT'
63
+ @config[:port].to_s
64
+ when 'SERVER_PROTOCOL'
65
+ `#@req.getHeader('protocol')`
66
+ when 'SERVER_SOFTWARE'
67
+ "#{@config[:handler]}/#{Up::VERSION} #{@config[:engine]}"
68
+ else
69
+ if key.start_with?('HTTP_')
70
+ key = key[5..].gsub(/_/, '-')
71
+ `#@req.getHeader(key.toLowerCase())`
72
+ else
73
+ nil
74
+ end
75
+ end
76
+ end
77
+
78
+ def req_headers
79
+ h = {}
80
+ `#@req.forEach((k, v) => { h.set(k, v); })`
81
+ h
82
+ end
83
+
84
+ def each
85
+ unless @got_them_all
86
+ RACK_VARS.each { |k| self[k] unless self.key?(k) }
87
+ @got_them_all = true
88
+ end
89
+ super
90
+ end
91
+
92
+ def to_s
93
+ unless @got_them_all
94
+ RACK_VARS.each { |k| self[k] unless self.key?(k) }
95
+ @got_them_all = true
96
+ end
97
+ super
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,25 @@
1
+ require 'up/u_web_socket/server'
2
+
3
+ module Up
4
+ module UWebSocket
5
+ module RackServer
6
+ def self.run(app, options = {})
7
+ raise "already running" if @server
8
+ @server = Up::UWebSocket::Server.new(app: app, **options).listen
9
+ true
10
+ end
11
+
12
+ def self.shutdown
13
+ @server&.stop
14
+ @server = nil
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ ENV['RACK_HANDLER'] ||= 'up'
21
+
22
+ begin
23
+ ::Rackup::Handler.register('up', Up::UWebSocket::RackServer) if defined?(::Rackup::Handler)
24
+ rescue StandardError
25
+ end
@@ -0,0 +1,82 @@
1
+ # backtick_javascript: true
2
+ require 'up/cli'
3
+ require 'up/u_web_socket/rack_env'
4
+
5
+ %x{
6
+ module.paths.push(process.cwd() + '/node_modules');
7
+ const uws = require('uWebSockets.js');
8
+ }
9
+
10
+ module Up
11
+ module UWebSocket
12
+ class Server
13
+ def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil)
14
+ @app = app
15
+ @scheme = scheme || 'http'
16
+ raise "unsupported scheme #{@scheme}" unless %w[http https].include?(@scheme)
17
+ @host = host || 'localhost'
18
+ @port = port&.to_i || 3000
19
+ @config = { handler: self.class.name, engine: "node/#{`process.version`}", port: port, scheme: scheme, host: host }.freeze
20
+ @ca_file = ca_file
21
+ @cert_file = cert_file
22
+ @key_file = key_file
23
+ @server = nil
24
+ end
25
+
26
+ %x{
27
+ self.handle_headers = function(rack_headers, uws_res) {
28
+ if (rack_headers.$$is_hash) {
29
+ var header, k, v;
30
+ for(header of rack_headers) {
31
+ k = header[0];
32
+ if (!k.startsWith('rack.')) {
33
+ v = header[1];
34
+ if (v.$$is_array) {
35
+ v = v.join("\n");
36
+ }
37
+ uws_res.writeHeader(k, v);
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+ self.handle_response = function(parts, uws_res) {
44
+ if (parts["$respond_to?"]('each')) {
45
+ #{`parts`.each { |part| `uws_res.write(part)` }}
46
+ } else if (parts["$respond_to?"]('call')) {
47
+ uws_res.write(parts.$call());
48
+ }
49
+ #{`parts`.close if `parts`.respond_to?(:close)}
50
+ }
51
+ }
52
+
53
+ def listen
54
+ raise "already running" if @server
55
+ %x{
56
+ const ouwr = Opal.Up.UWebSocket.RackEnv;
57
+ const ouws = Opal.Up.UWebSocket.Server;
58
+ if (#@scheme == 'https') {
59
+ #@server = uws.SSLApp({ ca_file_name: #@ca_file, cert_file_name: #@cert_file, key_file_name: #@key_file });
60
+ } else {
61
+ #@server = uws.App();
62
+ }
63
+ #@server.any('/*', (res, req) => {
64
+ const rack_res = #@app.$call(ouwr.$new(req, #@config));
65
+ res.writeStatus(`${rack_res[0].toString()} OK`);
66
+ ouws.handle_headers(rack_res[1], res);
67
+ ouws.handle_response(rack_res[2], res);
68
+ res.end();
69
+ });
70
+ #@server.listen(#@port, #@host, () => { console.log(`Server is running on ${#@scheme}://${#@host}:${#@port}`)});
71
+ }
72
+ end
73
+
74
+ def stop
75
+ if Up::CLI::stoppable?
76
+ `#@server.close()`
77
+ @server = nil
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,15 @@
1
+ require 'opal/platform'
2
+ require 'nodejs/file'
3
+ require 'nodejs/require'
4
+ require 'opal-parser'
5
+ require 'rack/builder'
6
+ require 'up/rack_builder_patch'
7
+ require 'up/u_web_socket/rack_server'
8
+
9
+ module Up
10
+ module CLI
11
+ def self.call
12
+ Up::UWebSocket::RackServer.run(get_app, get_options)
13
+ end
14
+ end
15
+ end
data/lib/up/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Up
2
- VERSION = '0.0.1'.freeze
2
+ VERSION = '0.0.2'.freeze
3
3
  end
data/opal-up.gemspec CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
14
14
  spec.license = 'MIT'
15
15
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test_app|test|spec|features)/}) }
16
16
  spec.bindir = 'bin'
17
- spec.executables = %w[up up_bun]
17
+ spec.executables = %w[up up_bun up_cluster up_node up_node_cluster]
18
18
  spec.require_paths = %w[lib]
19
19
 
20
20
  spec.add_dependency 'logger', '~> 1.6.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opal-up
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Biedermann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-02 00:00:00.000000000 Z
11
+ date: 2024-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logger
@@ -112,6 +112,9 @@ email:
112
112
  executables:
113
113
  - up
114
114
  - up_bun
115
+ - up_cluster
116
+ - up_node
117
+ - up_node_cluster
115
118
  extensions: []
116
119
  extra_rdoc_files: []
117
120
  files:
@@ -121,6 +124,9 @@ files:
121
124
  - README.md
122
125
  - bin/up
123
126
  - bin/up_bun
127
+ - bin/up_cluster
128
+ - bin/up_node
129
+ - bin/up_node_cluster
124
130
  - example_rack_app/Gemfile
125
131
  - example_rack_app/config.ru
126
132
  - example_rack_app/rack_app.rb
@@ -130,18 +136,26 @@ files:
130
136
  - example_sinatra_app/Gemfile
131
137
  - example_sinatra_app/config.ru
132
138
  - example_sinatra_app/sinatra_app.rb
133
- - lib/up-bun.rb
134
- - lib/up-node.rb
135
- - lib/up/bun.rb
136
- - lib/up/bun_cli.rb
137
- - lib/up/bun_rack.rb
138
- - lib/up/bun_rack_env.rb
139
+ - lib/up/bun/rack_env.rb
140
+ - lib/up/bun/rack_server.rb
141
+ - lib/up/bun/server.rb
142
+ - lib/up/bun/server_cli.rb
143
+ - lib/up/cli.rb
144
+ - lib/up/node/cluster.rb
145
+ - lib/up/node/cluster_cli.rb
146
+ - lib/up/node/rack_cluster.rb
147
+ - lib/up/node/rack_env.rb
148
+ - lib/up/node/rack_server.rb
149
+ - lib/up/node/server.rb
150
+ - lib/up/node/server_cli.rb
139
151
  - lib/up/rack_builder_patch.rb
140
- - lib/up/u_web_socket.rb
141
- - lib/up/u_web_socket_cluster.rb
142
- - lib/up/uws_cli.rb
143
- - lib/up/uws_rack.rb
144
- - lib/up/uws_rack_env.rb
152
+ - lib/up/u_web_socket/cluster.rb
153
+ - lib/up/u_web_socket/cluster_cli.rb
154
+ - lib/up/u_web_socket/rack_cluster.rb
155
+ - lib/up/u_web_socket/rack_env.rb
156
+ - lib/up/u_web_socket/rack_server.rb
157
+ - lib/up/u_web_socket/server.rb
158
+ - lib/up/u_web_socket/server_cli.rb
145
159
  - lib/up/version.rb
146
160
  - opal-up.gemspec
147
161
  - up_logo.svg