paper_trail_diff 0.2.0 → 0.3.1

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.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +62 -0
  3. data/QUICKSTART.md +44 -2
  4. data/README.md +188 -14
  5. data/lib/paper_trail_diff/activity_belongs_to_event_applier.rb +126 -0
  6. data/lib/paper_trail_diff/activity_child_candidate_loader.rb +73 -0
  7. data/lib/paper_trail_diff/activity_collection_event_applier.rb +137 -0
  8. data/lib/paper_trail_diff/activity_collection_record_updater.rb +67 -0
  9. data/lib/paper_trail_diff/activity_collection_route_change.rb +21 -0
  10. data/lib/paper_trail_diff/activity_collection_route_updater.rb +128 -0
  11. data/lib/paper_trail_diff/activity_event_record_normalizer.rb +42 -0
  12. data/lib/paper_trail_diff/activity_event_record_resolver.rb +120 -0
  13. data/lib/paper_trail_diff/activity_event_route_finder.rb +112 -0
  14. data/lib/paper_trail_diff/activity_event_snapshot_refresher.rb +59 -437
  15. data/lib/paper_trail_diff/activity_history.rb +136 -0
  16. data/lib/paper_trail_diff/activity_range.rb +28 -12
  17. data/lib/paper_trail_diff/activity_relationship.rb +55 -0
  18. data/lib/paper_trail_diff/activity_snapshot_delta.rb +64 -0
  19. data/lib/paper_trail_diff/activity_snapshot_sequence.rb +3 -3
  20. data/lib/paper_trail_diff/activity_timeline_builder.rb +54 -45
  21. data/lib/paper_trail_diff/activity_version_collector.rb +14 -17
  22. data/lib/paper_trail_diff/branch_snapshot_refresher.rb +7 -3
  23. data/lib/paper_trail_diff/collection_comparator.rb +155 -0
  24. data/lib/paper_trail_diff/collection_identity_index.rb +53 -0
  25. data/lib/paper_trail_diff/collection_transition.rb +25 -0
  26. data/lib/paper_trail_diff/comparison_batch.rb +151 -0
  27. data/lib/paper_trail_diff/engine.rb +5 -45
  28. data/lib/paper_trail_diff/errors.rb +9 -0
  29. data/lib/paper_trail_diff/historical_snapshot_store.rb +55 -3
  30. data/lib/paper_trail_diff/instrumentation.rb +30 -0
  31. data/lib/paper_trail_diff/live_endpoint_batch_loader.rb +133 -0
  32. data/lib/paper_trail_diff/live_endpoint_provider.rb +48 -0
  33. data/lib/paper_trail_diff/live_graph_collector.rb +52 -0
  34. data/lib/paper_trail_diff/paper_trail_adapter.rb +61 -34
  35. data/lib/paper_trail_diff/preloaded_endpoint_batch_loader.rb +48 -0
  36. data/lib/paper_trail_diff/prepared_edge_loader.rb +54 -17
  37. data/lib/paper_trail_diff/prepared_history.rb +14 -4
  38. data/lib/paper_trail_diff/prepared_history_loader.rb +17 -9
  39. data/lib/paper_trail_diff/prepared_record_index.rb +138 -10
  40. data/lib/paper_trail_diff/snapshot.rb +66 -3
  41. data/lib/paper_trail_diff/support.rb +18 -0
  42. data/lib/paper_trail_diff/time_activity_timeline_builder.rb +111 -0
  43. data/lib/paper_trail_diff/time_range.rb +85 -0
  44. data/lib/paper_trail_diff/time_version_range.rb +53 -0
  45. data/lib/paper_trail_diff/timeline_builder.rb +13 -7
  46. data/lib/paper_trail_diff/timeline_range.rb +72 -0
  47. data/lib/paper_trail_diff/version.rb +1 -1
  48. data/lib/paper_trail_diff/version_association_candidate_scope.rb +73 -0
  49. data/lib/paper_trail_diff.rb +83 -12
  50. data/sig/generated/paper_trail_diff/activity_belongs_to_event_applier.rbs +41 -0
  51. data/sig/generated/paper_trail_diff/activity_child_candidate_loader.rbs +40 -0
  52. data/sig/generated/paper_trail_diff/activity_collection_event_applier.rbs +46 -0
  53. data/sig/generated/paper_trail_diff/activity_collection_record_updater.rbs +25 -0
  54. data/sig/generated/paper_trail_diff/activity_collection_route_change.rbs +17 -0
  55. data/sig/generated/paper_trail_diff/activity_collection_route_updater.rbs +44 -0
  56. data/sig/generated/paper_trail_diff/activity_event_record_normalizer.rbs +19 -0
  57. data/sig/generated/paper_trail_diff/activity_event_record_resolver.rbs +44 -0
  58. data/sig/generated/paper_trail_diff/activity_event_route_finder.rbs +54 -0
  59. data/sig/generated/paper_trail_diff/activity_event_snapshot_refresher.rbs +20 -71
  60. data/sig/generated/paper_trail_diff/activity_history.rbs +79 -0
  61. data/sig/generated/paper_trail_diff/activity_range.rbs +14 -5
  62. data/sig/generated/paper_trail_diff/activity_relationship.rbs +23 -0
  63. data/sig/generated/paper_trail_diff/activity_snapshot_delta.rbs +33 -0
  64. data/sig/generated/paper_trail_diff/activity_snapshot_sequence.rbs +2 -2
  65. data/sig/generated/paper_trail_diff/activity_timeline_builder.rbs +15 -10
  66. data/sig/generated/paper_trail_diff/activity_version_collector.rbs +2 -5
  67. data/sig/generated/paper_trail_diff/branch_snapshot_refresher.rbs +2 -2
  68. data/sig/generated/paper_trail_diff/collection_comparator.rbs +59 -0
  69. data/sig/generated/paper_trail_diff/collection_identity_index.rbs +29 -0
  70. data/sig/generated/paper_trail_diff/collection_transition.rbs +18 -0
  71. data/sig/generated/paper_trail_diff/comparison_batch.rbs +65 -0
  72. data/sig/generated/paper_trail_diff/engine.rbs +0 -12
  73. data/sig/generated/paper_trail_diff/errors.rbs +12 -0
  74. data/sig/generated/paper_trail_diff/historical_snapshot_store.rbs +22 -2
  75. data/sig/generated/paper_trail_diff/instrumentation.rbs +12 -0
  76. data/sig/generated/paper_trail_diff/live_endpoint_batch_loader.rbs +52 -0
  77. data/sig/generated/paper_trail_diff/live_endpoint_provider.rbs +23 -0
  78. data/sig/generated/paper_trail_diff/live_graph_collector.rbs +27 -0
  79. data/sig/generated/paper_trail_diff/paper_trail_adapter.rbs +21 -10
  80. data/sig/generated/paper_trail_diff/preloaded_endpoint_batch_loader.rbs +24 -0
  81. data/sig/generated/paper_trail_diff/prepared_edge_loader.rbs +22 -8
  82. data/sig/generated/paper_trail_diff/prepared_history.rbs +6 -0
  83. data/sig/generated/paper_trail_diff/prepared_history_loader.rbs +4 -2
  84. data/sig/generated/paper_trail_diff/prepared_record_index.rbs +61 -6
  85. data/sig/generated/paper_trail_diff/snapshot.rbs +37 -2
  86. data/sig/generated/paper_trail_diff/support.rbs +6 -0
  87. data/sig/generated/paper_trail_diff/time_activity_timeline_builder.rbs +46 -0
  88. data/sig/generated/paper_trail_diff/time_range.rbs +41 -0
  89. data/sig/generated/paper_trail_diff/time_version_range.rbs +27 -0
  90. data/sig/generated/paper_trail_diff/timeline_builder.rbs +6 -5
  91. data/sig/generated/paper_trail_diff/timeline_range.rbs +41 -0
  92. data/sig/generated/paper_trail_diff/version_association_candidate_scope.rbs +32 -0
  93. data/sig/generated/paper_trail_diff.rbs +16 -8
  94. metadata +56 -4
@@ -0,0 +1,27 @@
1
+ # Generated from lib/paper_trail_diff/live_graph_collector.rb with RBS::Inline
2
+
3
+ module PaperTrailDiff
4
+ # Flattens an already-preloaded, explicitly bounded live association graph.
5
+ class LiveGraphCollector
6
+ # : (tree: AssociationTree, traversal: AssociationTraversal) -> void
7
+ def initialize: (tree: AssociationTree, traversal: AssociationTraversal) -> void
8
+
9
+ # : (Array[untyped]) -> Array[untyped]
10
+ def call: (Array[untyped]) -> Array[untyped]
11
+
12
+ private
13
+
14
+ @traversal: AssociationTraversal
15
+
16
+ @tree: AssociationTree
17
+
18
+ # : (Array[untyped], AssociationTree, path: String, into: Hash[Array[untyped], untyped]) -> void
19
+ def collect: (Array[untyped], AssociationTree, path: String, into: Hash[Array[untyped], untyped]) -> void
20
+
21
+ # : (untyped, Array[untyped], AssociationTree, path: String, into: Hash[Array[untyped], untyped]) -> void
22
+ def collect_group: (untyped, Array[untyped], AssociationTree, path: String, into: Hash[Array[untyped], untyped]) -> void
23
+
24
+ # : (Array[untyped], untyped) -> Array[untyped]
25
+ def children_for: (Array[untyped], untyped) -> Array[untyped]
26
+ end
27
+ end
@@ -3,20 +3,24 @@
3
3
  module PaperTrailDiff
4
4
  # PaperTrail/ActiveRecord boundary that produces plain record snapshots.
5
5
  class PaperTrailAdapter
6
- # : (associations: Array[String | Symbol], ignore: ignore_option) -> void
7
- def initialize: (associations: Array[String | Symbol], ignore: ignore_option) -> void
6
+ # : (associations: Array[String | Symbol], ignore: ignore_option, ?reload_live_endpoints: bool) -> void
7
+ def initialize: (associations: Array[String | Symbol], ignore: ignore_option, ?reload_live_endpoints: bool) -> void
8
8
 
9
9
  # : (untyped, untyped) -> Diff
10
10
  def compare: (untyped, untyped) -> Diff
11
11
 
12
- # : (untyped, from: untyped, to: untyped) -> Array[Step]
13
- def timeline: (untyped, from: untyped, to: untyped) -> Array[Step]
12
+ # Compares independent pairs and returns immutable results keyed by item identity.
13
+ # : (Array[comparison_input]) -> comparison_results
14
+ def compare_many: (Array[comparison_input]) -> comparison_results
14
15
 
15
- # : (untyped, from: untyped, to: untyped) -> Array[ActivityStep]
16
- def activity_timeline: (untyped, from: untyped, to: untyped) -> Array[ActivityStep]
16
+ # : (untyped, from: untyped, to: untyped, within: untyped) -> Array[Step]
17
+ def timeline: (untyped, from: untyped, to: untyped, within: untyped) -> Array[Step]
17
18
 
18
- # : (untyped, from: untyped, to: untyped, ?activity: bool) -> Analysis
19
- def analyze: (untyped, from: untyped, to: untyped, ?activity: bool) -> Analysis
19
+ # : (untyped, from: untyped, to: untyped, within: untyped) -> Array[ActivityStep]
20
+ def activity_timeline: (untyped, from: untyped, to: untyped, within: untyped) -> Array[ActivityStep]
21
+
22
+ # : (untyped, from: untyped, to: untyped, within: untyped, ?activity: bool) -> Analysis
23
+ def analyze: (untyped, from: untyped, to: untyped, within: untyped, ?activity: bool) -> Analysis
20
24
 
21
25
  private
22
26
 
@@ -28,6 +32,10 @@ module PaperTrailDiff
28
32
 
29
33
  @ignore_policy: IgnorePolicy
30
34
 
35
+ @instrumentation_payload: Hash[Symbol, untyped]
36
+
37
+ @live_endpoints: LiveEndpointProvider
38
+
31
39
  @normalizer: SnapshotNormalizer
32
40
 
33
41
  @snapshot_pool: SnapshotPool
@@ -42,8 +50,8 @@ module PaperTrailDiff
42
50
  # : () -> ActivitySnapshotProvider
43
51
  def build_activity_snapshotter: () -> ActivitySnapshotProvider
44
52
 
45
- # : (untyped, from: untyped, to: untyped) -> ActivityTimelineBuilder
46
- def activity_builder: (untyped, from: untyped, to: untyped) -> ActivityTimelineBuilder
53
+ # : (untyped, from: untyped, to: untyped, within: untyped) -> ActivityTimelineBuilder
54
+ def activity_builder: (untyped, from: untyped, to: untyped, within: untyped) -> ActivityTimelineBuilder
47
55
 
48
56
  # : (untyped) -> void
49
57
  def reject_live_habtm_activity!: (untyped) -> void
@@ -63,6 +71,9 @@ module PaperTrailDiff
63
71
  # : (untyped) -> RecordSnapshot
64
72
  def live_snapshot: (untyped) -> RecordSnapshot
65
73
 
74
+ # : (untyped) -> RecordSnapshot
75
+ def normalize_live_snapshot: (untyped) -> RecordSnapshot
76
+
66
77
  # : (untyped, historical: bool) -> void
67
78
  def prepare_traversal!: (untyped, historical: bool) -> void
68
79
 
@@ -0,0 +1,24 @@
1
+ # Generated from lib/paper_trail_diff/preloaded_endpoint_batch_loader.rb with RBS::Inline
2
+
3
+ module PaperTrailDiff
4
+ # Validates and reuses caller-owned live records without issuing association queries.
5
+ class PreloadedEndpointBatchLoader
6
+ # : (tree: AssociationTree, traversal: AssociationTraversal) -> void
7
+ def initialize: (tree: AssociationTree, traversal: AssociationTraversal) -> void
8
+
9
+ # : (Array[untyped]) -> Hash[identity, untyped]
10
+ def call: (Array[untyped]) -> Hash[identity, untyped]
11
+
12
+ private
13
+
14
+ @traversal: AssociationTraversal
15
+
16
+ @tree: AssociationTree
17
+
18
+ # : (untyped, AssociationTree, path: String) -> void
19
+ def validate_record: (untyped, AssociationTree, path: String) -> void
20
+
21
+ # : (untyped, AssociationTree, String, untyped) -> void
22
+ def validate_association: (untyped, AssociationTree, String, untyped) -> void
23
+ end
24
+ end
@@ -5,8 +5,8 @@ module PaperTrailDiff
5
5
  class PreparedEdgeLoader
6
6
  EDGE_LOADERS: untyped
7
7
 
8
- # : (PreparedRecordIndex, Array[untyped]) -> void
9
- def initialize: (PreparedRecordIndex, Array[untyped]) -> void
8
+ # : (PreparedRecordIndex, Array[untyped], ?start_at: untyped) -> void
9
+ def initialize: (PreparedRecordIndex, Array[untyped], ?start_at: untyped) -> void
10
10
 
11
11
  # : (untyped, Array[untyped], untyped) -> [Hash[String, Hash[Symbol, untyped]], Hash[String, Array[untyped]]?]
12
12
  def call: (untyped, Array[untyped], untyped) -> [ Hash[String, Hash[Symbol, untyped]], Hash[String, Array[untyped]]? ]
@@ -15,6 +15,8 @@ module PaperTrailDiff
15
15
 
16
16
  @records: PreparedRecordIndex
17
17
 
18
+ @start_at: untyped
19
+
18
20
  @transaction_ids: Array[untyped]
19
21
 
20
22
  # : (untyped, Array[untyped], untyped) -> [Hash[String, Hash[Symbol, untyped]], nil]
@@ -41,11 +43,17 @@ module PaperTrailDiff
41
43
  # : (Array[untyped], untyped) -> Array[untyped]
42
44
  def membership_ids: (Array[untyped], untyped) -> Array[untyped]
43
45
 
44
- # : (untyped, Array[untyped], untyped, String) -> Array[untyped]
45
- def historical_child_ids: (untyped, Array[untyped], untyped, String) -> Array[untyped]
46
+ # : (untyped, Array[untyped], untyped, String) -> Hash[String, Array[untyped]]
47
+ def historical_child_ids: (untyped, Array[untyped], untyped, String) -> Hash[String, Array[untyped]]
48
+
49
+ # : (untyped, Array[untyped], untyped, String) -> untyped
50
+ def historical_child_relation: (untyped, Array[untyped], untyped, String) -> untyped
51
+
52
+ # : (untyped) -> VersionAssociationCandidateScope
53
+ def child_candidate_scope: (untyped) -> VersionAssociationCandidateScope
46
54
 
47
- # : (untyped, Array[untyped], untyped, String) -> Array[untyped]
48
- def live_child_ids: (untyped, Array[untyped], untyped, String) -> Array[untyped]
55
+ # : (untyped, Array[untyped], untyped, String) -> Hash[String, Array[untyped]]
56
+ def live_child_ids: (untyped, Array[untyped], untyped, String) -> Hash[String, Array[untyped]]
49
57
 
50
58
  # : (untyped, untyped) -> untyped
51
59
  def target_class: (untyped, untyped) -> untyped
@@ -53,8 +61,14 @@ module PaperTrailDiff
53
61
  # : (Hash[String, Hash[Symbol, untyped]], untyped, untyped) -> void
54
62
  def add_identity: (Hash[String, Hash[Symbol, untyped]], untyped, untyped) -> void
55
63
 
56
- # : (untyped, Array[untyped]) -> Hash[String, Hash[Symbol, untyped]]
57
- def group_for: (untyped, Array[untyped]) -> Hash[String, Hash[Symbol, untyped]]
64
+ # : (untyped, Array[untyped], ?owners: Hash[String, Array[untyped]]?) -> Hash[String, Hash[Symbol, untyped]]
65
+ def group_for: (untyped, Array[untyped], ?owners: Hash[String, Array[untyped]]?) -> Hash[String, Hash[Symbol, untyped]]
66
+
67
+ # : (Array[Array[untyped]]) -> Hash[String, Array[untyped]]
68
+ def group_ids_by_owner: (Array[Array[untyped]]) -> Hash[String, Array[untyped]]
69
+
70
+ # : (Hash[String, Array[untyped]], Hash[String, Array[untyped]]) -> Hash[String, Array[untyped]]
71
+ def merge_owners: (Hash[String, Array[untyped]], Hash[String, Array[untyped]]) -> Hash[String, Array[untyped]]
58
72
 
59
73
  # : (untyped) -> String?
60
74
  def scalar_foreign_key: (untyped) -> String?
@@ -20,6 +20,9 @@ module PaperTrailDiff
20
20
  # : (untyped, untyped, Hash[String, Array[untyped]]) -> void
21
21
  def register_habtm: (untyped, untyped, Hash[String, Array[untyped]]) -> void
22
22
 
23
+ # : (untyped, untyped, untyped) -> [Hash[untyped, untyped], Hash[untyped, untyped]]?
24
+ def record_transition: (untyped, untyped, untyped) -> [ Hash[untyped, untyped], Hash[untyped, untyped] ]?
25
+
23
26
  # : (untyped, untyped, untyped, habtm_boundary: untyped) -> [bool, Array[untyped]]
24
27
  def resolve: (untyped, untyped, untyped, habtm_boundary: untyped) -> [ bool, Array[untyped] ]
25
28
 
@@ -57,6 +60,9 @@ module PaperTrailDiff
57
60
  # : (untyped, untyped, untyped) -> Array[untyped]
58
61
  def child_records: (untyped, untyped, untyped) -> Array[untyped]
59
62
 
63
+ # : (Hash[Symbol, untyped], untyped) -> Array[untyped]
64
+ def child_ids_for: (Hash[Symbol, untyped], untyped) -> Array[untyped]
65
+
60
66
  # : (untyped, untyped, untyped, untyped) -> Array[untyped]?
61
67
  def habtm_records: (untyped, untyped, untyped, untyped) -> Array[untyped]?
62
68
 
@@ -3,8 +3,8 @@
3
3
  module PaperTrailDiff
4
4
  # Expands the explicit association tree into a request-scoped PreparedHistory.
5
5
  class PreparedHistoryLoader
6
- # : (untyped, root_versions: Array[untyped], tree: AssociationTree, traversal: AssociationTraversal) -> void
7
- def initialize: (untyped, root_versions: Array[untyped], tree: AssociationTree, traversal: AssociationTraversal) -> void
6
+ # : (untyped, root_versions: Array[untyped], tree: AssociationTree, traversal: AssociationTraversal, ?root_ids: Array[untyped], ?start_at: untyped, ?live_records: Array[untyped]) -> void
7
+ def initialize: (untyped, root_versions: Array[untyped], tree: AssociationTree, traversal: AssociationTraversal, ?root_ids: Array[untyped], ?start_at: untyped, ?live_records: Array[untyped]) -> void
8
8
 
9
9
  # : () -> PreparedHistory
10
10
  def call: () -> PreparedHistory
@@ -21,6 +21,8 @@ module PaperTrailDiff
21
21
 
22
22
  @records: PreparedRecordIndex
23
23
 
24
+ @root_ids: Array[untyped]
25
+
24
26
  @traversal: AssociationTraversal
25
27
 
26
28
  @tree: AssociationTree
@@ -3,23 +3,58 @@
3
3
  module PaperTrailDiff
4
4
  # Immutable scalar state from a PaperTrail version or live-record fallback.
5
5
  class PreparedRecordState
6
+ attr_reader model_class: untyped
7
+
8
+ attr_reader attributes: Hash[untyped, untyped]
9
+
6
10
  # : (untyped) -> void
7
11
  def initialize: (untyped) -> void
8
12
 
13
+ # : (untyped, Hash[untyped, untyped]) -> PreparedRecordState
14
+ def self.from_attributes: (untyped, Hash[untyped, untyped]) -> PreparedRecordState
15
+
9
16
  # : () -> untyped
10
17
  def instantiate: () -> untyped
11
18
 
12
- @attributes: Hash[untyped, untyped]
19
+ private
20
+
21
+ # : (untyped, Hash[untyped, untyped]) -> void
22
+ def initialize_attributes: (untyped, Hash[untyped, untyped]) -> void
23
+ end
24
+
25
+ # Extracts a version's scalar state without constructing a disposable AR object.
26
+ class PreparedVersionStateLoader
27
+ # : () -> void
28
+ def initialize: () -> void
29
+
30
+ # : (untyped) -> PreparedRecordState?
31
+ def call: (untyped) -> PreparedRecordState?
32
+
33
+ private
34
+
35
+ @attribute_names: Hash[untyped, Array[String]]
36
+
37
+ @serializers: Hash[untyped, untyped]
38
+
39
+ # : (Hash[untyped, untyped]) -> Hash[String, untyped]
40
+ def stringify_keys: (Hash[untyped, untyped]) -> Hash[String, untyped]
13
41
 
14
- @model_class: untyped
42
+ # : (untyped, Hash[String, untyped]) -> untyped
43
+ def reification_class: (untyped, Hash[String, untyped]) -> untyped
44
+
45
+ # : (untyped, Hash[String, untyped]) -> bool
46
+ def direct_attributes?: (untyped, Hash[String, untyped]) -> bool
47
+
48
+ # : (untyped) -> untyped
49
+ def object_attribute_serializer: (untyped) -> untyped
15
50
  end
16
51
 
17
52
  # Versions and live fallback for one model identity.
18
53
  class PreparedRecordSeries
19
54
  attr_reader versions: Array[untyped]
20
55
 
21
- # : (versions: Array[untyped], live: PreparedRecordState?) -> void
22
- def initialize: (versions: Array[untyped], live: PreparedRecordState?) -> void
56
+ # : (versions: Array[untyped], live: PreparedRecordState?, ?state_loader: PreparedVersionStateLoader) -> void
57
+ def initialize: (versions: Array[untyped], live: PreparedRecordState?, ?state_loader: PreparedVersionStateLoader) -> void
23
58
 
24
59
  # : (untyped) -> untyped
25
60
  def record_before: (untyped) -> untyped
@@ -27,12 +62,22 @@ module PaperTrailDiff
27
62
  # : () -> Array[untyped]
28
63
  def records: () -> Array[untyped]
29
64
 
65
+ # : (untyped) -> [Hash[untyped, untyped], Hash[untyped, untyped]]?
66
+ def transition: (untyped) -> [ Hash[untyped, untyped], Hash[untyped, untyped] ]?
67
+
30
68
  private
31
69
 
32
70
  @live: PreparedRecordState?
33
71
 
72
+ @state_loader: PreparedVersionStateLoader
73
+
34
74
  @states: Hash[untyped, PreparedRecordState?]
35
75
 
76
+ @version_positions: Hash[String, Integer]
77
+
78
+ # : (Integer) -> PreparedRecordState?
79
+ def state_after: (Integer) -> PreparedRecordState?
80
+
36
81
  # : (untyped, untyped) -> bool
37
82
  def eligible?: (untyped, untyped) -> bool
38
83
 
@@ -45,8 +90,8 @@ module PaperTrailDiff
45
90
 
46
91
  # Request-scoped scalar history loaded once per model identity.
47
92
  class PreparedRecordIndex
48
- # : (untyped) -> void
49
- def initialize: (untyped) -> void
93
+ # : (untyped, ?live_records: Array[untyped]) -> void
94
+ def initialize: (untyped, ?live_records: Array[untyped]) -> void
50
95
 
51
96
  # : (untyped, Array[untyped]) -> void
52
97
  def load: (untyped, Array[untyped]) -> void
@@ -54,6 +99,9 @@ module PaperTrailDiff
54
99
  # : (untyped, untyped, untyped) -> untyped
55
100
  def record_before: (untyped, untyped, untyped) -> untyped
56
101
 
102
+ # : (untyped, untyped, untyped) -> [Hash[untyped, untyped], Hash[untyped, untyped]]?
103
+ def transition: (untyped, untyped, untyped) -> [ Hash[untyped, untyped], Hash[untyped, untyped] ]?
104
+
57
105
  # : (untyped, Array[untyped]) -> Array[untyped]
58
106
  def records_for: (untyped, Array[untyped]) -> Array[untyped]
59
107
 
@@ -62,10 +110,14 @@ module PaperTrailDiff
62
110
 
63
111
  private
64
112
 
113
+ @seeded_live_records: Hash[Array[String], untyped]
114
+
65
115
  @series: Hash[Array[String], PreparedRecordSeries]
66
116
 
67
117
  @start_time: untyped
68
118
 
119
+ @state_loader: PreparedVersionStateLoader
120
+
69
121
  # : (untyped, untyped) -> Array[String]
70
122
  def identity: (untyped, untyped) -> Array[String]
71
123
 
@@ -78,6 +130,9 @@ module PaperTrailDiff
78
130
  # : (untyped, Array[untyped]) -> Array[untyped]
79
131
  def versions_for: (untyped, Array[untyped]) -> Array[untyped]
80
132
 
133
+ # : (untyped, Array[untyped]) -> Array[untyped]
134
+ def available_live_records: (untyped, Array[untyped]) -> Array[untyped]
135
+
81
136
  # : (untyped, Array[untyped]) -> Array[untyped]
82
137
  def live_records_for: (untyped, Array[untyped]) -> Array[untyped]
83
138
  end
@@ -26,6 +26,16 @@ module PaperTrailDiff
26
26
 
27
27
  SUPPORTED_KINDS: untyped
28
28
 
29
+ # Non-semantic memoization shared by structurally adjacent snapshots. The
30
+ # cached value is derived only from frozen records and is itself immutable.
31
+ class IdentityIndexCache
32
+ # : () -> void
33
+ def initialize: () -> void
34
+
35
+ # : (Array[RecordSnapshot]) -> CollectionIdentityIndex
36
+ def index: (Array[RecordSnapshot]) -> CollectionIdentityIndex
37
+ end
38
+
29
39
  # : (Symbol) -> bool
30
40
  def self.collection_kind?: (Symbol) -> bool
31
41
 
@@ -33,11 +43,36 @@ module PaperTrailDiff
33
43
 
34
44
  attr_reader records: Array[RecordSnapshot]
35
45
 
36
- # : (kind: Symbol, records: Array[RecordSnapshot]) -> void
37
- def initialize: (kind: Symbol, records: Array[RecordSnapshot]) -> void
46
+ # : (kind: Symbol, records: Array[RecordSnapshot], ?identity_index_cache: untyped, ?transition: CollectionTransition?) -> void
47
+ def initialize: (kind: Symbol, records: Array[RecordSnapshot], ?identity_index_cache: untyped, ?transition: CollectionTransition?) -> void
48
+
49
+ # Builds a structurally adjacent collection snapshot for internal activity carry-forward.
50
+ # : (Array[RecordSnapshot], before: RecordSnapshot?, after: RecordSnapshot?, membership_preserved: bool) -> AssociationSnapshot
51
+ def transition_to: (Array[RecordSnapshot], before: RecordSnapshot?, after: RecordSnapshot?, membership_preserved: bool) -> AssociationSnapshot
52
+
53
+ # : (AssociationSnapshot) -> CollectionTransition?
54
+ def transition_from: (AssociationSnapshot) -> CollectionTransition?
55
+
56
+ # : (untyped, untyped) -> Integer?
57
+ def position: (untyped, untyped) -> Integer?
58
+
59
+ # : (untyped) -> Integer?
60
+ def position_for_id: (untyped) -> Integer?
61
+
62
+ # : () -> void
63
+ def validate_unique_identities!: () -> void
38
64
 
39
65
  # : () -> Hash[Symbol, untyped]
40
66
  def to_h: () -> Hash[Symbol, untyped]
67
+
68
+ private
69
+
70
+ @identity_index_cache: untyped
71
+
72
+ @transition: CollectionTransition?
73
+
74
+ # : () -> CollectionIdentityIndex
75
+ def identity_index: () -> CollectionIdentityIndex
41
76
  end
42
77
 
43
78
  # An immutable, ActiveRecord-independent representation of a reified record.
@@ -21,9 +21,15 @@ module PaperTrailDiff
21
21
  # : (String, String) -> String
22
22
  def self?.association_path: (String, String) -> String
23
23
 
24
+ # : (Hash[String, Hash[Symbol, untyped]], Hash[String, Hash[Symbol, untyped]]) -> Hash[String, Hash[Symbol, untyped]]
25
+ def self?.merge_record_groups: (Hash[String, Hash[Symbol, untyped]], Hash[String, Hash[Symbol, untyped]]) -> Hash[String, Hash[Symbol, untyped]]
26
+
24
27
  # : (untyped) -> untyped
25
28
  def self?.duplicate_and_freeze: (untyped) -> untyped
26
29
 
30
+ # : (Hash[String, Array[untyped]]?, Hash[String, Array[untyped]]?) -> Hash[String, Array[untyped]]?
31
+ def self?.merge_record_owners: (Hash[String, Array[untyped]]?, Hash[String, Array[untyped]]?) -> Hash[String, Array[untyped]]?
32
+
27
33
  # : (untyped) -> bool
28
34
  def self?.paper_trail_diff_value?: (untyped) -> bool
29
35
  end
@@ -0,0 +1,46 @@
1
+ # Generated from lib/paper_trail_diff/time_activity_timeline_builder.rb with RBS::Inline
2
+
3
+ module PaperTrailDiff
4
+ # Builds activity views for mutations selected by a wall-clock range.
5
+ class TimeActivityTimelineBuilder
6
+ # : (untyped, range: TimelineRange, tree: AssociationTree, snapshotter: untyped) -> void
7
+ def initialize: (untyped, range: TimelineRange, tree: AssociationTree, snapshotter: untyped) -> void
8
+
9
+ # : () -> Array[ActivityStep]
10
+ def build: () -> Array[ActivityStep]
11
+
12
+ # : () -> Analysis
13
+ def analyze: () -> Analysis
14
+
15
+ private
16
+
17
+ @range: TimelineRange
18
+
19
+ @record: untyped
20
+
21
+ @snapshotter: untyped
22
+
23
+ @tree: AssociationTree
24
+
25
+ # : () -> [ActivityHistory, Array[untyped]]
26
+ def history_and_versions: () -> [ ActivityHistory, Array[untyped] ]
27
+
28
+ # : (Array[untyped]) -> void
29
+ def prepare_history: (Array[untyped]) -> void
30
+
31
+ # : (Array[untyped]) -> Array[ActivityEvent]
32
+ def collect_events: (Array[untyped]) -> Array[ActivityEvent]
33
+
34
+ # : (Array[ActivityEvent]) -> bool
35
+ def time_events?: (Array[ActivityEvent]) -> bool
36
+
37
+ # : (ActivityEvent, Array[ActivityEvent]) -> bool
38
+ def later_event?: (ActivityEvent, Array[ActivityEvent]) -> bool
39
+
40
+ # : (Array[untyped], Hash[Array[untyped], RecordSnapshot?]) -> Array[Step]
41
+ def root_steps: (Array[untyped], Hash[Array[untyped], RecordSnapshot?]) -> Array[Step]
42
+
43
+ # : (untyped) -> Array[untyped]
44
+ def version_key: (untyped) -> Array[untyped]
45
+ end
46
+ end
@@ -0,0 +1,41 @@
1
+ # Generated from lib/paper_trail_diff/time_range.rb with RBS::Inline
2
+
3
+ module PaperTrailDiff
4
+ # Validates and applies a finite wall-clock range without loading model state.
5
+ class TimeRange
6
+ attr_reader begin_time: Time
7
+
8
+ attr_reader end_time: Time
9
+
10
+ # : (untyped) -> void
11
+ def initialize: (untyped) -> void
12
+
13
+ # : () -> bool
14
+ def exclude_end?: () -> bool
15
+
16
+ # : (untyped) -> bool
17
+ def include?: (untyped) -> bool
18
+
19
+ # : (untyped) -> untyped
20
+ def scope: (untyped) -> untyped
21
+
22
+ # : (untyped) -> untyped
23
+ def trailing_scope: (untyped) -> untyped
24
+
25
+ private
26
+
27
+ @exclude_end: bool
28
+
29
+ # : () -> Range[Time]
30
+ def query_range: () -> Range[Time]
31
+
32
+ # : (untyped, boundary: Symbol) -> Time
33
+ def coerce_time: (untyped, boundary: Symbol) -> Time
34
+
35
+ # : (untyped) -> Time
36
+ def time_value: (untyped) -> Time
37
+
38
+ # : () -> void
39
+ def validate_order!: () -> void
40
+ end
41
+ end
@@ -0,0 +1,27 @@
1
+ # Generated from lib/paper_trail_diff/time_version_range.rb with RBS::Inline
2
+
3
+ module PaperTrailDiff
4
+ # Selects in-range root versions plus one later reconstruction boundary.
5
+ class TimeVersionRange
6
+ # : (untyped, time_range: TimeRange) -> void
7
+ def initialize: (untyped, time_range: TimeRange) -> void
8
+
9
+ # : (?context_required: bool) -> Array[untyped]
10
+ def select: (?context_required: bool) -> Array[untyped]
11
+
12
+ private
13
+
14
+ @record: untyped
15
+
16
+ @time_range: TimeRange
17
+
18
+ # : () -> untyped
19
+ def versions_relation: () -> untyped
20
+
21
+ # : (untyped) -> untyped
22
+ def trailing_version: (untyped) -> untyped
23
+
24
+ # : (Array[untyped]) -> Array[untyped]
25
+ def ordered: (Array[untyped]) -> Array[untyped]
26
+ end
27
+ end
@@ -3,8 +3,8 @@
3
3
  module PaperTrailDiff
4
4
  # Selects and compares a chronological slice of a record's version history.
5
5
  class TimelineBuilder
6
- # : (untyped, from: untyped, to: untyped, snapshotter: untyped) -> void
7
- def initialize: (untyped, from: untyped, to: untyped, snapshotter: untyped) -> void
6
+ # : (untyped, from: untyped, to: untyped, snapshotter: untyped, ?within: untyped) -> void
7
+ def initialize: (untyped, from: untyped, to: untyped, snapshotter: untyped, ?within: untyped) -> void
8
8
 
9
9
  # : () -> Array[Step]
10
10
  def build: () -> Array[Step]
@@ -14,17 +14,18 @@ module PaperTrailDiff
14
14
 
15
15
  private
16
16
 
17
- @from: untyped
17
+ @range: TimelineRange
18
18
 
19
19
  @record: untyped
20
20
 
21
21
  @snapshotter: untyped
22
22
 
23
- @to: untyped
24
-
25
23
  # : (Array[untyped]) -> [Array[Step], RecordSnapshot?, RecordSnapshot?]
26
24
  def compare_history: (Array[untyped]) -> [ Array[Step], RecordSnapshot?, RecordSnapshot? ]
27
25
 
26
+ # : () -> [Array[Step], nil, nil]
27
+ def empty_history: () -> [ Array[Step], nil, nil ]
28
+
28
29
  # : () -> Array[untyped]
29
30
  def selected_versions: () -> Array[untyped]
30
31
  end
@@ -0,0 +1,41 @@
1
+ # Generated from lib/paper_trail_diff/timeline_range.rb with RBS::Inline
2
+
3
+ module PaperTrailDiff
4
+ # Chooses explicit-version or wall-clock selection for one timeline request.
5
+ class TimelineRange
6
+ attr_reader from: untyped
7
+
8
+ attr_reader to: untyped
9
+
10
+ attr_reader time_range: TimeRange?
11
+
12
+ # : (untyped, from: untyped, to: untyped, within: untyped) -> void
13
+ def initialize: (untyped, from: untyped, to: untyped, within: untyped) -> void
14
+
15
+ # : (?context_required: bool) -> Array[untyped]
16
+ def select: (?context_required: bool) -> Array[untyped]
17
+
18
+ # : () -> bool
19
+ def time?: () -> bool
20
+
21
+ # : () -> Time?
22
+ def begin_time: () -> Time?
23
+
24
+ # : (untyped) -> bool
25
+ def include?: (untyped) -> bool
26
+
27
+ private
28
+
29
+ @from: untyped
30
+
31
+ @record: untyped
32
+
33
+ @to: untyped
34
+
35
+ # : (untyped) -> TimeRange?
36
+ def build_time_range: (untyped) -> TimeRange?
37
+
38
+ # : () -> void
39
+ def validate_mode!: () -> void
40
+ end
41
+ end
@@ -0,0 +1,32 @@
1
+ # Generated from lib/paper_trail_diff/version_association_candidate_scope.rb with RBS::Inline
2
+
3
+ module PaperTrailDiff
4
+ # Selects association activity from a boundary forward plus the state at that boundary.
5
+ class VersionAssociationCandidateScope
6
+ # : (untyped, untyped, ?end_at: untyped) -> void
7
+ def initialize: (untyped, untyped, ?end_at: untyped) -> void
8
+
9
+ # : (untyped) -> untyped
10
+ def call: (untyped) -> untyped
11
+
12
+ private
13
+
14
+ @end_at: untyped
15
+
16
+ @start_at: untyped
17
+
18
+ @version_class: untyped
19
+
20
+ # : () -> String
21
+ def candidate_condition: () -> String
22
+
23
+ # : (String, String) -> String
24
+ def activity_condition: (String, String) -> String
25
+
26
+ # : (String, String) -> String
27
+ def column: (String, String) -> String
28
+
29
+ # : (String) -> String
30
+ def compact_sql: (String) -> String
31
+ end
32
+ end