beryl 0.2.5 → 0.3.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 024bc3d265686b410dc6f3fc59b3768f68387a6acea8c47e1871b037a4e81b19
4
- data.tar.gz: 7a5fad376ffce81ecba38189a661d0eaf1c82224b3667f99ba98c9d1886c9ca3
3
+ metadata.gz: '0359afa9fc5dcf6e6116594b9ba70c06425e9c889069e60c5398c1be9b39d100'
4
+ data.tar.gz: 505f33152ec6db4b9ddfd2dcbd30351357a3dacc5434493a67e271104cde0c40
5
5
  SHA512:
6
- metadata.gz: 1b035c97f8e44c4dcd69b092df5d2b83019b9f7e33c2eb728877c264ccab9ee15b2e05c5cf3f279b70bf96d2eb98a95d67ca593eb21e7256c091d1b5711f2e6c
7
- data.tar.gz: 4ca220ec4b41fcf09122d3fdd926095124f4b74c66a7d22b42b97153f09aa091cdc7551500708fcfa4db1d53ff6d23a1e2f949d3f988771584f598730dfe1947
6
+ metadata.gz: bce4b5249650d957206888567d29ca76d21038a11f228466da07dd1824ac2a0a76161bbc84cbf89f61e32bea48f3322302e0dd75294c1dd5f69c67a8c77f8135
7
+ data.tar.gz: 68bc437aa950783b2c37ed46410140067202e30103d35c901273f4eaa4cbd8e47da4390c607d9268a05cd5256c78c9d2225869a6ce9467c404dc511bf1b68a54
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- beryl (0.2.4)
4
+ beryl (0.2.5)
5
5
  bowser
6
6
  capybara
7
7
  opal
data/app/initial_state.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  {
2
2
  content: 'here we will load something',
3
3
  counter: 0,
4
- route: nil
5
4
  }
data/app/routes.rb ADDED
@@ -0,0 +1,5 @@
1
+ route '/', :homepage
2
+
3
+ route '/page-x', :page_x
4
+
5
+ route 'dupa/:id', :dupa_page
data/app/view.rb CHANGED
@@ -1,8 +1,17 @@
1
1
  require 'beryl/view'
2
- require 'something'
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
- Something.new.render(state)
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 Something < Beryl::Widget
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
@@ -0,0 +1,7 @@
1
+ require 'beryl/widget'
2
+
3
+ class NotFound < Beryl::Widget
4
+ def render(state)
5
+ text "Not found..."
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'beryl/widget'
2
+
3
+ class PageX < Beryl::Widget
4
+ def render(state)
5
+ text "Other route: #{state[:route]}"
6
+ end
7
+ 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
- [200, { 'Content-Type' => 'text/html; charset=utf-8' }, [response]]
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(eval(File.read('app/initial_state.rb'))).gsub('"', '&quot;')
41
+ Serializer.serialize(@state).gsub('"', '&quot;')
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"></div>
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
@@ -15,6 +15,8 @@ module Beryl
15
15
  item['value'].to_i
16
16
  when 'String'
17
17
  item['value']
18
+ when 'Symbol'
19
+ item['value'].to_sym
18
20
  end
19
21
  end
20
22
  end
@@ -1,7 +1,7 @@
1
1
  require 'opal'
2
2
  require 'native'
3
3
  require 'beryl/deserializer'
4
- require 'beryl/runtime'
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('&quot;', '"')
21
21
  state = Beryl::Deserializer.deserialize(serialized_state)
22
- Beryl::Runtime.new(root, state, @view).run
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 Runtime
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
@@ -1,3 +1,3 @@
1
1
  module Beryl
2
- VERSION = '0.2.5'
2
+ VERSION = '0.3.0'
3
3
  end
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.2.5
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-09-28 00:00:00.000000000 Z
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/something.rb
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/runtime.rb
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