volt 0.9.3.pre1 → 0.9.3.pre2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/CHANGELOG.md +15 -1
- data/Gemfile +30 -3
- data/README.md +7 -2
- data/Rakefile +17 -0
- data/app/volt/models/user.rb +1 -1
- data/app/volt/tasks/live_query/live_query.rb +0 -1
- data/app/volt/tasks/live_query/live_query_pool.rb +8 -2
- data/app/volt/tasks/live_query/query_tracker.rb +2 -2
- data/app/volt/tasks/query_tasks.rb +10 -27
- data/app/volt/tasks/store_tasks.rb +6 -5
- data/app/volt/tasks/user_tasks.rb +2 -2
- data/docs/UPGRADE_GUIDE.md +14 -0
- data/lib/volt/boot.rb +1 -0
- data/lib/volt/cli/asset_compile.rb +25 -7
- data/lib/volt/cli/console.rb +6 -5
- data/lib/volt/cli/generate.rb +2 -2
- data/lib/volt/config.rb +2 -1
- data/lib/volt/controllers/http_controller.rb +4 -3
- data/lib/volt/controllers/model_controller.rb +41 -19
- data/lib/volt/controllers/template_helpers.rb +19 -0
- data/lib/volt/extra_core/array.rb +6 -0
- data/lib/volt/extra_core/hash.rb +8 -26
- data/lib/volt/extra_core/string.rb +1 -1
- data/lib/volt/models/array_model.rb +12 -4
- data/lib/volt/models/associations.rb +11 -13
- data/lib/volt/models/buffer.rb +1 -1
- data/lib/volt/models/model.rb +22 -13
- data/lib/volt/models/model_helpers/model_change_helpers.rb +0 -1
- data/lib/volt/models/model_helpers/model_helpers.rb +11 -0
- data/lib/volt/models/permissions.rb +9 -12
- data/lib/volt/models/persistors/array_store.rb +7 -7
- data/lib/volt/models/persistors/base.rb +9 -0
- data/lib/volt/models/persistors/cookies.rb +0 -4
- data/lib/volt/models/persistors/flash.rb +0 -4
- data/lib/volt/models/persistors/local_store.rb +0 -4
- data/lib/volt/models/persistors/model_store.rb +13 -21
- data/lib/volt/models/persistors/page.rb +22 -0
- data/lib/volt/models/persistors/params.rb +0 -4
- data/lib/volt/models/persistors/query/query_listener.rb +3 -2
- data/lib/volt/models/url.rb +2 -2
- data/lib/volt/models/validators/unique_validator.rb +1 -1
- data/lib/volt/models.rb +1 -0
- data/lib/volt/page/bindings/attribute_binding.rb +2 -2
- data/lib/volt/page/bindings/base_binding.rb +7 -3
- data/lib/volt/page/bindings/bindings.rb +9 -0
- data/lib/volt/page/bindings/content_binding.rb +2 -2
- data/lib/volt/page/bindings/each_binding.rb +16 -12
- data/lib/volt/page/bindings/event_binding.rb +4 -4
- data/lib/volt/page/bindings/if_binding.rb +3 -3
- data/lib/volt/page/bindings/view_binding.rb +4 -4
- data/lib/volt/page/bindings/yield_binding.rb +3 -3
- data/lib/volt/page/channel.rb +6 -0
- data/lib/volt/page/channel_stub.rb +1 -1
- data/lib/volt/page/page.rb +20 -54
- data/lib/volt/page/path_string_renderer.rb +5 -6
- data/lib/volt/page/string_template_renderer.rb +2 -2
- data/lib/volt/page/targets/attribute_section.rb +47 -0
- data/lib/volt/page/targets/base_section.rb +5 -5
- data/lib/volt/page/targets/binding_document/component_node.rb +6 -1
- data/lib/volt/page/template_renderer.rb +4 -4
- data/lib/volt/reactive/computation.rb +32 -3
- data/lib/volt/router/routes.rb +5 -5
- data/lib/volt/server/component_templates.rb +30 -2
- data/lib/volt/server/forking_server.rb +2 -2
- data/lib/volt/server/message_bus/base_message_bus.rb +52 -0
- data/lib/volt/server/message_bus/message_encoder.rb +64 -0
- data/lib/volt/server/message_bus/peer_to_peer/peer_connection.rb +186 -0
- data/lib/volt/server/message_bus/peer_to_peer/peer_server.rb +78 -0
- data/lib/volt/server/message_bus/peer_to_peer/server_tracker.rb +57 -0
- data/lib/volt/server/message_bus/peer_to_peer/socket_with_timeout.rb +27 -0
- data/lib/volt/server/message_bus/peer_to_peer.rb +198 -0
- data/lib/volt/server/message_bus/redis.rb +1 -0
- data/lib/volt/server/rack/asset_files.rb +2 -2
- data/lib/volt/server/rack/component_paths.rb +1 -1
- data/lib/volt/server/rack/http_resource.rb +3 -2
- data/lib/volt/server/rack/opal_files.rb +6 -9
- data/lib/volt/server/websocket/websocket_handler.rb +0 -3
- data/lib/volt/server.rb +5 -3
- data/lib/volt/spec/setup.rb +11 -12
- data/lib/volt/tasks/dispatcher.rb +8 -12
- data/lib/volt/tasks/task_handler.rb +3 -2
- data/lib/volt/utils/csso_patch.rb +24 -0
- data/lib/volt/utils/promise_patch.rb +2 -0
- data/lib/volt/version.rb +1 -1
- data/lib/volt/volt/app.rb +73 -36
- data/lib/volt/volt/server_setup/app.rb +81 -0
- data/lib/volt.rb +22 -1
- data/spec/apps/kitchen_sink/Gemfile +1 -1
- data/spec/controllers/http_controller_spec.rb +5 -3
- data/spec/controllers/model_controller_spec.rb +2 -2
- data/spec/extra_core/hash_spec.rb +9 -0
- data/spec/integration/list_spec.rb +3 -3
- data/spec/models/associations_spec.rb +10 -2
- data/spec/models/dirty_spec.rb +7 -7
- data/spec/models/model_spec.rb +10 -2
- data/spec/models/permissions_spec.rb +9 -0
- data/spec/models/persistors/store_spec.rb +8 -0
- data/spec/page/bindings/content_binding_spec.rb +6 -2
- data/spec/page/bindings/each_binding_spec.rb +59 -0
- data/spec/page/bindings/if_binding_spec.rb +57 -0
- data/spec/page/path_string_renderer_spec.rb +5 -5
- data/spec/reactive/computation_spec.rb +65 -1
- data/spec/router/routes_spec.rb +1 -1
- data/spec/server/html_parser/sandlebars_parser_spec.rb +12 -22
- data/spec/server/message_bus/message_encoder_spec.rb +49 -0
- data/spec/server/message_bus/peer_to_peer/peer_connection_spec.rb +108 -0
- data/spec/server/message_bus/peer_to_peer/peer_server_spec.rb +66 -0
- data/spec/server/message_bus/peer_to_peer/socket_with_timeout_spec.rb +11 -0
- data/spec/server/message_bus/peer_to_peer_spec.rb +11 -0
- data/spec/server/rack/asset_files_spec.rb +1 -1
- data/spec/server/rack/http_resource_spec.rb +4 -4
- data/spec/spec_helper.rb +16 -3
- data/spec/tasks/dispatcher_spec.rb +17 -5
- data/spec/tasks/live_query_spec.rb +1 -1
- data/spec/tasks/query_tracker_spec.rb +34 -34
- data/spec/tasks/user_tasks_spec.rb +4 -2
- data/templates/project/Gemfile.tt +14 -3
- data/templates/project/config/app.rb.tt +27 -2
- data/volt.gemspec +3 -8
- metadata +32 -101
- data/docs/FAQ.md +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 424f310e39b6096bf3372ff3dd5b90e6936718ef
|
4
|
+
data.tar.gz: fa76365d2cc587f7985e39008f13825f02c6515d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c6371586b5afc5278951bf89478153b6e854edb444503ca8ea312071f74d350c2807aa67eede9f8d64a97bc8c8208649dafd46ae723f58c1cb4308566b3a0ce5
|
7
|
+
data.tar.gz: 86c5ef5a2b1da23d537103884ee7cdd840be23dae4a59ae22e0c2be0b3ac56652541fcbd5dd808b79c474cda6846e4847ef2839c9a91c5009da931952937c563
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.2.0
|
1
|
+
2.2.0
|
data/CHANGELOG.md
CHANGED
@@ -1,17 +1,31 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## 0.9.3.
|
3
|
+
## 0.9.3.pre2
|
4
4
|
### Added
|
5
5
|
- Added validations block for conditional validation runs
|
6
|
+
- you can now set the NO_FORKING=true ENV to prevent using the forking server in development.
|
7
|
+
- models without an assigned persistor now use the page persistor (which now can provide basic querying)
|
8
|
+
- Volt now pushes updates between mulitple app instances. Updates are pushed between any servers, clients, runners, etc.. that are connected to the same database via the MessageBus (see next)
|
9
|
+
- Volt now comes with a "MessageBus" built in. The message bus provides a pub/sub interface for the app "cluster". Volt provides a default message bus implementation using peer to peer sockets that are automatically managed via the database.
|
6
10
|
|
7
11
|
### Changed
|
8
12
|
- All logic associated with mongo has been moved into the volt-mongo gem. If you are migrating from a previous version, be sure to add ```gem 'volt-mongo'``` to the Gemfile.
|
13
|
+
- models using the page or store persistor now auto-generate an id when created. This simplifies things since models always have an id. It makes association easier as well. (internally that is)
|
14
|
+
- models now use ```.id``` instead of ```._id``` Queries and saves are mapped to _id in the volt-mongo gem
|
15
|
+
- fixed issue where ```volt precompile``` would compile in extra assets from non-component gems.
|
16
|
+
- Lots of internal changes:
|
17
|
+
- bindings were refactored to pass around a Volt::App instead of a Volt::Page.
|
18
|
+
- controllers now take a Volt::App when created directly.
|
19
|
+
- You can now use .each in attribute bindings.
|
20
|
+
- We moved to csso as the css compressor because it does not require libv8, only an execjs runtime.
|
9
21
|
|
10
22
|
## 0.9.2
|
11
23
|
### Changed
|
12
24
|
- We released 0.9.1 with a bug for destroy (doh!). Specs added and bug fixed.
|
13
25
|
|
14
26
|
## 0.9.1
|
27
|
+
[0.9.1 Update Blog Post](http://blog.voltframework.com/post/118260814159/0-9-1-already-thats-how-we-roll)
|
28
|
+
|
15
29
|
### Added
|
16
30
|
- Mailer! - volt now includes the volt-mailer gem out of the box. (you can remove it if you don't need/want it). See https://github.com/voltrb/volt-mailer for more info.
|
17
31
|
|
data/Gemfile
CHANGED
@@ -5,6 +5,12 @@ gemspec
|
|
5
5
|
# volt-mongo gem for testing
|
6
6
|
gem 'volt-mongo'
|
7
7
|
|
8
|
+
# Use rbnacl for message bus encrpytion
|
9
|
+
# (optional, if you don't need encryption, disable in app.rb and remove)
|
10
|
+
gem 'rbnacl', require: false
|
11
|
+
gem 'rbnacl-libsodium', require: false
|
12
|
+
|
13
|
+
|
8
14
|
group :development do
|
9
15
|
# For testing the kitchen sink app
|
10
16
|
# Twitter bootstrap
|
@@ -24,13 +30,34 @@ group :development do
|
|
24
30
|
end
|
25
31
|
|
26
32
|
group :development, :test do
|
27
|
-
|
33
|
+
platform :mri do
|
34
|
+
gem 'bson_ext'
|
28
35
|
|
29
|
-
|
30
|
-
|
36
|
+
# For running tests
|
37
|
+
gem 'thin'
|
38
|
+
end
|
39
|
+
|
40
|
+
platform :jruby do
|
41
|
+
# For running tests
|
42
|
+
gem 'puma'
|
43
|
+
end
|
31
44
|
end
|
32
45
|
|
33
46
|
platform :mri do
|
34
47
|
# The implementation of ReadWriteLock in Volt uses concurrent ruby and ext helps performance.
|
35
48
|
gem 'concurrent-ruby-ext'
|
49
|
+
|
50
|
+
# For debugging
|
51
|
+
gem 'pry-byebug', '~> 2.0.0', require: false
|
52
|
+
|
53
|
+
# For Yard Formatting, in MRI block because redcarpet doesn't install on jruby
|
54
|
+
gem 'redcarpet', '~> 3.2.2', require: false
|
55
|
+
gem 'github-markup', '~> 1.3.1', require: false
|
56
|
+
|
57
|
+
# Sauce has a dependency that doesn't run on ruby <= 2.0.0
|
58
|
+
# (which older jruby versions don't support)
|
59
|
+
# TODO: Move out of MRI block once jruby 9k is outs
|
60
|
+
gem 'sauce', '~> 3.5.3', require: false
|
61
|
+
gem 'sauce-connect', '~> 3.5.0', require: false
|
62
|
+
|
36
63
|
end
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[![
|
1
|
+
[![Pledgie](https://pledgie.com/campaigns/26731.png?skin_name=chrome)](https://pledgie.com/campaigns/26731)
|
2
2
|
[![Gem Version](https://badge.fury.io/rb/volt.svg)](http://badge.fury.io/rb/volt)
|
3
3
|
[![Code Climate](https://codeclimate.com/github/voltrb/volt/badges/gpa.svg)](https://codeclimate.com/github/voltrb/volt)
|
4
4
|
[![Coverage Status](https://coveralls.io/repos/voltrb/volt/badge.svg?branch=master)](https://coveralls.io/r/voltrb/volt?branch=master)[![Build Status](http://img.shields.io/travis/voltrb/volt/master.svg?style=flat)](https://travis-ci.org/voltrb/volt)
|
@@ -36,5 +36,10 @@ There is also a [work in progress tutorial](https://github.com/rhgraysonii/volt_
|
|
36
36
|
|
37
37
|
You want to contribute? Great! Thanks for being awesome! At the moment, we have a big internal todo list, hop on https://gitter.im/voltrb/volt so we don't duplicate work. Pull requests are always welcome, but asking about helping on Gitter should save some duplication.
|
38
38
|
|
39
|
+
# Support
|
39
40
|
|
40
|
-
|
41
|
+
VoltFramework is currently a labor of love mainly built by a small group of core developers. Donations are always welcome and will help Volt get to production faster :-) Also, if you or your company is interested in sponsoring Volt, please talk to @ryanstout in the [gitter](https://gitter.im/voltrb/volt)
|
42
|
+
|
43
|
+
[![Pledgie](https://pledgie.com/campaigns/26731.png?skin_name=chrome)](https://pledgie.com/campaigns/26731)
|
44
|
+
|
45
|
+
Bitcoins can also be sent to 1AYiL3MiSVe2QFyexzozUvFFH7uGCJgJMZ
|
data/Rakefile
CHANGED
@@ -31,6 +31,23 @@ task :test do
|
|
31
31
|
Rake::Task['ruby:rspec'].invoke
|
32
32
|
end
|
33
33
|
|
34
|
+
task :opal_specs_in_browser do
|
35
|
+
require 'volt/server/websocket/rack_server_adaptor'
|
36
|
+
require 'rack/cascade'
|
37
|
+
|
38
|
+
server = Rack::Handler.get(RUNNING_SERVER)
|
39
|
+
|
40
|
+
Opal::Processor.source_map_enabled = false
|
41
|
+
app = Opal::Server.new { |s|
|
42
|
+
s.main = 'opal/rspec/sprockets_runner'
|
43
|
+
s.append_path 'spec'
|
44
|
+
s.append_path 'app'
|
45
|
+
s.debug = false
|
46
|
+
}
|
47
|
+
|
48
|
+
server.run(app, {})
|
49
|
+
end
|
50
|
+
|
34
51
|
# Rubocop task
|
35
52
|
RuboCop::RakeTask.new(:rubocop) do |task|
|
36
53
|
task.options = ['--display-cop-names']
|
data/app/volt/models/user.rb
CHANGED
@@ -5,8 +5,9 @@ require 'volt/utils/generic_pool'
|
|
5
5
|
# queries.
|
6
6
|
|
7
7
|
class LiveQueryPool < Volt::GenericPool
|
8
|
-
def initialize(data_store)
|
8
|
+
def initialize(data_store, volt_app)
|
9
9
|
@data_store = data_store
|
10
|
+
@volt_app = volt_app
|
10
11
|
super()
|
11
12
|
end
|
12
13
|
|
@@ -17,11 +18,16 @@ class LiveQueryPool < Volt::GenericPool
|
|
17
18
|
super(collection, query)
|
18
19
|
end
|
19
20
|
|
20
|
-
def updated_collection(collection, skip_channel)
|
21
|
+
def updated_collection(collection, skip_channel, from_message_bus=false)
|
21
22
|
# collection = collection.to_sym
|
22
23
|
lookup_all(collection).each do |live_query|
|
23
24
|
live_query.run(skip_channel)
|
24
25
|
end
|
26
|
+
|
27
|
+
msg_bus = @volt_app.message_bus
|
28
|
+
if !from_message_bus && collection != 'active_volt_instances' && msg_bus
|
29
|
+
msg_bus.publish('volt_collection_update', collection)
|
30
|
+
end
|
25
31
|
end
|
26
32
|
|
27
33
|
private
|
@@ -23,8 +23,8 @@ class QueryTracker
|
|
23
23
|
@results = @data_store.query(@live_query.collection, @live_query.query)
|
24
24
|
|
25
25
|
# Update the current_ids
|
26
|
-
@current_ids = @results.map { |r| r[
|
27
|
-
@results_hash = Hash[@results.map { |r| [r[
|
26
|
+
@current_ids = @results.map { |r| r[:id] }
|
27
|
+
@results_hash = Hash[@results.map { |r| [r[:id], r] }]
|
28
28
|
|
29
29
|
process_changes(skip_channel)
|
30
30
|
end
|
@@ -1,29 +1,13 @@
|
|
1
|
-
require_relative 'live_query/live_query_pool'
|
2
|
-
|
3
1
|
class QueryTasks < Volt::Task
|
4
|
-
@@channel_live_queries = {}
|
5
|
-
|
6
|
-
def self.live_query_pool
|
7
|
-
@@live_query_pool ||= LiveQueryPool.new(Volt::DataStore.fetch)
|
8
|
-
end
|
9
|
-
|
10
2
|
# The dispatcher passes its self in
|
11
|
-
def initialize(channel, dispatcher = nil)
|
3
|
+
def initialize(volt_app, channel, dispatcher = nil)
|
4
|
+
@volt_app = volt_app
|
12
5
|
@channel = channel
|
13
6
|
@dispatcher = dispatcher
|
14
|
-
|
15
|
-
# Load the query pool if not already setup
|
16
|
-
self.class.live_query_pool
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.reset!
|
20
|
-
@@channel_live_queries = {}
|
21
|
-
@@live_query_pool = nil
|
22
|
-
live_query_pool
|
23
7
|
end
|
24
8
|
|
25
9
|
def add_listener(collection, query)
|
26
|
-
live_query =
|
10
|
+
live_query = @volt_app.live_query_pool.lookup(collection, query)
|
27
11
|
track_channel_in_live_query(live_query)
|
28
12
|
|
29
13
|
if @channel
|
@@ -53,14 +37,12 @@ class QueryTasks < Volt::Task
|
|
53
37
|
end
|
54
38
|
end
|
55
39
|
|
56
|
-
# @@live_query_pool.print
|
57
|
-
|
58
40
|
[initial_data, error]
|
59
41
|
end
|
60
42
|
|
61
43
|
def initial_data
|
62
44
|
data = live_query.initial_data
|
63
|
-
data[:
|
45
|
+
data[:id] = data[:id].to_s
|
64
46
|
|
65
47
|
data
|
66
48
|
end
|
@@ -68,13 +50,13 @@ class QueryTasks < Volt::Task
|
|
68
50
|
# Remove a listening channel, the LiveQuery will automatically remove
|
69
51
|
# itsself from the pool when there are no channels.
|
70
52
|
def remove_listener(collection, query)
|
71
|
-
live_query =
|
53
|
+
live_query = @volt_app.live_query_pool.lookup(collection, query)
|
72
54
|
live_query.remove_channel(@channel)
|
73
55
|
end
|
74
56
|
|
75
57
|
# Removes a channel from all associated live queries
|
76
58
|
def close!
|
77
|
-
live_queries =
|
59
|
+
live_queries = @volt_app.channel_live_queries[@channel]
|
78
60
|
|
79
61
|
if live_queries
|
80
62
|
live_queries.each do |live_query|
|
@@ -82,14 +64,15 @@ class QueryTasks < Volt::Task
|
|
82
64
|
end
|
83
65
|
end
|
84
66
|
|
85
|
-
|
67
|
+
@volt_app.channel_live_queries.delete(@channel)
|
86
68
|
end
|
87
69
|
|
88
70
|
private
|
89
71
|
|
90
72
|
# Tracks that this channel will be notified from the live query.
|
91
73
|
def track_channel_in_live_query(live_query)
|
92
|
-
|
93
|
-
|
74
|
+
channel_live_queries = @volt_app.channel_live_queries
|
75
|
+
channel_live_queries[@channel] ||= []
|
76
|
+
channel_live_queries[@channel] << live_query
|
94
77
|
end
|
95
78
|
end
|
@@ -2,7 +2,8 @@ require 'mongo'
|
|
2
2
|
require 'volt/models'
|
3
3
|
|
4
4
|
class StoreTasks < Volt::Task
|
5
|
-
def initialize(channel = nil, dispatcher = nil)
|
5
|
+
def initialize(volt_app, channel = nil, dispatcher = nil)
|
6
|
+
@volt_app = volt_app
|
6
7
|
@channel = channel
|
7
8
|
@dispatcher = dispatcher
|
8
9
|
end
|
@@ -18,7 +19,7 @@ class StoreTasks < Volt::Task
|
|
18
19
|
collection = store.send(:"_#{path[-2]}")
|
19
20
|
|
20
21
|
# See if the model has already been made
|
21
|
-
collection.
|
22
|
+
collection.where(id: data[:id]).fetch_first do |model|
|
22
23
|
# Otherwise assign to the collection
|
23
24
|
model ||= collection
|
24
25
|
|
@@ -70,18 +71,18 @@ class StoreTasks < Volt::Task
|
|
70
71
|
query = nil
|
71
72
|
|
72
73
|
Volt.skip_permissions do
|
73
|
-
query = store.
|
74
|
+
query = store.get(collection).where(id: id)
|
74
75
|
end
|
75
76
|
|
76
77
|
query.fetch_first do |model|
|
77
78
|
if model
|
78
79
|
if model.can_delete?
|
79
|
-
db.delete(collection, '
|
80
|
+
db.delete(collection, 'id' => id)
|
80
81
|
else
|
81
82
|
fail "Permissions did not allow #{collection} #{id} to be deleted."
|
82
83
|
end
|
83
84
|
|
84
|
-
|
85
|
+
@volt_app.live_query_pool.updated_collection(collection, @channel)
|
85
86
|
else
|
86
87
|
fail "Could not find #{id} in #{collection}"
|
87
88
|
end
|
@@ -21,10 +21,10 @@ class UserTasks < Volt::Task
|
|
21
21
|
# TODO: returning here should be possible, but causes some issues
|
22
22
|
# Salt the user id with the app_secret so the end user can't
|
23
23
|
# tamper with the cookie
|
24
|
-
signature = Digest::SHA256.hexdigest(salty_user_id(user.
|
24
|
+
signature = Digest::SHA256.hexdigest(salty_user_id(user.id))
|
25
25
|
|
26
26
|
# Return user_id:hash on user id
|
27
|
-
next "#{user.
|
27
|
+
next "#{user.id}:#{signature}"
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# 0.9.2 to 0.9.3
|
2
|
+
|
3
|
+
Add the following to your gemfile:
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
# Use rbnacl for message bus encrpytion
|
7
|
+
# (optional, if you don't need encryption, disable in app.rb and remove)
|
8
|
+
gem 'rbnacl', require: false
|
9
|
+
gem 'rbnacl-libsodium', require: false
|
10
|
+
|
11
|
+
# Asset compilation gems, they will be required when needed.
|
12
|
+
gem 'csso-rails', '~> 0.3.4', require: false
|
13
|
+
gem 'uglifier', '>= 2.4.0', require: false
|
14
|
+
```
|
data/lib/volt/boot.rb
CHANGED
@@ -9,7 +9,7 @@ module Volt
|
|
9
9
|
private
|
10
10
|
|
11
11
|
def compile
|
12
|
-
|
12
|
+
puts 'compiling project...'
|
13
13
|
require 'fileutils'
|
14
14
|
ENV['SERVER'] = 'true'
|
15
15
|
|
@@ -38,20 +38,35 @@ module Volt
|
|
38
38
|
@index_files = IndexFiles.new(@app, @component_paths, @opal_files)
|
39
39
|
@component_handler = ComponentHandler.new(@component_paths)
|
40
40
|
|
41
|
+
puts 'Compile Opal for components'
|
41
42
|
write_component_js
|
43
|
+
puts 'Copy assets'
|
42
44
|
write_sprockets
|
45
|
+
puts 'Compile JS/CSS'
|
43
46
|
write_js_and_css
|
47
|
+
puts 'Write index files'
|
44
48
|
write_index
|
45
49
|
|
46
|
-
puts "
|
50
|
+
puts "compiled"
|
51
|
+
end
|
52
|
+
|
53
|
+
def logical_paths_and_full_paths
|
54
|
+
@opal_files.environment.each_file do |full_path|
|
55
|
+
logical_path = @opal_files.environment.send(:logical_path_for_filename, full_path, []).to_s
|
56
|
+
|
57
|
+
yield(logical_path, full_path.to_s)
|
58
|
+
end
|
59
|
+
|
47
60
|
end
|
48
61
|
|
49
62
|
def write_sprockets
|
50
63
|
# Serve the opal files
|
51
|
-
|
52
|
-
logical_path = logical_path.to_s
|
64
|
+
logical_paths_and_full_paths do |logical_path, full_path|
|
53
65
|
# Only include files that aren't compiled elsewhere, like fonts
|
54
|
-
if !logical_path[/[.](y|css|js|html|erb)$/] &&
|
66
|
+
if !logical_path[/[.](y|css|js|html|erb)$/] &&
|
67
|
+
File.extname(logical_path) != '' &&
|
68
|
+
# opal includes some node modules in the standard lib that we don't need to compile in
|
69
|
+
(full_path !~ /\/opal/ && full_path !~ /\/stdlib\// && logical_path !~ /^node_js\//)
|
55
70
|
write_sprocket_file(logical_path)
|
56
71
|
end
|
57
72
|
end
|
@@ -70,8 +85,11 @@ module Volt
|
|
70
85
|
path = "#{@root_path}/public/assets/#{logical_path}"
|
71
86
|
|
72
87
|
begin
|
73
|
-
|
74
|
-
|
88
|
+
# Only write out the assets
|
89
|
+
# if logical_path =~ /\/assets\//
|
90
|
+
content = @opal_files.environment[logical_path].to_s
|
91
|
+
write_file(path, content)
|
92
|
+
# end
|
75
93
|
rescue Sprockets::FileNotFound, SyntaxError => e
|
76
94
|
# ignore
|
77
95
|
end
|
data/lib/volt/cli/console.rb
CHANGED
@@ -31,11 +31,11 @@ module Volt
|
|
31
31
|
class Console
|
32
32
|
module Helpers
|
33
33
|
def store
|
34
|
-
|
34
|
+
@volt_app.page.store
|
35
35
|
end
|
36
36
|
|
37
37
|
def page
|
38
|
-
|
38
|
+
@volt_app.page.page
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -50,15 +50,16 @@ module Volt
|
|
50
50
|
require 'volt/volt/core'
|
51
51
|
require 'volt/server/socket_connection_handler_stub'
|
52
52
|
|
53
|
-
|
53
|
+
# Boot the volt app
|
54
|
+
volt_app = Volt.boot(Dir.pwd)
|
54
55
|
|
55
|
-
|
56
|
+
SocketConnectionHandlerStub.dispatcher = Dispatcher.new(volt_app)
|
56
57
|
|
57
58
|
Pry.config.prompt_name = 'volt'
|
58
59
|
|
60
|
+
Pry.main.instance_variable_set('@volt_app', volt_app)
|
59
61
|
Pry.main.send(:include, Volt::Console::Helpers)
|
60
62
|
|
61
|
-
# $page.pry
|
62
63
|
Pry.start
|
63
64
|
end
|
64
65
|
end
|
data/lib/volt/cli/generate.rb
CHANGED
@@ -62,7 +62,7 @@ class Generate < Thor
|
|
62
62
|
method_option :name, type: :string, banner: 'The name of the model controller.'
|
63
63
|
method_option :component, type: :string, default: 'main', banner: 'The component the controller should be created in.', required: false
|
64
64
|
def controller(name, component = 'main')
|
65
|
-
controller_name = name.underscore.
|
65
|
+
controller_name = name.underscore.pluralize + '_controller' unless name =~ /_controller$/
|
66
66
|
output_file = Dir.pwd + "/app/#{component.underscore}/controllers/#{controller_name}.rb"
|
67
67
|
spec_file = Dir.pwd + "/spec/app/#{component.underscore}/integration/#{name.underscore.pluralize}_spec.rb"
|
68
68
|
|
@@ -85,7 +85,7 @@ class Generate < Thor
|
|
85
85
|
method_option :name, type: :string, banner: 'The name of the view.'
|
86
86
|
method_option :component, type: :string, default: 'main', banner: 'The component the view should be created in.', required: false
|
87
87
|
def view(name, component = 'main')
|
88
|
-
name = name.underscore.
|
88
|
+
name = name.underscore.pluralize
|
89
89
|
view_folder = Dir.pwd + "/app/#{component}/views/#{name}/"
|
90
90
|
directory('view', view_folder, view_name: name, component: component)
|
91
91
|
controller(name, component) unless controller_exists?(name, component)
|
data/lib/volt/config.rb
CHANGED
@@ -8,11 +8,12 @@ module Volt
|
|
8
8
|
attr_reader :params, :response_headers, :request
|
9
9
|
|
10
10
|
# Initialzed with the params parsed from the route and the HttpRequest
|
11
|
-
def initialize(params, request)
|
11
|
+
def initialize(volt_app, params, request)
|
12
|
+
@volt_app = volt_app
|
12
13
|
@response_headers = HttpResponseHeader.new
|
13
14
|
@response_body = []
|
14
15
|
@request = request
|
15
|
-
@params = Volt::Model.new(params.symbolize_keys.merge(request.params))
|
16
|
+
@params = Volt::Model.new(params.symbolize_keys.merge(request.params), persistor: Volt::Persistors::Params)
|
16
17
|
end
|
17
18
|
|
18
19
|
def perform(action)
|
@@ -25,7 +26,7 @@ module Volt
|
|
25
26
|
private
|
26
27
|
|
27
28
|
def store
|
28
|
-
|
29
|
+
@volt_app.page.store
|
29
30
|
end
|
30
31
|
|
31
32
|
def head(status, additional_headers = {})
|
@@ -1,11 +1,18 @@
|
|
1
1
|
require 'volt/reactive/reactive_accessors'
|
2
2
|
require 'volt/controllers/actions'
|
3
|
+
require 'volt/controllers/template_helpers'
|
3
4
|
|
4
5
|
module Volt
|
5
6
|
class ModelController
|
6
7
|
include ReactiveAccessors
|
7
8
|
include Actions
|
8
9
|
|
10
|
+
# A model controller will have its
|
11
|
+
# class VoltTemplates
|
12
|
+
# include TemplateHelpers
|
13
|
+
# end
|
14
|
+
|
15
|
+
class_attribute :default_model
|
9
16
|
reactive_accessor :current_model
|
10
17
|
reactive_accessor :last_promise
|
11
18
|
|
@@ -29,8 +36,7 @@ module Volt
|
|
29
36
|
# ```yield_html``` and it will be run again when anything in the template changes.
|
30
37
|
def yield_html
|
31
38
|
if (template_path = attrs.content_template_path)
|
32
|
-
|
33
|
-
@yield_renderer ||= StringTemplateRenderer.new($page, self, template_path)
|
39
|
+
@yield_renderer ||= StringTemplateRenderer.new(@volt_app, self, template_path)
|
34
40
|
@yield_renderer.html
|
35
41
|
else
|
36
42
|
# no template, empty string
|
@@ -39,7 +45,7 @@ module Volt
|
|
39
45
|
end
|
40
46
|
|
41
47
|
def self.model(val)
|
42
|
-
|
48
|
+
self.default_model = val
|
43
49
|
end
|
44
50
|
|
45
51
|
# Sets the current model on this controller
|
@@ -85,20 +91,35 @@ module Volt
|
|
85
91
|
model
|
86
92
|
end
|
87
93
|
|
88
|
-
def self.new(*args, &block)
|
94
|
+
def self.new(volt_app, *args, &block)
|
89
95
|
inst = allocate
|
90
96
|
|
91
|
-
inst.model = @default_model if @default_model
|
92
|
-
|
93
97
|
# In MRI initialize is private for some reason, so call it with send
|
94
|
-
inst.send(:initialize, *args, &block)
|
98
|
+
inst.send(:initialize, volt_app, *args, &block)
|
99
|
+
|
100
|
+
if inst.instance_variable_get('@__init_called')
|
101
|
+
inst.instance_variable_set('@__init_called', nil)
|
102
|
+
else
|
103
|
+
# Initialize was not called, we should warn since this is probably not
|
104
|
+
# the intended behavior.
|
105
|
+
Volt.logger.warn("super should be called when creating a custom initialize on class #{inst.class.to_s}")
|
106
|
+
end
|
95
107
|
|
96
108
|
inst
|
97
109
|
end
|
98
110
|
|
99
111
|
attr_accessor :attrs
|
100
112
|
|
101
|
-
def initialize(*args)
|
113
|
+
def initialize(volt_app, *args)
|
114
|
+
@volt_app = volt_app
|
115
|
+
@page = volt_app.page
|
116
|
+
|
117
|
+
# Track that the initialize was called
|
118
|
+
@__init_called = true
|
119
|
+
|
120
|
+
default_model = self.class.default_model
|
121
|
+
self.model = default_model if default_model
|
122
|
+
|
102
123
|
if args[0]
|
103
124
|
# Assign the first passed in argument to attrs
|
104
125
|
self.attrs = args[0]
|
@@ -106,6 +127,7 @@ module Volt
|
|
106
127
|
# If a model attribute is passed in, we assign it directly
|
107
128
|
self.model = attrs.locals[:model] if attrs.respond_to?(:model)
|
108
129
|
end
|
130
|
+
|
109
131
|
end
|
110
132
|
|
111
133
|
def go(url)
|
@@ -124,39 +146,39 @@ module Volt
|
|
124
146
|
end
|
125
147
|
|
126
148
|
def page
|
127
|
-
|
149
|
+
@page.page
|
128
150
|
end
|
129
151
|
|
130
152
|
def store
|
131
|
-
|
153
|
+
@page.store
|
132
154
|
end
|
133
155
|
|
134
156
|
def flash
|
135
|
-
|
157
|
+
@page.flash
|
136
158
|
end
|
137
159
|
|
138
160
|
def params
|
139
|
-
|
161
|
+
@page.params
|
140
162
|
end
|
141
163
|
|
142
164
|
def local_store
|
143
|
-
|
165
|
+
@page.local_store
|
144
166
|
end
|
145
167
|
|
146
168
|
def cookies
|
147
|
-
|
169
|
+
@page.cookies
|
148
170
|
end
|
149
171
|
|
150
172
|
def url
|
151
|
-
|
173
|
+
@page.url
|
152
174
|
end
|
153
175
|
|
154
176
|
def channel
|
155
|
-
|
177
|
+
@page.channel
|
156
178
|
end
|
157
179
|
|
158
180
|
def tasks
|
159
|
-
|
181
|
+
@page.tasks
|
160
182
|
end
|
161
183
|
|
162
184
|
def controller
|
@@ -164,11 +186,11 @@ module Volt
|
|
164
186
|
end
|
165
187
|
|
166
188
|
def url_for(params)
|
167
|
-
|
189
|
+
@page.url.url_for(params)
|
168
190
|
end
|
169
191
|
|
170
192
|
def url_with(params)
|
171
|
-
|
193
|
+
@page.url.url_with(params)
|
172
194
|
end
|
173
195
|
|
174
196
|
# loaded? is a quick way to see if the model for the controller is loaded
|