hyper-mesh 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (234) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +21 -13
  3. data/docs/action_cable_quickstart.md +9 -7
  4. data/docs/activerecord_api.md +73 -0
  5. data/docs/client_side_scoping.md +5 -5
  6. data/docs/configuration_details.md +11 -0
  7. data/docs/pusher_faker_quickstart.md +95 -6
  8. data/docs/pusher_quickstart.md +96 -8
  9. data/docs/simple_poller_quickstart.md +21 -55
  10. data/docs/todo-example.md +2 -0
  11. data/docs/words-example.md +3 -0
  12. data/examples/action-cable/Gemfile +7 -8
  13. data/examples/action-cable/Gemfile.lock +28 -46
  14. data/examples/{simple-poller/app/assets/javascripts/channels → action-cable/app/assets/images}/.keep +0 -0
  15. data/examples/action-cable/app/assets/javascripts/application.js +5 -3
  16. data/examples/action-cable/app/assets/javascripts/cable.js +13 -0
  17. data/examples/{simple-poller/app/controllers/concerns → action-cable/app/assets/javascripts/channels}/.keep +0 -0
  18. data/examples/{simple-poller → action-cable}/app/channels/application_cable/channel.rb +0 -0
  19. data/examples/{simple-poller → action-cable}/app/channels/application_cable/connection.rb +0 -0
  20. data/examples/action-cable/app/controllers/test_controller.rb +0 -1
  21. data/examples/{simple-poller/app/models/concerns → action-cable/app/models/public}/.keep +0 -0
  22. data/examples/action-cable/app/policies/application_policy.rb +9 -1
  23. data/examples/action-cable/app/views/components.rb +2 -3
  24. data/examples/action-cable/bin/spring +4 -3
  25. data/examples/action-cable/config/application.rb +1 -11
  26. data/examples/action-cable/config/environments/development.rb +12 -1
  27. data/examples/action-cable/config/initializers/hyper_mesh.rb +4 -0
  28. data/examples/action-cable/config/routes.rb +1 -1
  29. data/examples/action-cable/config/secrets.yml +2 -2
  30. data/examples/action-cable/db/migrate/{20160921223808_create_words.rb → 20161114213840_create_words.rb} +0 -0
  31. data/examples/action-cable/db/schema.rb +14 -1
  32. data/examples/action-cable/db/seeds.rb +7 -0
  33. data/examples/{simple-poller/app/views/components → action-cable/lib/assets}/.keep +0 -0
  34. data/examples/action-cable/lib/tasks/.keep +0 -0
  35. data/examples/action-cable/test/controllers/.keep +0 -0
  36. data/examples/action-cable/test/fixtures/.keep +0 -0
  37. data/examples/action-cable/test/fixtures/files/.keep +0 -0
  38. data/examples/action-cable/test/fixtures/words.yml +7 -0
  39. data/examples/action-cable/test/helpers/.keep +0 -0
  40. data/examples/action-cable/test/integration/.keep +0 -0
  41. data/examples/action-cable/test/mailers/.keep +0 -0
  42. data/examples/action-cable/test/models/.keep +0 -0
  43. data/examples/action-cable/test/models/word_test.rb +7 -0
  44. data/examples/action-cable/test/test_helper.rb +10 -0
  45. data/examples/pusher-fake/.gitignore +21 -0
  46. data/examples/pusher-fake/Gemfile +59 -0
  47. data/examples/pusher-fake/Gemfile.lock +262 -0
  48. data/examples/pusher-fake/README.md +24 -0
  49. data/examples/pusher-fake/Rakefile +6 -0
  50. data/examples/pusher-fake/app/assets/config/manifest.js +3 -0
  51. data/examples/pusher-fake/app/assets/images/.keep +0 -0
  52. data/examples/pusher-fake/app/assets/javascripts/application.js +21 -0
  53. data/examples/pusher-fake/app/assets/stylesheets/application.css +15 -0
  54. data/examples/pusher-fake/app/controllers/application_controller.rb +3 -0
  55. data/examples/pusher-fake/app/controllers/test_controller.rb +5 -0
  56. data/examples/pusher-fake/app/models/models.rb +2 -0
  57. data/examples/pusher-fake/app/models/public/.keep +0 -0
  58. data/examples/pusher-fake/app/models/public/application_record.rb +3 -0
  59. data/examples/pusher-fake/app/models/public/word.rb +2 -0
  60. data/examples/pusher-fake/app/policies/application_policy.rb +14 -0
  61. data/examples/pusher-fake/app/views/components.rb +16 -0
  62. data/examples/pusher-fake/app/views/components/app.rb +18 -0
  63. data/examples/pusher-fake/app/views/layouts/application.html.erb +14 -0
  64. data/examples/pusher-fake/app/views/layouts/mailer.html.erb +13 -0
  65. data/examples/pusher-fake/app/views/layouts/mailer.text.erb +1 -0
  66. data/examples/pusher-fake/bin/bundle +3 -0
  67. data/examples/pusher-fake/bin/rails +9 -0
  68. data/examples/pusher-fake/bin/rake +9 -0
  69. data/examples/pusher-fake/bin/setup +34 -0
  70. data/examples/pusher-fake/bin/spring +16 -0
  71. data/examples/pusher-fake/bin/update +29 -0
  72. data/examples/pusher-fake/config.ru +5 -0
  73. data/examples/pusher-fake/config/application.rb +20 -0
  74. data/examples/pusher-fake/config/boot.rb +3 -0
  75. data/examples/pusher-fake/config/database.yml +25 -0
  76. data/examples/pusher-fake/config/environment.rb +5 -0
  77. data/examples/pusher-fake/config/environments/development.rb +56 -0
  78. data/examples/pusher-fake/config/environments/production.rb +86 -0
  79. data/examples/pusher-fake/config/environments/test.rb +42 -0
  80. data/examples/pusher-fake/config/initializers/application_controller_renderer.rb +6 -0
  81. data/examples/pusher-fake/config/initializers/assets.rb +11 -0
  82. data/examples/pusher-fake/config/initializers/backtrace_silencers.rb +7 -0
  83. data/examples/pusher-fake/config/initializers/cookies_serializer.rb +5 -0
  84. data/examples/pusher-fake/config/initializers/filter_parameter_logging.rb +4 -0
  85. data/examples/pusher-fake/config/initializers/hyper_mesh.rb +21 -0
  86. data/examples/pusher-fake/config/initializers/inflections.rb +16 -0
  87. data/examples/pusher-fake/config/initializers/mime_types.rb +4 -0
  88. data/examples/pusher-fake/config/initializers/new_framework_defaults.rb +24 -0
  89. data/examples/pusher-fake/config/initializers/session_store.rb +3 -0
  90. data/examples/pusher-fake/config/initializers/wrap_parameters.rb +14 -0
  91. data/examples/pusher-fake/config/locales/en.yml +23 -0
  92. data/examples/pusher-fake/config/puma.rb +47 -0
  93. data/examples/pusher-fake/config/routes.rb +5 -0
  94. data/examples/pusher-fake/config/secrets.yml +22 -0
  95. data/examples/pusher-fake/config/spring.rb +6 -0
  96. data/examples/{simple-poller/db/migrate/20161013220135_create_words.rb → pusher-fake/db/migrate/20161114213840_create_words.rb} +0 -0
  97. data/examples/pusher-fake/db/schema.rb +34 -0
  98. data/examples/pusher-fake/db/seeds.rb +7 -0
  99. data/examples/pusher-fake/lib/assets/.keep +0 -0
  100. data/examples/pusher-fake/lib/tasks/.keep +0 -0
  101. data/examples/pusher-fake/log/.keep +0 -0
  102. data/examples/pusher-fake/public/404.html +67 -0
  103. data/examples/pusher-fake/public/422.html +67 -0
  104. data/examples/pusher-fake/public/500.html +66 -0
  105. data/examples/pusher-fake/public/apple-touch-icon-precomposed.png +0 -0
  106. data/examples/pusher-fake/public/apple-touch-icon.png +0 -0
  107. data/examples/pusher-fake/public/favicon.ico +0 -0
  108. data/examples/pusher-fake/public/robots.txt +5 -0
  109. data/examples/pusher-fake/test/controllers/.keep +0 -0
  110. data/examples/pusher-fake/test/fixtures/.keep +0 -0
  111. data/examples/pusher-fake/test/fixtures/files/.keep +0 -0
  112. data/examples/pusher-fake/test/fixtures/words.yml +7 -0
  113. data/examples/pusher-fake/test/helpers/.keep +0 -0
  114. data/examples/pusher-fake/test/integration/.keep +0 -0
  115. data/examples/pusher-fake/test/mailers/.keep +0 -0
  116. data/examples/pusher-fake/test/models/.keep +0 -0
  117. data/examples/pusher-fake/test/models/word_test.rb +7 -0
  118. data/examples/pusher-fake/test/test_helper.rb +10 -0
  119. data/examples/pusher-fake/tmp/.keep +0 -0
  120. data/examples/pusher-fake/vendor/assets/javascripts/.keep +0 -0
  121. data/examples/pusher-fake/vendor/assets/stylesheets/.keep +0 -0
  122. data/examples/pusher/.gitignore +21 -0
  123. data/examples/pusher/Gemfile +58 -0
  124. data/examples/pusher/Gemfile.lock +236 -0
  125. data/examples/pusher/README.md +24 -0
  126. data/examples/pusher/Rakefile +6 -0
  127. data/examples/pusher/app/assets/config/manifest.js +3 -0
  128. data/examples/pusher/app/assets/images/.keep +0 -0
  129. data/examples/pusher/app/assets/javascripts/application.js +21 -0
  130. data/examples/pusher/app/assets/stylesheets/application.css +15 -0
  131. data/examples/pusher/app/controllers/application_controller.rb +3 -0
  132. data/examples/pusher/app/controllers/test_controller.rb +5 -0
  133. data/examples/pusher/app/models/models.rb +2 -0
  134. data/examples/pusher/app/models/public/.keep +0 -0
  135. data/examples/pusher/app/models/public/application_record.rb +3 -0
  136. data/examples/pusher/app/models/public/word.rb +2 -0
  137. data/examples/pusher/app/policies/application_policy.rb +14 -0
  138. data/examples/pusher/app/views/components.rb +16 -0
  139. data/examples/pusher/app/views/components/app.rb +18 -0
  140. data/examples/pusher/app/views/layouts/application.html.erb +14 -0
  141. data/examples/pusher/app/views/layouts/mailer.html.erb +13 -0
  142. data/examples/pusher/app/views/layouts/mailer.text.erb +1 -0
  143. data/examples/pusher/bin/bundle +3 -0
  144. data/examples/pusher/bin/rails +9 -0
  145. data/examples/pusher/bin/rake +9 -0
  146. data/examples/pusher/bin/setup +34 -0
  147. data/examples/pusher/bin/spring +16 -0
  148. data/examples/pusher/bin/update +29 -0
  149. data/examples/pusher/config.ru +5 -0
  150. data/examples/pusher/config/application.rb +20 -0
  151. data/examples/pusher/config/boot.rb +3 -0
  152. data/examples/pusher/config/database.yml +25 -0
  153. data/examples/pusher/config/environment.rb +5 -0
  154. data/examples/pusher/config/environments/development.rb +56 -0
  155. data/examples/pusher/config/environments/production.rb +86 -0
  156. data/examples/pusher/config/environments/test.rb +42 -0
  157. data/examples/pusher/config/initializers/application_controller_renderer.rb +6 -0
  158. data/examples/pusher/config/initializers/assets.rb +11 -0
  159. data/examples/pusher/config/initializers/backtrace_silencers.rb +7 -0
  160. data/examples/pusher/config/initializers/cookies_serializer.rb +5 -0
  161. data/examples/pusher/config/initializers/filter_parameter_logging.rb +4 -0
  162. data/examples/pusher/config/initializers/hyper_mesh.rb +10 -0
  163. data/examples/pusher/config/initializers/inflections.rb +16 -0
  164. data/examples/pusher/config/initializers/mime_types.rb +4 -0
  165. data/examples/pusher/config/initializers/new_framework_defaults.rb +24 -0
  166. data/examples/pusher/config/initializers/session_store.rb +3 -0
  167. data/examples/pusher/config/initializers/wrap_parameters.rb +14 -0
  168. data/examples/pusher/config/locales/en.yml +23 -0
  169. data/examples/pusher/config/puma.rb +47 -0
  170. data/examples/pusher/config/routes.rb +5 -0
  171. data/examples/pusher/config/secrets.yml +22 -0
  172. data/examples/pusher/config/spring.rb +6 -0
  173. data/examples/pusher/db/migrate/20161114213840_create_words.rb +9 -0
  174. data/examples/pusher/db/schema.rb +34 -0
  175. data/examples/pusher/db/seeds.rb +7 -0
  176. data/examples/pusher/lib/assets/.keep +0 -0
  177. data/examples/pusher/lib/tasks/.keep +0 -0
  178. data/examples/pusher/log/.keep +0 -0
  179. data/examples/pusher/public/404.html +67 -0
  180. data/examples/pusher/public/422.html +67 -0
  181. data/examples/pusher/public/500.html +66 -0
  182. data/examples/pusher/public/apple-touch-icon-precomposed.png +0 -0
  183. data/examples/pusher/public/apple-touch-icon.png +0 -0
  184. data/examples/pusher/public/favicon.ico +0 -0
  185. data/examples/pusher/public/robots.txt +5 -0
  186. data/examples/pusher/test/controllers/.keep +0 -0
  187. data/examples/pusher/test/fixtures/.keep +0 -0
  188. data/examples/pusher/test/fixtures/files/.keep +0 -0
  189. data/examples/pusher/test/fixtures/words.yml +7 -0
  190. data/examples/pusher/test/helpers/.keep +0 -0
  191. data/examples/pusher/test/integration/.keep +0 -0
  192. data/examples/pusher/test/mailers/.keep +0 -0
  193. data/examples/pusher/test/models/.keep +0 -0
  194. data/examples/pusher/test/models/word_test.rb +7 -0
  195. data/examples/pusher/test/test_helper.rb +10 -0
  196. data/examples/pusher/tmp/.keep +0 -0
  197. data/examples/pusher/vendor/assets/javascripts/.keep +0 -0
  198. data/examples/pusher/vendor/assets/stylesheets/.keep +0 -0
  199. data/examples/simple-poller/Gemfile +7 -14
  200. data/examples/simple-poller/Gemfile.lock +23 -66
  201. data/examples/simple-poller/app/assets/javascripts/application.js +5 -4
  202. data/examples/simple-poller/app/controllers/test_controller.rb +0 -1
  203. data/examples/simple-poller/app/policies/application_policy.rb +10 -1
  204. data/examples/simple-poller/app/views/components.rb +4 -6
  205. data/examples/simple-poller/app/views/components/app.rb +2 -24
  206. data/examples/simple-poller/app/views/layouts/application.html.erb +1 -1
  207. data/examples/simple-poller/bin/bundle +0 -0
  208. data/examples/simple-poller/bin/rails +0 -0
  209. data/examples/simple-poller/bin/rake +0 -0
  210. data/examples/simple-poller/bin/setup +0 -0
  211. data/examples/simple-poller/bin/spring +0 -0
  212. data/examples/simple-poller/bin/update +0 -0
  213. data/examples/simple-poller/config/application.rb +1 -1
  214. data/examples/simple-poller/config/environments/development.rb +13 -1
  215. data/examples/simple-poller/config/environments/production.rb +1 -1
  216. data/examples/simple-poller/config/initializers/hyper_mesh.rb +9 -0
  217. data/examples/simple-poller/config/initializers/session_store.rb +1 -1
  218. data/examples/simple-poller/config/routes.rb +1 -1
  219. data/examples/simple-poller/config/secrets.yml +2 -2
  220. data/examples/simple-poller/db/migrate/20161114213840_create_words.rb +9 -0
  221. data/examples/simple-poller/db/schema.rb +14 -1
  222. data/lib/hypermesh/version.rb +1 -1
  223. data/lib/reactive_record/active_record/reactive_record/dummy_value.rb +2 -0
  224. data/spec/synchromesh/{connection_spec.rb → unit_tests/connection_spec.rb} +0 -0
  225. data/spec/synchromesh/unit_tests/dummy_value_spec.rb +26 -0
  226. metadata +184 -20
  227. data/examples/action-cable/config/initializers/synchromesh.rb +0 -5
  228. data/examples/action-cable/rails_cache_dir2/C91/480/synchromesh_active_connections +0 -0
  229. data/examples/simple-poller/app/helpers/application_helper.rb +0 -2
  230. data/examples/simple-poller/app/jobs/application_job.rb +0 -2
  231. data/examples/simple-poller/app/mailers/application_mailer.rb +0 -4
  232. data/examples/simple-poller/config/cable.yml +0 -9
  233. data/examples/simple-poller/config/initializers/synchromesh.rb +0 -15
  234. data/hyper-mesh-0.4.0.gem +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ed2a9b3886af2207f09a5e8ce3db7cb0383c2617
4
- data.tar.gz: 3aacee91de89e22c2279324f4fc4e8ae91eb658d
3
+ metadata.gz: 06482f0ee34e8ee178f10efe5c5425a8fa0268fe
4
+ data.tar.gz: f8588709cf6970fae4b300418925533757421286
5
5
  SHA512:
6
- metadata.gz: 029224667501009cc0e60988b14bbdfda286fa2f06ebf2f0d4ff78a07035925054724481dc538e0028b0a5952343f77f124ef463af3ad590d60bdab776bc621c
7
- data.tar.gz: 2997bb5b724ded7d1ebbef695385161d49a75c52e86b9a1803e11e2c7dd04dcb4fad07fef5c94c0e0cbe6d09b83d020df3d942571d073f596aaa80abeb648e2c
6
+ metadata.gz: 4e34b870273c9e7dbaba3bc8788bd45e27cee418f272ec65957292656bfa76e51933d0e8bcf49ab178d93f5ba3dee8de36ead41229b3806f774494e8b9223eb9
7
+ data.tar.gz: ea01368f7c042bde2b004b17fa462829b2cfd6cd39d83c8542b50c3555a0f0eaaa62e4f47dd3f2c776848dfdf0e3f22020adc032ac71cbf6374a205a8c836484
data/README.md CHANGED
@@ -63,7 +63,14 @@ class WordOfTheDay < React::Component::Base
63
63
  BUTTON { 'pick another' }.on(:click) { pick_entry! }
64
64
  end
65
65
  end
66
- ```
66
+ ```
67
+
68
+ For more complete examples with *push* updates checkout any of the apps in the `examples` directory, or build your own in 5 minutes following one of the quickstart guides:
69
+
70
+ + [Rails 5 with ActionCable](/docs/action_cable_quickstart.md)
71
+ + [Using Pusher.com](/docs/pusher_quickstart.md)
72
+ + [Using Pusher-Faker](/docs/pusher_quickstart.md)
73
+ + [Using Simple Polling](/docs/simple_poller_quickstart.md)
67
74
 
68
75
  ## Basic Installation and Setup
69
76
 
@@ -95,19 +102,18 @@ After restarting, and reloading your browsers you will see changes broadcast to
95
102
 
96
103
  For setting up the other possible transports following one of these guides:
97
104
 
98
- The easiest way to setup a true push transport is to use the Pusher-Fake gem. Get started with this [guide.](docs/pusher_faker_quickstart.md)
105
+ + [Rails 5 with ActionCable](/docs/action_cable_quickstart.md)
106
+ + [Using Pusher.com](/docs/pusher_quickstart.md)
107
+ + [Using Pusher-Faker](/docs/pusher_quickstart.md)
108
+ + [Using Simple Polling](/docs/simple_poller_quickstart.md)
99
109
 
100
- or if you are already using Pusher follow this [guide.](docs/pusher_quickstart.md)
110
+ ## Advanced Configuration
101
111
 
102
- or if you are on Rails 5, and want to use ActionCable follow this [guide.](docs/action_cable_quickstart.md)
103
-
104
- ## Basic Configuration
105
-
106
- For complete details on configuration settings go [here](/docs/configuration_details.md)
112
+ The above guides will work in most cases, but for complete details on configuration settings go [here](/docs/configuration_details.md)
107
113
 
108
114
  ## ActiveRecord API
109
115
 
110
- HyperMesh uses a large subset of the ActiveRecord API modified only when necessary to accommodate the asynchronous nature of the client.
116
+ HyperMesh uses a large subset of the ActiveRecord API modified only when necessary to accommodate the asynchronous nature of the client. You can access your ActiveRecord models just like you would in models, controllers, or in ERB or HAML view templates.
111
117
 
112
118
  See this [guide](/docs/activerecord_api.md) for details.
113
119
 
@@ -115,7 +121,7 @@ See this [guide](/docs/activerecord_api.md) for details.
115
121
 
116
122
  ## Client Side Scoping
117
123
 
118
- By default scopes will be recalculated on the server. To offload this to the client HyperMesh adds some features to the `ActiveRecord` `scope` method. Details [here.](docs/client_side_scoping.md)
124
+ By default scopes will be recalculated on the server. For simple scopes that do not use joins or includes no additional action needs to be taken to make scopes work with HyperMesh. For scopes that do use joins, or if you want to offload the scoping computation from the server to the client read more [here.](docs/client_side_scoping.md)
119
125
 
120
126
  ## Authorization
121
127
 
@@ -141,7 +147,7 @@ this results in an error like this:
141
147
  Exception raised while rendering #<TopLevelRailsComponent:0x53e>
142
148
  ReferenceError: Pusher is not defined
143
149
  ```
144
- To resolve make sure you `require 'pusher'` in your application.js file if using pusher.
150
+ To resolve make sure you `require 'pusher'` in your application.js file if using pusher. **DO NOT** require pusher from your components manifest as this will cause prerendering to fail.
145
151
 
146
152
  - No create/update/destroy policies
147
153
  You must explicitly allow changes to the models to be made by the client. If you don't you will
@@ -177,11 +183,11 @@ You are still referencing the old reactive-ruby or reactrb gems either directly
177
183
 
178
184
  Sometimes you need to figure out what connections are available, or what attributes are readable etc.
179
185
 
180
- Its all to do with your policies, but perhaps you just need a little investigation.
186
+ Its usually all to do with your policies, but perhaps you just need a little investigation.
181
187
 
182
188
  You can bring up a console within the controller context by browsing `localhost:3000/rr/console`
183
189
 
184
- *Note: change `rr` to wherever you are mounting reactive record in your routes file.*
190
+ *Note: change `rr` to wherever you are mounting HyperMesh in your routes file.*
185
191
 
186
192
  *Note: in rails 4, you will need to add the gem 'web-console' to your development section*
187
193
 
@@ -219,6 +225,8 @@ You can of course simulate server side changes to your models through this conso
219
225
 
220
226
  ## Development
221
227
 
228
+ HyperMesh is the merger of `reactive-record` and `synchromesh` gems. As such a lot of the internal names are still using either ReactiveRecord or Synchromesh module names.
229
+
222
230
  The original `ReactiveRecord` specs were written in opal-rspec. These are being migrated to
223
231
  use server rspec with isomorphic helpers. There are about 170 of the original tests left and to run these you
224
232
 
@@ -31,14 +31,11 @@ If you are already using ActionCable in your app that is fine, as HyperMesh will
31
31
 
32
32
  Otherwise go through the following steps to setup ActionCable.
33
33
 
34
- ##### Make sure the `action_cable` js file in your assets
34
+ ##### Make sure the `action_cable` js file is required in your assets
35
35
 
36
- ```javascript
37
- //app/assets/javascripts/application.js
38
- ...
39
- //= require action_cable
40
- Opal.load('components');
41
- ```
36
+ Typically `app/assets/javascripts/application.js` will finish with a `require_tree .` and this will pull in the `cable.js` file which will pull in `action_cable.js`
37
+
38
+ However at a minimum if `application.js` simply does a `require action_cable` that will be sufficient for HyperMesh.
42
39
 
43
40
  ##### Make sure you have a cable.yml file
44
41
 
@@ -74,6 +71,11 @@ If you don't already have a model to play with, add one now:
74
71
 
75
72
  `bundle exec rake db:migrate`
76
73
 
74
+ Move `app/models/word.rb` to `app/models/public/word.rb` and move
75
+ `app/models/application_record.rb` to `app/models/public/application_record.rb`
76
+
77
+ **Leave** `app/models/model.rb` where it is. This is your models client side manifest file.
78
+
77
79
  Whatever model(s) you will plan to access on the client need to moved to the `app/models/public` directory. This allows reactive-record to build a client side proxy for the models. Models not moved will be completely invisible on the client side.
78
80
 
79
81
  **Important** in rails 5 there is also a base `ApplicationRecord` class, that all other models are built from. This class must be moved to the public directory as well.
@@ -0,0 +1,73 @@
1
+ ## ActiveRecord API
2
+
3
+ HyperMesh uses a subset of the standard ActiveRecord API to give your client side HyperReact components access to your server side models.
4
+
5
+ ### Class Methods
6
+
7
+ `scope` and `default_scope`: HyperMesh adds four new options to these methods: `joins`, `client`, `select` and `server`. The `joins` option provides information on how the scope will be joined with other models. The `client` and `select` options allow scoping to be done on the client side to offload this from the server, and the `server` option is there just for symmetry with the othe options. See the [Client Side Scoping](/docs/client_side_scoping.md) page for more details.
8
+
9
+ ```ruby
10
+ # the scope proc is executed on the server
11
+ scope :active, -> () { where(completed: true) }
12
+
13
+ # if the scope does a join (or include) this must be indicated
14
+ # using the joins: option.
15
+ scope :with_recent_comments,
16
+ -> { joins(:comments).where('comment.created_at >= ?', Time.now-1.week) },
17
+ joins: ['comments'] # or joins: 'comments'
18
+
19
+ # the server side proc can be indicated by the server: option
20
+ # an optional client side proc can be provided to compute the scope
21
+ # locally at the client
22
+ scope :completed,
23
+ server: -> { where(complete: true) }
24
+ client: -> { complete }
25
+ ```
26
+
27
+ `unscoped` and `all`: These builtin scopes work just like standard ActiveRecord.
28
+
29
+ ```ruby
30
+ Word.all.each { |word| LI { word.text }}
31
+ ```
32
+
33
+ `belongs_to, has_many, has_one`: These all work as on the server. However it is important that you fully specify both sides of the relationship. This is not always necessary on the server because ActiveRecord uses the table schema to work things out.
34
+
35
+ ```ruby
36
+ class Todo < ActiveRecord::Base
37
+ belongs_to :assigned_to, class_name: 'User'
38
+ end
39
+
40
+ class User < ActiveRecord::Base
41
+ has_many :todos, foreign_key: 'assigned_to_id'
42
+ end
43
+ ```
44
+
45
+ `composed_of`: You can create aggregate models like ActiveRecord.
46
+
47
+ `column_names`: returns a list of the database columns.
48
+
49
+ `columns_hash`: returns the details of the columns specification. Note that on the server `columns_hash` returns a hash of objects specifying column information. On the client the entire structure is just one big hash of hashes.
50
+
51
+ `abstract_class=`, `abstract_class?`, `primary_key`, `primary_key=`, `inheritance_column`, `inheritance_column=`, `model_name`: All work as on the server. See ActiveRecord documentation for more info.
52
+
53
+ `new`: Takes a hash of attributes and initializes a new unsaved record. The values of any attributes not specified in the hash will be taken from the models default values specified in the `columns_hash`.
54
+
55
+ If new is passed a native javascript object it will be treated as a hash and converted accordingly.
56
+
57
+ `create`: Short hand for `new(...).save`. See the `save` instance method for details on how saving is done.
58
+
59
+ `limit` and `offset`: These builtin scopes behave as they do on the server:
60
+
61
+ ```ruby
62
+ Word.offset(500).limit(20) # get words 500-519
63
+ ```
64
+
65
+ `find`: takes an id and returns the corresponding record.
66
+
67
+ `find_by`: takes single item hash indicating an attribute value pair to find.
68
+
69
+ `find_by_...`: i.e. `find_by_first_name` these will find the first record with a matching attribute.
70
+
71
+ ```ruby
72
+ Word.find_by_text('hello') # short for Word.find_by(text: 'hello')
73
+ ```
@@ -2,15 +2,15 @@
2
2
 
3
3
  When the client receives notification that a record has changed HyperMesh finds the set of currently rendered scopes that might be effected, and requests them to be updated from the server.
4
4
 
5
- On the server scopes are a useful way to structure code. **On the client** scopes are vital as they limit the amount of data loaded, viewed, and updated on the client. Consider a factory floor management system that shows *job* state as work flows through the factory. There may be millions of jobs that a production floor browser is authorized to view, but at any time there are probably only 50 being shown. Using ActiveRecord scopes is the way synchromesh keeps the data requested by the browser limited to a reasonable amount.
5
+ On the server scopes are a useful way to structure code. **On the client** scopes are vital as they limit the amount of data loaded, viewed, and updated on the client. Consider a factory floor management system that shows *job* state as work flows through the factory. There may be millions of jobs that a production floor browser is authorized to view, but at any time there are probably only 50 being shown. Using ActiveRecord scopes is the way HyperMesh keeps the data requested by the browser limited to a reasonable amount.
6
6
 
7
7
  To make scopes work efficiently on the client HyperMesh adds some features to the ActiveRecord `scope` and `default_scope` macros. Note you must use the `scope` macro (and not class methods) for things to work with HyperMesh.
8
8
 
9
9
  The additional features are accessed via the `:joins`, `:client`, and `:select` options.
10
10
 
11
- The `:joins` option tells the synchromesh client which models are joined with the scope. *You must add a `:joins` option if the scope has any data base join operations in it, otherwise if a joined model changes, synchromesh will not know to update the scope.*
11
+ The `:joins` option tells the HyperMesh client which models are joined with the scope. *You must add a `:joins` option if the scope has any data base join operations in it, otherwise if a joined model changes, HyperMesh will not know to update the scope.*
12
12
 
13
- The `:client` option provides the client a way to update scopes without having to contact the server. Unlike the `:joins` option this is an optimization and is not required for scopes to work.
13
+ The `:client` and `:select` options provide the client a way to update scopes without having to contact the server. Unlike the `:joins` option this is an optimization and is not required for scopes to work.
14
14
 
15
15
  ```ruby
16
16
  class Todo < ActiveRecord::Base
@@ -34,7 +34,7 @@ class Todo < ActiveRecord::Base
34
34
  # Now with_recent_comments will be re-evaluated whenever a Todo record, or a Comment
35
35
  # joined with a Todo change.
36
36
 
37
- # Normally whenever synchromesh detects that a scope may be effected by a changed
37
+ # Normally whenever HyperMesh detects that a scope may be effected by a changed
38
38
  # model, it will request the scope be re-evaluated on the server. To offload this
39
39
  # computation to the client provide a client side scope method:
40
40
 
@@ -46,7 +46,7 @@ class Todo < ActiveRecord::Base
46
46
  # The client proc is executed on each candidate record, and if it returns true the record
47
47
  # will be added to the scope.
48
48
 
49
- # Instead of a client proc you can provide a select proc, which will receive the entire,
49
+ # Instead of a client proc you can provide a select proc, which will receive the entire
50
50
  # collection which can then be filtered and sorted.
51
51
 
52
52
  scope :sort_by_created_at,
@@ -1,3 +1,14 @@
1
+ # HyperMesh Configuration
2
+
3
+
4
+ # ![](/work-in-progress-drinking.png) WARNING DOCS AND EXAMPLES ARE BEING REWRITTEN MANY LINKS MAY BE BROKEN STAY TUNED OR CHECK IN AT [![Join the chat at https://gitter.im/reactrb/chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/reactrb/chat?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) FOR MORE INFO
5
+
6
+ There are XXX parts to the HyperMesh configuration:
7
+
8
+ 1. Model classes
9
+ 2. Policies
10
+ 3. Push Transport
11
+
1
12
  ## Installation
2
13
 
3
14
  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.
@@ -1,15 +1,39 @@
1
- ### Pusher-Fake
1
+ ### Pusher-Fake Quickstart
2
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:
3
+ The [Pusher-Fake](https://github.com/tristandunn/pusher-fake) gem will provide a transport using the same protocol as pusher.com. You can use it to locally test an app that will be put into production using pusher.com.
4
+
5
+ #### 1 Add the Pusher, Pusher-Fake and HyperLoop gems to your Rails app
6
+
7
+ - add `gem 'pusher'` to your Gemfile.
8
+ - add `gem 'pusher-fake'` to the development and test sections of your Gemfile.
9
+
10
+ If you have not already installed the `hyper-react` and `hyper-mesh` gems, then do so now using the [hyper-rails](https://github.com/ruby-hyperloop/hyper-rails) gem.
11
+
12
+ - add `gem 'hyper-rails'` to your gem file (in the development section)
13
+ - run `bundle install`
14
+ - run `rails g hyperloop:install --all` (make sure to use the --all option)
15
+ - run `bundle update`
16
+
17
+ #### 2 Add the pusher js file to your application.js file
5
18
 
6
19
  ```ruby
7
- # typically config/initializers/HyperMesh.rb
20
+ # app/assets/javascript/application.js
21
+ ...
22
+ //= require 'hyper-mesh/pusher'
23
+ //= require_tree .
24
+ Opal.load('components');
25
+ ```
26
+
27
+ #### 3 Set the transport
28
+
29
+ Once you have HyperMesh, and pusher installed then add this initializer:
30
+ ```ruby
31
+ # typically app/config/initializers/HyperMesh.rb
8
32
  # or you can do a similar setup in your tests (see this gem's specs)
9
33
  require 'pusher'
10
34
  require 'pusher-fake'
11
- # The app_id, key, and secret need to be assigned directly to Pusher
12
- # so PusherFake will work.
35
+ # Assign any values to the Pusher app_id, key, and secret config values.
36
+ # These can be fake values or the real values for your pusher account.
13
37
  Pusher.app_id = "MY_TEST_ID" # you use the real or fake values
14
38
  Pusher.key = "MY_TEST_KEY"
15
39
  Pusher.secret = "MY_TEST_SECRET"
@@ -26,3 +50,68 @@ HyperMesh.configuration do |config|
26
50
  }.merge(PusherFake.configuration.web_options)
27
51
  end
28
52
  ```
53
+
54
+ #### 4 Try It Out
55
+
56
+ If you don't already have a model to play with, add one now:
57
+
58
+ `bundle exec rails generate model Word text:string`
59
+
60
+ `bundle exec rake db:migrate`
61
+
62
+ Move `app/models/word.rb` to `app/models/public/word.rb`
63
+
64
+ **Leave** `app/models/model.rb` where it is. This is your models client side manifest file.
65
+
66
+ Whatever model(s) you will plan to access on the client need to moved to the `app/models/public` directory. This allows reactive-record to build a client side proxy for the models. Models not moved will be completely invisible on the client side.
67
+
68
+ **Important** in rails 5 there is also a base `ApplicationRecord` class, that all other models are built from. This class must be moved to the public directory as well.
69
+
70
+ If you don't already have a component to play with, here is a simple one (make sure you added the Word model):
71
+
72
+ ```ruby
73
+ # app/views/components/app.rb
74
+ class App < React::Component::Base
75
+
76
+ def add_new_word
77
+ # for fun we will use setgetgo.com to get random words!
78
+ HTTP.get("http://randomword.setgetgo.com/get.php", dataType: :jsonp) do |response|
79
+ Word.new(text: response.json[:Word]).save
80
+ end
81
+ end
82
+
83
+ render(DIV) do
84
+ SPAN { "Count of Words: #{Word.count}" }
85
+ BUTTON { "add another" }.on(:click) { add_new_word }
86
+ UL do
87
+ Word.each { |word| LI { word.text } }
88
+ end
89
+ end
90
+ end
91
+ ```
92
+
93
+ Add a controller:
94
+
95
+ ```ruby
96
+ #app/controllers/test_controller.rb
97
+ class TestController < ApplicationController
98
+ def app
99
+ render_component
100
+ end
101
+ end
102
+ ```
103
+
104
+ Add the `test` route to your routes file:
105
+
106
+ ```ruby
107
+ #app/config/routes.rb
108
+
109
+ get 'test', to: 'test#app'
110
+
111
+ ```
112
+
113
+ Fire up rails with `bundle exec rails s` and open your app in a couple of browsers. As data changes you should see them all updating together.
114
+
115
+ You can also fire up a rails console, and then for example do a `Word.new(text: "Hello").save` and again see any browsers updating.
116
+
117
+ If you want to go into more details with the example check out [words-example](/docs/words-example.md)
@@ -1,17 +1,105 @@
1
- ### Pusher Configuration
1
+ ### PusherQuickstart
2
2
 
3
- Add `gem 'pusher'` to your gem file, and add `//= require 'HyperMesh/pusher'` to your application.js file.
3
+ [Pusher.com](https://pusher.com/) provides a production ready push transport for your App. You can combine this with [Pusher-Fake](/docs/pusher_faker_quickstart.md) for local testing as well. You can get a free pusher account and API keys at [https://pusher.com](https://pusher.com)
4
+
5
+ #### 1 Add the Pusher and HyperLoop gems to your Rails app
6
+
7
+ - add `gem 'pusher'` to your Gemfile.
8
+
9
+ If you have not already installed the `hyper-react` and `hyper-mesh` gems, then do so now using the [hyper-rails](https://github.com/ruby-hyperloop/hyper-rails) gem.
10
+
11
+ - add `gem 'hyper-rails'` to your gem file (in the development section)
12
+ - run `bundle install`
13
+ - run `rails g hyperloop:install --all` (make sure to use the --all option)
14
+ - run `bundle update`
15
+
16
+ #### 2 Add the pusher js file to your application.js file
4
17
 
5
18
  ```ruby
6
- # typically config/initializers/HyperMesh.rb
19
+ # app/assets/javascript/application.js
20
+ ...
21
+ //= require 'hyper-mesh/pusher'
22
+ //= require_tree .
23
+ Opal.load('components');
24
+ ```
25
+
26
+ #### 3 Set the transport
27
+
28
+ Once you have HyperMesh and pusher installed then add this initializer:
29
+ ```ruby
30
+ # config/initializers/HyperMesh.rb
7
31
  HyperMesh.configuration do |config|
8
32
  config.transport = :pusher
33
+ config.channel_prefix = "HyperMesh"
9
34
  config.opts = {
10
- app_id: '2xxxx2',
11
- key: 'dxxxxxxxxxxxxxxxxxx9',
12
- secret: '2xxxxxxxxxxxxxxxxxx2',
13
- encrypted: false # optional defaults to true
35
+ app_id: "2....9",
36
+ key: "f.....g",
37
+ secret: "1.......3"
14
38
  }
15
- config.channel_prefix = 'syncromesh' # or any other string you want
16
39
  end
17
40
  ```
41
+
42
+ #### 4 Try It Out
43
+
44
+ If you don't already have a model to play with, add one now:
45
+
46
+ `bundle exec rails generate model Word text:string`
47
+
48
+ `bundle exec rake db:migrate`
49
+
50
+ Move `app/models/word.rb` to `app/models/public/word.rb`
51
+
52
+ **Leave** `app/models/model.rb` where it is. This is your models client side manifest file.
53
+
54
+ Whatever model(s) you will plan to access on the client need to moved to the `app/models/public` directory. This allows reactive-record to build a client side proxy for the models. Models not moved will be completely invisible on the client side.
55
+
56
+ **Important** in rails 5 there is also a base `ApplicationRecord` class, that all other models are built from. This class must be moved to the public directory as well.
57
+
58
+ If you don't already have a component to play with, here is a simple one (make sure you added the Word model):
59
+
60
+ ```ruby
61
+ # app/views/components/app.rb
62
+ class App < React::Component::Base
63
+
64
+ def add_new_word
65
+ # for fun we will use setgetgo.com to get random words!
66
+ HTTP.get("http://randomword.setgetgo.com/get.php", dataType: :jsonp) do |response|
67
+ Word.new(text: response.json[:Word]).save
68
+ end
69
+ end
70
+
71
+ render(DIV) do
72
+ SPAN { "Count of Words: #{Word.count}" }
73
+ BUTTON { "add another" }.on(:click) { add_new_word }
74
+ UL do
75
+ Word.each { |word| LI { word.text } }
76
+ end
77
+ end
78
+ end
79
+ ```
80
+
81
+ Add a controller:
82
+
83
+ ```ruby
84
+ #app/controllers/test_controller.rb
85
+ class TestController < ApplicationController
86
+ def app
87
+ render_component
88
+ end
89
+ end
90
+ ```
91
+
92
+ Add the `test` route to your routes file:
93
+
94
+ ```ruby
95
+ #app/config/routes.rb
96
+
97
+ get 'test', to: 'test#app'
98
+
99
+ ```
100
+
101
+ Fire up rails with `bundle exec rails s` and open your app in a couple of browsers. As data changes you should see them all updating together.
102
+
103
+ You can also fire up a rails console, and then for example do a `Word.new(text: "Hello").save` and again see any browsers updating.
104
+
105
+ If you want to go into more details with the example check out [words-example](/docs/words-example.md)