snappier 0.1.1 → 0.1.3

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
  SHA256:
3
- metadata.gz: a44e2f17a1206aea3035128b9d17325d26a1deac42391cbb279ff7178734b367
4
- data.tar.gz: 3beeaa24a2d05bf6d473a53912cc770bc00a6179fd9e60f9fc45080a52c099a5
3
+ metadata.gz: 61932de9cdce32aa92b7837f38387b9fc763c7729e6d9f57886a2896c2c716cf
4
+ data.tar.gz: d5d06a0b18c6279cafa7d703f238ccbac5c1812a4a6b435e82db6b3f6a16bc0b
5
5
  SHA512:
6
- metadata.gz: '058f1a6f65c067d9a76da692572b46a1f8c2d994939cb78b784766d9edb00ad07985fcbd39823e33bbcbc6454807f873aa1ee026a438839e69f735d0bbca565f'
7
- data.tar.gz: d73c327fd27b0e264253f7c4fd81d7dc40caed14c6a6f82a273f8ff9389f271ce5568b03031d691c6afcd9ad365da6ebe9860218230d34f20d2e8ead01f2e4f6
6
+ metadata.gz: 2e071037c3b594612045befde4d73c0e471ba76ce1793ce720958d52fd9d6f4035cefe3cd9f073b142ea61a3cb5344ed1411865810ec9a311b5f2b3c570ec4bb
7
+ data.tar.gz: '09993e8a427a9c657f82c0fb8a3e49c326ca47bc100976c14883bce2f15775c771f7bf6624adf1f3f8d9b136050a2609f36d129a10d7b20336dcb757db476089'
data/.rubocop.yml CHANGED
@@ -30,8 +30,14 @@ RSpec/MultipleExpectations:
30
30
  RSpec/VerifiedDoubles:
31
31
  Enabled: false
32
32
 
33
+ Metrics/AbcSize:
34
+ Max: 50
35
+
36
+ Metrics/CyclomaticComplexity:
37
+ Max: 15
38
+
33
39
  Metrics/MethodLength:
34
- Max: 20
40
+ Max: 30
35
41
 
36
- Metrics/AbcSize:
37
- Max: 20
42
+ Metrics/PerceivedComplexity:
43
+ Max: 30
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+
5
+ module Snappier
6
+ module Changes
7
+ def self.between(previous_state, current_state)
8
+ {}.tap { |changes| append_changes(changes, previous_state, current_state) }
9
+ end
10
+
11
+ def self.append_changes(changes, previous_state, current_state, path = [])
12
+ previous_state ||= {}
13
+ current_state ||= {}
14
+ keys = Set.new(previous_state.keys + current_state.keys)
15
+
16
+ keys.each do |key|
17
+ previous_value = previous_state[key]
18
+ current_value = current_state[key]
19
+
20
+ if previous_value.is_a?(Array) || current_value.is_a?(Array)
21
+ append_changes_for_collections(changes, previous_value, current_value, path + [key])
22
+ next
23
+ end
24
+
25
+ if previous_value.is_a?(Hash) || current_value.is_a?(Hash)
26
+ previous_id = (previous_value || {}).delete("id")
27
+ current_id = (current_value || {}).delete("id")
28
+
29
+ if previous_id || current_id
30
+ if previous_id == current_id
31
+ append_changes(changes, previous_value, current_value, path + [key, previous_id])
32
+ else
33
+ append_changes(changes, previous_value, {}, path + [key, previous_id])
34
+ append_changes(changes, {}, current_value, path + [key, current_id])
35
+ end
36
+ else
37
+ append_changes(changes, previous_value, current_value, path + [key])
38
+ end
39
+
40
+ next
41
+ end
42
+
43
+ next if previous_value == current_value
44
+
45
+ changes[path + [key]] = [previous_value, current_value]
46
+ end
47
+ end
48
+
49
+ def self.append_changes_for_collections(changes, previous_collection, current_collection, path)
50
+ ids = Set.new
51
+ previous_collection.each { |e| ids << e["id"] if e["id"] }
52
+ current_collection.each { |e| ids << e["id"] if e["id"] }
53
+
54
+ if ids.empty?
55
+ changes[path] = [previous_collection, current_collection]
56
+ return
57
+ end
58
+
59
+ ids.each do |id|
60
+ previous_value = previous_collection.find { |r| r["id"] == id } || {}
61
+ current_value = current_collection.find { |r| r["id"] == id } || {}
62
+ previous_value.delete("id")
63
+ current_value.delete("id")
64
+
65
+ append_changes(changes, previous_value, current_value, path + [id])
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "registry"
4
+ require_relative "changes"
4
5
 
5
6
  module Snappier
6
7
  module Replay
@@ -11,7 +12,7 @@ module Snappier
11
12
  content = current.delete(:content)
12
13
  current[:who] = content.delete("who")
13
14
  current[:state] = content.delete("state")
14
- current[:changes] = changes(previous_state, current[:state])
15
+ current[:changes] = Changes.between(previous_state, current[:state])
15
16
 
16
17
  yield(current)
17
18
 
@@ -19,20 +20,6 @@ module Snappier
19
20
  end
20
21
  end
21
22
 
22
- def self.changes(previous_state, current_state)
23
- changes = {}
24
-
25
- keys = Set.new(previous_state.keys + current_state.keys)
26
-
27
- keys.each do |key|
28
- next if previous_state[key] == current_state[key]
29
-
30
- changes[key] = [previous_state[key], current_state[key]]
31
- end
32
-
33
- changes
34
- end
35
-
36
23
  def self.for_entity(entity)
37
24
  self.for(type: entity.class.name, id: entity.id)
38
25
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Snappier
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.3"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snappier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Ryall
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-05-25 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: sidekiq
@@ -38,6 +38,7 @@ files:
38
38
  - Rakefile
39
39
  - exe/snappier_replay
40
40
  - lib/snappier.rb
41
+ - lib/snappier/changes.rb
41
42
  - lib/snappier/file_persistence.rb
42
43
  - lib/snappier/job.rb
43
44
  - lib/snappier/registry.rb
@@ -67,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
68
  - !ruby/object:Gem::Version
68
69
  version: '0'
69
70
  requirements: []
70
- rubygems_version: 3.6.2
71
+ rubygems_version: 3.6.7
71
72
  specification_version: 4
72
73
  summary: Audit trail for data by persisting full snapshots.
73
74
  test_files: []