raindeer 0.4.0 → 0.6.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 +4 -4
- data/lib/matrix/cursor.rb +2 -2
- data/lib/matrix/effects/color_effect.rb +14 -0
- data/lib/matrix/effects/effect.rb +17 -0
- data/lib/matrix/effects/leet_effect.rb +33 -0
- data/lib/matrix/matrix.rb +14 -8
- data/lib/matrix/stream.rb +4 -12
- data/lib/pages/pages.rb +48 -0
- data/lib/raindeer/boot.rb +73 -0
- data/lib/router/router.rb +7 -1
- data/lib/router/wildcard_route_event.rb +15 -0
- data/lib/support/config_loader.rb +3 -2
- data/lib/system/dashboard_node.rbx +16 -14
- data/lib/system/events_node.rbx +28 -26
- data/lib/system/layouts/layout_node.rbx +36 -35
- data/lib/system/routes_node.rbx +27 -25
- data/lib/system/{system.rb → system_routes.rb} +0 -2
- data/lib/version.rb +1 -1
- metadata +51 -5
- data/lib/boot.rb +0 -37
- data/lib/raindeer.rb +0 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1e0b76037f60987d82171f076418703e068203ea1a9326964c630049a7aef633
|
|
4
|
+
data.tar.gz: 92a5be3103a09b81f287f3dafb74d75cf41761271d2c917500bf762fefb4613a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 06b5fb27769c9319b0c0dbe7ef75cbdab5f5ea6e1c9b116bcd73faffbb9c56211a9818e62aae4ebe27b3a120eb0fc689caabe55e14d751f7461a85a0aeaf9448
|
|
7
|
+
data.tar.gz: d96c8de0e0d25782b167c7fd72bd610463f353379df85024323edfaae941490bb7f751db37effb4112aa31788ba3de9f757bb38c16be937f03ed3329739f9bf5
|
data/lib/matrix/cursor.rb
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'effect'
|
|
4
|
+
|
|
5
|
+
module Rain
|
|
6
|
+
class ColorEffect < Effect
|
|
7
|
+
def render(output:, next_output:, **)
|
|
8
|
+
color = next_output ? @config.cell_color : @config.lead_color
|
|
9
|
+
|
|
10
|
+
return Paint[output, '#006ab0'] if @config.leet_keys.invert.key?(output)
|
|
11
|
+
output ? Paint[output, color] : Paint[' ']
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rain
|
|
4
|
+
class Effect
|
|
5
|
+
attr_accessor :last_output
|
|
6
|
+
|
|
7
|
+
def initialize(config:)
|
|
8
|
+
@config = config
|
|
9
|
+
@last_output = {}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def save(output:, x:, y:)
|
|
13
|
+
@last_output[x] ||= {}
|
|
14
|
+
@last_output[x][y] = output
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'effect'
|
|
4
|
+
|
|
5
|
+
module Rain
|
|
6
|
+
class LeetEffect < Effect
|
|
7
|
+
def initialize(config:)
|
|
8
|
+
super(config:)
|
|
9
|
+
|
|
10
|
+
@leet_numbers = @config.leet_keys.transform_keys(&:to_s)
|
|
11
|
+
@leet_letters = @leet_numbers.invert
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def render(output:, next_output:, x:, y:)
|
|
15
|
+
output = filter(output:, next_output:, x:, y:)
|
|
16
|
+
save(output:, x:, y:)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def filter(output:, next_output:, x:, y:)
|
|
22
|
+
return unless output
|
|
23
|
+
|
|
24
|
+
character = output.downcase
|
|
25
|
+
last_character = @last_output.dig(x, y)
|
|
26
|
+
|
|
27
|
+
return @leet_numbers[character] if @leet_letters.key?(last_character) && rand < 0.99
|
|
28
|
+
return @leet_numbers[character] if @leet_numbers.key?(character) && rand < 0.005
|
|
29
|
+
|
|
30
|
+
output
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
data/lib/matrix/matrix.rb
CHANGED
|
@@ -5,17 +5,20 @@ require 'low_type'
|
|
|
5
5
|
require 'observers'
|
|
6
6
|
require 'paint'
|
|
7
7
|
|
|
8
|
-
require_relative '
|
|
8
|
+
require_relative 'effects/color_effect'
|
|
9
|
+
require_relative 'effects/leet_effect'
|
|
9
10
|
require_relative 'stream'
|
|
11
|
+
require_relative '../support/config_loader'
|
|
10
12
|
|
|
11
13
|
module Rain
|
|
12
14
|
class Matrix
|
|
13
15
|
include LowType
|
|
14
16
|
include Observers
|
|
15
17
|
|
|
16
|
-
def initialize(event_pool:, config: ConfigLoader.load('
|
|
18
|
+
def initialize(event_pool:, config: ConfigLoader.load('matrix.yaml'))
|
|
17
19
|
@event_pool = event_pool
|
|
18
20
|
@config = config
|
|
21
|
+
@effects = [LeetEffect.new(config:), ColorEffect.new(config:)]
|
|
19
22
|
|
|
20
23
|
@screen_size = nil
|
|
21
24
|
|
|
@@ -66,6 +69,8 @@ module Rain
|
|
|
66
69
|
stream
|
|
67
70
|
end
|
|
68
71
|
|
|
72
|
+
# Where streams become the final output on the matrix.
|
|
73
|
+
# @columns - A column contains a particular stream
|
|
69
74
|
def render_streams(show_output: true) # rubocop:disable Metrics/AbcSize
|
|
70
75
|
@streams.each_value(&:render)
|
|
71
76
|
|
|
@@ -74,17 +79,18 @@ module Rain
|
|
|
74
79
|
output = ''.dup
|
|
75
80
|
|
|
76
81
|
(0...@screen_size[:row_count]).each do |row_index|
|
|
77
|
-
|
|
78
|
-
cell_colors = []
|
|
82
|
+
row_outputs = []
|
|
79
83
|
|
|
80
84
|
# Rendering streams can happen before redrawing streams, so @columns may not be populated yet.
|
|
81
85
|
(0...column_count).each do |column_index|
|
|
82
|
-
|
|
83
|
-
cell_outputs << (@columns[column_index].nil? ? nil : @columns[column_index].outputs[row_index])
|
|
86
|
+
row_outputs << (@columns[column_index].nil? ? nil : @columns[column_index].outputs[row_index])
|
|
84
87
|
end
|
|
85
88
|
|
|
86
|
-
output << "\n" +
|
|
87
|
-
|
|
89
|
+
output << "\n" + row_outputs.map.with_index do |output, col_index| # rubocop:disable Style/StringConcatenation
|
|
90
|
+
@effects.reduce(output) do |out, effect|
|
|
91
|
+
next_output = @columns[col_index].nil? ? nil : @columns[col_index].outputs[row_index + 1]
|
|
92
|
+
effect.render(output: out, next_output:, x: row_index, y: col_index)
|
|
93
|
+
end
|
|
88
94
|
end.join(' ')
|
|
89
95
|
end
|
|
90
96
|
|
data/lib/matrix/stream.rb
CHANGED
|
@@ -8,7 +8,7 @@ require_relative 'cursor'
|
|
|
8
8
|
module Rain
|
|
9
9
|
class Stream
|
|
10
10
|
include Observers
|
|
11
|
-
attr_reader :index, :inputs, :outputs, :delays, :
|
|
11
|
+
attr_reader :index, :inputs, :outputs, :delays, :head_cursor, :tail_cursor
|
|
12
12
|
|
|
13
13
|
ARROW = ['│', '▼'].freeze
|
|
14
14
|
|
|
@@ -19,13 +19,11 @@ module Rain
|
|
|
19
19
|
|
|
20
20
|
@inputs = []
|
|
21
21
|
@delays = []
|
|
22
|
-
@colors = []
|
|
23
22
|
@outputs = []
|
|
24
23
|
|
|
25
24
|
@event_cursor = 0
|
|
26
25
|
@head_cursor = Cursor.new
|
|
27
|
-
@tail_cursor = Cursor.new
|
|
28
|
-
@tail_cursor.index = 0
|
|
26
|
+
@tail_cursor = Cursor.new(index: 0)
|
|
29
27
|
|
|
30
28
|
@show_cursor = Cursor.new
|
|
31
29
|
@hide_cursor = Cursor.new
|
|
@@ -75,10 +73,7 @@ module Rain
|
|
|
75
73
|
# │ s │ 75 │ │ Then sets a "250" delay for the Hide Cursor.
|
|
76
74
|
# │ t │ 75 │ │
|
|
77
75
|
# └─────┴─────┴─────┘
|
|
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
|
|
76
|
+
def render(duration: nil)
|
|
82
77
|
@show_cursor.increment(delays:, inputs:, duration:) do |index|
|
|
83
78
|
prev_index = index.zero? ? @inputs.count - 1 : index - 1
|
|
84
79
|
next_index = index + 1 >= @inputs.count ? 0 : index + 1
|
|
@@ -86,8 +81,6 @@ module Rain
|
|
|
86
81
|
if @inputs[index]
|
|
87
82
|
@outputs[index] = @inputs[index]
|
|
88
83
|
@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
84
|
@inputs[index] = nil
|
|
92
85
|
end
|
|
93
86
|
end
|
|
@@ -130,7 +123,7 @@ module Rain
|
|
|
130
123
|
# │o│ 1. The minimum delay
|
|
131
124
|
# │u│ 2. The time elapsed between events divided by the number of cells
|
|
132
125
|
# │t│
|
|
133
|
-
# │e│ ◀── A cursor moves to the next cell after a delay
|
|
126
|
+
# │e│ ◀── A cursor moves to the next cell after a delay.
|
|
134
127
|
# └─┘
|
|
135
128
|
def redraw_event(current_event:, past_event:)
|
|
136
129
|
variable_delay = variable_delay(current_event:, past_event:)
|
|
@@ -171,7 +164,6 @@ module Rain
|
|
|
171
164
|
@inputs = @inputs.fill(nil, old_index...cell_count)[0...cell_count]
|
|
172
165
|
@outputs = @outputs.fill(nil, old_index...cell_count)[0...cell_count]
|
|
173
166
|
@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
167
|
end
|
|
176
168
|
|
|
177
169
|
def randomize_start_index
|
data/lib/pages/pages.rb
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'kramdown'
|
|
4
|
+
require 'kramdown-parser-gfm'
|
|
5
|
+
require 'rouge'
|
|
6
|
+
|
|
7
|
+
module Rain
|
|
8
|
+
class Pages
|
|
9
|
+
include LowType
|
|
10
|
+
|
|
11
|
+
attr_reader :url_paths
|
|
12
|
+
|
|
13
|
+
Result = Struct.new(:metadata, :html)
|
|
14
|
+
|
|
15
|
+
def initialize(metadata:)
|
|
16
|
+
@url_paths = metadata.url_paths
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def process(file_path:)
|
|
20
|
+
metadata, text = parse_file(file_path:)
|
|
21
|
+
html = Kramdown::Document.new(text, input: 'GFM', syntax_highlighter: 'rouge').to_html
|
|
22
|
+
|
|
23
|
+
Result.new(metadata, html)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def parse_file(file_path:)
|
|
29
|
+
dash_lines = []
|
|
30
|
+
data_lines = []
|
|
31
|
+
text_lines = []
|
|
32
|
+
|
|
33
|
+
File.foreach(file_path).with_index do |line, index|
|
|
34
|
+
if line.strip == '---' && dash_lines.count < 2
|
|
35
|
+
dash_lines << line
|
|
36
|
+
next
|
|
37
|
+
elsif dash_lines.count > 0 && dash_lines.count < 2
|
|
38
|
+
data_lines << line
|
|
39
|
+
next
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
text_lines << line
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
[YAML.safe_load(data_lines.join, symbolize_names: true), text_lines.join.strip]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'low_event'
|
|
4
|
+
require 'low_node'
|
|
5
|
+
require 'low_type'
|
|
6
|
+
require 'observers'
|
|
7
|
+
require 'providers'
|
|
8
|
+
|
|
9
|
+
require_relative '../pages/pages'
|
|
10
|
+
require_relative '../router/router'
|
|
11
|
+
require_relative '../support/config_loader'
|
|
12
|
+
|
|
13
|
+
#################################################
|
|
14
|
+
# INTERNAL API
|
|
15
|
+
#################################################
|
|
16
|
+
|
|
17
|
+
module Rain
|
|
18
|
+
env = {
|
|
19
|
+
host: ENV.fetch('RAIN_HOST', nil),
|
|
20
|
+
port: ENV.fetch('RAIN_PORT', nil),
|
|
21
|
+
web_root: ENV.fetch('RAIN_WEB_ROOT', nil),
|
|
22
|
+
debug_mode: ConfigLoader.parse_boolean(ENV.fetch('RAIN_DEBUG', true)),
|
|
23
|
+
matrix_mode: ConfigLoader.parse_boolean(ENV.fetch('RAIN_MATRIX', nil)),
|
|
24
|
+
mirror_mode: ConfigLoader.parse_boolean(ENV.fetch('RAIN_MIRROR', nil))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
config = ConfigLoader.load('config.yaml', env)
|
|
28
|
+
|
|
29
|
+
Providers.define('rain.router') do
|
|
30
|
+
require_relative '../router/router'
|
|
31
|
+
Router.new
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
Providers.define('rain.matrix') do
|
|
35
|
+
require_relative '../matrix/matrix'
|
|
36
|
+
Matrix.new(event_pool: Providers['low.event.pool'])
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
Providers.define('low.loop') do
|
|
40
|
+
require 'low_loop'
|
|
41
|
+
LowLoop.new(config:, router: Providers['rain.router'], renderer: Providers['rain.matrix'])
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
#################################################
|
|
46
|
+
# EXTERNAL API
|
|
47
|
+
#################################################
|
|
48
|
+
|
|
49
|
+
module Raindeer
|
|
50
|
+
class << self
|
|
51
|
+
def router(&block)
|
|
52
|
+
Providers['rain.router'].instance_eval(&block)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#################################################
|
|
58
|
+
# USER CODE
|
|
59
|
+
#################################################
|
|
60
|
+
|
|
61
|
+
require 'antlers' # LowLoad supports antlers but doesn't make it a hard dependency.
|
|
62
|
+
require 'lowload'
|
|
63
|
+
LowLoad.dirload(File.expand_path('../system', __dir__))
|
|
64
|
+
|
|
65
|
+
application_path = File.expand_path('app', Dir.pwd)
|
|
66
|
+
return unless Dir.exist?(application_path)
|
|
67
|
+
|
|
68
|
+
metadata = LowLoad.dirload(application_path)
|
|
69
|
+
return unless Dir.exist?(File.expand_path('pages', application_path))
|
|
70
|
+
|
|
71
|
+
Providers.define('rain.pages', eager: true) do
|
|
72
|
+
Rain::Pages.new(metadata:)
|
|
73
|
+
end
|
data/lib/router/router.rb
CHANGED
|
@@ -6,6 +6,7 @@ require 'providers'
|
|
|
6
6
|
require_relative 'route'
|
|
7
7
|
require_relative 'route_event'
|
|
8
8
|
require_relative 'trie'
|
|
9
|
+
require_relative 'wildcard_route_event'
|
|
9
10
|
|
|
10
11
|
module Rain
|
|
11
12
|
class Router
|
|
@@ -58,9 +59,14 @@ module Rain
|
|
|
58
59
|
@trie.match(path: event.request.path.delete_suffix('/')).each do |route_event|
|
|
59
60
|
response_event = route_event.trigger
|
|
60
61
|
end
|
|
61
|
-
|
|
62
62
|
return response_event if response_event
|
|
63
63
|
|
|
64
|
+
if @routes['/*']
|
|
65
|
+
route = Route.new(path: event.request.path, verbs: @routes['/*'].verbs)
|
|
66
|
+
wildcard_event = WildcardRouteEvent.trigger(key: '/*', action: :render, route:)
|
|
67
|
+
return wildcard_event if wildcard_event
|
|
68
|
+
end
|
|
69
|
+
|
|
64
70
|
Low::Events::StatusEvent.trigger(status: Low::Types::Status[404], request: event.request)
|
|
65
71
|
end
|
|
66
72
|
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'low_event'
|
|
4
|
+
|
|
5
|
+
module Rain
|
|
6
|
+
class WildcardRouteEvent < ::LowEvent
|
|
7
|
+
attr_reader :route, :params
|
|
8
|
+
|
|
9
|
+
def initialize(key:, route:, action: :render)
|
|
10
|
+
super(key:, action:)
|
|
11
|
+
|
|
12
|
+
@route = route
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -6,8 +6,9 @@ require 'yaml'
|
|
|
6
6
|
module Rain
|
|
7
7
|
class ConfigLoader
|
|
8
8
|
class << self
|
|
9
|
-
def load(
|
|
10
|
-
|
|
9
|
+
def load(file_path, overrides = {})
|
|
10
|
+
file_path = File.expand_path("../../../config/#{file_path}", __FILE__) unless File.exist?(file_path)
|
|
11
|
+
config_file = YAML.safe_load_file(file_path, permitted_classes: [Symbol], symbolize_names: true)
|
|
11
12
|
|
|
12
13
|
# Environment variables override config file.
|
|
13
14
|
config_data = config_file.merge(overrides) do |_key, old_value, new_value|
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
module System
|
|
4
|
+
class DashboardNode < LowNode
|
|
5
|
+
observe '/system'
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
def initialize(event:)
|
|
8
|
+
@node_count = LowNode.count
|
|
9
|
+
@event_count = LowEvent.count
|
|
10
|
+
end
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
def render(event:) # rubocop:disable Lint/UnusedMethodArgument
|
|
13
|
+
<{ LayoutNode: }>
|
|
14
|
+
<h1>{"Dashboard"}</h1>
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
<div class="grid">
|
|
17
|
+
<{ StatFormatter title='Nodes' stat=@node_count }>
|
|
18
|
+
<{ StatFormatter title='Events' stat=@event_count }>
|
|
19
|
+
</div>
|
|
20
|
+
<{ :LayoutNode }>
|
|
21
|
+
end
|
|
20
22
|
end
|
|
21
23
|
end
|
data/lib/system/events_node.rbx
CHANGED
|
@@ -1,35 +1,37 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
module System
|
|
4
|
+
class EventsNode < LowNode
|
|
5
|
+
observe '/system/events'
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
def initialize(event:)
|
|
8
|
+
# TODO: Include types that can be observed keys too like Status and Status[404].
|
|
9
|
+
@event_types = LowEvent.events
|
|
10
|
+
end
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
def render(event:)
|
|
13
|
+
<{ LayoutNode: }>
|
|
14
|
+
<h1>{"Events"}</h1>
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
<tr>
|
|
18
|
-
<th scope="col">Event</th>
|
|
19
|
-
<th scope="col">Observers</th>
|
|
20
|
-
</tr>
|
|
21
|
-
</thead>
|
|
22
|
-
<tbody>
|
|
23
|
-
<{ for: observer_key in: @event_types }>
|
|
16
|
+
<table>
|
|
17
|
+
<thead>
|
|
24
18
|
<tr>
|
|
25
|
-
<
|
|
26
|
-
<
|
|
27
|
-
<{ ObserversFormatter observer_key=observer_key }>
|
|
28
|
-
</td>
|
|
19
|
+
<th scope="col">Event</th>
|
|
20
|
+
<th scope="col">Observers</th>
|
|
29
21
|
</tr>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
</thead>
|
|
23
|
+
<tbody>
|
|
24
|
+
<{ for: observer_key in: @event_types }>
|
|
25
|
+
<tr>
|
|
26
|
+
<td>{observer_key}</td>
|
|
27
|
+
<td>
|
|
28
|
+
<{ ObserversFormatter observer_key=observer_key }>
|
|
29
|
+
</td>
|
|
30
|
+
</tr>
|
|
31
|
+
<{ :for }>
|
|
32
|
+
</tbody>
|
|
33
|
+
</table>
|
|
34
|
+
<{ :LayoutNode }>
|
|
35
|
+
end
|
|
34
36
|
end
|
|
35
37
|
end
|
|
@@ -1,41 +1,42 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
<
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
3
|
+
module System
|
|
4
|
+
class LayoutNode < LowNode
|
|
5
|
+
def render(event:)
|
|
6
|
+
<html>
|
|
7
|
+
<head>
|
|
8
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
|
|
9
|
+
<link rel="stylesheet" href="/system/system.css">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<header>
|
|
13
|
+
<div class="container">
|
|
14
|
+
<a id="favicon" href="/system"><img src="/system/favicon.svg"/></a>
|
|
15
|
+
<nav id="navbar">
|
|
16
|
+
<ul>
|
|
17
|
+
<li><a href="/system">{"Dashboard"}</a>
|
|
18
|
+
<li><a href="/system/events">{"Events"}</a>
|
|
19
|
+
<li><a href="/system/routes">{"Routes"}</a>
|
|
20
|
+
</ul>
|
|
21
|
+
</nav>
|
|
22
|
+
</div>
|
|
23
|
+
</header>
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
<main class="container">
|
|
26
|
+
<{ :slot }>
|
|
27
|
+
</main>
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
29
|
+
<footer>
|
|
30
|
+
<div class="container">
|
|
31
|
+
<ul>
|
|
32
|
+
<li><a href="https://raindeer.dev">{"Website"}</a></li>
|
|
33
|
+
<li><a href="https://raindeer.dev/docs">{"Docs"}</a></li>
|
|
34
|
+
<li><a href="https://github.com/raindeer-rb/raindeer">{"Source code"}</a></li>
|
|
35
|
+
</ul>
|
|
36
|
+
</div>
|
|
37
|
+
</footer>
|
|
38
|
+
</body>
|
|
39
|
+
</html>
|
|
40
|
+
end
|
|
40
41
|
end
|
|
41
42
|
end
|
data/lib/system/routes_node.rbx
CHANGED
|
@@ -1,34 +1,36 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
module System
|
|
4
|
+
class RoutesNode < LowNode
|
|
5
|
+
observe '/system/routes'
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
def initialize(event:)
|
|
8
|
+
@routes = Providers['rain.router'].routes
|
|
9
|
+
end
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
def render(event:)
|
|
12
|
+
<{ LayoutNode: }>
|
|
13
|
+
<h1>{"Routes"}</h1>
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
<tr>
|
|
17
|
-
<th scope="col">HTTP Verbs</th>
|
|
18
|
-
<th scope="col">Route</th>
|
|
19
|
-
<th scope="col">Observers</th>
|
|
20
|
-
</tr>
|
|
21
|
-
</thead>
|
|
22
|
-
<tbody>
|
|
23
|
-
<{ for: path, route in: @routes }>
|
|
15
|
+
<table>
|
|
16
|
+
<thead>
|
|
24
17
|
<tr>
|
|
25
|
-
<
|
|
26
|
-
<
|
|
27
|
-
<
|
|
18
|
+
<th scope="col">HTTP Verbs</th>
|
|
19
|
+
<th scope="col">Route</th>
|
|
20
|
+
<th scope="col">Observers</th>
|
|
28
21
|
</tr>
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
</thead>
|
|
23
|
+
<tbody>
|
|
24
|
+
<{ for: path, route in: @routes }>
|
|
25
|
+
<tr>
|
|
26
|
+
<td><{ LabelFormatter labels=route.verbs }></td>
|
|
27
|
+
<td>{route.path}</td>
|
|
28
|
+
<td><{ ObserversFormatter observer_key=route.path }></td>
|
|
29
|
+
</tr>
|
|
30
|
+
<{ :for }>
|
|
31
|
+
</tbody>
|
|
32
|
+
</table>
|
|
33
|
+
<{ :LayoutNode }>
|
|
34
|
+
end
|
|
33
35
|
end
|
|
34
36
|
end
|
data/lib/version.rb
CHANGED
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.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- maedi
|
|
@@ -37,6 +37,48 @@ dependencies:
|
|
|
37
37
|
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: '0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: kramdown
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: kramdown-parser-gfm
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: rouge
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0'
|
|
75
|
+
type: :runtime
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0'
|
|
40
82
|
- !ruby/object:Gem::Dependency
|
|
41
83
|
name: low_event
|
|
42
84
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -184,16 +226,20 @@ executables: []
|
|
|
184
226
|
extensions: []
|
|
185
227
|
extra_rdoc_files: []
|
|
186
228
|
files:
|
|
187
|
-
- lib/boot.rb
|
|
188
229
|
- lib/matrix/cursor.rb
|
|
230
|
+
- lib/matrix/effects/color_effect.rb
|
|
231
|
+
- lib/matrix/effects/effect.rb
|
|
232
|
+
- lib/matrix/effects/leet_effect.rb
|
|
189
233
|
- lib/matrix/matrix.rb
|
|
190
234
|
- lib/matrix/stream.rb
|
|
191
|
-
- lib/
|
|
235
|
+
- lib/pages/pages.rb
|
|
236
|
+
- lib/raindeer/boot.rb
|
|
192
237
|
- lib/router/route.rb
|
|
193
238
|
- lib/router/route_event.rb
|
|
194
239
|
- lib/router/router.rb
|
|
195
240
|
- lib/router/trie.rb
|
|
196
241
|
- lib/router/trie_node.rb
|
|
242
|
+
- lib/router/wildcard_route_event.rb
|
|
197
243
|
- lib/support/config_loader.rb
|
|
198
244
|
- lib/system/dashboard_node.rbx
|
|
199
245
|
- lib/system/events_node.rbx
|
|
@@ -204,7 +250,7 @@ files:
|
|
|
204
250
|
- lib/system/routes_node.rbx
|
|
205
251
|
- lib/system/status_404_node.rbx
|
|
206
252
|
- lib/system/status_node.rbx
|
|
207
|
-
- lib/system/
|
|
253
|
+
- lib/system/system_routes.rb
|
|
208
254
|
- lib/version.rb
|
|
209
255
|
homepage: https://codeberg.org/raindeer/raindeer
|
|
210
256
|
licenses: []
|
|
@@ -225,7 +271,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
225
271
|
- !ruby/object:Gem::Version
|
|
226
272
|
version: '0'
|
|
227
273
|
requirements: []
|
|
228
|
-
rubygems_version: 4.0.
|
|
274
|
+
rubygems_version: 4.0.6
|
|
229
275
|
specification_version: 4
|
|
230
276
|
summary: Deer to be different
|
|
231
277
|
test_files: []
|
data/lib/boot.rb
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'low_event'
|
|
4
|
-
require 'low_node'
|
|
5
|
-
require 'low_type'
|
|
6
|
-
require 'providers'
|
|
7
|
-
|
|
8
|
-
require_relative 'support/config_loader'
|
|
9
|
-
|
|
10
|
-
env = {
|
|
11
|
-
host: ENV.fetch('RAIN_HOST', nil),
|
|
12
|
-
port: ENV.fetch('RAIN_PORT', nil),
|
|
13
|
-
web_root: ENV.fetch('RAIN_WEB_ROOT', nil),
|
|
14
|
-
debug_mode: Rain::ConfigLoader.parse_boolean(ENV.fetch('RAIN_DEBUG', true)),
|
|
15
|
-
matrix_mode: Rain::ConfigLoader.parse_boolean(ENV.fetch('RAIN_MATRIX', nil)),
|
|
16
|
-
mirror_mode: Rain::ConfigLoader.parse_boolean(ENV.fetch('RAIN_MIRROR', nil))
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
config = Rain::ConfigLoader.load('./config/config.yaml', env)
|
|
20
|
-
|
|
21
|
-
Providers.define('rain.router') do
|
|
22
|
-
require_relative 'router/router'
|
|
23
|
-
Rain::Router.new
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
Providers.define('rain.matrix') do
|
|
27
|
-
require_relative 'matrix/matrix'
|
|
28
|
-
Rain::Matrix.new(event_pool: Providers['low.event.pool'])
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
Providers.define('low.loop') do
|
|
32
|
-
require 'low_loop'
|
|
33
|
-
LowLoop.new(config:, router: Providers['rain.router'], renderer: Providers['rain.matrix'])
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
require 'lowload'
|
|
37
|
-
LowLoad.dirload(File.expand_path('system', __dir__))
|
data/lib/raindeer.rb
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'low_event'
|
|
4
|
-
require 'low_node'
|
|
5
|
-
require 'low_type'
|
|
6
|
-
require 'observers'
|
|
7
|
-
require 'providers'
|
|
8
|
-
|
|
9
|
-
require_relative 'router/router'
|
|
10
|
-
|
|
11
|
-
module Raindeer
|
|
12
|
-
class << self
|
|
13
|
-
def router(&block)
|
|
14
|
-
Providers['rain.router'].instance_eval(&block)
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|