volt 0.9.3.pre1 → 0.9.3.pre2
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/.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
|
-
[](https://pledgie.com/campaigns/26731)
|
|
2
2
|
[](http://badge.fury.io/rb/volt)
|
|
3
3
|
[](https://codeclimate.com/github/voltrb/volt)
|
|
4
4
|
[](https://coveralls.io/r/voltrb/volt?branch=master)[](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
|
+
[](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
|