hyper-mesh 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +59 -204
  3. data/config/routes.rb +1 -1
  4. data/docs/action_cable_quickstart.md +13 -36
  5. data/docs/configuration_details.md +62 -0
  6. data/docs/pusher_faker_quickstart.md +28 -0
  7. data/docs/pusher_quickstart.md +17 -0
  8. data/docs/simple_poller_quickstart.md +5 -0
  9. data/examples/words/Gemfile +4 -3
  10. data/examples/words/Gemfile.lock +33 -32
  11. data/examples/words/app/views/components.rb +4 -2
  12. data/examples/words/config/initializers/hyper_mesh.rb +14 -0
  13. data/examples/words/config/routes.rb +1 -1
  14. data/hyper-mesh-0.4.0.gem +0 -0
  15. data/lib/hyper-mesh.rb +2 -1
  16. data/lib/hypermesh/version.rb +1 -1
  17. data/lib/reactive_record/active_record/public_columns_hash.rb +2 -2
  18. data/lib/reactive_record/active_record/reactive_record/isomorphic_base.rb +1 -1
  19. data/lib/reactive_record/engine.rb +2 -4
  20. data/lib/reactive_record/permissions.rb +30 -7
  21. data/lib/synchromesh/client_drivers.rb +3 -5
  22. data/lib/synchromesh/connection.rb +34 -8
  23. data/lib/synchromesh/synchromesh.rb +11 -7
  24. data/lib/synchromesh/synchromesh_controller.rb +9 -1
  25. data/path_release_steps.md +9 -0
  26. data/reactive_record_test_app/Gemfile +2 -1
  27. data/reactive_record_test_app/Gemfile.lock +6 -6
  28. data/reactive_record_test_app/config/application.rb +0 -1
  29. data/reactive_record_test_app/config/initializers/hyper_mesh_legacy_behavior.rb +5 -0
  30. data/reactive_record_test_app/config/routes.rb +3 -3
  31. data/spec/reactive_record/edge_cases_spec.rb +1 -1
  32. data/spec/reactive_record/many_to_many_spec.rb +1 -1
  33. data/spec/reactive_record/revert_spec.rb +1 -0
  34. data/spec/reactive_record/update_associations_spec.rb +1 -0
  35. data/spec/reactive_record/update_scopes_spec.rb +1 -0
  36. data/spec/synchromesh/crud_access_regulation/broadcast_controls_access_spec.rb +0 -6
  37. data/spec/synchromesh/crud_access_regulation/model_policies_spec.rb +8 -6
  38. data/spec/synchromesh/integration/has_many_through_spec.rb +0 -4
  39. data/spec/test_app/config/routes.rb +1 -1
  40. data/work-in-progress-drinking.png +0 -0
  41. metadata +8 -4
  42. data/examples/words/config/initializers/synchromesh.rb +0 -5
  43. data/lib/synchromesh/reactive_record/permission_patches.rb +0 -43
@@ -0,0 +1,62 @@
1
+ ## Installation
2
+
3
+ If you do not already have hyper-react installed, then use the reactrb-rails-generator gem to setup hyper-react, reactive-record and associated gems.
4
+
5
+ Then add this line to your application's Gemfile:
6
+
7
+ ```ruby
8
+ gem 'HyperMesh'
9
+ ```
10
+
11
+ And then execute:
12
+
13
+ $ bundle install
14
+
15
+ Also you must `require 'hyper-tracemesh'` from your client side code. The easiest way is to
16
+ find the `require 'reactive-record'` line (typically in `components.rb`) and replace it with
17
+ `require 'HyperMesh'`.
18
+
19
+ ## Configuration
20
+
21
+ Add an initializer like this:
22
+
23
+ ```ruby
24
+ # for rails this would go in: config/initializers/HyperMesh.rb
25
+ HyperMesh.configuration do |config|
26
+ config.transport = :simple_poller # or :none, action_cable, :pusher - see below)
27
+ end
28
+ # for a minimal setup you will need to define at least one channel, which you can do
29
+ # in the same file as your initializer.
30
+ # Normally you would put these policies in the app/policies/ directory
31
+ class ApplicationPolicy
32
+ # allow all clients to connect to the Application channel
33
+ regulate_connection { true } # or always_allow_connection for short
34
+ # broadcast all model changes over the Application channel *DANGEROUS*
35
+ regulate_all_broadcasts { |policy| policy.send_all }
36
+ end
37
+ ```
38
+
39
+ Assuming you are up and running with Hyper-React on Rails:
40
+
41
+ 1. **Add the gem**
42
+ add `gem 'hyper-mesh'`, and bundle install
43
+ 6. **Add the models directory to asset path**
44
+ ```ruby
45
+ # application.rb
46
+ config.assets.paths << ::Rails.root.join('app', 'models').to_s
47
+ ```
48
+
49
+ 2. **Require HyperMesh instead of HyperReact**
50
+ replace `require 'hyper-react'` with `require 'hyper-mesh'` in the components manifest (`app/views/components.rb`.)
51
+ 3. **Require your models on the client_side_scoping**
52
+ add `require 'models'` to the bottom of the components manifest
53
+ 4. add a models manifest in the models directory:
54
+ ```ruby
55
+ # app/models/models.rb
56
+ require_tree './public'
57
+ ```
58
+ 5. create a `public` directory in your models directory and move any models that you want access to on the client into this directory. Access to these models will be protected by *Policies* you will be creating later.
59
+
60
+ A minimal HyperMesh configuration consists of a simple initializer file, and at least one *Policy* class that will *authorize* who gets to see what.
61
+
62
+ The initializer file specifies what transport will be used. Currently you can use [Pusher](http://pusher.com), ActionCable (if using Rails 5), Pusher-Fake (for development) or a Simple Poller for testing etc.
@@ -0,0 +1,28 @@
1
+ ### Pusher-Fake
2
+
3
+ You can also use the [Pusher-Fake](https://github.com/tristandunn/pusher-fake) gem while in development. Setup is a little tricky. First
4
+ add `gem 'pusher-fake'` to the development and/or test section of your gem file. Then setup your config file:
5
+
6
+ ```ruby
7
+ # typically config/initializers/HyperMesh.rb
8
+ # or you can do a similar setup in your tests (see this gem's specs)
9
+ require 'pusher'
10
+ require 'pusher-fake'
11
+ # The app_id, key, and secret need to be assigned directly to Pusher
12
+ # so PusherFake will work.
13
+ Pusher.app_id = "MY_TEST_ID" # you use the real or fake values
14
+ Pusher.key = "MY_TEST_KEY"
15
+ Pusher.secret = "MY_TEST_SECRET"
16
+ # The next line actually starts the pusher-fake server (see the Pusher-Fake readme for details.)
17
+ require 'pusher-fake/support/base' # if using pusher with rspec change this to pusher-fake/support/rspec
18
+ # now copy over the credentials, and merge with PusherFake's config details
19
+ HyperMesh.configuration do |config|
20
+ config.transport = :pusher
21
+ config.channel_prefix = "HyperMesh"
22
+ config.opts = {
23
+ app_id: Pusher.app_id,
24
+ key: Pusher.key,
25
+ secret: Pusher.secret
26
+ }.merge(PusherFake.configuration.web_options)
27
+ end
28
+ ```
@@ -0,0 +1,17 @@
1
+ ### Pusher Configuration
2
+
3
+ Add `gem 'pusher'` to your gem file, and add `//= require 'HyperMesh/pusher'` to your application.js file.
4
+
5
+ ```ruby
6
+ # typically config/initializers/HyperMesh.rb
7
+ HyperMesh.configuration do |config|
8
+ config.transport = :pusher
9
+ config.opts = {
10
+ app_id: '2xxxx2',
11
+ key: 'dxxxxxxxxxxxxxxxxxx9',
12
+ secret: '2xxxxxxxxxxxxxxxxxx2',
13
+ encrypted: false # optional defaults to true
14
+ }
15
+ config.channel_prefix = 'syncromesh' # or any other string you want
16
+ end
17
+ ```
@@ -29,6 +29,11 @@ Once you have hyper-react installed then add this initializer:
29
29
  #config/initializers/synchromesh.rb
30
30
  HyperMesh.configuration do |config|
31
31
  config.transport = :simple_poller
32
+ # options
33
+ config.opts = {
34
+ seconds_between_poll: 5, # default is 0.5 you may need to increase if testing with Selenium
35
+ seconds_polled_data_will_be_retained: 1.hour # clears channel data after this time, default is 5 minutes
36
+ }
32
37
  end
33
38
  ```
34
39
 
@@ -43,16 +43,17 @@ group :development do
43
43
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
44
44
  gem 'spring'
45
45
  gem 'spring-watcher-listen', '~> 2.0.0'
46
+ gem 'pry'
46
47
  end
47
48
 
48
49
  # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
49
50
  gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
50
51
 
51
52
  gem 'hyper-react'
53
+ gem 'opal-browser'
52
54
  gem 'react-rails', '>= 1.3.0'
53
55
  gem 'opal-rails', '>= 0.8.1'
54
56
  gem 'therubyracer', platforms: :ruby
55
57
  gem 'react-router-rails', '~> 0.13.3'
56
- gem 'reactrb-router'
57
- gem 'reactive-record', '>= 0.8.0'
58
- gem 'synchromesh', path: '../..'
58
+ gem 'hyper-router'
59
+ gem 'hyper-mesh', path: '../..'
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- synchromesh (0.4.0)
4
+ hyper-mesh (0.4.1)
5
5
  activerecord (>= 0.3.0)
6
- reactive-record (>= 0.7.43)
6
+ hyper-react (>= 0.10.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
@@ -45,13 +45,14 @@ GEM
45
45
  i18n (~> 0.7)
46
46
  minitest (~> 5.1)
47
47
  tzinfo (~> 1.1)
48
- arel (7.1.2)
48
+ arel (7.1.4)
49
49
  babel-source (5.8.35)
50
50
  babel-transpiler (0.7.0)
51
51
  babel-source (>= 4.0, < 6)
52
52
  execjs (~> 2.0)
53
53
  builder (3.2.2)
54
- byebug (9.0.5)
54
+ byebug (9.0.6)
55
+ coderay (1.1.1)
55
56
  coffee-rails (4.2.1)
56
57
  coffee-script (>= 2.2.0)
57
58
  railties (>= 4.0.0, < 5.2.x)
@@ -68,6 +69,13 @@ GEM
68
69
  globalid (0.3.7)
69
70
  activesupport (>= 4.1.0)
70
71
  hike (1.2.3)
72
+ hyper-react (0.10.0)
73
+ opal (>= 0.8.0)
74
+ opal-activesupport (>= 0.2.0)
75
+ react-rails
76
+ hyper-router (2.4.0)
77
+ hyper-react
78
+ opal-browser
71
79
  i18n (0.7.0)
72
80
  jbuilder (2.6.0)
73
81
  activesupport (>= 3.0.0, < 5.1)
@@ -89,13 +97,12 @@ GEM
89
97
  mime-types-data (~> 3.2015)
90
98
  mime-types-data (3.2016.0521)
91
99
  mini_portile2 (2.1.0)
92
- minitest (5.9.0)
100
+ minitest (5.9.1)
93
101
  multi_json (1.12.1)
94
102
  nio4r (1.2.1)
95
- nokogiri (1.6.8)
103
+ nokogiri (1.6.8.1)
96
104
  mini_portile2 (~> 2.1.0)
97
- pkg-config (~> 1.1.7)
98
- opal (0.10.2)
105
+ opal (0.10.3)
99
106
  hike (~> 1.2)
100
107
  sourcemap (~> 0.1.0)
101
108
  sprockets (~> 3.1)
@@ -115,7 +122,10 @@ GEM
115
122
  rails (>= 4.0, < 6.0)
116
123
  sprockets-rails (< 3.0)
117
124
  paggio (0.2.6)
118
- pkg-config (1.1.7)
125
+ pry (0.10.4)
126
+ coderay (~> 1.1.0)
127
+ method_source (~> 0.8.1)
128
+ slop (~> 3.4)
119
129
  puma (3.6.0)
120
130
  rack (2.0.1)
121
131
  rack-test (0.6.3)
@@ -144,7 +154,7 @@ GEM
144
154
  rake (>= 0.8.7)
145
155
  thor (>= 0.18.1, < 2.0)
146
156
  rake (11.3.0)
147
- rb-fsevent (0.9.7)
157
+ rb-fsevent (0.9.8)
148
158
  rb-inotify (0.9.7)
149
159
  ffi (>= 0.5.0)
150
160
  react-rails (1.4.2)
@@ -157,20 +167,8 @@ GEM
157
167
  react-router-rails (0.13.3.2)
158
168
  rails (>= 3.1)
159
169
  react-rails (~> 1.4.0)
160
- reactive-record (0.8.3)
161
- opal-browser
162
- opal-rails
163
- rails (>= 3.2.13)
164
- react-rails
165
- hyper-react
166
- hyper-react (0.8.8)
167
- opal (>= 0.8.0)
168
- opal-activesupport (>= 0.2.0)
169
- opal-browser (= 0.2.0)
170
170
  reactrb-rails-generator (0.2.0)
171
171
  rails (>= 4.0.0)
172
- reactrb-router (0.8.2)
173
- hyper-react
174
172
  ref (2.0.0)
175
173
  sass (3.4.22)
176
174
  sass-rails (5.0.6)
@@ -179,11 +177,13 @@ GEM
179
177
  sprockets (>= 2.8, < 4.0)
180
178
  sprockets-rails (>= 2.0, < 4.0)
181
179
  tilt (>= 1.1, < 3)
180
+ slop (3.6.0)
182
181
  sourcemap (0.1.1)
183
- spring (1.7.2)
184
- spring-watcher-listen (2.0.0)
182
+ spring (2.0.0)
183
+ activesupport (>= 4.2)
184
+ spring-watcher-listen (2.0.1)
185
185
  listen (>= 2.7, < 4.0)
186
- spring (~> 1.2)
186
+ spring (>= 1.2, < 3.0)
187
187
  sprockets (3.7.0)
188
188
  concurrent-ruby (~> 1.0)
189
189
  rack (> 1, < 3)
@@ -191,7 +191,7 @@ GEM
191
191
  actionpack (>= 3.0)
192
192
  activesupport (>= 3.0)
193
193
  sprockets (>= 2.8, < 4.0)
194
- sqlite3 (1.3.11)
194
+ sqlite3 (1.3.12)
195
195
  therubyracer (0.12.2)
196
196
  libv8 (~> 3.16.14.0)
197
197
  ref
@@ -203,9 +203,9 @@ GEM
203
203
  turbolinks-source (5.0.0)
204
204
  tzinfo (1.2.2)
205
205
  thread_safe (~> 0.1)
206
- uglifier (3.0.2)
206
+ uglifier (3.0.3)
207
207
  execjs (>= 0.3.0, < 3)
208
- web-console (3.3.1)
208
+ web-console (3.4.0)
209
209
  actionview (>= 5.0)
210
210
  activemodel (>= 5.0)
211
211
  debug_inspector
@@ -220,23 +220,24 @@ PLATFORMS
220
220
  DEPENDENCIES
221
221
  byebug
222
222
  coffee-rails (~> 4.2)
223
+ hyper-mesh!
224
+ hyper-react
225
+ hyper-router
223
226
  jbuilder (~> 2.5)
224
227
  jquery-rails
225
228
  listen (~> 3.0.5)
229
+ opal-browser
226
230
  opal-rails (>= 0.8.1)
231
+ pry
227
232
  puma (~> 3.0)
228
233
  rails (~> 5.0.0, >= 5.0.0.1)
229
234
  react-rails (>= 1.3.0)
230
235
  react-router-rails (~> 0.13.3)
231
- reactive-record (>= 0.8.0)
232
- hyper-react
233
236
  reactrb-rails-generator
234
- reactrb-router
235
237
  sass-rails (~> 5.0)
236
238
  spring
237
239
  spring-watcher-listen (~> 2.0.0)
238
240
  sqlite3
239
- synchromesh!
240
241
  therubyracer
241
242
  turbolinks (~> 5)
242
243
  tzinfo-data
@@ -1,7 +1,9 @@
1
1
  # app/views/components.rb
2
2
  require 'opal'
3
3
  require 'react'
4
- require 'hyper-react'
4
+ #require 'hyper-react'
5
+ require 'hyper-mesh'
6
+
5
7
  if React::IsomorphicHelpers.on_opal_client?
6
8
  require 'opal-jquery'
7
9
  require 'browser'
@@ -9,7 +11,7 @@ if React::IsomorphicHelpers.on_opal_client?
9
11
  require 'browser/delay'
10
12
  # add any additional requires that can ONLY run on client here
11
13
  end
12
- require 'reactrb-router'
14
+ require 'hyper-router'
13
15
  require 'react_router'
14
16
  require 'hyper-mesh'
15
17
  require 'models'
@@ -0,0 +1,14 @@
1
+ #config/initializers/hyper_mesh.rb
2
+
3
+ #puts "***** #{__FILE__} ****"
4
+ #binding.pry
5
+ #File.join(Rails.root, 'app', 'models', 'public')
6
+ #binding.pry
7
+ #Opal.append_path File.join(Rails.root, 'app', 'models').untaint
8
+
9
+
10
+
11
+ HyperMesh.configuration do |config|
12
+ config.transport = :action_cable
13
+ config.channel_prefix = "synchromesh"
14
+ end
@@ -1,5 +1,5 @@
1
1
  Rails.application.routes.draw do
2
- mount ReactiveRecord::Engine => '/rr'
2
+ mount HyperMesh::Engine => '/rr'
3
3
  get 'test', to: 'test#app'
4
4
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
5
5
  end
Binary file
@@ -49,11 +49,12 @@ else
49
49
  require "reactive_record/serializers"
50
50
  require "reactive_record/pry"
51
51
  require_relative 'active_record_base'
52
- require 'synchromesh/synchromesh_controller'
53
52
  require 'hypermesh/version'
54
53
  require 'synchromesh/connection'
55
54
  require 'synchromesh/synchromesh'
56
55
  require 'synchromesh/policy'
56
+ require 'synchromesh/synchromesh_controller'
57
+
57
58
  Opal.append_path File.expand_path('../sources/', __FILE__).untaint
58
59
  Opal.append_path File.expand_path('../', __FILE__).untaint
59
60
  Opal.append_path File.expand_path('../../vendor', __FILE__).untaint
@@ -1,3 +1,3 @@
1
1
  module Hypermesh
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -7,11 +7,11 @@ module ActiveRecord
7
7
  def self.public_columns_hash
8
8
  return @public_columns_hash if @public_columns_hash
9
9
  Dir.glob(Rails.root.join('app/models/public/*.rb')).each do |file|
10
- require_dependency(file) rescue nil
10
+ require_dependency(file)
11
11
  end
12
12
  @public_columns_hash = {}
13
13
  descendants.each do |model|
14
- @public_columns_hash[model.name] = model.columns_hash
14
+ @public_columns_hash[model.name] = model.columns_hash rescue nil
15
15
  end
16
16
  @public_columns_hash
17
17
  end
@@ -55,7 +55,7 @@ module ReactiveRecord
55
55
  end
56
56
  path = ::Rails.application.routes.routes.detect do |route|
57
57
  # not sure why the second check is needed. It happens in the test app
58
- route.app == ReactiveRecord::Engine or (route.app.respond_to?(:app) and route.app.app == ReactiveRecord::Engine)
58
+ route.app == HyperMesh::Engine or (route.app.respond_to?(:app) and route.app.app == HyperMesh::Engine)
59
59
  end.path.spec
60
60
  "<script type='text/javascript'>\n"+
61
61
  "window.ReactiveRecordEnginePath = '#{path}';\n"+
@@ -1,6 +1,4 @@
1
- #require 'rails'
2
-
3
- module ReactiveRecord
1
+ module HyperMesh
4
2
  class Engine < ::Rails::Engine
5
3
  isolate_namespace ReactiveRecord
6
4
  config.generators do |g|
@@ -10,4 +8,4 @@ module ReactiveRecord
10
8
  g.helper false
11
9
  end
12
10
  end
13
- end
11
+ end
@@ -6,24 +6,47 @@ module ReactiveRecord
6
6
  end
7
7
  end
8
8
 
9
+ module HyperMesh
10
+ class InternalPolicy
11
+
12
+ def self.accessible_attributes_for(model, acting_user)
13
+ user_channels = ClassConnectionRegulation.connections_for(acting_user, false) +
14
+ InstanceConnectionRegulation.connections_for(acting_user, false)
15
+ internal_policy = InternalPolicy.new(model, model.attribute_names, user_channels)
16
+ ChannelBroadcastRegulation.broadcast(internal_policy)
17
+ InstanceBroadcastRegulation.broadcast(model, internal_policy)
18
+ internal_policy.accessible_attributes_for
19
+ end
20
+
21
+ def accessible_attributes_for
22
+ accessible_attributes = Set.new
23
+ @channel_sets.each do |channel, attribute_set|
24
+ accessible_attributes.merge attribute_set
25
+ end
26
+ accessible_attributes << :id unless accessible_attributes.empty?
27
+ accessible_attributes
28
+ end
29
+ end
30
+ end
31
+
9
32
  class ActiveRecord::Base
10
33
 
11
34
  attr_accessor :acting_user
12
35
 
36
+ def view_permitted?(attribute)
37
+ HyperMesh::InternalPolicy.accessible_attributes_for(self, acting_user).include? attribute.to_sym
38
+ end
39
+
13
40
  def create_permitted?
14
- true
41
+ false
15
42
  end
16
43
 
17
44
  def update_permitted?
18
- true
45
+ false
19
46
  end
20
47
 
21
48
  def destroy_permitted?
22
- true
23
- end
24
-
25
- def view_permitted?(attribute)
26
- true
49
+ false
27
50
  end
28
51
 
29
52
  def only_changed?(*attributes)