hyper-mesh 0.4.0 → 0.5.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.
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)