beryl 0.2.5 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/app/initial_state.rb +0 -1
- data/app/routes.rb +5 -0
- data/app/view.rb +11 -2
- data/app/{something.rb → widgets/homepage.rb} +2 -10
- data/app/widgets/not_found.rb +7 -0
- data/app/widgets/page_x.rb +7 -0
- data/config.ru +5 -1
- data/lib/beryl/backend.rb +26 -3
- data/lib/beryl/backend_runtime.rb +54 -0
- data/lib/beryl/deserializer.rb +2 -0
- data/lib/beryl/frontend.rb +3 -2
- data/lib/beryl/{runtime.rb → frontend_runtime.rb} +22 -3
- data/lib/beryl/html_renderer.rb +30 -0
- data/lib/beryl/routing/matcher.rb +29 -0
- data/lib/beryl/routing/router.rb +32 -0
- data/lib/beryl/version.rb +1 -1
- metadata +11 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0359afa9fc5dcf6e6116594b9ba70c06425e9c889069e60c5398c1be9b39d100'
|
4
|
+
data.tar.gz: 505f33152ec6db4b9ddfd2dcbd30351357a3dacc5434493a67e271104cde0c40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bce4b5249650d957206888567d29ca76d21038a11f228466da07dd1824ac2a0a76161bbc84cbf89f61e32bea48f3322302e0dd75294c1dd5f69c67a8c77f8135
|
7
|
+
data.tar.gz: 68bc437aa950783b2c37ed46410140067202e30103d35c901273f4eaa4cbd8e47da4390c607d9268a05cd5256c78c9d2225869a6ce9467c404dc511bf1b68a54
|
data/Gemfile.lock
CHANGED
data/app/initial_state.rb
CHANGED
data/app/routes.rb
ADDED
data/app/view.rb
CHANGED
@@ -1,8 +1,17 @@
|
|
1
1
|
require 'beryl/view'
|
2
|
-
require '
|
2
|
+
require 'widgets/homepage'
|
3
|
+
require 'widgets/page_x'
|
4
|
+
require 'widgets/not_found'
|
3
5
|
|
4
6
|
class View < Beryl::View
|
5
7
|
def render
|
6
|
-
|
8
|
+
case state[:route]
|
9
|
+
when :homepage
|
10
|
+
Homepage.new.render(state)
|
11
|
+
when :page_x
|
12
|
+
PageX.new.render(state)
|
13
|
+
else
|
14
|
+
NotFound.new.render(state)
|
15
|
+
end
|
7
16
|
end
|
8
17
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'beryl/widget'
|
2
2
|
|
3
|
-
class
|
3
|
+
class Homepage < Beryl::Widget
|
4
4
|
def render(state)
|
5
5
|
column :fill_width, :fill_height do
|
6
6
|
row :fill_width do
|
@@ -38,12 +38,4 @@ class Something < Beryl::Widget
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
41
|
-
end
|
42
|
-
|
43
|
-
|
44
|
-
# column :fill_width, :fill_height do
|
45
|
-
# text 'Bart', height: 100, width: 300
|
46
|
-
# text 'Abc', proportional_height: 2
|
47
|
-
# text 'Karol', :fill_height
|
48
|
-
# text 'Xyz', proportional_height: 3
|
49
|
-
# end
|
41
|
+
end
|
data/config.ru
CHANGED
@@ -1,5 +1,9 @@
|
|
1
|
+
app_path = File.expand_path('../app', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(app_path) unless $LOAD_PATH.include?(app_path)
|
3
|
+
|
1
4
|
require 'beryl/backend'
|
2
5
|
require 'rack'
|
6
|
+
require 'view'
|
3
7
|
|
4
8
|
use Rack::Static, :urls => ['/build']
|
5
|
-
run Beryl::Backend.new
|
9
|
+
run Beryl::Backend.new(View.new)
|
data/lib/beryl/backend.rb
CHANGED
@@ -1,16 +1,31 @@
|
|
1
1
|
require 'command_handler'
|
2
2
|
require 'json'
|
3
3
|
require 'serializer'
|
4
|
+
require 'beryl/routing/router'
|
5
|
+
require 'beryl/html_renderer'
|
6
|
+
require 'beryl/backend_runtime'
|
4
7
|
|
5
8
|
module Beryl
|
6
9
|
class Backend
|
10
|
+
def initialize(view)
|
11
|
+
@view = view
|
12
|
+
initial_state = eval(File.read('app/initial_state.rb'))
|
13
|
+
@state = initial_state.clone
|
14
|
+
end
|
15
|
+
|
7
16
|
def call(env)
|
8
17
|
req = Rack::Request.new(env)
|
9
18
|
case req.path_info
|
10
19
|
when '/command'
|
11
20
|
[200, { 'Content-Type' => 'application/json; charset=utf-8' }, [handle_command(req)]]
|
12
21
|
else
|
13
|
-
|
22
|
+
router = Beryl::Routing::Router.new
|
23
|
+
route = router.match(req.path_info)
|
24
|
+
@state[:route] = route[0]
|
25
|
+
@state[:params] = route[1]
|
26
|
+
puts "STATE = #{@state}"
|
27
|
+
code = (route[0] != :not_found ? 200 : 404)
|
28
|
+
[code, { 'Content-Type' => 'text/html; charset=utf-8' }, [response]]
|
14
29
|
end
|
15
30
|
end
|
16
31
|
|
@@ -23,7 +38,15 @@ module Beryl
|
|
23
38
|
end
|
24
39
|
|
25
40
|
def hydrate_state
|
26
|
-
Serializer.serialize(
|
41
|
+
Serializer.serialize(@state).gsub('"', '"')
|
42
|
+
end
|
43
|
+
|
44
|
+
def render
|
45
|
+
runtime = Beryl::BackendRuntime.new(@state, @view)
|
46
|
+
runtime.process_all_messages
|
47
|
+
@view.state = runtime.state
|
48
|
+
virtual_dom = VirtualDOM.new(@view.render)
|
49
|
+
HTMLRenderer.new.render(virtual_dom.dom.first)
|
27
50
|
end
|
28
51
|
|
29
52
|
def response
|
@@ -35,7 +58,7 @@ module Beryl
|
|
35
58
|
<link rel="stylesheet" type="text/css" href="build/style.css">
|
36
59
|
</head>
|
37
60
|
<body>
|
38
|
-
<div id="beryl" data-beryl="#{hydrate_state}" class="bg-color-255-255-255-255 font-color-0-0-0-255 font-size-20 font-open-sanshelveticaverdanasans-serif s e ui s e"
|
61
|
+
<div id="beryl" data-beryl="#{hydrate_state}" class="bg-color-255-255-255-255 font-color-0-0-0-255 font-size-20 font-open-sanshelveticaverdanasans-serif s e ui s e">#{render}</div>
|
39
62
|
</body>
|
40
63
|
</html>
|
41
64
|
HEREDOC
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Beryl
|
2
|
+
class BackendRuntime
|
3
|
+
attr_reader :state
|
4
|
+
|
5
|
+
def initialize(state, view)
|
6
|
+
@messages = []
|
7
|
+
@state = state
|
8
|
+
@view = view
|
9
|
+
@commands = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def push(message)
|
13
|
+
@messages << message
|
14
|
+
end
|
15
|
+
|
16
|
+
def process_all_messages
|
17
|
+
while @messages.any?
|
18
|
+
message = @messages.shift
|
19
|
+
result = transition(message.first, message.last)
|
20
|
+
@state = result.is_a?(Array) ? result.first : result
|
21
|
+
command = result.is_a?(Array) ? result[1] : nil
|
22
|
+
run_command(result[1], result[2]) if command
|
23
|
+
if @commands.any?
|
24
|
+
while @commands.any? do end # TODO: refactor
|
25
|
+
process_all_messages
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def run
|
31
|
+
process
|
32
|
+
render
|
33
|
+
end
|
34
|
+
|
35
|
+
def run_command(type, payload)
|
36
|
+
puts 'running command'
|
37
|
+
end
|
38
|
+
|
39
|
+
def transition(type, payload)
|
40
|
+
case type
|
41
|
+
|
42
|
+
when :IncrementClicked
|
43
|
+
@state.merge(counter: @state[:counter] + 1)
|
44
|
+
|
45
|
+
when :LoadClicked
|
46
|
+
[@state, :FetchData, key_1: 1, key_2: 2]
|
47
|
+
|
48
|
+
when :LoadSuccess
|
49
|
+
@state.merge(content: payload[:data])
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/beryl/deserializer.rb
CHANGED
data/lib/beryl/frontend.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'opal'
|
2
2
|
require 'native'
|
3
3
|
require 'beryl/deserializer'
|
4
|
-
require 'beryl/
|
4
|
+
require 'beryl/frontend_runtime'
|
5
5
|
|
6
6
|
module Beryl
|
7
7
|
class Frontend
|
@@ -19,7 +19,8 @@ module Beryl
|
|
19
19
|
root = document.getElementById('beryl')
|
20
20
|
serialized_state = root.getAttribute('data-beryl').gsub('"', '"')
|
21
21
|
state = Beryl::Deserializer.deserialize(serialized_state)
|
22
|
-
|
22
|
+
puts "STATE = #{state.inspect}"
|
23
|
+
Beryl::FrontendRuntime.new(root, state, @view).run
|
23
24
|
end
|
24
25
|
end
|
25
26
|
end
|
@@ -4,12 +4,15 @@ require 'bowser/http'
|
|
4
4
|
require 'serializer'
|
5
5
|
|
6
6
|
module Beryl
|
7
|
-
class
|
7
|
+
class FrontendRuntime
|
8
|
+
attr_reader :state
|
9
|
+
|
8
10
|
def initialize(root, state, view)
|
9
11
|
@messages = []
|
10
12
|
@root = root
|
11
13
|
@state = state
|
12
14
|
@view = view
|
15
|
+
@commands = []
|
13
16
|
end
|
14
17
|
|
15
18
|
def push(message)
|
@@ -33,17 +36,33 @@ module Beryl
|
|
33
36
|
end
|
34
37
|
end
|
35
38
|
|
39
|
+
def process_all_messages
|
40
|
+
while @messages.any?
|
41
|
+
message = @messages.shift
|
42
|
+
result = transition(message.first, message.last)
|
43
|
+
@state = result.is_a?(Array) ? result.first : result
|
44
|
+
command = result.is_a?(Array) ? result[1] : nil
|
45
|
+
run_command(result[1], result[2]) if command
|
46
|
+
if @commands.any?
|
47
|
+
while @commands.any? do end # TODO: refactor
|
48
|
+
process_all_messages
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
36
53
|
def run
|
37
54
|
process
|
38
55
|
render
|
39
56
|
end
|
40
57
|
|
41
58
|
def run_command(type, payload)
|
59
|
+
uuid = SecureRandom.uuid
|
60
|
+
@commands << uuid
|
42
61
|
Task.new do
|
43
62
|
Bowser::HTTP.fetch('/command', method: :post, data: { type: type, payload: Serializer.serialize(payload) })
|
44
63
|
.then(&:json) # JSONify the response
|
45
|
-
.then { |response| puts response }
|
46
|
-
.catch { |exception| warn exception.message }
|
64
|
+
.then { |response| puts response; @commands.delete(uuid) }
|
65
|
+
.catch { |exception| warn exception.message; @commands.delete(uuid) }
|
47
66
|
end
|
48
67
|
end
|
49
68
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Beryl
|
2
|
+
class HTMLRenderer
|
3
|
+
def render(element)
|
4
|
+
return element[:props][:nodeValue] if element[:type] == 'text'
|
5
|
+
"#{open_tag(element)}#{children(element)}#{close_tag(element)}"
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def children(element)
|
11
|
+
element[:children].each_with_object('') do |child, html|
|
12
|
+
html << render(child)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def close_tag(element)
|
17
|
+
"</#{element[:type]}>"
|
18
|
+
end
|
19
|
+
|
20
|
+
def open_tag(element)
|
21
|
+
"<#{element[:type]}#{props(element[:props])}>"
|
22
|
+
end
|
23
|
+
|
24
|
+
def props(props)
|
25
|
+
props.each_with_object('') do |(key, value), html|
|
26
|
+
html << " #{key}=\"#{value}\""
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Beryl
|
2
|
+
module Routing
|
3
|
+
module Matcher
|
4
|
+
extend self
|
5
|
+
|
6
|
+
DEFAULT_CONSTRAINT = '.*'
|
7
|
+
|
8
|
+
def match(route, path)
|
9
|
+
params = params(route)
|
10
|
+
r = params.each_with_object("#{route.clone}") do |param, result|
|
11
|
+
result.sub!(":#{param}", "(#{DEFAULT_CONSTRAINT})")
|
12
|
+
end
|
13
|
+
regex = /\A#{r}\z/
|
14
|
+
matched = regex.match(path)
|
15
|
+
return false unless matched
|
16
|
+
params(route).each_with_object({}).with_index do |(param, result), index|
|
17
|
+
result[param] = matched[index + 1]
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def params(route)
|
25
|
+
route.scan(/:[[:lower:]_]+[[:lower:][:digit:]_]*/).map { |param| param[1..-1].to_sym }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'beryl/routing/matcher'
|
2
|
+
|
3
|
+
module Beryl
|
4
|
+
module Routing
|
5
|
+
class Router
|
6
|
+
attr_reader :routes
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@routes = []
|
10
|
+
draw
|
11
|
+
end
|
12
|
+
|
13
|
+
def match(path)
|
14
|
+
@routes.each do |route|
|
15
|
+
matched = Beryl::Routing::Matcher.match(route[0], path)
|
16
|
+
return [route[1], matched] if matched
|
17
|
+
end
|
18
|
+
[:not_found]
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def draw
|
24
|
+
eval(File.open(File.expand_path('./app/routes.rb')).read)
|
25
|
+
end
|
26
|
+
|
27
|
+
def route(path, route)
|
28
|
+
@routes << [path, route]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/beryl/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beryl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bart Blast
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -139,8 +139,11 @@ files:
|
|
139
139
|
- Rakefile-template
|
140
140
|
- app/frontend.rb
|
141
141
|
- app/initial_state.rb
|
142
|
-
- app/
|
142
|
+
- app/routes.rb
|
143
143
|
- app/view.rb
|
144
|
+
- app/widgets/homepage.rb
|
145
|
+
- app/widgets/not_found.rb
|
146
|
+
- app/widgets/page_x.rb
|
144
147
|
- beryl.gemspec
|
145
148
|
- bin/console
|
146
149
|
- bin/setup
|
@@ -148,9 +151,13 @@ files:
|
|
148
151
|
- lib/beryl.rb
|
149
152
|
- lib/beryl/Rakefile
|
150
153
|
- lib/beryl/backend.rb
|
154
|
+
- lib/beryl/backend_runtime.rb
|
151
155
|
- lib/beryl/deserializer.rb
|
152
156
|
- lib/beryl/frontend.rb
|
153
|
-
- lib/beryl/
|
157
|
+
- lib/beryl/frontend_runtime.rb
|
158
|
+
- lib/beryl/html_renderer.rb
|
159
|
+
- lib/beryl/routing/matcher.rb
|
160
|
+
- lib/beryl/routing/router.rb
|
154
161
|
- lib/beryl/style.css
|
155
162
|
- lib/beryl/utils.rb
|
156
163
|
- lib/beryl/version.rb
|