Module: ArSync
- Defined in:
- lib/ar_sync.rb,
lib/ar_sync/core.rb,
lib/ar_sync/rails.rb,
lib/ar_sync/config.rb,
lib/ar_sync/version.rb,
lib/generators/ar_sync/types/types_generator.rb,
lib/generators/ar_sync/install/install_generator.rb
Defined Under Namespace
Modules: ApiControllerConcern, ModelBase, Rails, StaticJsonConcern, TypeScript
Classes: ApiNotFound, Collection, CollectionWithOrder, Config, InstallGenerator, SyncSchemaBase, TypesGenerator
Constant Summary
collapse
- VERSION =
'1.1.3'
Class Method Summary
collapse
-
.config ⇒ Object
-
.configure {|config| ... } ⇒ Object
-
.on_notification(&block) ⇒ Object
-
.serialize(record_or_records, query, user: nil) ⇒ Object
-
.signed_key(key, time) ⇒ Object
-
.skip_notification? ⇒ Boolean
-
.sync_key(model, to_user = nil, signature: true) ⇒ Object
-
.sync_send(to:, action:, model:, path: nil, field: nil, to_user: nil) ⇒ Object
-
.sync_serialize(target, user, query) ⇒ Object
-
.validate_expiration(signed_key) ⇒ Object
-
.with_compact_notification ⇒ Object
-
.without_notification ⇒ Object
Class Method Details
.config ⇒ Object
10
11
12
|
# File 'lib/ar_sync/config.rb', line 10
def self.config
@config ||= Config.new :current_user, nil, nil
end
|
14
15
16
|
# File 'lib/ar_sync/config.rb', line 14
def self.configure
yield config
end
|
.on_notification(&block) ⇒ Object
12
13
14
|
# File 'lib/ar_sync/core.rb', line 12
def self.on_notification(&block)
@sync_send_block = block
end
|
.serialize(record_or_records, query, user: nil) ⇒ Object
80
81
82
|
# File 'lib/ar_sync/core.rb', line 80
def self.serialize(record_or_records, query, user: nil)
ArSerializer.serialize record_or_records, query, context: user, use: :sync
end
|
.signed_key(key, time) ⇒ Object
76
77
78
|
# File 'lib/ar_sync/core.rb', line 76
def self.signed_key(key, time)
"#{key};#{time};#{Digest::SHA256.hexdigest("#{config.key_secret}#{key};#{time}")[0, 16]}"
end
|
.skip_notification? ⇒ Boolean
26
27
28
|
# File 'lib/ar_sync/core.rb', line 26
def self.skip_notification?
Thread.current[:ar_sync_skip_notification]
end
|
.sync_key(model, to_user = nil, signature: true) ⇒ Object
56
57
58
59
60
61
62
63
64
65
66
|
# File 'lib/ar_sync/core.rb', line 56
def self.sync_key(model, to_user = nil, signature: true)
if model.is_a? ArSync::Collection
key = [to_user&.id, model.klass.name, model.name].join '/'
else
key = [to_user&.id, model.class.name, model.id].join '/'
end
key = Digest::SHA256.hexdigest("#{config.key_secret}#{key}")[0, 32] if config.key_secret
key = "#{config.key_prefix}#{key}" if config.key_prefix
key = signature && config.key_expires_in ? signed_key(key, Time.now.to_i.to_s) : key
key + ';/'
end
|
.sync_send(to:, action:, model:, path: nil, field: nil, to_user: nil) ⇒ Object
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
# File 'lib/ar_sync/core.rb', line 39
def self.sync_send(to:, action:, model:, path: nil, field: nil, to_user: nil)
key = sync_key to, to_user, signature: false
e = { action: action }
e[:field] = field if field
if model
e[:class] = model.class.base_class.name
e[:id] = model.id
end
event = ["#{key}#{path}", e]
buffer = Thread.current[:ar_sync_compact_notifications]
if buffer
buffer << event
else
@sync_send_block&.call [event]
end
end
|
.sync_serialize(target, user, query) ⇒ Object
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
# File 'lib/ar_sync/core.rb', line 84
def self.sync_serialize(target, user, query)
case target
when ArSync::Collection, ArSync::ModelBase
serialized = ArSerializer.serialize target, query, context: user, use: :sync
return serialized if target.is_a? ArSync::ModelBase
{
_sync: { keys: [ArSync.sync_key(target), ArSync.sync_key(target, user)] },
ordering: target.ordering,
collection: serialized
}
when ActiveRecord::Relation, Array
ArSync.serialize target.to_a, query, user: user
when ArSerializer::Serializable
ArSync.serialize target, query, user: user
else
target
end
end
|
.validate_expiration(signed_key) ⇒ Object
68
69
70
71
72
73
74
|
# File 'lib/ar_sync/core.rb', line 68
def self.validate_expiration(signed_key)
signed_key = signed_key.to_s
return signed_key unless config.key_expires_in
key, time, signature, other = signed_key.split ';', 4
return unless signed_key(key, time) == [key, time, signature].join(';')
[key, other].compact.join ';' if Time.now.to_i - time.to_i < config.key_expires_in
end
|
.with_compact_notification ⇒ Object
16
17
18
19
20
21
22
23
24
|
# File 'lib/ar_sync/core.rb', line 16
def self.with_compact_notification
key = :ar_sync_compact_notifications
Thread.current[key] = []
yield
ensure
events = Thread.current[key]
Thread.current[key] = nil
@sync_send_block&.call events if events.present?
end
|
.without_notification ⇒ Object
30
31
32
33
34
35
36
37
|
# File 'lib/ar_sync/core.rb', line 30
def self.without_notification
key = :ar_sync_skip_notification
flag_was = Thread.current[key]
Thread.current[key] = true
yield
ensure
Thread.current[key] = flag_was
end
|