lux-fw 0.5.32 → 0.5.33

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.version +1 -1
  3. data/lib/README.md +30 -0
  4. data/lib/lux/README.md +10 -0
  5. data/lib/lux/application/README.md +147 -0
  6. data/lib/lux/cache/README.md +47 -0
  7. data/lib/lux/config/README.md +63 -0
  8. data/lib/lux/controller/README.md +49 -0
  9. data/lib/lux/current/README.md +14 -0
  10. data/lib/lux/delayed_job/README.md +3 -0
  11. data/lib/lux/error/README.md +41 -0
  12. data/lib/lux/event_bus/README.md +36 -0
  13. data/lib/lux/mailer/README.md +73 -0
  14. data/lib/lux/response/README.md +1 -0
  15. data/lib/lux/view/README.md +85 -0
  16. data/misc/demo/Gemfile +4 -0
  17. data/misc/demo/Rakefile +3 -0
  18. data/misc/demo/app/assets/css/main/index.scss +1 -0
  19. data/misc/demo/app/cells/cell.scss +5 -0
  20. data/misc/demo/app/cells/demo.haml +1 -0
  21. data/misc/demo/app/views/layouts/main.haml +10 -0
  22. data/misc/demo/app/views/main/root/index.haml +9 -0
  23. data/misc/demo/config.ru +5 -0
  24. data/misc/demo/public/manifest.json +5 -0
  25. data/misc/demo/tmp/assets/d-app-assets-css-main-index.scss +1 -0
  26. data/misc/demo/tmp/assets/d-app-cells-cell.scss +5 -0
  27. data/misc/demo/yarn.lock +2656 -0
  28. data/misc/lux.png +0 -0
  29. data/misc/nginx.conf +60 -0
  30. data/misc/siege-and-puma.txt +3 -0
  31. data/plugins/api/README.md +49 -0
  32. data/plugins/db/README.md +29 -0
  33. data/plugins/db/auto_migrate/db.rake +15 -0
  34. data/plugins/exceptions/exceptions.rake +43 -0
  35. data/plugins/html/README.md +3 -0
  36. data/plugins/js_widgets/README.md +5 -0
  37. data/plugins/js_widgets/js/html_tag.coffee +42 -0
  38. data/plugins/js_widgets/js/widgets.coffee +161 -0
  39. data/tasks/nginx.rake +23 -0
  40. metadata +38 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 809c29122351db4ad4bd4de489f14f54c263b8911cc6d41b91d411beeaffe959
4
- data.tar.gz: f4912bd49fbe63229dbccab2582c13cdf308299e4194a001c150e5e54765e7ae
3
+ metadata.gz: 3d0b06d65d3e76de965f29a418513ce4f7cae994353e31d072cbeb5224057996
4
+ data.tar.gz: 42158b78a77c6bcbdd001804c57752f6e2d35fd809d6bdfe324193019d8aef8f
5
5
  SHA512:
6
- metadata.gz: d919b51494836f5e12af3fe372689ed721607205d92bc2668dc075f795b65cb867bd0b642b228bf98cdca30e071acaf4fbaf10c68dc5057a2ddfc43ef88ea660
7
- data.tar.gz: 2e514b0713c9d3dd9ad2e7c4ff91386a30fc839335a60ffa7c10d504eea8a2b1b8f76785c2568d2bd0ecc8f697d6ba5c6d674bf59fe45c502cf3b510b90490c4
6
+ metadata.gz: bb2144cef763d0bc2ee5532bd2be220f1deb232c9d9aaf21dfe4ededf13114f0007bb63f96deee4f7f2600e1d6e4740197929aa125988a7dd2fa526f499ea2a5
7
+ data.tar.gz: 40567507bed00de677822736bfa49efef2414ebe1c4751720eda24c27c694a990307fc4cabb834dd1249b6a0b43ea9b01ffbdd08106ff04b03c6d0dbee2fae46
data/.version CHANGED
@@ -1 +1 @@
1
- 0.5.32
1
+ 0.5.33
@@ -0,0 +1,30 @@
1
+ # LUX - ruby web framework
2
+
3
+ ![Lux logo](https://i.imgur.com/Zy7DLXU.png)
4
+
5
+ * rack based
6
+ * explicit, avoid magic when possible
7
+
8
+ created by @dux in 2017
9
+
10
+ ## How to start
11
+
12
+ First, make sure you have `ruby 2.x+`, `npm 6.x+` and `yarn 1.x+` installed.
13
+
14
+ Install Lux framework.
15
+
16
+ `gem install lux-fw`
17
+
18
+ Create new template for lux app
19
+
20
+ `lux new my-app`
21
+
22
+ Start the app
23
+
24
+ `lux s`
25
+
26
+ Look at the generated code and play with it.
27
+
28
+ ## Lux components
29
+
30
+
@@ -0,0 +1,10 @@
1
+ # Page render flow
2
+
3
+ ## Example config ru
4
+ ```
5
+ $lux_start_time = Time.now
6
+ require './config/application'
7
+ Lux.serve self
8
+ ```
9
+
10
+ * if you define `$lux_start_time` you will get speed load statistics
@@ -0,0 +1,147 @@
1
+ ## Lux::Application - main application controller and router
2
+
3
+ * can capture errors with `on_error` instance method
4
+ * calls `before`, `routes` and `after` class filters on every request
5
+ * routes requests to controllers via `map`, `root` and `call` methods
6
+
7
+ ### Instance methods
8
+
9
+ #### root
10
+
11
+ executes if nav.root is empty
12
+
13
+ #### map
14
+
15
+ map specific nav root to Controller and calls if root mathes
16
+
17
+ for example if path is /blogs
18
+
19
+ `map blogs: Main::BlogController`
20
+
21
+ will call instance method call with @path expanded
22
+
23
+ `Main::BlogController.new.call(*@path)`
24
+
25
+ more examples
26
+
27
+ * `map blog: BlogController` will call `BlogController.action(:blog)`
28
+ * `map blog: 'blog#single'` will call `BlogController.action(:single)`
29
+ * `map blog: -> { BlogController.custom(:whatever) }`
30
+
31
+ ### call
32
+
33
+ Calls specific controller action inside call.
34
+
35
+ ```ruby
36
+ call 'main/links#index'
37
+ call [Main::LinksController, :index]
38
+ call -> { [200, {}, ['OK']]}
39
+ ```
40
+
41
+ ### Router example
42
+
43
+ For Lux routing you need to know only few things
44
+
45
+ * taget can be 5 object variants, look at root example
46
+ * "root" method calls object if nav.root is blank?
47
+ * "map" method calls object if nav.first == match
48
+ * "namespace" method accepts block that wraps map calls.
49
+
50
+ ```ruby
51
+ Lux.app do
52
+
53
+ def api_router
54
+ error :forbiden, 'Only POST requests are allowed' if Lux.prod? && !post?
55
+ Lux::Api.call nav.path
56
+ end
57
+
58
+ before do
59
+ check_subdomain
60
+ end
61
+
62
+ after do
63
+ error 404
64
+ end
65
+
66
+ ###
67
+
68
+ routes do
69
+ # we show on root method, that target can be multiple object types, 5 variants
70
+ root [RootController, :index] # calls RootController#index
71
+ root 'root#call' # calls RootController#call
72
+ root :call_root # calls "call_root" method in current scope
73
+ root 'root' # calls RootController#index
74
+ root 'root#foo' # calls RootController#foo
75
+
76
+ # we can route based on the user status
77
+ root User.current ? 'main/root' : 'guest'
78
+
79
+ # map "/api" to "api_router" method
80
+ map api: :api_router
81
+
82
+ # with MainController
83
+ # map MainController do
84
+ map 'main' do
85
+ map :search # map "/search" to MainController#search
86
+ map '/login' # map "/login" to MainController#login
87
+ end
88
+
89
+ # map "/foo/dux/baz" route to MainController#foo with params[:bar] == 'dux'
90
+ map '/foo/:bar/baz' => 'main#foo'
91
+
92
+ # if method "city" in current scope returns true
93
+ namespace :city do
94
+ # call MainController#city if request.method == 'GET'
95
+ map 'main#city' if get?
96
+ end
97
+
98
+ # if we match '/foo' route
99
+ namespace 'foo' do
100
+ # call MainController#foo with params[:bar] == '...'
101
+ map '/baz/:bar' => 'main#foo'
102
+ end
103
+ end
104
+ end
105
+ ```
106
+
107
+ ### Router rescues example
108
+
109
+ ```ruby
110
+ Lux.app do
111
+ def on_error error
112
+
113
+ message = case error
114
+ when PG::ConnectionBad
115
+ msg = error.message || 'DB connection error, please refresh page.'
116
+ msg = "PG: #{msg}"
117
+ Lux.logger(:db_error).error msg
118
+ msg
119
+
120
+ when Lux::Error
121
+ # for handled errors
122
+ # show HTTP errors in a browser without a log
123
+ Main::RootController.action(:error, error)
124
+
125
+ else
126
+ # raise errors in developmet
127
+ raise error if Lux.dev?
128
+
129
+ key = Lux.error.log error
130
+ "#{error.class}: #{error.message} \n\nkey: #{key}"
131
+ end
132
+
133
+ # use default error formater
134
+ Lux.error message
135
+ end
136
+ end
137
+
138
+ if Lux.prod?
139
+ Lux.config.error_logger = proc do |error|
140
+ # log and show error page in a production
141
+ key = SimpleException.log error
142
+ Lux.cache.fetch('error-mail-%s' % key) { Mailer.error(error, key).deliver }
143
+ Lux.logger(:exceptions).error [key, User.current.try(:email).or('guest'), error.message].join(' - ')
144
+ key
145
+ end
146
+ end
147
+ ```
@@ -0,0 +1,47 @@
1
+ ## Lux::Cache - Mimics Rails.cache interface
2
+
3
+ Alias - `Lux.cache`
4
+
5
+ ### Define
6
+
7
+ use RAM cache in development, as default
8
+
9
+ ```
10
+ Lux::Cache.server = :memcached
11
+ ```
12
+
13
+ You can use memcached or redis in production
14
+
15
+ ```
16
+ Lux::Cache.server = Dalli::Client.new('localhost:11211', { :namespace=>Digest::MD5.hexdigest(__FILE__)[0,4], :compress => true, :expires_in => 1.hour })
17
+ ```
18
+
19
+ ### Lux::Cache instance methods
20
+
21
+ Mimics Rails cache methods
22
+
23
+ ```
24
+ Lux.cache.read(key)
25
+ Lux.cache.get(key)
26
+
27
+ Lux.cache.read_multi(*args)
28
+ Lux.cache.get_multi(*args)
29
+
30
+ Lux.cache.write(key, data, ttl=nil)
31
+ Lux.cache.set(key, data, ttl=nil)
32
+
33
+ Lux.cache.delete(key, data=nil)
34
+
35
+ Lux.cache.fetch(key, ttl=nil, &block)
36
+
37
+ Lux.cache.is_available?
38
+ ```
39
+
40
+ Has method to generate cache key
41
+
42
+ ```
43
+ # generates unique cache key based on set of data
44
+ # Lux.cache.generate_key([User, Product.find(3), 'data', @product.updated_at])
45
+
46
+ Lux.cache.generate_key(*data)
47
+ ```
@@ -0,0 +1,63 @@
1
+ # Lux::Config - Config loader helpers
2
+
3
+ Methods for config and pluin loading.
4
+
5
+ ## Lux::Config::Plugins
6
+
7
+ * loads plugins in selected namespace, default namespace :main
8
+ * gets plugins in selected namespace
9
+
10
+ ```ruby
11
+ Lux.plugin name_or_folder
12
+ Lux.plugin name: :foo, folder: '/.../...', namespace: [:main, :admin]
13
+ Lux.plugin name: :bar
14
+
15
+ Luxp.lugin.folders :admin # => [:foo]
16
+ Luxp.lugin.folders # => [:foo, :bar]
17
+ ```
18
+
19
+ ## Lux::Config::Secrets
20
+
21
+ Similar to rails 5.1+, we can encode secrets for easy config.
22
+
23
+ * using JWT HS512
24
+ * create and write sectes in YAML format in `./tmp/secrets.yaml`
25
+ * run `lux secrets` to compile secretes to `./config/secrets.txt`
26
+ * use "shared" hash for shared secrets
27
+ * sectets are available in app via `Lux.secrets`, as struct object
28
+
29
+ ### lux secrets
30
+
31
+ * compiles unencoded sectes from `./tmp/secrets.yaml` to `./config/secrets.txt`
32
+ * creates editable file `./tmp/secrets.yaml` from `./config/secrets.txt` if one exists
33
+ * shows available secrets for current environment
34
+
35
+ ### Example
36
+
37
+ Env development
38
+
39
+ Secrets file `./tmp/secrets.yaml`
40
+
41
+ ```
42
+ shared:
43
+ x: s
44
+ b:
45
+ c: nested
46
+
47
+ production:
48
+ a: p
49
+
50
+ development:
51
+ a: d
52
+ ```
53
+
54
+ `lux secrets` - will compile secrets or create template if needed
55
+
56
+ `lux c` - console
57
+
58
+ ```ruby
59
+ Lux.secrets.a == "d"
60
+ Lux.secrets.x == "s"
61
+ Lux.secrets.b.c == "nested"
62
+ ```
63
+
@@ -0,0 +1,49 @@
1
+ ## Lux::Controller - Simplified Rails like view controllers
2
+
3
+ Controllers are Lux view models
4
+
5
+ * all cells shoud inherit from Lux::Controller
6
+ * `before`, `before_action` and `after` class methods supportd
7
+ * instance_method `on_error` is supported
8
+ * calls templates as default action, behaves as Rails controller.
9
+
10
+ ### Example code
11
+
12
+ ```ruby
13
+ require 'lux-fw'
14
+
15
+ class Main::RootController < Lux::Controller
16
+ # action to perform before
17
+ before do
18
+ @org = Org.find @org_id if @org_id
19
+ # ...
20
+ end
21
+ # action to perform before
22
+
23
+ before_action do |action_name|
24
+ next if action_name == :index
25
+ # ...
26
+ end
27
+
28
+ ###
29
+
30
+ mock :show # mock `show` action
31
+
32
+ def index
33
+ render text: 'Hello world'
34
+ end
35
+
36
+ def foo
37
+ # renders ./app/views/main/root/foo.(haml, erb)
38
+ end
39
+
40
+ def baz
41
+ send_file local_file, file_name: 'local.txt'
42
+ end
43
+
44
+ def bar
45
+ render json: { data: 'Bar text' }
46
+ end
47
+
48
+ end
49
+ ```
@@ -0,0 +1,14 @@
1
+ ## Lux::Current - Main state object
2
+
3
+ Current application state as single object. Defined in Thread.current, available everywhere.
4
+
5
+ `Lux.current` - current response state
6
+
7
+ * `session` - session, encoded in cookie
8
+ * `locale` - locale, default nil
9
+ * `request` - Rack request
10
+ * `response` - Lux response object
11
+ * `nav` - lux nav object
12
+ * `cookies` - Rack cookies
13
+ * `can_clear_cache` - set to true if user can force refresh cache
14
+
@@ -0,0 +1,3 @@
1
+ ## Delayed job
2
+
3
+ to do
@@ -0,0 +1,41 @@
1
+ ## Lux::Errors - In case of error
2
+
3
+ ### module Lux::Error
4
+
5
+ ```ruby
6
+ # try to execute part of the code, log exeception if fails
7
+ def try(name, &block)
8
+
9
+ # HTML render style for default Lux error
10
+ def render(desc)
11
+
12
+ # show error page
13
+ def show(desc)
14
+
15
+ # show inline error
16
+ def inline(name=nil, o=nil)
17
+
18
+ # log exeption
19
+ def log(exp_object)
20
+ ```
21
+
22
+
23
+ ### defines standard Lux errors and erro generating helpers
24
+
25
+ ```ruby
26
+ # 400: for bad parameter request or similar
27
+ Lux::Error.forbidden foo
28
+
29
+ # 401: for unauthorized access
30
+ Lux::Error.forbidden foo
31
+
32
+ # 403: for unalloed access
33
+ Lux::Error.forbidden foo
34
+
35
+ # 404: for not found pages
36
+ Lux::Error.not_found foo
37
+
38
+ # 503: for too many requests at the same time
39
+ Lux::Error.forbidden foo
40
+
41
+ ```
@@ -0,0 +1,36 @@
1
+ # Super simple event pub/sub
2
+
3
+ ## to add events
4
+
5
+ ```ruby
6
+ Lux::EventBus.on('test') { |arg| puts 'foo: %s' % arg }
7
+ Lux.event.on('test', :foo) { |arg| puts 'bar: %s' % arg }
8
+ Lux.event.on('test', :foo) { |arg| puts 'baz: %s' % arg }
9
+ Lux.event.on('test') { |arg| raise 'abc' }
10
+
11
+ ###
12
+ # foo: xxx
13
+ # baz: xxx
14
+ # error logged
15
+ ```
16
+
17
+
18
+ ## to call
19
+
20
+ ```ruby
21
+ Lux.event.call 'test', 'xxx'
22
+ ```
23
+
24
+
25
+ ## Error handler
26
+
27
+ Default event bus error handle.
28
+
29
+ ```ruby
30
+ Lux.config.on_event_bus_error = proc do |error, name|
31
+ Lux.logger(:event_bus).error '[%s] %s' % [name, error.message]
32
+ end
33
+ ```
34
+
35
+
36
+