action_cable_notifications 0.1.27 → 0.1.28

Sign up to get free protection for your applications and to get access to all the features.
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: