action_cable_notifications 0.1.27 → 0.1.28

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bbf5459391f70a5ea26fcbe49d73d658ee0018e1
4
- data.tar.gz: 139cee45492e3dbac434fa59428784ee779ffc14
3
+ metadata.gz: 6a2dc5fdc10bc32033f2ecf6d124718ab3949382
4
+ data.tar.gz: a8a4331d41f25160ca387f189df4ef087472ee91
5
5
  SHA512:
6
- metadata.gz: f81b284758a85fb93d2c189ae4ec8b4f642ba4855309534017e0f3def93260851545d35a23a4ea5a1ba125c58c331c9df50cc29d9fa939e563786b272a1c9164
7
- data.tar.gz: dbdf1d02cc3bc63458ddc7e460f8e47a48d58031a2b6008ca22943b1fc1a84fbda856962241dba5e43ad3b8773a1d018a4954aaf2563248935758f9b4641f885
6
+ metadata.gz: 1ab592b4eee5232708d9e768bd8d5dec672e77ad4ab28bfd6124bc5e99421dfc652235f4e0e659c5f71c76d6a64b7e261eea87422f38abf3b528c2d463a91e4f
7
+ data.tar.gz: 52f6f172a7090127f99e195e546c5f72fd0c56ecf68c2c9c5048e3660c60667ce39a150f8995dfd733223f68c1b3f75407a6b023563a85be933ab6120f197a38
@@ -28,6 +28,9 @@ class CableNotifications.Collection
28
28
  # Cleanup performed commands
29
29
  _.remove(@commandsCache, {performed: true})
30
30
 
31
+ # Clears the data array before fetching data
32
+ @data.splice(0,@data.length)
33
+
31
34
  # Fetch data from upstream server when connection is resumed
32
35
  @fetch()
33
36
 
@@ -18,6 +18,9 @@ class CableNotifications.Store.DefaultCallbacks
18
18
  _.each packet.data, (fields) ->
19
19
  collection.update({id: fields.id}, fields)
20
20
 
21
+ upsert: (packet, collection) ->
22
+ collection.upsert({id: packet.id}, packet.data)
23
+
21
24
  upsert_many: (packet, collection) ->
22
25
  _.each packet.data, (fields) ->
23
26
  collection.upsert({id: fields.id}, fields)
@@ -6,10 +6,7 @@ module ActionCableNotifications
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  included do
9
- # class variables
10
- class_attribute :ActionCableNotifications
11
9
 
12
- self.ActionCableNotifications = {}
13
10
  end
14
11
 
15
12
  #
@@ -28,7 +25,7 @@ module ActionCableNotifications
28
25
  def action(data)
29
26
  data.deep_symbolize_keys!
30
27
 
31
- channel_options = self.ActionCableNotifications[data[:collection]]
28
+ channel_options = @ActionCableNotificationsOptions[data[:collection]]
32
29
  if channel_options
33
30
  model = channel_options[:model]
34
31
  broadcasting = channel_options[:broadcasting]
@@ -65,8 +62,9 @@ module ActionCableNotifications
65
62
  end
66
63
 
67
64
  def initialize(*args)
68
- super
69
65
  @collections = {}
66
+ @ActionCableNotificationsOptions = {}
67
+ super
70
68
  end
71
69
 
72
70
  def subscribed
@@ -97,16 +95,19 @@ module ActionCableNotifications
97
95
  # Default options
98
96
  options = {
99
97
  broadcasting: model.model_name.collection,
100
- params: nil
98
+ params: params,
99
+ cache: false,
100
+ model_options: {},
101
+ channel_options: {}
101
102
  }.merge(options)
102
103
 
103
104
  # These options cannot be overridden
104
105
  options[:model] = model
105
- options[:channel] = self
106
+ # options[:channel] = self
106
107
  model_name = model.model_name.collection
107
108
 
108
109
  # Sets channel options
109
- self.ActionCableNotifications[model_name] = options
110
+ @ActionCableNotificationsOptions[model_name] = options
110
111
 
111
112
  # Checks if model already includes notification callbacks
112
113
  if !model.respond_to? :ActionCableNotificationsOptions
@@ -115,12 +116,12 @@ module ActionCableNotifications
115
116
 
116
117
  # Sets broadcast options if they are not already present in the model
117
118
  if not model.ActionCableNotificationsOptions.key? options[:broadcasting]
118
- model.broadcast_notifications_from options[:broadcasting], options
119
+ model.broadcast_notifications_from options[:broadcasting], options[:model_options]
119
120
  end
120
121
 
121
122
  # Start streaming
122
123
  stream_from options[:broadcasting], coder: ActiveSupport::JSON do |packet|
123
- transmit_packet(packet)
124
+ transmit_packet(packet, options)
124
125
  end
125
126
 
126
127
  end
@@ -130,9 +131,19 @@ module ActionCableNotifications
130
131
  #
131
132
  # @param [Hash] packet Packet with changes notifications
132
133
  #
133
- def transmit_packet(packet)
134
+ def transmit_packet(packet, options={})
135
+ # Default options
136
+ options = {
137
+ cache: false
138
+ }.merge(options)
139
+
134
140
  packet = packet.as_json.deep_symbolize_keys!
135
- if update_cache(packet)
141
+
142
+ if options[:cache]==true
143
+ if update_cache(packet)
144
+ transmit packet
145
+ end
146
+ else
136
147
  transmit packet
137
148
  end
138
149
  end
@@ -12,17 +12,27 @@ module ActionCableNotifications
12
12
  params = data[:params] || {}
13
13
 
14
14
  # Get results using provided parameters and model configured scope
15
- results = data[:model].
15
+ begin
16
+ results = data[:model].
16
17
  select(params[:select] || []).
17
18
  limit(params[:limit]).
18
19
  where(params[:where] || {}).
19
20
  scoped_collection(data[:model_options][:scope]).
20
21
  to_a() rescue []
21
22
 
22
- response = { collection: data[:model].model_name.collection,
23
- msg: 'upsert_many',
24
- data: results
25
- }
23
+ response = {
24
+ collection: data[:model].model_name.collection,
25
+ msg: 'upsert_many',
26
+ data: results
27
+ }
28
+ rescue Exception => e
29
+ response = {
30
+ collection: data[:model].model_name.collection,
31
+ msg: 'error',
32
+ command: data[:command],
33
+ error: e.message
34
+ }
35
+ end
26
36
 
27
37
  # Send data to the client
28
38
  transmit_packet response
@@ -62,7 +72,7 @@ module ActionCableNotifications
62
72
  }
63
73
 
64
74
  # Send error notification to the client
65
- transmit response
75
+ transmit_packet response
66
76
  end
67
77
 
68
78
  end
@@ -99,7 +109,7 @@ module ActionCableNotifications
99
109
  }
100
110
 
101
111
  # Send error notification to the client
102
- transmit response
112
+ transmit_packet response
103
113
  end
104
114
 
105
115
  end
@@ -134,7 +144,7 @@ module ActionCableNotifications
134
144
  }
135
145
 
136
146
  # Send error notification to the client
137
- transmit response
147
+ transmit_packet response
138
148
  end
139
149
 
140
150
  end
@@ -8,13 +8,14 @@ module ActionCableNotifications
8
8
  self.ActionCableNotificationsOptions = {}
9
9
 
10
10
  # Register Callbacks
11
+ before_update :prepare_update
11
12
  after_update :notify_update
12
13
  after_create :notify_create
13
14
  after_destroy :notify_destroy
14
- end
15
15
 
16
- module ClassMethods
16
+ end
17
17
 
18
+ class_methods do
18
19
  #
19
20
  # Sets or removes notificacions options for Active Record model
20
21
  #
@@ -25,7 +26,9 @@ module ActionCableNotifications
25
26
  # Default options
26
27
  options = {
27
28
  actions: [:create, :update, :destroy],
28
- scope: :all # Default collection scope
29
+ track_scope_changes: true,
30
+ scope: :all, # Default collection scope
31
+ records: []
29
32
  }.merge(options)
30
33
 
31
34
  self.ActionCableNotificationsOptions[broadcasting.to_s] = options
@@ -74,7 +77,7 @@ module ActionCableNotifications
74
77
  self.ActionCableNotificationsOptions.each do |broadcasting, options|
75
78
  if options[:actions].include? :create
76
79
  # Checks if record is within scope before broadcasting
77
- if self.class.scoped_collection(options[:scope]).where(id: self.id)
80
+ if options[:scope]==:all or self.class.scoped_collection(options[:scope]).where(id: self.id).present?
78
81
  ActionCable.server.broadcast broadcasting,
79
82
  collection: self.model_name.collection,
80
83
  msg: 'create',
@@ -85,32 +88,74 @@ module ActionCableNotifications
85
88
  end
86
89
  end
87
90
 
91
+ def prepare_update
92
+ self.ActionCableNotificationsOptions.each do |broadcasting, options|
93
+ if options[:actions].include? :update
94
+ if options[:scope]==:all
95
+ options[:records].push self
96
+ else
97
+ record = self.class.scoped_collection(options[:scope]).where(id: self.id)
98
+ if record.present?
99
+ options[:records].push record.first
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+
88
106
  #
89
- # Broadcast notifications when a record is updated. Only changed
90
- # field will be sent.
107
+ # Broadcast notifications when a record is updated. Only changed fields will be sent
108
+ # if they are within configured scope
91
109
  #
92
110
  def notify_update
93
- changes = {}
94
- self.changes.each do |k,v|
95
- changes[k] = v[1]
96
- end
97
-
98
- if !changes.empty?
111
+ # Checks if there are changes in the model
112
+ if !self.changes.empty?
99
113
  self.ActionCableNotificationsOptions.each do |broadcasting, options|
100
114
  if options[:actions].include? :update
101
- # Checks if record is within scope before broadcasting
102
- if self.class.scoped_collection(options[:scope]).where(id: self.id)
103
- # XXX: Performance required. For small data sets this should be
104
- # fast enough, but for large data sets this could be slow. As
105
- # clients should have a limited subset of the dataset loaded at a
106
- # time, caching the results already sent to clients in server memory
107
- # should not have a big impact in memory usage but can improve
108
- # performance for large data sets where only a sub
115
+ # Checks if previous record was within scope
116
+ record = options[:records].detect{|r| r.id==self.id}
117
+ was_in_scope = record.present?
118
+ options[:records].delete(record) if was_in_scope
119
+
120
+ # Checks if current record is within scope
121
+ if options[:track_scope_changes]==true
122
+ is_in_scope = false
123
+ if options[:scope]==:all
124
+ record = self
125
+ is_in_scope = true
126
+ else
127
+ record = self.class.scoped_collection(options[:scope]).where(id: self.id)
128
+ if record.present?
129
+ record = record.first
130
+ is_in_scope = true
131
+ end
132
+ end
133
+ else
134
+ is_in_scope = was_in_scope
135
+ end
136
+
137
+ # Broadcasts notifications about model changes
138
+ if is_in_scope
139
+ # Get model changes and applies them to the scoped collection record
140
+ changes = {}
141
+ self.changes.each do |k,v|
142
+ if record.respond_to?(k)
143
+ changes[k] = v[1]
144
+ end
145
+ end
146
+
147
+ if !changes.empty?
148
+ ActionCable.server.broadcast broadcasting,
149
+ collection: self.model_name.collection,
150
+ msg: 'upsert',
151
+ id: self.id,
152
+ data: changes
153
+ end
154
+ elsif was_in_scope # checks if needs to delete the record if its no longer in scope
109
155
  ActionCable.server.broadcast broadcasting,
110
156
  collection: self.model_name.collection,
111
- msg: 'update',
112
- id: self.id,
113
- data: changes
157
+ msg: 'destroy',
158
+ id: self.id
114
159
  end
115
160
  end
116
161
  end
@@ -122,9 +167,9 @@ module ActionCableNotifications
122
167
  #
123
168
  def notify_destroy
124
169
  self.ActionCableNotificationsOptions.each do |broadcasting, options|
125
- if options[:actions].include? :destroy
170
+ if options[:scope]==:all or options[:actions].include? :destroy
126
171
  # Checks if record is within scope before broadcasting
127
- if self.class.scoped_collection(options[:scope]).where(id: self.id)
172
+ if options[:scope]==:all or self.class.scoped_collection(options[:scope]).where(id: self.id).present?
128
173
  ActionCable.server.broadcast broadcasting,
129
174
  collection: self.model_name.collection,
130
175
  msg: 'destroy',
@@ -1,3 +1,3 @@
1
1
  module ActionCableNotifications
2
- VERSION = '0.1.27'
2
+ VERSION = '0.1.28'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_cable_notifications
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.27
4
+ version: 0.1.28
5
5
  platform: ruby
6
6
  authors:
7
7
  - ByS Sistemas de Control
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-09 00:00:00.000000000 Z
11
+ date: 2017-05-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -86,6 +86,20 @@ dependencies:
86
86
  - - ">="
87
87
  - !ruby/object:Gem::Version
88
88
  version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: awesome_print
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
89
103
  description: Rails engine that provides Automatic realtime notification broadcast
90
104
  for ActiveRecord models changes using Action Cable and websockets
91
105
  email: