raindeer 0.1.2 → 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: 8ff951a5eafc6d661e188c1eb78fb01ae2a148544fd897da8731800305335f2f
4
- data.tar.gz: d821af08d8333a88da073564db2f699e905de22fa825ed89ac41dca5dd48fd4b
3
+ metadata.gz: 8d79ce92ce79c7e46122adb4e9ba39968d9bf220cca424deba580f3a74ac26c6
4
+ data.tar.gz: 6970876678afd4bf8395135d52a9c1ff20858170282e3c97c540f1458338d4ea
5
5
  SHA512:
6
- metadata.gz: 6c8cc7383ae033d78736e5c7db85057f4a2ab4bbd8b5634d4efc7164b96112dd25ac94e31216f9cbe2ab06a99fa70f1b34a9f742da6725ff3f0fe7295b99f0f2
7
- data.tar.gz: 52bd7181b0e4bb0a9a4cf17a0802428849a1a0e5543f1443721661c58c229f528e6e49fc0f97866a5092d2e42772a2ca26cbdd67d61da7b5bca50857ade3bd0c
6
+ metadata.gz: 947dd01220faa492c9abf83e78aae9ec07d5e6c5794724aa24dda43be39e8fe82822734c068612f1176246c64b3e5f34e205d5b2fbb7d5517be598d3e927b1f2
7
+ data.tar.gz: bb4fff4358eae10a7b3ee1085ad9bd35bd7ac795c639dcb48b8e7c7deea3055e592a1f196931fc98ad64161631b5107bd1ca75fe29086d415891e7cfc23d84d3
data/lib/boot.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'low_loop'
4
- require 'low_dependency'
3
+ require 'low_event'
4
+ require 'low_node'
5
+ require 'low_type'
6
+ require 'providers'
5
7
 
6
8
  require_relative 'support/config_loader'
7
9
 
@@ -15,12 +17,20 @@ env = {
15
17
 
16
18
  config = Rain::ConfigLoader.load('./config/config.yaml', env)
17
19
 
18
- LowDependency.provide('rain.router') do
19
- RainRouter.new
20
+ Providers.define('rain.router') do
21
+ require_relative 'router/router'
22
+ Rain::Router.new
20
23
  end
21
24
 
22
- LowDependency.provide('low.loop') do
23
- LowLoop.new(config:, router: Low::Providers['rain.router'])
25
+ Providers.define('rain.matrix') do
26
+ require_relative 'matrix/matrix'
27
+ Rain::Matrix.new(event_pool: Providers['low.event.pool'])
24
28
  end
25
29
 
26
- require_relative 'system/system'
30
+ Providers.define('low.loop') do
31
+ require 'low_loop'
32
+ LowLoop.new(config:, router: Providers['rain.router'], renderer: Providers['rain.matrix'])
33
+ end
34
+
35
+ require 'lowload'
36
+ LowLoad.dirload(File.expand_path('system', __dir__))
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rain
4
+ class Cursor
5
+ attr_accessor :index, :first_update, :last_update
6
+
7
+ def initialize
8
+ @index = -1
9
+ @first_update = now
10
+ @last_update = now
11
+ end
12
+
13
+ # Unit tests use "duration" to skip forward in time, while feature tests and the real world use old fashioned linear time.
14
+ def increment(delays:, inputs:, duration: nil)
15
+ next_index = next_index(loop_count: inputs.count)
16
+
17
+ return unless delays[next_index] && (duration || now - @last_update) >= delays[next_index]
18
+
19
+ @index = next_index
20
+ @last_update = now
21
+
22
+ yield index
23
+ end
24
+
25
+ def iterate(inputs:, loop_count:)
26
+ inputs.each do |input|
27
+ @index += 1
28
+ @index = 0 if index >= loop_count
29
+
30
+ yield index, input
31
+ end
32
+ end
33
+
34
+ def increase_index(loop_count:)
35
+ @index += 1
36
+ @index = 0 if @index >= loop_count
37
+ end
38
+
39
+ def next_index(loop_count:)
40
+ next_index = @index + 1
41
+ next_index = 0 if next_index >= loop_count
42
+ next_index
43
+ end
44
+
45
+ private
46
+
47
+ def now
48
+ Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'low_event'
4
+ require 'observers'
5
+ require 'paint'
6
+
7
+ require_relative '../support/config_loader'
8
+ require_relative 'stream'
9
+
10
+ module Rain
11
+ class Matrix
12
+ include Observers
13
+
14
+ def initialize(event_pool:, config: ConfigLoader.load('./config/matrix.yaml'))
15
+ @event_pool = event_pool
16
+ @config = config
17
+
18
+ @screen_size = nil
19
+
20
+ @last_stream_index = -1
21
+ @streams = {} # TODO: Could be a "stream pool" like event pool (a pool hash).
22
+ @columns = []
23
+ end
24
+
25
+ def redraw(screen_size:)
26
+ @setup ||= setup
27
+
28
+ @streams.each_value do |stream|
29
+ stream.redraw(cell_count: screen_size[:row_count])
30
+ end
31
+ end
32
+
33
+ def render(screen_size:, show_output: true)
34
+ if screen_size != @screen_size
35
+ @screen_size = screen_size
36
+ redraw(screen_size:)
37
+ end
38
+
39
+ render_streams(show_output:)
40
+ end
41
+
42
+ # TODO: Introduce "on :new_event_tree do |event|" block construct in LowEvent for making event handlers more obvious.
43
+ # TODO: Observers should allow arbitrary params when triggering and observing.
44
+ def new_event_tree(event: Low::Events::EventTree)
45
+ stream = upsert_stream(event_tree: event)
46
+ stream.redraw(cell_count: @screen_size[:row_count])
47
+ end
48
+
49
+ private
50
+
51
+ def setup
52
+ @event_pool.event_trees.each_value do |event_tree|
53
+ upsert_stream(event_tree:)
54
+ end
55
+
56
+ observe @event_pool
57
+
58
+ true
59
+ end
60
+
61
+ def upsert_stream(event_tree:)
62
+ stream = @streams[event_tree.request_id] ||= Stream.new(index: generate_index, config: @config, event_tree:)
63
+ @columns[stream.index] = stream
64
+ stream
65
+ end
66
+
67
+ def render_streams(show_output: true) # rubocop:disable Metrics/AbcSize
68
+ @streams.each_value(&:render)
69
+
70
+ return unless show_output
71
+
72
+ output = ''.dup
73
+
74
+ (0...@screen_size[:row_count]).each do |row_index|
75
+ cell_outputs = []
76
+ cell_colors = []
77
+
78
+ # Rendering streams can happen before redrawing streams, so @columns may not be populated yet.
79
+ (0...column_count).each do |column_index|
80
+ cell_colors << (@columns[column_index].nil? ? nil : @columns[column_index].colors[row_index])
81
+ cell_outputs << (@columns[column_index].nil? ? nil : @columns[column_index].outputs[row_index])
82
+ end
83
+
84
+ output << "\n" + cell_outputs.zip(cell_colors).map do |cell, color| # rubocop:disable Style/StringConcatenation
85
+ cell ? Paint[cell, color] : Paint[' ']
86
+ end.join(' ')
87
+ end
88
+
89
+ system 'clear'
90
+ print output.delete_prefix("\n").delete_suffix("\n")
91
+ end
92
+
93
+ def generate_index
94
+ case @config.start_col
95
+ when :random
96
+ rand(0...column_count)
97
+ when :latest
98
+ @last_stream_index += 1
99
+ return @last_stream_index = 0 if @last_stream_index >= column_count
100
+
101
+ @last_stream_index
102
+ end
103
+ end
104
+
105
+ def column_count
106
+ return @screen_size[:column_count] if @screen_size[:column_count] < 10
107
+
108
+ (@screen_size[:column_count] / 2).to_i.clamp(1, nil)
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'low_event'
4
+ require 'observers'
5
+
6
+ require_relative 'cursor'
7
+
8
+ module Rain
9
+ class Stream
10
+ include Observers
11
+ attr_reader :index, :inputs, :outputs, :delays, :colors, :head_cursor, :tail_cursor
12
+
13
+ ARROW = ['│', '▼'].freeze
14
+
15
+ def initialize(index:, config:, event_tree:)
16
+ @index = index
17
+ @config = config
18
+ @event_tree = event_tree
19
+
20
+ @inputs = []
21
+ @delays = []
22
+ @colors = []
23
+ @outputs = []
24
+
25
+ @event_cursor = 0
26
+ @head_cursor = Cursor.new
27
+ @tail_cursor = Cursor.new
28
+ @tail_cursor.index = 0
29
+
30
+ @show_cursor = Cursor.new
31
+ @hide_cursor = Cursor.new
32
+
33
+ observe event_tree
34
+ end
35
+
36
+ # TODO: Use "on :branch do |event|" syntax.
37
+ def branch(event: Low::Events::BranchEvent) # rubocop:disable Lint/UnusedMethodArgument
38
+ redraw(cell_count: @inputs.count)
39
+ end
40
+
41
+ # Draw event names onto the current amount of cells in a stream, using cursors. Called when there's a new event.
42
+ #
43
+ # INPUT DELAY OUTPUT
44
+ # ┌─────┬─────┬─────┐
45
+ # │ R │ 75 │ │ ◀── 2. Tail Cursor begins at index zero or a random starting index.
46
+ # │ e │ 75 │ │ A Head Cursor that wraps around will push the Tail Cursor down to be just beneath it.
47
+ # │ q │ 75 │ │ The Show Cursor will start at the Tail Cursor index.
48
+ # │ u │ 75 │ │
49
+ # │ │ 75 │ │ ◀── 1. Head Cursor begins at index zero or a random starting index.
50
+ # │ │ 75 │ │ It populates input for every character in an event name.
51
+ # │ │ 75 │ │ Then sets a "75" delay for the Show Cursor.
52
+ # └─────┴─────┴─────┘
53
+ def redraw(cell_count:)
54
+ randomize_start_index if first_cell_redraw? && @config.start_row == :random
55
+ resize_cells(cell_count:) if cell_count != @inputs.count
56
+
57
+ (@event_cursor...@event_tree.sequence.count).each do |event_index|
58
+ current_event = @event_tree.sequence[event_index]
59
+ past_event = @event_tree.sequence[event_index - 1]
60
+
61
+ redraw_event(current_event:, past_event:)
62
+ @event_cursor += 1
63
+ end
64
+ end
65
+
66
+ # Render a cell's input as output after a delay, using cursors. Called on every frame.
67
+ #
68
+ # INPUT DELAY OUTPUT
69
+ # ┌─────┬─────┬─────┐
70
+ # │ │ 0 │ │ ◀── 2. Hide Cursor moves the input to the output after a delay.
71
+ # │ │ 250 │ e │ The nil input replaces the previous output of "R".
72
+ # │ │ 250 │ q │
73
+ # │ │ 250 │ u │ ◀── 1. Show Cursor moves the input to the output after a delay.
74
+ # │ e │ 75 │ │ Leaving behind nil input.
75
+ # │ s │ 75 │ │ Then sets a "250" delay for the Hide Cursor.
76
+ # │ t │ 75 │ │
77
+ # └─────┴─────┴─────┘
78
+ #
79
+ # TODO: Refactor "@colors" into an Effect that happens dynamically on render rather than stored as a column of data.
80
+ # This will reduce the "Metrics/AbcSize" complexity.
81
+ def render(duration: nil) # rubocop:disable Metrics/AbcSize
82
+ @show_cursor.increment(delays:, inputs:, duration:) do |index|
83
+ prev_index = index.zero? ? @inputs.count - 1 : index - 1
84
+ next_index = index + 1 >= @inputs.count ? 0 : index + 1
85
+
86
+ if @inputs[index]
87
+ @outputs[index] = @inputs[index]
88
+ @delays[index] = @config.fade_delay
89
+ @colors[prev_index] = @config.cell_color if @colors[prev_index]
90
+ @colors[index] = @outputs[next_index] ? @config.cell_color : @config.lead_color
91
+ @inputs[index] = nil
92
+ end
93
+ end
94
+
95
+ fade(duration:) if @config.fade
96
+ end
97
+
98
+ private
99
+
100
+ def fade(duration: nil)
101
+ fade_start_delay = rand(5_000..10_000)
102
+ return unless (now - @show_cursor.first_update) >= fade_start_delay || duration
103
+
104
+ @hide_cursor.increment(delays:, inputs:, duration:) do |index|
105
+ if @inputs[index].nil? && @outputs[index]
106
+ @outputs[index] = @inputs[index]
107
+ @delays[index] = 0
108
+ end
109
+ end
110
+ end
111
+
112
+ def now
113
+ Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
114
+ end
115
+
116
+ # A column of cells representing sequential events.
117
+ # ┌─┐
118
+ # │R│ FIRST EVENT
119
+ # │e│ Each cell will render input as output after a minimum delay (since there's no prior event).
120
+ # │q│
121
+ # │u│
122
+ # │e│
123
+ # │s│
124
+ # │t│
125
+ # └─┘ ◀── Time has passed between events.
126
+ # ┌─┐
127
+ # │││ SECOND EVENT
128
+ # │▼│ The next event has data to work with, it can represent the time it took to get from the previous event to the next.
129
+ # │R│ Each cell will delay render for the larger duration of either:
130
+ # │o│ 1. The minimum delay
131
+ # │u│ 2. The time elapsed between events divided by the number of cells
132
+ # │t│
133
+ # │e│ ◀── A cursor moves to the next cell after a delay and colors the leading cell white.
134
+ # └─┘
135
+ def redraw_event(current_event:, past_event:)
136
+ variable_delay = variable_delay(current_event:, past_event:)
137
+
138
+ characters = event_name(current_event:)
139
+ characters = [*ARROW, *characters] if @event_cursor > 0
140
+
141
+ @head_cursor.iterate(inputs: characters, loop_count: @inputs.count) do |index, input|
142
+ @inputs[index] = input
143
+ @delays[index] = first_cell_redraw? ? 0 : variable_delay # Don't add delay to the first cell, looks stuck.
144
+
145
+ @tail_cursor.increase_index(loop_count: @inputs.count) if @head_cursor.index == @tail_cursor.index
146
+ end
147
+
148
+ @hide_cursor.index = @head_cursor.index # Everything after me is old so it can fade away.
149
+ end
150
+
151
+ def variable_delay(current_event:, past_event:)
152
+ if @event_cursor.zero?
153
+ @config.min_delay
154
+ else
155
+ difference = current_event.created_at - past_event.created_at
156
+ difference.zero? ? @config.min_delay : (difference / inputs.count).to_i.clamp(@config.min_delay, nil)
157
+ end
158
+ end
159
+
160
+ def event_name(current_event:)
161
+ current_event.class.name.split('::').last.delete_suffix('Event').chars
162
+ end
163
+
164
+ def first_cell_redraw?
165
+ @head_cursor.index == -1
166
+ end
167
+
168
+ def resize_cells(cell_count:)
169
+ old_index = (@inputs.count - 1).clamp(0, nil)
170
+
171
+ @inputs = @inputs.fill(nil, old_index...cell_count)[0...cell_count]
172
+ @outputs = @outputs.fill(nil, old_index...cell_count)[0...cell_count]
173
+ @delays = @delays.fill(@config.min_delay, old_index...cell_count)[0...cell_count]
174
+ @colors = @colors.fill(@config.cell_color, old_index...cell_count)[0...cell_count]
175
+ end
176
+
177
+ def randomize_start_index
178
+ random_index = rand(0..2)
179
+
180
+ @head_cursor.index = random_index
181
+ @tail_cursor.index = random_index
182
+
183
+ @show_cursor.index = random_index
184
+ end
185
+ end
186
+ end
data/lib/raindeer.rb CHANGED
@@ -1,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'low_dependency'
4
3
  require 'low_event'
5
4
  require 'low_node'
6
5
  require 'low_type'
7
6
  require 'observers'
7
+ require 'providers'
8
8
 
9
9
  require_relative 'router/router'
10
10
 
11
- class Raindeer
11
+ module Raindeer
12
12
  class << self
13
13
  def router(&block)
14
- Low::Providers['rain.router'].instance_eval(&block)
14
+ Providers['rain.router'].instance_eval(&block)
15
15
  end
16
16
  end
17
17
  end
@@ -7,7 +7,7 @@ module Rain
7
7
  attr_reader :route, :params
8
8
 
9
9
  def initialize(route:, action: :render, params: Hash | nil)
10
- super(action:)
10
+ super(key: route.path, action:)
11
11
 
12
12
  @route = route
13
13
  @params = params
data/lib/router/router.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'low_dependency'
4
3
  require 'low_event'
4
+ require 'providers'
5
5
 
6
6
  require_relative 'route'
7
7
  require_relative 'route_event'
@@ -33,19 +33,19 @@ module Rain
33
33
  @breadcrumbs.pop
34
34
  end
35
35
 
36
- def get(path = String, &block)
36
+ def get(path, &block)
37
37
  route(path, 'GET', &block)
38
38
  end
39
39
 
40
- def post(path = String, &block)
40
+ def post(path, &block)
41
41
  route(path, 'POST', &block)
42
42
  end
43
43
 
44
- def update(path = String, &block)
44
+ def update(path, &block)
45
45
  route(path, 'UPDATE', &block)
46
46
  end
47
47
 
48
- def delete(path = String, &block)
48
+ def delete(path, &block)
49
49
  route(path, 'DELETE', &block)
50
50
  end
51
51
 
@@ -54,18 +54,14 @@ module Rain
54
54
  def handle(event:)
55
55
  response_event = nil
56
56
 
57
- @trie.match(path: event.request.path).each do |route_event|
58
- response_event = trigger route_event.route.path, event: route_event
57
+ # The last route event will render a response event which we want to return to the request event.
58
+ @trie.match(path: event.request.path.delete_suffix('/')).each do |route_event|
59
+ response_event = route_event.trigger
59
60
  end
60
61
 
61
- if response_event.nil?
62
- status = Low::Types::Status[404]
63
- response_event = trigger status, action: :render, event: Low::Events::StatusEvent.new(status:, request: event.request)
64
- end
62
+ return response_event if response_event
65
63
 
66
- response_event
64
+ Low::Events::StatusEvent.trigger(status: Low::Types::Status[404], request: event.request)
67
65
  end
68
66
  end
69
67
  end
70
-
71
- RainRouter = Rain::Router
data/lib/router/trie.rb CHANGED
@@ -66,7 +66,7 @@ module Rain
66
66
 
67
67
  private
68
68
 
69
- # End nodes render events, mid nodes handle events.
69
+ # Mid nodes handle events, end nodes render events.
70
70
  def route_event(next_index:, params:, path:, route:)
71
71
  action = path[next_index].nil? ? :render : :handle
72
72
  RouteEvent.new(action:, route:, params:)
@@ -6,11 +6,11 @@ require 'yaml'
6
6
  module Rain
7
7
  class ConfigLoader
8
8
  class << self
9
- def load(filepath, env = {})
10
- config_file = YAML.safe_load_file(filepath, symbolize_names: true)
9
+ def load(filepath, overrides = {})
10
+ config_file = YAML.safe_load_file(filepath, permitted_classes: [Symbol], symbolize_names: true)
11
11
 
12
12
  # Environment variables override config file.
13
- config_data = config_file.merge(env) do |_key, old_value, new_value|
13
+ config_data = config_file.merge(overrides) do |_key, old_value, new_value|
14
14
  new_value.nil? ? old_value : new_value
15
15
  end
16
16
 
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DashboardNode < LowNode
4
+ observe '/system'
5
+
6
+ def render(event:) # rubocop:disable Lint/UnusedMethodArgument
7
+ <{ LayoutNode: }>
8
+ <h1>{"Dashboard"}</h1>
9
+ <{ :LayoutNode }>
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Error404Node < LowNode
4
+ observe Low::Types::Status[404]
5
+
6
+ def render(event:) # rubocop:disable Lint/UnusedMethodArgument
7
+ <div class="page-not-found">
8
+ <em>404</em>
9
+ </div>
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EventsNode < LowNode
4
+ observe '/system/events'
5
+
6
+ def initialize(event:)
7
+ @events = 'TODO: Populate via LowEvent inherited hook.'
8
+ end
9
+
10
+ def render(event:)
11
+ <{ LayoutNode: }>
12
+ <h1>{"Events"}</h1>
13
+
14
+ {@events}
15
+
16
+ <table>
17
+ <thead>
18
+ <tr>
19
+ <th scope="col">HTTP Verbs</th>
20
+ <th scope="col">Route</th>
21
+ <th scope="col">Observers</th>
22
+ </tr>
23
+ </thead>
24
+ <tbody>
25
+ <tr>
26
+ <td>1</td>
27
+ <td>2</td>
28
+ <td>3</td>
29
+ </tr>
30
+ </tbody>
31
+ </table>
32
+ <{ :LayoutNode }>
33
+ end
34
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ class LayoutNode < LowNode
4
+ def render(event:)
5
+ <html>
6
+ <head>
7
+ <link rel="stylesheet" href="/assets/pico.min.css">
8
+ <link rel="stylesheet" href="/assets/system.css">
9
+ </head>
10
+ <body>
11
+ <header>
12
+ <div class="container">
13
+ <a id="favicon" href="/system"><img src="/assets/favicon.svg"/></a>
14
+ <nav id="navbar">
15
+ <ul>
16
+ <li><a href="/system">{"Dashboard"}</a>
17
+ <li><a href="/system/events">{"Events"}</a>
18
+ <li><a href="/system/routes">{"Routes"}</a>
19
+ </ul>
20
+ </nav>
21
+ </div>
22
+ </header>
23
+
24
+ <main class="container">
25
+ <{ :slot }>
26
+ </main>
27
+
28
+ <footer>
29
+ <div class="container">
30
+ <ul>
31
+ <li><a href="https://raindeer.dev">{"Website"}</a></li>
32
+ <li><a href="https://raindeer.dev/docs">{"Docs"}</a></li>
33
+ <li><a href="https://github.com/raindeer-rb/raindeer">{"Source code"}</a></li>
34
+ </ul>
35
+ </div>
36
+ </footer>
37
+ </body>
38
+ </html>
39
+ end
40
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RoutesNode < LowNode
4
+ observe '/system/routes'
5
+
6
+ def initialize(event:)
7
+ @routes = Providers['rain.router'].routes
8
+ end
9
+
10
+ def render(event:)
11
+ <{ LayoutNode: }>
12
+ <h1>{"Routes"}</h1>
13
+
14
+ {@routes}
15
+
16
+ <table>
17
+ <thead>
18
+ <tr>
19
+ <th scope="col">HTTP Verbs</th>
20
+ <th scope="col">Route</th>
21
+ <th scope="col">Observers</th>
22
+ </tr>
23
+ </thead>
24
+ <tbody>
25
+ <tr>
26
+ <td>1</td>
27
+ <td>2</td>
28
+ <td>3</td>
29
+ </tr>
30
+ </tbody>
31
+ </table>
32
+ <{ :LayoutNode }>
33
+ end
34
+ end
data/lib/system/system.rb CHANGED
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../raindeer'
4
- require_relative 'system_node'
5
4
 
6
5
  Raindeer.router do
7
- get '/system'
6
+ get '/system' do
7
+ get '/events'
8
+ get '/routes'
9
+ end
8
10
  end
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Raindeer
4
- VERSION = '0.1.2'
4
+ VERSION = '0.3.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: raindeer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - maedi
@@ -24,7 +24,7 @@ dependencies:
24
24
  - !ruby/object:Gem::Version
25
25
  version: '0'
26
26
  - !ruby/object:Gem::Dependency
27
- name: low_dependency
27
+ name: paint
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - ">="
@@ -39,6 +39,20 @@ dependencies:
39
39
  version: '0'
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: low_event
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '0.5'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '0.5'
54
+ - !ruby/object:Gem::Dependency
55
+ name: lowload
42
56
  requirement: !ruby/object:Gem::Requirement
43
57
  requirements:
44
58
  - - ">="
@@ -55,16 +69,16 @@ dependencies:
55
69
  name: low_loop
56
70
  requirement: !ruby/object:Gem::Requirement
57
71
  requirements:
58
- - - ">="
72
+ - - "~>"
59
73
  - !ruby/object:Gem::Version
60
- version: '0'
74
+ version: '0.5'
61
75
  type: :runtime
62
76
  prerelease: false
63
77
  version_requirements: !ruby/object:Gem::Requirement
64
78
  requirements:
65
- - - ">="
79
+ - - "~>"
66
80
  - !ruby/object:Gem::Version
67
- version: '0'
81
+ version: '0.5'
68
82
  - !ruby/object:Gem::Dependency
69
83
  name: low_node
70
84
  requirement: !ruby/object:Gem::Requirement
@@ -149,6 +163,20 @@ dependencies:
149
163
  - - ">="
150
164
  - !ruby/object:Gem::Version
151
165
  version: '0'
166
+ - !ruby/object:Gem::Dependency
167
+ name: providers
168
+ requirement: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ type: :runtime
174
+ prerelease: false
175
+ version_requirements: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
152
180
  description: A new Ruby framework. Coming soon...
153
181
  email:
154
182
  - maediprichard@gmail.com
@@ -157,6 +185,9 @@ extensions: []
157
185
  extra_rdoc_files: []
158
186
  files:
159
187
  - lib/boot.rb
188
+ - lib/matrix/cursor.rb
189
+ - lib/matrix/matrix.rb
190
+ - lib/matrix/stream.rb
160
191
  - lib/raindeer.rb
161
192
  - lib/router/route.rb
162
193
  - lib/router/route_event.rb
@@ -164,9 +195,12 @@ files:
164
195
  - lib/router/trie.rb
165
196
  - lib/router/trie_node.rb
166
197
  - lib/support/config_loader.rb
167
- - lib/system/page_not_found_node.rb
198
+ - lib/system/dashboard_node.rbx
199
+ - lib/system/error_404_node.rbx
200
+ - lib/system/events_node.rbx
201
+ - lib/system/layout_node.rbx
202
+ - lib/system/routes_node.rbx
168
203
  - lib/system/system.rb
169
- - lib/system/system_node.rb
170
204
  - lib/version.rb
171
205
  homepage: https://codeberg.org/raindeer/raindeer
172
206
  licenses: []
@@ -187,7 +221,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
221
  - !ruby/object:Gem::Version
188
222
  version: '0'
189
223
  requirements: []
190
- rubygems_version: 3.7.2
224
+ rubygems_version: 4.0.6
191
225
  specification_version: 4
192
226
  summary: Deer to be different
193
227
  test_files: []
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class PageNotFoundNode < LowNode
4
- observe Status[404]
5
-
6
- def render(event: StatusEvent) # rubocop:disable Lint/UnusedMethodArgument
7
- <<~HTML
8
- <div class="page-not-found">
9
- <em>404</em>
10
- </div>
11
- HTML
12
- end
13
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'page_not_found_node'
4
-
5
- class SystemNode < LowNode
6
- observe '/system'
7
-
8
- def render(event: RouteEvent) # rubocop:disable Lint/UnusedMethodArgument
9
- 'SYSTEM!'
10
- end
11
- end