opal-up 0.0.1 → 0.0.3

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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +209 -0
  3. data/README.md +108 -23
  4. data/bin/up +5 -22
  5. data/bin/up_bun +5 -16
  6. data/bin/up_cluster +12 -0
  7. data/bin/up_node +12 -0
  8. data/bin/up_node_cluster +12 -0
  9. data/bin/up_ruby +4 -0
  10. data/bin/up_ruby_cluster +4 -0
  11. data/ext/up_ext/App.h +606 -0
  12. data/ext/up_ext/AsyncSocket.h +355 -0
  13. data/ext/up_ext/AsyncSocketData.h +87 -0
  14. data/ext/up_ext/BloomFilter.h +83 -0
  15. data/ext/up_ext/ChunkedEncoding.h +236 -0
  16. data/ext/up_ext/ClientApp.h +36 -0
  17. data/ext/up_ext/HttpContext.h +502 -0
  18. data/ext/up_ext/HttpContextData.h +56 -0
  19. data/ext/up_ext/HttpErrors.h +53 -0
  20. data/ext/up_ext/HttpParser.h +680 -0
  21. data/ext/up_ext/HttpResponse.h +578 -0
  22. data/ext/up_ext/HttpResponseData.h +95 -0
  23. data/ext/up_ext/HttpRouter.h +380 -0
  24. data/ext/up_ext/Loop.h +204 -0
  25. data/ext/up_ext/LoopData.h +112 -0
  26. data/ext/up_ext/MoveOnlyFunction.h +377 -0
  27. data/ext/up_ext/PerMessageDeflate.h +315 -0
  28. data/ext/up_ext/ProxyParser.h +163 -0
  29. data/ext/up_ext/QueryParser.h +120 -0
  30. data/ext/up_ext/TopicTree.h +363 -0
  31. data/ext/up_ext/Utilities.h +66 -0
  32. data/ext/up_ext/WebSocket.h +381 -0
  33. data/ext/up_ext/WebSocketContext.h +434 -0
  34. data/ext/up_ext/WebSocketContextData.h +109 -0
  35. data/ext/up_ext/WebSocketData.h +86 -0
  36. data/ext/up_ext/WebSocketExtensions.h +256 -0
  37. data/ext/up_ext/WebSocketHandshake.h +145 -0
  38. data/ext/up_ext/WebSocketProtocol.h +506 -0
  39. data/ext/up_ext/bsd.c +767 -0
  40. data/ext/up_ext/bsd.h +109 -0
  41. data/ext/up_ext/context.c +524 -0
  42. data/ext/up_ext/epoll_kqueue.c +458 -0
  43. data/ext/up_ext/epoll_kqueue.h +67 -0
  44. data/ext/up_ext/extconf.rb +5 -0
  45. data/ext/up_ext/internal.h +224 -0
  46. data/ext/up_ext/libusockets.h +350 -0
  47. data/ext/up_ext/libuwebsockets.cpp +1374 -0
  48. data/ext/up_ext/libuwebsockets.h +260 -0
  49. data/ext/up_ext/loop.c +386 -0
  50. data/ext/up_ext/loop_data.h +38 -0
  51. data/ext/up_ext/socket.c +231 -0
  52. data/ext/up_ext/up_ext.c +278 -0
  53. data/lib/up/bun/rack_env.rb +104 -0
  54. data/lib/up/bun/rack_server.rb +25 -0
  55. data/lib/up/bun/server.rb +89 -0
  56. data/lib/up/bun/server_cli.rb +15 -0
  57. data/lib/up/cli.rb +151 -0
  58. data/lib/up/node/cluster.rb +39 -0
  59. data/lib/up/node/cluster_cli.rb +15 -0
  60. data/lib/up/node/rack_cluster.rb +25 -0
  61. data/lib/up/node/rack_env.rb +106 -0
  62. data/lib/up/node/rack_server.rb +25 -0
  63. data/lib/up/node/server.rb +84 -0
  64. data/lib/up/node/server_cli.rb +15 -0
  65. data/lib/up/ruby/cluster_cli.rb +10 -0
  66. data/lib/up/ruby/rack_cluster.rb +26 -0
  67. data/lib/up/ruby/rack_env.rb +97 -0
  68. data/lib/up/ruby/rack_server.rb +26 -0
  69. data/lib/up/ruby/server_cli.rb +10 -0
  70. data/lib/up/u_web_socket/cluster.rb +39 -0
  71. data/lib/up/u_web_socket/cluster_cli.rb +15 -0
  72. data/lib/up/u_web_socket/rack_cluster.rb +25 -0
  73. data/lib/up/u_web_socket/rack_env.rb +101 -0
  74. data/lib/up/u_web_socket/rack_server.rb +25 -0
  75. data/lib/up/u_web_socket/server.rb +82 -0
  76. data/lib/up/u_web_socket/server_cli.rb +15 -0
  77. data/lib/up/version.rb +1 -1
  78. metadata +96 -29
  79. data/.gitignore +0 -5
  80. data/Gemfile +0 -2
  81. data/example_rack_app/Gemfile +0 -3
  82. data/example_rack_app/config.ru +0 -6
  83. data/example_rack_app/rack_app.rb +0 -5
  84. data/example_roda_app/Gemfile +0 -6
  85. data/example_roda_app/config.ru +0 -6
  86. data/example_roda_app/roda_app.rb +0 -35
  87. data/example_sinatra_app/Gemfile +0 -6
  88. data/example_sinatra_app/config.ru +0 -6
  89. data/example_sinatra_app/sinatra_app.rb +0 -7
  90. data/lib/up/bun.rb +0 -91
  91. data/lib/up/bun_cli.rb +0 -32
  92. data/lib/up/bun_rack.rb +0 -19
  93. data/lib/up/bun_rack_env.rb +0 -102
  94. data/lib/up/u_web_socket.rb +0 -83
  95. data/lib/up/u_web_socket_cluster.rb +0 -89
  96. data/lib/up/uws_cli.rb +0 -32
  97. data/lib/up/uws_rack.rb +0 -19
  98. data/lib/up/uws_rack_env.rb +0 -99
  99. data/lib/up-bun.rb +0 -7
  100. data/lib/up-node.rb +0 -7
  101. data/opal-up.gemspec +0 -27
  102. data/up_logo.svg +0 -256
@@ -0,0 +1,89 @@
1
+ # backtick_javascript: true
2
+ require 'up/cli'
3
+ require 'up/bun/rack_env'
4
+
5
+ module Up
6
+ module Bun
7
+ class Server
8
+ def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil)
9
+ @app = app
10
+ @scheme = scheme || 'http'
11
+ raise "unsupported scheme #{@scheme}" unless %w[http https].include?(@scheme)
12
+ @host = host || 'localhost'
13
+ @port = port&.to_i || 3000
14
+ @config = { handler: self.class.name, engine: "bun/#{`process.version`}", port: port, scheme: scheme, host: host }.freeze
15
+ @ca_file = ca_file
16
+ @cert_file = cert_file
17
+ @key_file = key_file
18
+ @server = nil
19
+ end
20
+
21
+ %x{
22
+ self.handle_headers = function(rack_headers, bun_hdr) {
23
+ if (rack_headers.$$is_hash) {
24
+ var header, k, v;
25
+ for(header of rack_headers) {
26
+ k = header[0];
27
+ if (!k.startsWith('rack.')) {
28
+ v = header[1];
29
+ if (v.$$is_array) {
30
+ v = v.join("\n");
31
+ }
32
+ bun_hdr.set(k, v);
33
+ }
34
+ }
35
+ }
36
+ }
37
+
38
+ self.handle_response = function(parts, body) {
39
+ if (parts["$respond_to?"]('each')) {
40
+ // this is not technically correct, just to make things work
41
+ #{`parts`.each { |part| `body = body + part` }}
42
+ } else if (parts["$respond_to?"]('call')) {
43
+ body = parts.$call();
44
+ }
45
+ #{`parts`.close if `parts`.respond_to?(:close)}
46
+ return body;
47
+ }
48
+ }
49
+ def listen
50
+ raise "already running" if @server
51
+ %x{
52
+ const oubr = Opal.Up.Bun.RackEnv;
53
+ const oubs = Opal.Up.Bun.Server;
54
+
55
+ var server_options = {
56
+ port: #@port,
57
+ hostname: #@host,
58
+ development: false,
59
+ fetch(req) {
60
+ const rack_res = #@app.$call(oubr.$new(req, #@config));
61
+ const hdr = new Headers();
62
+ oubs.handle_headers(rack_res[1]);
63
+ var body = '';
64
+ body = oubs.handle_response(rack_res[2], body);
65
+ return new Response(body, {status: rack_res[0], statusText: 'OK', headers: hdr});
66
+ }
67
+ };
68
+ if (#@scheme === 'https') {
69
+ server_options.tls = {
70
+ key: Bun.file(#@key_file),
71
+ cert: Bun.file(#@cert_file),
72
+ ca: Bun.file(#@ca_file)
73
+ };
74
+ }
75
+
76
+ #@server = Bun.serve(server_options);
77
+ console.log(`Server is running on ${#@scheme}://${#@host}:${#@port}`);
78
+ }
79
+ end
80
+
81
+ def stop
82
+ if Up::CLI::stoppable?
83
+ `#@server.stop()`
84
+ @server = nil
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,15 @@
1
+ require 'opal/platform'
2
+ require 'bun/file'
3
+ require 'nodejs/require'
4
+ require 'opal-parser'
5
+ require 'rack/builder'
6
+ require 'up/rack_builder_patch'
7
+ require 'up/bun/rack_server'
8
+
9
+ module Up
10
+ module CLI
11
+ def self.call
12
+ Up::Bun::RackServer.run(get_app, get_options)
13
+ end
14
+ end
15
+ end
data/lib/up/cli.rb ADDED
@@ -0,0 +1,151 @@
1
+ require 'optparse'
2
+ require 'up/version'
3
+
4
+ module Up
5
+ module CLI
6
+ class Options < OptionParser
7
+ attr_reader :options
8
+ def initialize
9
+ super
10
+ @options = {}
11
+ self.banner = 'Usage: up [options]'
12
+ separator ''
13
+ on('-h', '--help', 'Show this message') do
14
+ puts self
15
+ exit
16
+ end
17
+ on('-p', '--port PORT', String, 'Port number the server will listen to') do |port|
18
+ options[:port] = port.to_i
19
+ end
20
+ on('-b', '--bind ADDRESS', String, 'Address the server will listen to') do |host|
21
+ options[:host] = host
22
+ end
23
+ on('-s', '--secure', "Use secure sockets.\nWhen using secure sockets, the -a, -c and -k options must be provided") do
24
+ options[:scheme] = 'https'
25
+ end
26
+ on('-a', '--ca-file FILE', String, 'File with CA certs') do |ca_file|
27
+ options[:ca_file] = ca_file
28
+ end
29
+ on('-c', '--cert-file FILE', String, 'File with the servers certificate') do |cert_file|
30
+ options[:cert_file] = cert_file
31
+ end
32
+ on('-k', '--key-file FILE', String, 'File with the servers certificate') do |key_file|
33
+ options[:key_file] = key_file
34
+ end
35
+ on('-v', '--version', 'Show version') do
36
+ puts "Up! v#{Up::VERSION}"
37
+ exit
38
+ end
39
+ end
40
+
41
+ def parse!
42
+ super
43
+ if options[:scheme] == 'https'
44
+ if !options[:ca_file] || !options[:cert_file] || !options[:key_file]
45
+ puts "When using -s or --secure the -a,-c- and -k options must be given too!"
46
+ exit 2
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ class << self
53
+ if RUBY_ENGINE != 'opal'
54
+ def setup_bun
55
+ bun_cmd = `which bun`
56
+ if !bun_cmd || bun_cmd.empty?
57
+ puts "Please install bun first!"
58
+ exit 2
59
+ end
60
+ true
61
+ end
62
+
63
+ def setup_node
64
+ node_cmd = `which node`
65
+ if !node_cmd || node_cmd.empty?
66
+ puts "Please install node first!"
67
+ exit 2
68
+ end
69
+ true
70
+ end
71
+
72
+ def setup_u_web_socket
73
+ setup_node
74
+ npm_cmd = `which npm`
75
+ if !npm_cmd || npm_cmd.empty?
76
+ puts "Please install npm first!"
77
+ exit 2
78
+ end
79
+ npm_cmd.chop! if npm_cmd.end_with?("\n")
80
+ have_uws = `npm list|grep uWebSockets.js@20`
81
+ `npm i uNetworking/uWebSockets.js#v20.41.0` if have_uws.empty?
82
+ true
83
+ end
84
+ end
85
+
86
+ def get_options
87
+ options = Up::CLI::Options.new
88
+ options.parse!
89
+ options.options
90
+ rescue OptionParser::InvalidOption => e
91
+ $stderr.puts "#{$0}: #{e.message} (-h will show valid options)"
92
+ exit 64
93
+ end
94
+
95
+ def get_gems_for_cmd
96
+ # Opal does not yet support gems, so lets read the Gemfile and simply add each gem
97
+ # to the Opal load path and require it, works for some gems, fails for others
98
+ gems = ""
99
+ if File.exist?("Gemfile")
100
+ lines = File.readlines('Gemfile')
101
+ lines.each do |line|
102
+ m = /gem ['"](\w+)['"]/.match(line)
103
+ gems << " -g #{m[1]} -r #{m[1]}" if m && m[1] != 'opal-up'
104
+ end
105
+ end
106
+ gems
107
+ end
108
+
109
+ def try_file(filename)
110
+ return nil unless File.exist? filename
111
+ ::Rack::Builder.parse_file filename
112
+ end
113
+
114
+ def get_app(filename = 'config.ru')
115
+ app = nil
116
+ filename ||= 'config.ru'
117
+ app = try_file(filename)
118
+ unless app
119
+ filename = "#{filename}.ru"
120
+ app = try_file(filename)
121
+ end
122
+ raise "Something wrong with #{filename}\n" unless app
123
+ app
124
+ end
125
+
126
+ def stoppable?
127
+ sleep 0.1
128
+ puts 'deflating request chain links'
129
+ sleep 0.1
130
+ puts 'optimizing response distortion'
131
+ sleep 0.1
132
+ print 'releasing boost pressure: '
133
+ 3.times do
134
+ sleep 0.2
135
+ print '.'
136
+ end
137
+ 3.times do
138
+ puts "\n\033[5;31;47mRED ALERT: boost pressure to high, cannot open release valve!1!!!\033[0m"
139
+ sleep 0.1
140
+ print '.'
141
+ sleep 0.1
142
+ end
143
+ puts 'stopping engines failed, for further help see:'
144
+ puts 'https://www.youtube.com/watch?v=ecBco63zvas'
145
+ sleep 0.2
146
+ puts "Just kidding :)"
147
+ true
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,39 @@
1
+ # backtick_javascript: true
2
+ require 'up/node/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 Node
11
+ class Cluster < Up::Node::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/node/rack_cluster'
8
+
9
+ module Up
10
+ module CLI
11
+ def self.call
12
+ Up::Node::RackCluster.run(get_app, get_options)
13
+ end
14
+ end
15
+ end
@@ -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
+ `#@req.httpVersion`
50
+ when 'PATH_INFO'
51
+ `#@req.url`
52
+ when 'QUERY_STRING'
53
+ nil
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,10 @@
1
+ require 'rack/builder'
2
+ require 'up/ruby/rack_cluster'
3
+
4
+ module Up
5
+ module CLI
6
+ def self.call
7
+ Up::Ruby::RackCluster.run(get_app, get_options)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,26 @@
1
+ require 'up/ruby/rack_env'
2
+ require 'up_ext'
3
+
4
+ module Up
5
+ module Ruby
6
+ module RackCluster
7
+ def self.run(app, options = {})
8
+ raise "already running" if @server
9
+ @server = Up::Ruby::Cluster.new(app: app, **options).listen
10
+ true
11
+ end
12
+
13
+ def self.shutdown
14
+ @server&.stop
15
+ @server = nil
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ ENV['RACK_HANDLER'] ||= 'up'
22
+
23
+ begin
24
+ ::Rackup::Handler.register('up', Up::Ruby::RackCluster) if defined?(::Rackup::Handler)
25
+ rescue StandardError
26
+ end