cable_ready 4.5.0 → 5.0.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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +2 -376
  3. data/Gemfile +4 -1
  4. data/Gemfile.lock +146 -144
  5. data/README.md +54 -20
  6. data/Rakefile +8 -8
  7. data/app/assets/javascripts/cable_ready.js +1269 -0
  8. data/app/assets/javascripts/cable_ready.umd.js +1190 -0
  9. data/app/channels/cable_ready/stream.rb +14 -0
  10. data/app/helpers/cable_ready/view_helper.rb +58 -0
  11. data/app/jobs/cable_ready/broadcast_job.rb +15 -0
  12. data/app/models/concerns/cable_ready/updatable/collection_updatable_callbacks.rb +21 -0
  13. data/app/models/concerns/cable_ready/updatable/collections_registry.rb +59 -0
  14. data/app/models/concerns/cable_ready/updatable/memory_cache_debounce_adapter.rb +24 -0
  15. data/app/models/concerns/cable_ready/updatable/model_updatable_callbacks.rb +33 -0
  16. data/app/models/concerns/cable_ready/updatable.rb +211 -0
  17. data/app/models/concerns/extend_has_many.rb +15 -0
  18. data/bin/standardize +1 -1
  19. data/cable_ready.gemspec +20 -6
  20. data/lib/cable_ready/broadcaster.rb +4 -3
  21. data/lib/cable_ready/cable_car.rb +19 -0
  22. data/lib/cable_ready/channel.rb +29 -31
  23. data/lib/cable_ready/channels.rb +4 -5
  24. data/lib/cable_ready/compoundable.rb +11 -0
  25. data/lib/cable_ready/config.rb +28 -1
  26. data/lib/cable_ready/engine.rb +59 -0
  27. data/lib/cable_ready/identifiable.rb +48 -0
  28. data/lib/cable_ready/importmap.rb +4 -0
  29. data/lib/cable_ready/installer.rb +224 -0
  30. data/lib/cable_ready/operation_builder.rb +80 -0
  31. data/lib/cable_ready/sanity_checker.rb +63 -0
  32. data/lib/cable_ready/stream_identifier.rb +13 -0
  33. data/lib/cable_ready/version.rb +1 -1
  34. data/lib/cable_ready.rb +23 -10
  35. data/lib/cable_ready_helper.rb +13 -0
  36. data/lib/generators/cable_ready/channel_generator.rb +110 -0
  37. data/lib/generators/cable_ready/templates/app/javascript/channels/consumer.js.tt +6 -0
  38. data/lib/generators/cable_ready/templates/app/javascript/channels/index.js.esbuild.tt +4 -0
  39. data/lib/generators/cable_ready/templates/app/javascript/channels/index.js.importmap.tt +2 -0
  40. data/lib/generators/cable_ready/templates/app/javascript/channels/index.js.shakapacker.tt +5 -0
  41. data/lib/generators/cable_ready/templates/app/javascript/channels/index.js.vite.tt +1 -0
  42. data/lib/generators/cable_ready/templates/app/javascript/channels/index.js.webpacker.tt +5 -0
  43. data/lib/generators/cable_ready/templates/app/javascript/config/cable_ready.js.tt +4 -0
  44. data/lib/generators/cable_ready/templates/app/javascript/config/index.js.tt +1 -0
  45. data/lib/generators/cable_ready/templates/app/javascript/config/mrujs.js.tt +9 -0
  46. data/lib/generators/cable_ready/templates/app/javascript/controllers/%file_name%_controller.js.tt +38 -0
  47. data/lib/generators/cable_ready/templates/app/javascript/controllers/application.js.tt +11 -0
  48. data/lib/generators/cable_ready/templates/app/javascript/controllers/index.js.esbuild.tt +7 -0
  49. data/lib/generators/cable_ready/templates/app/javascript/controllers/index.js.importmap.tt +5 -0
  50. data/lib/generators/cable_ready/templates/app/javascript/controllers/index.js.shakapacker.tt +5 -0
  51. data/lib/generators/cable_ready/templates/app/javascript/controllers/index.js.vite.tt +5 -0
  52. data/lib/generators/cable_ready/templates/app/javascript/controllers/index.js.webpacker.tt +5 -0
  53. data/lib/generators/cable_ready/templates/config/initializers/cable_ready.rb +27 -0
  54. data/lib/generators/cable_ready/templates/esbuild.config.mjs.tt +94 -0
  55. data/lib/install/action_cable.rb +144 -0
  56. data/lib/install/broadcaster.rb +109 -0
  57. data/lib/install/bundle.rb +54 -0
  58. data/lib/install/compression.rb +51 -0
  59. data/lib/install/config.rb +39 -0
  60. data/lib/install/development.rb +34 -0
  61. data/lib/install/esbuild.rb +101 -0
  62. data/lib/install/importmap.rb +96 -0
  63. data/lib/install/initializers.rb +15 -0
  64. data/lib/install/mrujs.rb +121 -0
  65. data/lib/install/npm_packages.rb +13 -0
  66. data/lib/install/shakapacker.rb +65 -0
  67. data/lib/install/spring.rb +54 -0
  68. data/lib/install/updatable.rb +34 -0
  69. data/lib/install/vite.rb +66 -0
  70. data/lib/install/webpacker.rb +93 -0
  71. data/lib/install/yarn.rb +56 -0
  72. data/lib/tasks/cable_ready/cable_ready.rake +247 -0
  73. data/package.json +42 -13
  74. data/rollup.config.mjs +57 -0
  75. data/web-test-runner.config.mjs +12 -0
  76. data/yarn.lock +3252 -327
  77. metadata +138 -9
  78. data/tags +0 -62
@@ -11,9 +11,32 @@ module CableReady
11
11
  include Observable
12
12
  include Singleton
13
13
 
14
+ attr_accessor :on_failed_sanity_checks, :broadcast_job_queue, :precompile_assets, :updatable_debounce_time
15
+ attr_writer :verifier_key
16
+
17
+ def on_new_version_available
18
+ warn "NOTICE: The `config.on_new_version_available` option has been removed from the CableReady initializer. You can safely remove this option from your initializer."
19
+ end
20
+
21
+ def on_new_version_available=(_)
22
+ warn "NOTICE: The `config.on_new_version_available` option has been removed from the CableReady initializer. You can safely remove this option from your initializer."
23
+ end
24
+
14
25
  def initialize
15
26
  super
16
27
  @operation_names = Set.new(default_operation_names)
28
+ @on_failed_sanity_checks = :exit
29
+ @broadcast_job_queue = :default
30
+ @precompile_assets = true
31
+ @updatable_debounce_time = 0.1.seconds
32
+ end
33
+
34
+ def observers
35
+ @observer_peers&.keys || []
36
+ end
37
+
38
+ def verifier_key
39
+ @verifier_key || Rails.application.key_generator.generate_key("cable_ready/verifier_key")
17
40
  end
18
41
 
19
42
  def operation_names
@@ -33,6 +56,7 @@ module CableReady
33
56
  append
34
57
  clear_storage
35
58
  console_log
59
+ console_table
36
60
  dispatch_event
37
61
  go
38
62
  graft
@@ -42,9 +66,10 @@ module CableReady
42
66
  morph
43
67
  notification
44
68
  outer_html
45
- play_sound
46
69
  prepend
47
70
  push_state
71
+ redirect_to
72
+ reload
48
73
  remove
49
74
  remove_attribute
50
75
  remove_css_class
@@ -56,10 +81,12 @@ module CableReady
56
81
  set_cookie
57
82
  set_dataset_property
58
83
  set_focus
84
+ set_meta
59
85
  set_property
60
86
  set_storage_item
61
87
  set_style
62
88
  set_styles
89
+ set_title
63
90
  set_value
64
91
  text_content
65
92
  ]).freeze
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/engine"
4
+
5
+ module CableReady
6
+ class Engine < Rails::Engine
7
+ # If you don't want to precompile CableReady's assets (eg. because you're using webpack),
8
+ # you can do this in an initializer:
9
+ #
10
+ # config.after_initialize do
11
+ # config.assets.precompile -= CableReady::Engine::PRECOMPILE_ASSETS
12
+ # end
13
+ PRECOMPILE_ASSETS = %w[
14
+ cable_ready.js
15
+ cable_ready.umd.js
16
+ ]
17
+
18
+ initializer "cable_ready.assets" do |app|
19
+ if app.config.respond_to?(:assets) && CableReady.config.precompile_assets
20
+ app.config.assets.precompile += PRECOMPILE_ASSETS
21
+ end
22
+ end
23
+
24
+ initializer "cable_ready.sanity_check" do
25
+ SanityChecker.check! unless Rails.env.production?
26
+ end
27
+
28
+ initializer "cable_ready.mimetype" do
29
+ Mime::Type.register "text/vnd.cable-ready.json", :cable_ready
30
+ end
31
+
32
+ initializer "cable_ready.renderer" do
33
+ ActiveSupport.on_load(:action_controller) do
34
+ ActionController::Renderers.add :operations do |operations, options|
35
+ warn "DEPRECATED: CableReady's `render operations:` call has been renamed to `render cable_ready:`. Please update your render call."
36
+
37
+ response.content_type ||= Mime[:cable_ready]
38
+ response.headers["X-Cable-Ready-Version"] = CableReady::VERSION
39
+
40
+ render json: operations.respond_to?(:dispatch) ? operations.dispatch : operations
41
+ end
42
+
43
+ ActionController::Renderers.add :cable_ready do |operations, options|
44
+ response.content_type ||= Mime[:cable_ready]
45
+ response.headers["X-Cable-Ready-Version"] = CableReady::VERSION
46
+
47
+ render json: operations.respond_to?(:dispatch) ? operations.dispatch : operations
48
+ end
49
+ end
50
+ end
51
+
52
+ initializer "cable_ready.importmap", before: "importmap" do |app|
53
+ if app.config.respond_to?(:importmap)
54
+ app.config.importmap.paths << Engine.root.join("lib/cable_ready/importmap.rb")
55
+ app.config.importmap.cache_sweepers << Engine.root.join("app/assets/javascripts")
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_view"
4
+
5
+ module CableReady
6
+ module Identifiable
7
+ def dom_id(record, prefix = nil)
8
+ return record.to_dom_selector if record.respond_to?(:to_dom_selector)
9
+
10
+ prefix = prefix.to_s.strip if prefix
11
+
12
+ id = if record.respond_to?(:to_dom_id)
13
+ record.to_dom_id
14
+ elsif ar_relation?(record)
15
+ [prefix, record.model_name.plural].compact.join("_")
16
+ elsif ar_base?(record)
17
+ ActionView::RecordIdentifier.dom_id(record, prefix)
18
+ else
19
+ [prefix, record.to_s.strip].compact.join("_")
20
+ end
21
+
22
+ "##{id}".squeeze("#").strip.downcase
23
+ end
24
+
25
+ def identifiable?(obj)
26
+ (
27
+ obj.respond_to?(:to_dom_selector) ||
28
+ obj.respond_to?(:to_dom_id) ||
29
+ ar_relation?(obj) ||
30
+ ar_base?(obj)
31
+ )
32
+ end
33
+
34
+ private
35
+
36
+ def ar_relation?(obj)
37
+ return false if defined?(ActiveRecord).nil? || defined?(ActiveRecord::Relation).nil?
38
+
39
+ obj.is_a?(ActiveRecord::Relation)
40
+ end
41
+
42
+ def ar_base?(obj)
43
+ return false if defined?(ActiveRecord).nil? || defined?(ActiveRecord::Base).nil?
44
+
45
+ obj.is_a?(ActiveRecord::Base)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ pin "morphdom", to: "https://ga.jspm.io/npm:morphdom@2.6.1/dist/morphdom.js", preload: true
4
+ pin "cable_ready", to: "cable_ready.js", preload: true
@@ -0,0 +1,224 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cable_ready/version"
4
+
5
+ ### general utilities
6
+
7
+ def fetch(step_path, file)
8
+ relative_path = step_path + file
9
+ location = template_src + relative_path
10
+
11
+ Pathname.new(location)
12
+ end
13
+
14
+ def complete_step(step)
15
+ create_file "tmp/cable_ready_installer/#{step}", verbose: false
16
+ end
17
+
18
+ def create_or_append(path, *args, &block)
19
+ FileUtils.touch(path)
20
+ append_file(path, *args, &block)
21
+ end
22
+
23
+ def current_template
24
+ ENV["LOCATION"].split("/").last.gsub(".rb", "")
25
+ end
26
+
27
+ def pack_path_missing?
28
+ return false unless pack_path.nil?
29
+ halt "#{friendly_pack_path} is missing. You need a valid application pack file to proceed."
30
+ end
31
+
32
+ def halt(message)
33
+ say "❌ #{message}", :red
34
+ create_file "tmp/cable_ready_installer/halt", verbose: false
35
+ end
36
+
37
+ def backup(path, delete: false)
38
+ if !path.exist?
39
+ yield
40
+ return
41
+ end
42
+
43
+ backup_path = Pathname.new("#{path}.bak")
44
+ old_path = path.relative_path_from(Rails.root).to_s
45
+ filename = path.to_path.split("/").last
46
+
47
+ if backup_path.exist?
48
+ if backup_path.read == path.read
49
+ path.delete if delete
50
+ yield
51
+ return
52
+ end
53
+ backup_path.delete
54
+ end
55
+
56
+ copy_file(path, backup_path, verbose: false)
57
+ path.delete if delete
58
+
59
+ yield
60
+
61
+ if path.read != backup_path.read
62
+ create_or_append(backups_path, "#{old_path}\n", verbose: false)
63
+ end
64
+ say "📦 #{old_path} backed up as #{filename}.bak"
65
+ end
66
+
67
+ def add_gem(name)
68
+ create_or_append(add_gem_list, "#{name}\n", verbose: false)
69
+ say "☑️ Added #{name} to the Gemfile"
70
+ end
71
+
72
+ def remove_gem(name)
73
+ create_or_append(remove_gem_list, "#{name}\n", verbose: false)
74
+ say "❎ Removed #{name} from Gemfile"
75
+ end
76
+
77
+ def add_package(name)
78
+ create_or_append(package_list, "#{name}\n", verbose: false)
79
+ say "☑️ Enqueued #{name} to be added to dependencies"
80
+ end
81
+
82
+ def add_dev_package(name)
83
+ create_or_append(dev_package_list, "#{name}\n", verbose: false)
84
+ say "☑️ Enqueued #{name} to be added to dev dependencies"
85
+ end
86
+
87
+ def drop_package(name)
88
+ create_or_append(drop_package_list, "#{name}\n", verbose: false)
89
+ say "❎ Enqueued #{name} to be removed from dependencies"
90
+ end
91
+
92
+ def gemfile_hash
93
+ Digest::MD5.hexdigest(gemfile_path.read)
94
+ end
95
+
96
+ ### memoized values
97
+
98
+ def cr_npm_version
99
+ @cr_npm_version ||= CableReady::VERSION.gsub(".pre", "-pre")
100
+ end
101
+
102
+ def package_json
103
+ @package_json ||= Rails.root.join("package.json")
104
+ end
105
+
106
+ def entrypoint
107
+ @entrypoint ||= File.read("tmp/cable_ready_installer/entrypoint")
108
+ end
109
+
110
+ def bundler
111
+ @bundler ||= File.read("tmp/cable_ready_installer/bundler")
112
+ end
113
+
114
+ def config_path
115
+ @config_path ||= Rails.root.join(entrypoint, "config")
116
+ end
117
+
118
+ def importmap_path
119
+ @importmap_path ||= Rails.root.join("config/importmap.rb")
120
+ end
121
+
122
+ def friendly_importmap_path
123
+ @friendly_importmap_path ||= importmap_path.relative_path_from(Rails.root).to_s
124
+ end
125
+
126
+ def pack
127
+ @pack ||= pack_path.read
128
+ end
129
+
130
+ def friendly_pack_path
131
+ @friendly_pack_path ||= pack_path.relative_path_from(Rails.root).to_s
132
+ end
133
+
134
+ def pack_path
135
+ @pack_path ||= [
136
+ Rails.root.join(entrypoint, "application.js"),
137
+ Rails.root.join(entrypoint, "packs/application.js"),
138
+ Rails.root.join(entrypoint, "entrypoints/application.js")
139
+ ].find(&:exist?)
140
+ end
141
+
142
+ def package_list
143
+ @package_list ||= Rails.root.join("tmp/cable_ready_installer/npm_package_list")
144
+ end
145
+
146
+ def dev_package_list
147
+ @dev_package_list ||= Rails.root.join("tmp/cable_ready_installer/npm_dev_package_list")
148
+ end
149
+
150
+ def drop_package_list
151
+ @drop_package_list ||= Rails.root.join("tmp/cable_ready_installer/drop_npm_package_list")
152
+ end
153
+
154
+ def template_src
155
+ @template_src ||= File.read("tmp/cable_ready_installer/template_src")
156
+ end
157
+
158
+ def controllers_path
159
+ @controllers_path ||= Rails.root.join(entrypoint, "controllers")
160
+ end
161
+
162
+ def gemfile_path
163
+ @gemfile_path ||= Rails.root.join("Gemfile")
164
+ end
165
+
166
+ def gemfile
167
+ @gemfile ||= gemfile_path.read
168
+ end
169
+
170
+ def prefix
171
+ # standard:disable Style/RedundantStringEscape
172
+ @prefix ||= {
173
+ "vite" => "..\/",
174
+ "webpacker" => "",
175
+ "shakapacker" => "",
176
+ "importmap" => "",
177
+ "esbuild" => ".\/"
178
+ }[bundler]
179
+ # standard:enable Style/RedundantStringEscape
180
+ end
181
+
182
+ def application_record_path
183
+ @application_record_path ||= Rails.root.join("app/models/application_record.rb")
184
+ end
185
+
186
+ def action_cable_initializer_path
187
+ @action_cable_initializer_path ||= Rails.root.join("config/initializers/action_cable.rb")
188
+ end
189
+
190
+ def action_cable_initializer_working_path
191
+ @action_cable_initializer_working_path ||= Rails.root.join(working, "action_cable.rb")
192
+ end
193
+
194
+ def development_path
195
+ @development_path ||= Rails.root.join("config/environments/development.rb")
196
+ end
197
+
198
+ def development_working_path
199
+ @development_working_path ||= Rails.root.join(working, "development.rb")
200
+ end
201
+
202
+ def backups_path
203
+ @backups_path ||= Rails.root.join("tmp/cable_ready_installer/backups")
204
+ end
205
+
206
+ def add_gem_list
207
+ @add_gem_list ||= Rails.root.join("tmp/cable_ready_installer/add_gem_list")
208
+ end
209
+
210
+ def remove_gem_list
211
+ @remove_gem_list ||= Rails.root.join("tmp/cable_ready_installer/remove_gem_list")
212
+ end
213
+
214
+ def options_path
215
+ @options_path ||= Rails.root.join("tmp/cable_ready_installer/options")
216
+ end
217
+
218
+ def options
219
+ @options ||= YAML.safe_load(File.read(options_path))
220
+ end
221
+
222
+ def working
223
+ @working ||= Rails.root.join("tmp/cable_ready_installer/working")
224
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CableReady
4
+ class OperationBuilder
5
+ include Identifiable
6
+ attr_reader :identifier, :previous_selector
7
+
8
+ def self.finalizer_for(identifier)
9
+ proc {
10
+ channel = CableReady.config.observers.find { |o| o.try(:identifier) == identifier }
11
+ CableReady.config.delete_observer channel if channel
12
+ }
13
+ end
14
+
15
+ def initialize(identifier)
16
+ @identifier = identifier
17
+
18
+ reset!
19
+ CableReady.config.operation_names.each { |name| add_operation_method name }
20
+ CableReady.config.add_observer self, :add_operation_method
21
+ ObjectSpace.define_finalizer self, self.class.finalizer_for(identifier)
22
+ end
23
+
24
+ def add_operation_method(name)
25
+ return if respond_to?(name)
26
+ singleton_class.public_send :define_method, name, ->(*args) {
27
+ if args.one? && args.first.respond_to?(:to_operation_options) && [Array, Hash].include?(args.first.to_operation_options.class)
28
+ case args.first.to_operation_options
29
+ when Array
30
+ selector, options = nil, args.first.to_operation_options
31
+ .select { |e| e.is_a?(Symbol) && args.first.respond_to?("to_#{e}".to_sym) }
32
+ .each_with_object({}) { |option, memo| memo[option.to_s] = args.first.send("to_#{option}".to_sym) }
33
+ when Hash
34
+ selector, options = nil, args.first.to_operation_options
35
+ else
36
+ raise TypeError, ":to_operation_options returned an #{args.first.to_operation_options.class.name}. Must be an Array or Hash."
37
+ end
38
+ else
39
+ selector, options = nil, args.first || {} # 1 or 0 params
40
+ selector, options = options, {} unless options.is_a?(Hash) # swap if only selector provided
41
+ selector, options = args[0, 2] if args.many? # 2 or more params
42
+ options.stringify_keys!
43
+ options.each { |key, value| options[key] = value.send("to_#{key}".to_sym) if value.respond_to?("to_#{key}".to_sym) }
44
+ end
45
+ options["selector"] = selector if selector && options.exclude?("selector")
46
+ options["selector"] = previous_selector if previous_selector && options.exclude?("selector")
47
+ if options.include?("selector")
48
+ @previous_selector = options["selector"]
49
+ options["selector"] = identifiable?(previous_selector) ? dom_id(previous_selector) : previous_selector
50
+ end
51
+ options["operation"] = name.to_s.camelize(:lower)
52
+ @enqueued_operations << options
53
+ self
54
+ }
55
+ end
56
+
57
+ def to_json(*args)
58
+ @enqueued_operations.to_json(*args)
59
+ end
60
+
61
+ def apply!(operations = "[]")
62
+ operations = begin
63
+ JSON.parse(operations.is_a?(String) ? operations : operations.to_json)
64
+ rescue JSON::ParserError
65
+ {}
66
+ end
67
+ @enqueued_operations.concat(Array.wrap(operations))
68
+ self
69
+ end
70
+
71
+ def operations_payload
72
+ @enqueued_operations.map { |operation| operation.deep_transform_keys! { |key| key.to_s.camelize(:lower) } }
73
+ end
74
+
75
+ def reset!
76
+ @enqueued_operations = []
77
+ @previous_selector = nil
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CableReady::SanityChecker
4
+ LATEST_VERSION_FORMAT = /^(\d+\.\d+\.\d+)$/
5
+
6
+ class << self
7
+ def check!
8
+ return if ENV["SKIP_SANITY_CHECK"]
9
+ return if CableReady.config.on_failed_sanity_checks == :ignore
10
+ return if called_by_generate_config?
11
+ return if called_by_rake?
12
+
13
+ new
14
+ end
15
+
16
+ private
17
+
18
+ def called_by_generate_config?
19
+ ARGV.include?("cable_ready:initializer")
20
+ end
21
+
22
+ def called_by_rake?
23
+ File.basename($PROGRAM_NAME) == "rake"
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def initializer_missing?
30
+ File.exist?(Rails.root.join("config", "initializers", "cable_ready.rb")) == false
31
+ end
32
+
33
+ def warn_and_exit(text)
34
+ puts
35
+ puts "Heads up! 🔥"
36
+ puts
37
+ puts text
38
+ puts
39
+ if CableReady.config.on_failed_sanity_checks == :exit
40
+ puts <<~INFO
41
+ To ignore any warnings and start the application anyway, you can set the SKIP_SANITY_CHECK environment variable:
42
+
43
+ SKIP_SANITY_CHECK=true rails
44
+
45
+ To do this permanently, add the following directive to the CableReady initializer:
46
+
47
+ CableReady.configure do |config|
48
+ config.on_failed_sanity_checks = :warn
49
+ end
50
+
51
+ INFO
52
+ if initializer_missing?
53
+ puts <<~INFO
54
+ You can create a CableReady initializer with the command:
55
+
56
+ bundle exec rails generate cable_ready:initializer
57
+
58
+ INFO
59
+ end
60
+ exit false if Rails.env.test? == false
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CableReady
4
+ module StreamIdentifier
5
+ def verified_stream_identifier(signed_stream_identifier)
6
+ CableReady.signed_stream_verifier.verified signed_stream_identifier
7
+ end
8
+
9
+ def signed_stream_identifier(compoundable)
10
+ CableReady.signed_stream_verifier.generate compoundable
11
+ end
12
+ end
13
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CableReady
4
- VERSION = "4.5.0"
4
+ VERSION = "5.0.0"
5
5
  end
data/lib/cable_ready.rb CHANGED
@@ -1,20 +1,33 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "rails/engine"
4
- require "active_support/all"
5
- require "cable_ready/version"
3
+ require "open-uri"
4
+ require "active_support/message_verifier"
5
+ require "cable_ready/identifiable"
6
+ require "cable_ready/operation_builder"
6
7
  require "cable_ready/config"
7
8
  require "cable_ready/broadcaster"
9
+ require "cable_ready/engine"
10
+ require "cable_ready/sanity_checker"
11
+ require "cable_ready/compoundable"
12
+ require "cable_ready/channel"
13
+ require "cable_ready/channels"
14
+ require "cable_ready/cable_car"
15
+ require "cable_ready/stream_identifier"
16
+ require "cable_ready/version"
17
+ require "cable_ready_helper"
8
18
 
9
19
  module CableReady
10
- class Engine < Rails::Engine
11
- end
20
+ class << self
21
+ def config
22
+ CableReady::Config.instance
23
+ end
12
24
 
13
- def self.config
14
- CableReady::Config.instance
15
- end
25
+ def configure
26
+ yield config
27
+ end
16
28
 
17
- def self.configure
18
- yield config
29
+ def signed_stream_verifier
30
+ @signed_stream_verifier ||= ActiveSupport::MessageVerifier.new(config.verifier_key, digest: "SHA256", serializer: JSON)
31
+ end
19
32
  end
20
33
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # TODO: remove me once CableReady 5.0 was released
4
+
5
+ require_relative "../app/helpers/cable_ready/view_helper"
6
+
7
+ module CableReadyHelper
8
+ def self.included(base)
9
+ warn "NOTICE: `CableReadyHelper` was renamed to `CableReady::ViewHelper`. Please update your include accordingly."
10
+
11
+ base.include(::CableReady::ViewHelper)
12
+ end
13
+ end