cable_ready 5.0.0.pre1 → 5.0.0.pre5

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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -0
  3. data/Gemfile.lock +106 -98
  4. data/README.md +6 -2
  5. data/app/helpers/cable_ready_helper.rb +15 -2
  6. data/app/models/concerns/cable_ready/updatable/collection_updatable_callbacks.rb +19 -0
  7. data/app/models/concerns/cable_ready/updatable/collections_registry.rb +33 -0
  8. data/app/models/concerns/cable_ready/updatable/model_updatable_callbacks.rb +28 -0
  9. data/app/models/concerns/cable_ready/updatable.rb +98 -0
  10. data/app/models/concerns/extend_has_many.rb +13 -0
  11. data/lib/cable_ready/channels.rb +1 -1
  12. data/lib/cable_ready/compoundable.rb +1 -1
  13. data/lib/cable_ready/config.rb +2 -0
  14. data/lib/cable_ready/identifiable.rb +13 -2
  15. data/lib/cable_ready/operation_builder.rb +25 -14
  16. data/lib/cable_ready/sanity_checker.rb +50 -50
  17. data/lib/cable_ready/version.rb +1 -1
  18. data/lib/cable_ready.rb +3 -0
  19. data/lib/generators/cable_ready/{stream_from_generator.rb → helpers_generator.rb} +1 -1
  20. data/test/dummy/app/channels/application_cable/channel.rb +4 -0
  21. data/test/dummy/app/channels/application_cable/connection.rb +4 -0
  22. data/test/dummy/app/controllers/application_controller.rb +2 -0
  23. data/test/dummy/app/helpers/application_helper.rb +2 -0
  24. data/test/dummy/app/jobs/application_job.rb +7 -0
  25. data/test/dummy/app/mailers/application_mailer.rb +4 -0
  26. data/test/dummy/app/models/application_record.rb +3 -0
  27. data/test/dummy/app/models/global_idable_entity.rb +16 -0
  28. data/test/dummy/app/models/post.rb +4 -0
  29. data/test/dummy/app/models/section.rb +6 -0
  30. data/test/dummy/app/models/team.rb +6 -0
  31. data/test/dummy/app/models/topic.rb +4 -0
  32. data/test/dummy/app/models/user.rb +7 -0
  33. data/test/dummy/config/application.rb +22 -0
  34. data/test/dummy/config/boot.rb +5 -0
  35. data/test/dummy/config/environment.rb +5 -0
  36. data/test/dummy/config/environments/development.rb +76 -0
  37. data/test/dummy/config/environments/production.rb +120 -0
  38. data/test/dummy/config/environments/test.rb +59 -0
  39. data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
  40. data/test/dummy/config/initializers/assets.rb +12 -0
  41. data/test/dummy/config/initializers/backtrace_silencers.rb +8 -0
  42. data/test/dummy/config/initializers/cable_ready.rb +18 -0
  43. data/test/dummy/config/initializers/content_security_policy.rb +28 -0
  44. data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
  45. data/test/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  46. data/test/dummy/config/initializers/inflections.rb +16 -0
  47. data/test/dummy/config/initializers/mime_types.rb +4 -0
  48. data/test/dummy/config/initializers/permissions_policy.rb +11 -0
  49. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  50. data/test/dummy/config/puma.rb +43 -0
  51. data/test/dummy/config/routes.rb +3 -0
  52. data/test/dummy/db/migrate/20210902154139_create_users.rb +9 -0
  53. data/test/dummy/db/migrate/20210902154153_create_posts.rb +10 -0
  54. data/test/dummy/db/migrate/20210904081930_create_topics.rb +9 -0
  55. data/test/dummy/db/migrate/20210904093607_create_sections.rb +9 -0
  56. data/test/dummy/db/migrate/20210913191735_create_teams.rb +8 -0
  57. data/test/dummy/db/migrate/20210913191759_add_team_reference_to_users.rb +5 -0
  58. data/test/dummy/db/schema.rb +49 -0
  59. data/test/dummy/test/models/post_test.rb +7 -0
  60. data/test/dummy/test/models/section_test.rb +7 -0
  61. data/test/dummy/test/models/team_test.rb +7 -0
  62. data/test/dummy/test/models/topic_test.rb +7 -0
  63. data/test/dummy/test/models/user_test.rb +7 -0
  64. data/test/lib/cable_ready/cable_car_test.rb +25 -3
  65. data/test/lib/cable_ready/compoundable_test.rb +26 -0
  66. data/test/lib/cable_ready/helper_test.rb +25 -0
  67. data/test/lib/cable_ready/identifiable_test.rb +0 -6
  68. data/test/lib/cable_ready/operation_builder_test.rb +89 -28
  69. data/test/lib/cable_ready/updatable_test.rb +112 -0
  70. data/test/test_helper.rb +4 -1
  71. metadata +116 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1ea5fbe24e4f1b83076638efc0d58b4e988d7574bae4a87b118a082626a1c97b
4
- data.tar.gz: d4596c2299625e8982798a05fd49802328da88d19bb677f69173537b3cf0df93
3
+ metadata.gz: b9dba59f8450904ff70bffab769a99afa0b3c3dbbd10b4c57d6c90944a4597db
4
+ data.tar.gz: b343f3606f71d8172ca425a00f5006f1276b6b70ee4d121fbdc4fffa709f2ae6
5
5
  SHA512:
6
- metadata.gz: c283ad94d23983f2acdd5cdc008fa05d8ea89710b3022291378407664a3bb9a48423baa5b2bf3a29de0f96633f2591e854366520b180f80dabbe6d8ae021cf16
7
- data.tar.gz: ef3d75827a0e2774eb130dde7d56eea234f3dc515652e74800dc785e8327fad9d2619092a7fd5040dbe2095772e9b11d357fccde00eefa31cf40bfa27d8df5c1
6
+ metadata.gz: ccf966496f825c9294caba3c14b9e8a08b5abd9825dcba64b815131546bc3ba29f8200fa100aab5f709ad28bfd14ce826126f1be55a2e7362a8fa6a5240efeb3
7
+ data.tar.gz: 0c40edd97c070f8517ed0e467d312fb9040079d8009acee514a55b29675dfd220cdd9a58c5243575790b800281c62f60c4baafa4c0d8e0f9a3ea1e15ba8095c3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,50 @@
1
1
  # Changelog
2
2
 
3
+ ## [v5.0.0.pre3](https://github.com/stimulusreflex/cable_ready/tree/v5.0.0.pre3) (2021-08-22)
4
+
5
+ [Full Changelog](https://github.com/stimulusreflex/cable_ready/compare/v5.0.0.pre2...v5.0.0.pre3)
6
+
7
+ **Implemented enhancements:**
8
+
9
+ - redirect\_to operation [\#144](https://github.com/stimulusreflex/cable_ready/pull/144) ([leastbad](https://github.com/leastbad))
10
+ - RFC simplifed JSON payload + named batches [\#142](https://github.com/stimulusreflex/cable_ready/pull/142) ([leastbad](https://github.com/leastbad))
11
+
12
+ **Merged pull requests:**
13
+
14
+ - Bump path-parse from 1.0.6 to 1.0.7 [\#143](https://github.com/stimulusreflex/cable_ready/pull/143) ([dependabot[bot]](https://github.com/apps/dependabot))
15
+
16
+ ## [v5.0.0.pre2](https://github.com/stimulusreflex/cable_ready/tree/v5.0.0.pre2) (2021-07-21)
17
+
18
+ [Full Changelog](https://github.com/stimulusreflex/cable_ready/compare/v5.0.0.pre1...v5.0.0.pre2)
19
+
20
+ **Implemented enhancements:**
21
+
22
+ - register a CableReady JSON MIME type [\#140](https://github.com/stimulusreflex/cable_ready/pull/140) ([existentialmutt](https://github.com/existentialmutt))
23
+ - Smart options \(they grow up so fast\) [\#136](https://github.com/stimulusreflex/cable_ready/pull/136) ([leastbad](https://github.com/leastbad))
24
+ - Support `to_dom_selector` for operation selectors [\#135](https://github.com/stimulusreflex/cable_ready/pull/135) ([jaredcwhite](https://github.com/jaredcwhite))
25
+ - dom\_id should always be lowercase [\#129](https://github.com/stimulusreflex/cable_ready/pull/129) ([leastbad](https://github.com/leastbad))
26
+
27
+ **Fixed bugs:**
28
+
29
+ - Improve install experience [\#128](https://github.com/stimulusreflex/cable_ready/pull/128) ([leastbad](https://github.com/leastbad))
30
+
31
+ **Closed issues:**
32
+
33
+ - Idea: ability to pass any object which responds to `to_dom_selector` as a selector [\#134](https://github.com/stimulusreflex/cable_ready/issues/134)
34
+
35
+ **Merged pull requests:**
36
+
37
+ - Bump addressable from 2.7.0 to 2.8.0 [\#141](https://github.com/stimulusreflex/cable_ready/pull/141) ([dependabot[bot]](https://github.com/apps/dependabot))
38
+ - chore: make webpack happy with no sideEffects [\#138](https://github.com/stimulusreflex/cable_ready/pull/138) ([ParamagicDev](https://github.com/ParamagicDev))
39
+
40
+ ## [v5.0.0.pre1](https://github.com/stimulusreflex/cable_ready/tree/v5.0.0.pre1) (2021-06-02)
41
+
42
+ [Full Changelog](https://github.com/stimulusreflex/cable_ready/compare/v5.0.0.pre0...v5.0.0.pre1)
43
+
44
+ **Merged pull requests:**
45
+
46
+ - Include app folder in release [\#133](https://github.com/stimulusreflex/cable_ready/pull/133) ([julianrubisch](https://github.com/julianrubisch))
47
+
3
48
  ## [v5.0.0.pre0](https://github.com/stimulusreflex/cable_ready/tree/v5.0.0.pre0) (2021-05-20)
4
49
 
5
50
  [Full Changelog](https://github.com/stimulusreflex/cable_ready/compare/v4.5.0...v5.0.0.pre0)
data/Gemfile.lock CHANGED
@@ -1,113 +1,123 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cable_ready (5.0.0.pre0)
4
+ cable_ready (5.0.0.pre5)
5
5
  rails (>= 5.2)
6
6
  thread-local (>= 1.1.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- actioncable (6.1.3.2)
12
- actionpack (= 6.1.3.2)
13
- activesupport (= 6.1.3.2)
11
+ actioncable (6.1.4.1)
12
+ actionpack (= 6.1.4.1)
13
+ activesupport (= 6.1.4.1)
14
14
  nio4r (~> 2.0)
15
15
  websocket-driver (>= 0.6.1)
16
- actionmailbox (6.1.3.2)
17
- actionpack (= 6.1.3.2)
18
- activejob (= 6.1.3.2)
19
- activerecord (= 6.1.3.2)
20
- activestorage (= 6.1.3.2)
21
- activesupport (= 6.1.3.2)
16
+ actionmailbox (6.1.4.1)
17
+ actionpack (= 6.1.4.1)
18
+ activejob (= 6.1.4.1)
19
+ activerecord (= 6.1.4.1)
20
+ activestorage (= 6.1.4.1)
21
+ activesupport (= 6.1.4.1)
22
22
  mail (>= 2.7.1)
23
- actionmailer (6.1.3.2)
24
- actionpack (= 6.1.3.2)
25
- actionview (= 6.1.3.2)
26
- activejob (= 6.1.3.2)
27
- activesupport (= 6.1.3.2)
23
+ actionmailer (6.1.4.1)
24
+ actionpack (= 6.1.4.1)
25
+ actionview (= 6.1.4.1)
26
+ activejob (= 6.1.4.1)
27
+ activesupport (= 6.1.4.1)
28
28
  mail (~> 2.5, >= 2.5.4)
29
29
  rails-dom-testing (~> 2.0)
30
- actionpack (6.1.3.2)
31
- actionview (= 6.1.3.2)
32
- activesupport (= 6.1.3.2)
30
+ actionpack (6.1.4.1)
31
+ actionview (= 6.1.4.1)
32
+ activesupport (= 6.1.4.1)
33
33
  rack (~> 2.0, >= 2.0.9)
34
34
  rack-test (>= 0.6.3)
35
35
  rails-dom-testing (~> 2.0)
36
36
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
37
- actiontext (6.1.3.2)
38
- actionpack (= 6.1.3.2)
39
- activerecord (= 6.1.3.2)
40
- activestorage (= 6.1.3.2)
41
- activesupport (= 6.1.3.2)
37
+ actiontext (6.1.4.1)
38
+ actionpack (= 6.1.4.1)
39
+ activerecord (= 6.1.4.1)
40
+ activestorage (= 6.1.4.1)
41
+ activesupport (= 6.1.4.1)
42
42
  nokogiri (>= 1.8.5)
43
- actionview (6.1.3.2)
44
- activesupport (= 6.1.3.2)
43
+ actionview (6.1.4.1)
44
+ activesupport (= 6.1.4.1)
45
45
  builder (~> 3.1)
46
46
  erubi (~> 1.4)
47
47
  rails-dom-testing (~> 2.0)
48
48
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
49
- activejob (6.1.3.2)
50
- activesupport (= 6.1.3.2)
49
+ activejob (6.1.4.1)
50
+ activesupport (= 6.1.4.1)
51
51
  globalid (>= 0.3.6)
52
- activemodel (6.1.3.2)
53
- activesupport (= 6.1.3.2)
54
- activerecord (6.1.3.2)
55
- activemodel (= 6.1.3.2)
56
- activesupport (= 6.1.3.2)
57
- activestorage (6.1.3.2)
58
- actionpack (= 6.1.3.2)
59
- activejob (= 6.1.3.2)
60
- activerecord (= 6.1.3.2)
61
- activesupport (= 6.1.3.2)
52
+ activemodel (6.1.4.1)
53
+ activesupport (= 6.1.4.1)
54
+ activerecord (6.1.4.1)
55
+ activemodel (= 6.1.4.1)
56
+ activesupport (= 6.1.4.1)
57
+ activestorage (6.1.4.1)
58
+ actionpack (= 6.1.4.1)
59
+ activejob (= 6.1.4.1)
60
+ activerecord (= 6.1.4.1)
61
+ activesupport (= 6.1.4.1)
62
62
  marcel (~> 1.0.0)
63
- mini_mime (~> 1.0.2)
64
- activesupport (6.1.3.2)
63
+ mini_mime (>= 1.1.0)
64
+ activesupport (6.1.4.1)
65
65
  concurrent-ruby (~> 1.0, >= 1.0.2)
66
66
  i18n (>= 1.6, < 2)
67
67
  minitest (>= 5.1)
68
68
  tzinfo (~> 2.0)
69
69
  zeitwerk (~> 2.3)
70
- addressable (2.7.0)
70
+ addressable (2.8.0)
71
71
  public_suffix (>= 2.0.2, < 5.0)
72
72
  ast (2.4.2)
73
- async (1.29.0)
73
+ async (1.30.1)
74
74
  console (~> 1.10)
75
75
  nio4r (~> 2.3)
76
76
  timers (~> 4.1)
77
- async-http (0.56.2)
78
- async (~> 1.25)
79
- async-io (~> 1.28)
80
- async-pool (~> 0.2)
77
+ async-http (0.56.5)
78
+ async (>= 1.25)
79
+ async-io (>= 1.28)
80
+ async-pool (>= 0.2)
81
81
  protocol-http (~> 0.22.0)
82
82
  protocol-http1 (~> 0.14.0)
83
83
  protocol-http2 (~> 0.14.0)
84
- async-http-faraday (0.9.0)
84
+ async-http-faraday (0.11.0)
85
85
  async-http (~> 0.42)
86
86
  faraday
87
- async-io (1.31.0)
88
- async (~> 1.14)
89
- async-pool (0.3.6)
90
- async (~> 1.25)
87
+ async-io (1.32.2)
88
+ async
89
+ async-pool (0.3.8)
90
+ async (>= 1.25)
91
91
  builder (3.2.4)
92
92
  coderay (1.1.3)
93
- concurrent-ruby (1.1.8)
94
- console (1.12.0)
93
+ concurrent-ruby (1.1.9)
94
+ console (1.13.1)
95
95
  fiber-local
96
96
  crass (1.0.6)
97
97
  erubi (1.10.0)
98
- faraday (1.4.1)
98
+ faraday (1.7.0)
99
+ faraday-em_http (~> 1.0)
100
+ faraday-em_synchrony (~> 1.0)
99
101
  faraday-excon (~> 1.1)
102
+ faraday-httpclient (~> 1.0.1)
100
103
  faraday-net_http (~> 1.0)
101
104
  faraday-net_http_persistent (~> 1.1)
105
+ faraday-patron (~> 1.0)
106
+ faraday-rack (~> 1.0)
102
107
  multipart-post (>= 1.2, < 3)
103
108
  ruby2_keywords (>= 0.0.4)
109
+ faraday-em_http (1.0.0)
110
+ faraday-em_synchrony (1.0.0)
104
111
  faraday-excon (1.1.0)
105
112
  faraday-http-cache (2.2.0)
106
113
  faraday (>= 0.8)
114
+ faraday-httpclient (1.0.1)
107
115
  faraday-net_http (1.0.1)
108
- faraday-net_http_persistent (1.1.0)
116
+ faraday-net_http_persistent (1.2.0)
117
+ faraday-patron (1.0.0)
118
+ faraday-rack (1.0.0)
109
119
  fiber-local (1.0.0)
110
- github_changelog_generator (1.16.3)
120
+ github_changelog_generator (1.16.4)
111
121
  activesupport
112
122
  async (>= 1.25.0)
113
123
  async-http-faraday
@@ -116,37 +126,34 @@ GEM
116
126
  octokit (~> 4.6)
117
127
  rainbow (>= 2.2.1)
118
128
  rake (>= 10.0)
119
- retriable (~> 3.0)
120
- globalid (0.4.2)
121
- activesupport (>= 4.2.0)
129
+ globalid (0.5.2)
130
+ activesupport (>= 5.0)
122
131
  i18n (1.8.10)
123
132
  concurrent-ruby (~> 1.0)
124
- loofah (2.9.1)
133
+ loofah (2.12.0)
125
134
  crass (~> 1.0.2)
126
135
  nokogiri (>= 1.5.9)
127
136
  magic_frozen_string_literal (1.2.0)
128
137
  mail (2.7.1)
129
138
  mini_mime (>= 0.1.1)
130
- marcel (1.0.1)
139
+ marcel (1.0.2)
131
140
  method_source (0.9.2)
132
- mini_mime (1.0.3)
133
- mini_portile2 (2.5.1)
141
+ mini_mime (1.1.1)
134
142
  minitest (5.14.4)
135
- mocha (1.12.0)
143
+ mocha (1.13.0)
136
144
  multi_json (1.15.0)
137
145
  multipart-post (2.1.1)
138
- nio4r (2.5.7)
139
- nokogiri (1.11.5)
140
- mini_portile2 (~> 2.5.0)
146
+ nio4r (2.5.8)
147
+ nokogiri (1.12.5-x86_64-linux)
141
148
  racc (~> 1.4)
142
149
  octokit (4.21.0)
143
150
  faraday (>= 0.9)
144
151
  sawyer (~> 0.8.0, >= 0.5.3)
145
152
  parallel (1.20.1)
146
- parser (3.0.1.1)
153
+ parser (3.0.2.0)
147
154
  ast (~> 2.4.1)
148
155
  protocol-hpack (1.4.2)
149
- protocol-http (0.22.0)
156
+ protocol-http (0.22.5)
150
157
  protocol-http1 (0.14.1)
151
158
  protocol-http (~> 0.22)
152
159
  protocol-http2 (0.14.2)
@@ -162,53 +169,52 @@ GEM
162
169
  rack (2.2.3)
163
170
  rack-test (1.1.0)
164
171
  rack (>= 1.0, < 3)
165
- rails (6.1.3.2)
166
- actioncable (= 6.1.3.2)
167
- actionmailbox (= 6.1.3.2)
168
- actionmailer (= 6.1.3.2)
169
- actionpack (= 6.1.3.2)
170
- actiontext (= 6.1.3.2)
171
- actionview (= 6.1.3.2)
172
- activejob (= 6.1.3.2)
173
- activemodel (= 6.1.3.2)
174
- activerecord (= 6.1.3.2)
175
- activestorage (= 6.1.3.2)
176
- activesupport (= 6.1.3.2)
172
+ rails (6.1.4.1)
173
+ actioncable (= 6.1.4.1)
174
+ actionmailbox (= 6.1.4.1)
175
+ actionmailer (= 6.1.4.1)
176
+ actionpack (= 6.1.4.1)
177
+ actiontext (= 6.1.4.1)
178
+ actionview (= 6.1.4.1)
179
+ activejob (= 6.1.4.1)
180
+ activemodel (= 6.1.4.1)
181
+ activerecord (= 6.1.4.1)
182
+ activestorage (= 6.1.4.1)
183
+ activesupport (= 6.1.4.1)
177
184
  bundler (>= 1.15.0)
178
- railties (= 6.1.3.2)
185
+ railties (= 6.1.4.1)
179
186
  sprockets-rails (>= 2.0.0)
180
187
  rails-dom-testing (2.0.3)
181
188
  activesupport (>= 4.2.0)
182
189
  nokogiri (>= 1.6)
183
- rails-html-sanitizer (1.3.0)
190
+ rails-html-sanitizer (1.4.2)
184
191
  loofah (~> 2.3)
185
- railties (6.1.3.2)
186
- actionpack (= 6.1.3.2)
187
- activesupport (= 6.1.3.2)
192
+ railties (6.1.4.1)
193
+ actionpack (= 6.1.4.1)
194
+ activesupport (= 6.1.4.1)
188
195
  method_source
189
- rake (>= 0.8.7)
196
+ rake (>= 0.13)
190
197
  thor (~> 1.0)
191
198
  rainbow (3.0.0)
192
- rake (13.0.3)
199
+ rake (13.0.6)
193
200
  regexp_parser (2.1.1)
194
- retriable (3.1.2)
195
201
  rexml (3.2.5)
196
- rubocop (1.14.0)
202
+ rubocop (1.18.4)
197
203
  parallel (~> 1.10)
198
204
  parser (>= 3.0.0.0)
199
205
  rainbow (>= 2.2.2, < 4.0)
200
206
  regexp_parser (>= 1.8, < 3.0)
201
207
  rexml
202
- rubocop-ast (>= 1.5.0, < 2.0)
208
+ rubocop-ast (>= 1.8.0, < 2.0)
203
209
  ruby-progressbar (~> 1.7)
204
210
  unicode-display_width (>= 1.4.0, < 3.0)
205
- rubocop-ast (1.5.0)
211
+ rubocop-ast (1.10.0)
206
212
  parser (>= 3.0.1.1)
207
- rubocop-performance (1.11.2)
213
+ rubocop-performance (1.11.4)
208
214
  rubocop (>= 1.7.0, < 2.0)
209
215
  rubocop-ast (>= 0.4.0)
210
216
  ruby-progressbar (1.11.0)
211
- ruby2_keywords (0.0.4)
217
+ ruby2_keywords (0.0.5)
212
218
  sawyer (0.8.2)
213
219
  addressable (>= 2.3.5)
214
220
  faraday (> 0.8, < 2.0)
@@ -219,9 +225,10 @@ GEM
219
225
  actionpack (>= 4.0)
220
226
  activesupport (>= 4.0)
221
227
  sprockets (>= 3.0.0)
222
- standard (1.1.1)
223
- rubocop (= 1.14.0)
224
- rubocop-performance (= 1.11.2)
228
+ sqlite3 (1.4.2)
229
+ standard (1.1.7)
230
+ rubocop (= 1.18.4)
231
+ rubocop-performance (= 1.11.4)
225
232
  standardrb (1.0.0)
226
233
  standard
227
234
  thor (1.1.0)
@@ -230,7 +237,7 @@ GEM
230
237
  tzinfo (2.0.4)
231
238
  concurrent-ruby (~> 1.0)
232
239
  unicode-display_width (2.0.0)
233
- websocket-driver (0.7.3)
240
+ websocket-driver (0.7.5)
234
241
  websocket-extensions (>= 0.1.0)
235
242
  websocket-extensions (0.1.5)
236
243
  zeitwerk (2.4.2)
@@ -246,7 +253,8 @@ DEPENDENCIES
246
253
  pry
247
254
  pry-nav
248
255
  rake
256
+ sqlite3
249
257
  standardrb
250
258
 
251
259
  BUNDLED WITH
252
- 2.2.3
260
+ 2.2.19
data/README.md CHANGED
@@ -2,8 +2,12 @@
2
2
  <img src="https://gitcdn.link/repo/stimulusreflex/cable_ready/master/assets/cable-ready-logo-with-copy.svg" width="360" />
3
3
  <h1 align="center">Welcome to CableReady 👋</h1>
4
4
  <p align="center">
5
- <img src="https://img.shields.io/gem/v/cable_ready.svg?color=red" />
6
- <img src="https://img.shields.io/npm/v/cable_ready.svg?color=blue" />
5
+ <a href="https://rubygems.org/gems/cable_ready">
6
+ <img src="https://img.shields.io/gem/v/cable_ready.svg?color=red" />
7
+ </a>
8
+ <a href="https://www.npmjs.com/package/cable_ready">
9
+ <img src="https://img.shields.io/npm/v/cable_ready.svg?color=blue" />
10
+ </a>
7
11
  <a href="https://www.npmjs.com/package/cable_ready">
8
12
  <img alt="downloads" src="https://img.shields.io/npm/dm/cable_ready.svg?color=blue" target="_blank" />
9
13
  </a>
@@ -4,8 +4,21 @@ module CableReadyHelper
4
4
  include CableReady::Compoundable
5
5
  include CableReady::StreamIdentifier
6
6
 
7
- def stream_from(*keys)
7
+ def stream_from(*keys, html_options: {})
8
+ tag.stream_from(**build_options(*keys, html_options))
9
+ end
10
+
11
+ def updates_for(*keys, url: nil, debounce: nil, html_options: {}, &block)
12
+ options = build_options(*keys, html_options)
13
+ options[:url] = url if url
14
+ options[:debounce] = debounce if debounce
15
+ tag.updates_for(**options) { capture(&block) }
16
+ end
17
+
18
+ private
19
+
20
+ def build_options(*keys, html_options)
8
21
  keys.select!(&:itself)
9
- tag.stream_from(identifier: signed_stream_identifier(compound(keys)))
22
+ {identifier: signed_stream_identifier(compound(keys))}.merge(html_options)
10
23
  end
11
24
  end
@@ -0,0 +1,19 @@
1
+ module CableReady
2
+ module Updatable
3
+ class CollectionUpdatableCallbacks
4
+ def initialize(operation)
5
+ @operation = operation
6
+ end
7
+
8
+ def after_commit(model)
9
+ update_collections(model)
10
+ end
11
+
12
+ private
13
+
14
+ def update_collections(model)
15
+ model.class.cable_ready_collections.broadcast_for!(model, @operation)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,33 @@
1
+ module CableReady
2
+ module Updatable
3
+ class CollectionsRegistry
4
+ def initialize
5
+ @registered_collections = []
6
+ end
7
+
8
+ def register(collection)
9
+ @registered_collections << collection
10
+ end
11
+
12
+ def broadcast_for!(model, operation)
13
+ @registered_collections.select { |c| c[:options][:on].include?(operation) }
14
+ .each do |collection|
15
+ resource = find_resource_for_update(collection, model)
16
+ next if resource.nil?
17
+
18
+ collection[:klass].cable_ready_update_collection(resource, collection[:name]) if collection[:options][:if].call(resource)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def find_resource_for_update(collection, model)
25
+ raise ArgumentError, "Could not find inverse_of for #{collection[:name]}" unless collection[:inverse_association]
26
+
27
+ resource = model
28
+ resource = resource.send(collection[:through_association].underscore) if collection[:through_association]
29
+ resource.send(collection[:inverse_association].underscore)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ module CableReady
2
+ module Updatable
3
+ class ModelUpdatableCallbacks
4
+ def initialize(operation, enabled_operations = %i[create update destroy])
5
+ @operation = operation
6
+ @enabled_operations = enabled_operations
7
+ end
8
+
9
+ def after_commit(model)
10
+ return unless @enabled_operations.include?(@operation)
11
+
12
+ send("broadcast_#{@operation}", model)
13
+ end
14
+
15
+ private
16
+
17
+ def broadcast_create(model)
18
+ ActionCable.server.broadcast(model.class, {})
19
+ end
20
+ alias_method :broadcast_destroy, :broadcast_create
21
+
22
+ def broadcast_update(model)
23
+ ActionCable.server.broadcast(model.class, {})
24
+ ActionCable.server.broadcast(model.to_global_id, {})
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CableReady
4
+ module Updatable
5
+ extend ::ActiveSupport::Concern
6
+
7
+ included do |base|
8
+ if base < ActiveRecord::Base
9
+ include ExtendHasMany
10
+
11
+ after_commit CollectionUpdatableCallbacks.new(:create), on: :create
12
+ after_commit CollectionUpdatableCallbacks.new(:update), on: :update
13
+ after_commit CollectionUpdatableCallbacks.new(:destroy), on: :destroy
14
+
15
+ def self.enable_updates(*options)
16
+ options = options.extract_options!
17
+ options = {
18
+ on: [:create, :update, :destroy],
19
+ if: -> { true }
20
+ }.merge(options)
21
+
22
+ enabled_operations = Array(options[:on])
23
+
24
+ after_commit(ModelUpdatableCallbacks.new(:create, enabled_operations), {on: :create, if: options[:if]})
25
+ after_commit(ModelUpdatableCallbacks.new(:update, enabled_operations), {on: :update, if: options[:if]})
26
+ after_commit(ModelUpdatableCallbacks.new(:destroy, enabled_operations), {on: :destroy, if: options[:if]})
27
+ end
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ module ClassMethods
34
+ def has_many(name, scope = nil, **options, &extension)
35
+ option = options.delete(:enable_updates)
36
+ broadcast = option.present?
37
+ result = super
38
+ enrich_association_with_updates(name, option) if broadcast
39
+ result
40
+ end
41
+
42
+ def cable_ready_collections
43
+ @cable_ready_collections ||= CollectionsRegistry.new
44
+ end
45
+
46
+ def cable_ready_update_collection(resource, name)
47
+ identifier = resource.to_global_id.to_s + ":" + name.to_s
48
+ ActionCable.server.broadcast(identifier, {})
49
+ end
50
+
51
+ def enrich_association_with_updates(name, option)
52
+ reflection = reflect_on_association(name)
53
+
54
+ inverse_of = reflection.inverse_of&.name&.to_s
55
+ through_association = nil
56
+
57
+ if reflection.through_reflection?
58
+ inverse_of = reflection.through_reflection.inverse_of&.name&.to_s
59
+ through_association = reflection.through_reflection.name.to_s.singularize
60
+ end
61
+
62
+ options = {
63
+ on: [:create, :update, :destroy],
64
+ if: ->(resource) { true }
65
+ }
66
+
67
+ case option
68
+ when TrueClass
69
+ # proceed!
70
+ when FalseClass
71
+ options[:on] = []
72
+ when Array
73
+ options[:on] = option
74
+ when Symbol
75
+ options[:on] = [option]
76
+ when Hash
77
+ option[:on] = Array(option[:on]) if option[:on]
78
+ options = options.merge!(option)
79
+ when Proc
80
+ options[:if] = option
81
+ else
82
+ raise ArgumentError, "Invalid enable_updates option #{option}"
83
+ end
84
+
85
+ reflection.klass.send(:include, CableReady::Updatable) unless reflection.klass.respond_to?(:cable_ready_collections)
86
+
87
+ reflection.klass.cable_ready_collections.register({
88
+ klass: self,
89
+ foreign_key: reflection.foreign_key,
90
+ name: name,
91
+ inverse_association: inverse_of,
92
+ through_association: through_association,
93
+ options: options
94
+ })
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ExtendHasMany
4
+ extend ::ActiveSupport::Concern
5
+
6
+ class_methods do
7
+ def has_many(*args, &block)
8
+ options = args.extract_options!
9
+ options[:extend] = Array(options[:extend]).push(ClassMethods)
10
+ super(*args, **options, &block)
11
+ end
12
+ end
13
+ end
@@ -13,7 +13,7 @@ module CableReady
13
13
 
14
14
  def [](*keys)
15
15
  keys.select!(&:itself)
16
- identifier = keys.many? || (keys.one? && keys.first.is_a?(ActiveRecord::Base)) ? compound(keys) : keys.pop
16
+ identifier = keys.many? || (keys.one? && keys.first.respond_to?(:to_global_id)) ? compound(keys) : keys.pop
17
17
  @channels[identifier] ||= CableReady::Channel.new(identifier)
18
18
  end
19
19
 
@@ -4,7 +4,7 @@ module CableReady
4
4
  module Compoundable
5
5
  def compound(keys)
6
6
  keys.map { |key|
7
- key.class < ActiveRecord::Base ? key.to_global_id.to_s : key.to_s
7
+ key.respond_to?(:to_global_id) ? key.to_global_id.to_s : key.to_s
8
8
  }.join(":")
9
9
  end
10
10
  end
@@ -54,6 +54,8 @@ module CableReady
54
54
  outer_html
55
55
  prepend
56
56
  push_state
57
+ redirect_to
58
+ reload
57
59
  remove
58
60
  remove_attribute
59
61
  remove_css_class