nats_wave 1.1.8 → 1.1.10

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.
@@ -1,216 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module NatsWave
4
- module ActiveRecordExtension
5
- extend ActiveSupport::Concern
6
-
7
- module ClassMethods
8
- def nats_publishable(options = {})
9
- include NatsWave::NatsPublishable
10
- class_attribute :nats_publishing_options
11
- self.nats_publishing_options = {
12
- enabled: true,
13
- actions: %i[create update
14
- destroy],
15
- skip_attributes: [],
16
- include_associations: [],
17
- async: true
18
- }.merge(options)
19
-
20
- # Register this model for publishing
21
- NatsWave.configuration&.add_publication(name,
22
- nats_publishing_options[:actions])
23
- end
24
- end
25
- end
26
-
27
- module NatsPublishable
28
- extend ActiveSupport::Concern
29
-
30
- included do
31
- after_commit :publish_to_nats_on_create, on: :create, if: :should_publish_create?
32
- after_commit :publish_to_nats_on_update, on: :update,
33
- if: :should_publish_update?
34
- after_commit :publish_to_nats_on_destroy, on: :destroy,
35
- if: :should_publish_destroy?
36
- end
37
-
38
- class_methods do
39
- def nats_wave_enabled?
40
- nats_publishing_options[:enabled]
41
- end
42
-
43
- def nats_wave_actions
44
- nats_publishing_options[:actions]
45
- end
46
-
47
- def nats_wave_skip_attributes
48
- nats_publishing_options[:skip_attributes]
49
- end
50
-
51
- def nats_wave_unique_attributes
52
- # Override this method in your models to define unique attributes for syncing
53
- %i[email slug code external_icn].select do |attr|
54
- column_names.include?(attr.to_s)
55
- end
56
- end
57
-
58
- def nats_wave_skip_sync_attributes
59
- # Override this method to define attributes that shouldn't be synced from other instances
60
- %w[created_at updated_at]
61
- end
62
-
63
- def nats_wave_attribute_transformations
64
- # Override this method to define custom transformations
65
- {}
66
- end
67
- end
68
-
69
- private
70
-
71
- def should_publish_create?
72
- should_publish_action?(:create)
73
- end
74
-
75
- def should_publish_update?
76
- should_publish_action?(:update) && has_significant_changes?
77
- end
78
-
79
- def should_publish_destroy?
80
- should_publish_action?(:destroy)
81
- end
82
-
83
- def should_publish_action?(action)
84
- return false unless self.class.nats_wave_enabled?
85
- return false unless self.class.nats_wave_actions.include?(action)
86
- return false if Thread.current[:skip_nats_wave_publishing]
87
- return false if @skip_nats_wave_publishing
88
-
89
- # Check conditional options
90
- return false if nats_publishing_options[:if] && !instance_eval(&nats_publishing_options[:if])
91
-
92
- return false if nats_publishing_options[:unless] && instance_eval(&nats_publishing_options[:unless])
93
-
94
- true
95
- end
96
-
97
- def has_significant_changes?
98
- skip_attrs = self.class.nats_wave_skip_attributes.map(&:to_s)
99
- significant_changes = previous_changes.except(*skip_attrs, 'updated_at')
100
- significant_changes.any?
101
- end
102
-
103
- def publish_to_nats_on_create
104
- publish_to_nats('create', attributes, build_metadata)
105
- end
106
-
107
- def publish_to_nats_on_update
108
- publish_to_nats('update', previous_changes, build_metadata)
109
- end
110
-
111
- def publish_to_nats_on_destroy
112
- publish_to_nats('destroy', attributes, build_metadata)
113
- end
114
-
115
- def publish_to_nats(action, _data, metadata)
116
- subject = build_nats_subject(action)
117
-
118
- NatsWave.client.publish(
119
- subject: subject,
120
- model: self.class.name,
121
- action: action,
122
- data: publishable_attributes,
123
- metadata: metadata
124
- )
125
- rescue StandardError => e
126
- NatsWave.logger.error("Failed to publish NATS event: #{e.message}")
127
- # Don't raise to avoid breaking the main transaction
128
- end
129
-
130
- def build_nats_subject(action)
131
- prefix = nats_publishing_options&.dig(:subject_prefix)
132
- model_name = self.class.name.underscore
133
-
134
- if prefix
135
- "#{prefix}.#{model_name}.#{action}"
136
- else
137
- "#{model_name}.#{action}"
138
- end
139
- end
140
-
141
- def publishable_attributes
142
- attrs = if nats_publishing_options&.dig(:only)
143
- attributes.slice(*nats_publishing_options[:only].map(&:to_s))
144
- elsif nats_publishing_options&.dig(:except)
145
- attributes.except(*nats_publishing_options[:except].map(&:to_s))
146
- else
147
- attributes
148
- end
149
-
150
- # Add associations if configured
151
- attrs.merge!(serialize_associations) if nats_publishing_options[:include_associations].present?
152
-
153
- attrs
154
- end
155
-
156
- def serialize_associations
157
- associations = {}
158
-
159
- self.class.reflect_on_all_associations.each do |association|
160
- unless nats_publishing_options[:include_associations].include?(association.name)
161
- next
162
- end
163
-
164
- case association.macro
165
- when :belongs_to
166
- if (related = send(association.name))
167
- associations["#{association.name}_id"] =
168
- related.id
169
- if association.polymorphic?
170
- associations["#{association.name}_type"] =
171
- related.class.name
172
- end
173
- end
174
- when :has_many, :has_and_belongs_to_many
175
- if respond_to?("#{association.name}_ids")
176
- associations["#{association.name.to_s.singularize}_ids"] =
177
- send("#{association.name}_ids")
178
- end
179
- when :has_one
180
- if (related = send(association.name))
181
- associations["#{association.name}_id"] =
182
- related.id
183
- end
184
- end
185
- end
186
-
187
- associations
188
- end
189
-
190
- def build_metadata
191
- metadata = {
192
- model_id: id,
193
- model_type: self.class.name,
194
- table_name: self.class.table_name,
195
- primary_key: self.class.primary_key
196
- }
197
-
198
- # Add custom metadata if method exists
199
- metadata.merge!(nats_wave_metadata) if respond_to?(:nats_wave_metadata,
200
- true)
201
-
202
- # Add configured metadata
203
- metadata.merge!(nats_publishing_options[:metadata]) if nats_publishing_options[:metadata]
204
-
205
- metadata
206
- end
207
-
208
- def skip_nats_wave_publishing!
209
- @skip_nats_wave_publishing = true
210
- end
211
-
212
- def enable_nats_wave_publishing!
213
- @skip_nats_wave_publishing = false
214
- end
215
- end
216
- end