paper_trail_diff 0.14.0 → 0.15.0
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 +4 -4
- data/CHANGELOG.md +343 -0
- data/QUICKSTART.md +21 -4
- data/README.md +58 -55
- data/docs/architecture.md +32 -11
- data/docs/performance.md +116 -391
- data/docs/reference.md +345 -106
- data/docs/testing.md +63 -7
- data/lib/paper_trail_diff/activity_boundary.rb +83 -26
- data/lib/paper_trail_diff/activity_child_candidate_loader.rb +2 -1
- data/lib/paper_trail_diff/activity_event.rb +41 -10
- data/lib/paper_trail_diff/activity_history.rb +34 -9
- data/lib/paper_trail_diff/activity_range.rb +18 -3
- data/lib/paper_trail_diff/activity_snapshot_sequence.rb +76 -37
- data/lib/paper_trail_diff/activity_target_candidate_loader.rb +5 -5
- data/lib/paper_trail_diff/activity_timeline_builder.rb +266 -111
- data/lib/paper_trail_diff/activity_transaction_grouper.rb +2 -1
- data/lib/paper_trail_diff/activity_tree_filter.rb +114 -0
- data/lib/paper_trail_diff/activity_version_collector.rb +7 -5
- data/lib/paper_trail_diff/activity_view.rb +69 -0
- data/lib/paper_trail_diff/analysis.rb +13 -1
- data/lib/paper_trail_diff/analysis_batch.rb +24 -30
- data/lib/paper_trail_diff/approximate_paths.rb +48 -0
- data/lib/paper_trail_diff/association_activity_edge.rb +6 -6
- data/lib/paper_trail_diff/association_discovery.rb +9 -1
- data/lib/paper_trail_diff/association_key.rb +56 -0
- data/lib/paper_trail_diff/association_traversal.rb +13 -4
- data/lib/paper_trail_diff/batch_boundary_resolver.rb +3 -4
- data/lib/paper_trail_diff/batch_preload.rb +53 -0
- data/lib/paper_trail_diff/batched_root_analyzer.rb +12 -14
- data/lib/paper_trail_diff/batched_root_versions.rb +38 -14
- data/lib/paper_trail_diff/change_row.rb +133 -0
- data/lib/paper_trail_diff/collection_comparator.rb +5 -32
- data/lib/paper_trail_diff/configuration.rb +35 -12
- data/lib/paper_trail_diff/deleted_analysis_batch.rb +18 -18
- data/lib/paper_trail_diff/deleted_root_filter.rb +79 -0
- data/lib/paper_trail_diff/deprecation.rb +61 -0
- data/lib/paper_trail_diff/diagnostics.rb +84 -99
- data/lib/paper_trail_diff/endpoint.rb +26 -3
- data/lib/paper_trail_diff/errors.rb +3 -1
- data/lib/paper_trail_diff/fallback_paths.rb +38 -0
- data/lib/paper_trail_diff/historical_association_reifier.rb +2 -4
- data/lib/paper_trail_diff/historical_filter.rb +19 -10
- data/lib/paper_trail_diff/historical_snapshot_store.rb +57 -67
- data/lib/paper_trail_diff/live_endpoint_batch_loader.rb +1 -35
- data/lib/paper_trail_diff/nested_comparator.rb +19 -18
- data/lib/paper_trail_diff/paper_trail_adapter.rb +122 -127
- data/lib/paper_trail_diff/preloaded_endpoint_batch_loader.rb +13 -1
- data/lib/paper_trail_diff/prepared_activity_index.rb +1 -1
- data/lib/paper_trail_diff/prepared_edge_loader.rb +2 -1
- data/lib/paper_trail_diff/prepared_history.rb +9 -1
- data/lib/paper_trail_diff/prepared_history_loader.rb +1 -0
- data/lib/paper_trail_diff/prepared_record_index.rb +38 -7
- data/lib/paper_trail_diff/root_version_selection.rb +4 -2
- data/lib/paper_trail_diff/scope_condition.rb +76 -21
- data/lib/paper_trail_diff/scope_ranking.rb +12 -2
- data/lib/paper_trail_diff/scoped_analysis.rb +11 -0
- data/lib/paper_trail_diff/scoped_analysis_builder.rb +16 -8
- data/lib/paper_trail_diff/scoped_root_selection.rb +18 -12
- data/lib/paper_trail_diff/snapshot.rb +16 -1
- data/lib/paper_trail_diff/support.rb +29 -2
- data/lib/paper_trail_diff/time_range.rb +32 -10
- data/lib/paper_trail_diff/timeline_builder.rb +7 -7
- data/lib/paper_trail_diff/timeline_range.rb +9 -1
- data/lib/paper_trail_diff/timeline_snapshot_provider.rb +24 -17
- data/lib/paper_trail_diff/transaction_cut.rb +181 -0
- data/lib/paper_trail_diff/traversal_preparer.rb +134 -29
- data/lib/paper_trail_diff/version.rb +1 -1
- data/lib/paper_trail_diff/version_boundary.rb +37 -8
- data/lib/paper_trail_diff/version_query.rb +34 -10
- data/lib/paper_trail_diff/version_scope_filter.rb +9 -10
- data/lib/paper_trail_diff/version_sequence_diagnostics.rb +31 -16
- data/lib/paper_trail_diff/version_table.rb +60 -0
- data/lib/paper_trail_diff.rb +98 -56
- data/sig/generated/paper_trail_diff/activity_boundary.rbs +54 -19
- data/sig/generated/paper_trail_diff/activity_event.rbs +25 -4
- data/sig/generated/paper_trail_diff/activity_history.rbs +21 -6
- data/sig/generated/paper_trail_diff/activity_range.rbs +9 -2
- data/sig/generated/paper_trail_diff/activity_snapshot_sequence.rbs +48 -9
- data/sig/generated/paper_trail_diff/activity_timeline_builder.rbs +134 -30
- data/sig/generated/paper_trail_diff/activity_tree_filter.rbs +73 -0
- data/sig/generated/paper_trail_diff/activity_version_collector.rbs +2 -0
- data/sig/generated/paper_trail_diff/activity_view.rbs +42 -0
- data/sig/generated/paper_trail_diff/analysis.rbs +8 -1
- data/sig/generated/paper_trail_diff/analysis_batch.rbs +8 -15
- data/sig/generated/paper_trail_diff/approximate_paths.rbs +23 -0
- data/sig/generated/paper_trail_diff/association_discovery.rbs +5 -0
- data/sig/generated/paper_trail_diff/association_key.rbs +29 -0
- data/sig/generated/paper_trail_diff/association_traversal.rbs +4 -0
- data/sig/generated/paper_trail_diff/batch_preload.rbs +29 -0
- data/sig/generated/paper_trail_diff/batched_root_analyzer.rbs +9 -10
- data/sig/generated/paper_trail_diff/batched_root_versions.rbs +14 -4
- data/sig/generated/paper_trail_diff/change_row.rbs +86 -0
- data/sig/generated/paper_trail_diff/collection_comparator.rbs +2 -16
- data/sig/generated/paper_trail_diff/configuration.rbs +19 -3
- data/sig/generated/paper_trail_diff/deleted_analysis_batch.rbs +8 -8
- data/sig/generated/paper_trail_diff/deleted_root_filter.rbs +48 -0
- data/sig/generated/paper_trail_diff/deprecation.rbs +35 -0
- data/sig/generated/paper_trail_diff/diagnostics.rbs +37 -30
- data/sig/generated/paper_trail_diff/endpoint.rbs +11 -2
- data/sig/generated/paper_trail_diff/errors.rbs +3 -1
- data/sig/generated/paper_trail_diff/fallback_paths.rbs +22 -0
- data/sig/generated/paper_trail_diff/historical_filter.rbs +12 -2
- data/sig/generated/paper_trail_diff/historical_snapshot_store.rbs +33 -28
- data/sig/generated/paper_trail_diff/live_endpoint_batch_loader.rbs +0 -15
- data/sig/generated/paper_trail_diff/nested_comparator.rbs +10 -7
- data/sig/generated/paper_trail_diff/paper_trail_adapter.rbs +54 -52
- data/sig/generated/paper_trail_diff/preloaded_endpoint_batch_loader.rbs +9 -1
- data/sig/generated/paper_trail_diff/prepared_history.rbs +5 -0
- data/sig/generated/paper_trail_diff/prepared_record_index.rbs +19 -2
- data/sig/generated/paper_trail_diff/root_version_selection.rbs +2 -0
- data/sig/generated/paper_trail_diff/scope_condition.rbs +43 -9
- data/sig/generated/paper_trail_diff/scope_ranking.rbs +8 -0
- data/sig/generated/paper_trail_diff/scoped_analysis.rbs +6 -0
- data/sig/generated/paper_trail_diff/scoped_analysis_builder.rbs +6 -1
- data/sig/generated/paper_trail_diff/scoped_root_selection.rbs +8 -4
- data/sig/generated/paper_trail_diff/snapshot.rbs +8 -0
- data/sig/generated/paper_trail_diff/support.rbs +15 -0
- data/sig/generated/paper_trail_diff/time_range.rbs +20 -6
- data/sig/generated/paper_trail_diff/timeline_builder.rbs +2 -2
- data/sig/generated/paper_trail_diff/timeline_range.rbs +2 -0
- data/sig/generated/paper_trail_diff/timeline_snapshot_provider.rbs +17 -7
- data/sig/generated/paper_trail_diff/transaction_cut.rbs +94 -0
- data/sig/generated/paper_trail_diff/traversal_preparer.rbs +66 -8
- data/sig/generated/paper_trail_diff/version_boundary.rbs +20 -3
- data/sig/generated/paper_trail_diff/version_query.rbs +18 -2
- data/sig/generated/paper_trail_diff/version_scope_filter.rbs +4 -5
- data/sig/generated/paper_trail_diff/version_sequence_diagnostics.rbs +16 -9
- data/sig/generated/paper_trail_diff/version_table.rbs +30 -0
- data/sig/generated/paper_trail_diff.rbs +29 -26
- metadata +46 -10
- data/lib/paper_trail_diff/activity_grouping.rb +0 -38
- data/lib/paper_trail_diff/batch_safety.rb +0 -63
- data/lib/paper_trail_diff/time_activity_timeline_builder.rb +0 -223
- data/sig/generated/paper_trail_diff/activity_grouping.rbs +0 -22
- data/sig/generated/paper_trail_diff/batch_safety.rbs +0 -30
- data/sig/generated/paper_trail_diff/time_activity_timeline_builder.rbs +0 -92
|
@@ -7,19 +7,26 @@ module PaperTrailDiff
|
|
|
7
7
|
|
|
8
8
|
attr_reader branches: Array[String]?
|
|
9
9
|
|
|
10
|
-
# : (version: untyped, branches: Array[String]?) -> void
|
|
11
|
-
def initialize: (version: untyped, branches: Array[String]?) -> void
|
|
10
|
+
# : (version: untyped, branches: Array[String]?, ?join: bool) -> void
|
|
11
|
+
def initialize: (version: untyped, branches: Array[String]?, ?join: bool) -> void
|
|
12
12
|
|
|
13
13
|
# : () -> bool
|
|
14
14
|
def root?: () -> bool
|
|
15
|
+
|
|
16
|
+
# Whether the version is of a through's join row, which links the root to
|
|
17
|
+
# a target without being one.
|
|
18
|
+
# : () -> bool
|
|
19
|
+
def join?: () -> bool
|
|
20
|
+
|
|
21
|
+
@join: bool
|
|
15
22
|
end
|
|
16
23
|
|
|
17
24
|
# Accumulates each version once while retaining every selected root branch.
|
|
18
25
|
class ActivityEventRegistry
|
|
19
26
|
def initialize: () -> untyped
|
|
20
27
|
|
|
21
|
-
# : (Array[untyped], ?branch: String?) -> void
|
|
22
|
-
def add: (Array[untyped], ?branch: String?) -> void
|
|
28
|
+
# : (Array[untyped], ?branch: String?, ?join: bool) -> void
|
|
29
|
+
def add: (Array[untyped], ?branch: String?, ?join: bool) -> void
|
|
23
30
|
|
|
24
31
|
# : () -> Array[ActivityEvent]
|
|
25
32
|
def to_a: () -> Array[ActivityEvent]
|
|
@@ -34,6 +41,20 @@ module PaperTrailDiff
|
|
|
34
41
|
|
|
35
42
|
# Resolves the branch union that PT-AT exposes atomically for one transaction.
|
|
36
43
|
class ActivityTransactionGroups
|
|
44
|
+
# A range ending at a version ends at the state before that version's
|
|
45
|
+
# transaction: PT-AT rebuilds its associations without the changes saved
|
|
46
|
+
# alongside it. A descendant version from that transaction, such as the
|
|
47
|
+
# child update behind a `touch: true` parent version, is therefore past the
|
|
48
|
+
# end. Kept, it would open a step whose change the closing state cannot
|
|
49
|
+
# show, and that change would be reported nowhere. A range ending at a time
|
|
50
|
+
# has no transaction to stop before.
|
|
51
|
+
# : (Array[ActivityEvent], untyped) -> Array[ActivityEvent]
|
|
52
|
+
def self.before_closing: (Array[ActivityEvent], untyped) -> Array[ActivityEvent]
|
|
53
|
+
|
|
54
|
+
# A version without a transaction shares one with nothing.
|
|
55
|
+
# : (untyped) -> Array[untyped]?
|
|
56
|
+
def self.transaction_key: (untyped) -> Array[untyped]?
|
|
57
|
+
|
|
37
58
|
# : (Array[ActivityEvent]) -> void
|
|
38
59
|
def initialize: (Array[ActivityEvent]) -> void
|
|
39
60
|
|
|
@@ -24,14 +24,19 @@ module PaperTrailDiff
|
|
|
24
24
|
|
|
25
25
|
# Builds activity steps while retaining root snapshots for combined analysis.
|
|
26
26
|
class ActivityHistoryBuilder
|
|
27
|
-
#
|
|
28
|
-
|
|
27
|
+
# `closing` is the snapshot after the last event when the range closes on
|
|
28
|
+
# the current record. Any other range ends at a root event, or at events
|
|
29
|
+
# after a window whose steps are not reported, so nothing reads it.
|
|
30
|
+
# : (Array[untyped], Array[ActivityEvent], untyped, view: ActivityView, ?current: untyped, ?include_step: untyped, ?closing: RecordSnapshot?) -> void
|
|
31
|
+
def initialize: (Array[untyped], Array[ActivityEvent], untyped, view: ActivityView, ?current: untyped, ?include_step: untyped, ?closing: RecordSnapshot?) -> void
|
|
29
32
|
|
|
30
33
|
# : () -> ActivityHistory
|
|
31
34
|
def call: () -> ActivityHistory
|
|
32
35
|
|
|
33
36
|
private
|
|
34
37
|
|
|
38
|
+
@closing: RecordSnapshot?
|
|
39
|
+
|
|
35
40
|
@current: untyped
|
|
36
41
|
|
|
37
42
|
@events: Array[ActivityEvent]
|
|
@@ -40,6 +45,8 @@ module PaperTrailDiff
|
|
|
40
45
|
|
|
41
46
|
@include_step: untyped
|
|
42
47
|
|
|
48
|
+
@passed_reported: bool
|
|
49
|
+
|
|
43
50
|
@previous_boundary: ActivityBoundary?
|
|
44
51
|
|
|
45
52
|
@previous_event: ActivityEvent?
|
|
@@ -52,20 +59,28 @@ module PaperTrailDiff
|
|
|
52
59
|
|
|
53
60
|
@selected_last_snapshot: RecordSnapshot?
|
|
54
61
|
|
|
55
|
-
@snapshots: bool
|
|
56
|
-
|
|
57
62
|
@snapshotter: untyped
|
|
58
63
|
|
|
59
64
|
@steps: Array[ActivityStep]
|
|
60
65
|
|
|
66
|
+
@view: ActivityView
|
|
67
|
+
|
|
61
68
|
# : () -> void
|
|
62
69
|
def reset: () -> void
|
|
63
70
|
|
|
71
|
+
# : () -> ActivityTreeFilter
|
|
72
|
+
def filter: () -> ActivityTreeFilter
|
|
73
|
+
|
|
64
74
|
# : () -> ActivitySnapshotSequence
|
|
65
75
|
def sequence: () -> ActivitySnapshotSequence
|
|
66
76
|
|
|
67
|
-
#
|
|
68
|
-
|
|
77
|
+
# A left-out event bounds nothing. A reported step it would have opened
|
|
78
|
+
# still moves the reported range's end past it, to the next boundary.
|
|
79
|
+
# : (ActivityEvent, RecordSnapshot?, bool) -> void
|
|
80
|
+
def consume: (ActivityEvent, RecordSnapshot?, bool) -> void
|
|
81
|
+
|
|
82
|
+
# : (ActivityEvent) -> void
|
|
83
|
+
def pass: (ActivityEvent) -> void
|
|
69
84
|
|
|
70
85
|
# : (RecordSnapshot?) -> void
|
|
71
86
|
def capture_first: (RecordSnapshot?) -> void
|
|
@@ -13,8 +13,9 @@ module PaperTrailDiff
|
|
|
13
13
|
# : (untyped) -> bool
|
|
14
14
|
def include?: (untyped) -> bool
|
|
15
15
|
|
|
16
|
-
# Narrows an Active Record version relation by timestamp
|
|
17
|
-
# remains in #include? so this
|
|
16
|
+
# Narrows an Active Record version relation by timestamp, and to the
|
|
17
|
+
# start's transaction. Exact tie-breaking remains in #include? so this
|
|
18
|
+
# works for integer, UUID, and custom version IDs.
|
|
18
19
|
# : (untyped) -> untyped
|
|
19
20
|
def scope: (untyped) -> untyped
|
|
20
21
|
|
|
@@ -33,10 +34,16 @@ module PaperTrailDiff
|
|
|
33
34
|
|
|
34
35
|
@end_key: Array[untyped]?
|
|
35
36
|
|
|
37
|
+
@opening_transaction: Array[untyped]?
|
|
38
|
+
|
|
36
39
|
@start_key: Array[untyped]?
|
|
37
40
|
|
|
38
41
|
@start_time: untyped
|
|
39
42
|
|
|
43
|
+
# A range starting at a version starts before that version's transaction,
|
|
44
|
+
# where PT-AT reads its associations. A version saved earlier in it, such
|
|
45
|
+
# as the child update behind a `touch: true` parent version, is a change
|
|
46
|
+
# inside the range.
|
|
40
47
|
# : (untyped, Array[untyped]) -> bool
|
|
41
48
|
def after_start?: (untyped, Array[untyped]) -> bool
|
|
42
49
|
|
|
@@ -1,13 +1,44 @@
|
|
|
1
1
|
# Generated from lib/paper_trail_diff/activity_snapshot_sequence.rb with RBS::Inline
|
|
2
2
|
|
|
3
3
|
module PaperTrailDiff
|
|
4
|
-
#
|
|
4
|
+
# Prepares the snapshot store for an activity build, one root at a time.
|
|
5
|
+
# Before that, it reads the live record a range closes on.
|
|
5
6
|
class ActivitySnapshotProvider
|
|
6
|
-
#
|
|
7
|
-
|
|
7
|
+
# `snapshotter` reads a full snapshot with a given history, and `refresher`
|
|
8
|
+
# builds the incremental refresher for one root's snapshots.
|
|
9
|
+
# : (store: HistoricalSnapshotStore, snapshotter: untyped, refresher: untyped) -> void
|
|
10
|
+
def initialize: (store: HistoricalSnapshotStore, snapshotter: untyped, refresher: untyped) -> void
|
|
11
|
+
|
|
12
|
+
# Roots a batch prepared together share its history, so consecutive ones
|
|
13
|
+
# share these snapshots too, and the caches their refresher builds. They
|
|
14
|
+
# are the same for any root with that history, so reusing them depends on
|
|
15
|
+
# nothing but the history.
|
|
16
|
+
# : (untyped, Array[untyped], ?start_at: untyped, ?end_at: untyped) -> PreparedActivitySnapshots
|
|
17
|
+
def prepare: (untyped, Array[untyped], ?start_at: untyped, ?end_at: untyped) -> PreparedActivitySnapshots
|
|
8
18
|
|
|
9
|
-
# : (untyped,
|
|
10
|
-
def
|
|
19
|
+
# : (untyped, untyped) -> RecordSnapshot?
|
|
20
|
+
def call: (untyped, untyped) -> RecordSnapshot?
|
|
21
|
+
|
|
22
|
+
@last: PreparedActivitySnapshots?
|
|
23
|
+
|
|
24
|
+
@refresher: untyped
|
|
25
|
+
|
|
26
|
+
@snapshotter: untyped
|
|
27
|
+
|
|
28
|
+
@store: HistoricalSnapshotStore
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# One root's full and incremental snapshots during an activity build. Each
|
|
32
|
+
# read passes along the history prepared for this root, so none depends on
|
|
33
|
+
# which root was prepared last.
|
|
34
|
+
class PreparedActivitySnapshots
|
|
35
|
+
attr_reader history: PreparedHistory?
|
|
36
|
+
|
|
37
|
+
# : (PreparedHistory?, store: HistoricalSnapshotStore, snapshotter: untyped, refresher: untyped) -> void
|
|
38
|
+
def initialize: (PreparedHistory?, store: HistoricalSnapshotStore, snapshotter: untyped, refresher: untyped) -> void
|
|
39
|
+
|
|
40
|
+
# : () -> PreparedActivityIndex?
|
|
41
|
+
def activity_index: () -> PreparedActivityIndex?
|
|
11
42
|
|
|
12
43
|
# : (untyped, untyped) -> RecordSnapshot?
|
|
13
44
|
def call: (untyped, untyped) -> RecordSnapshot?
|
|
@@ -18,16 +49,24 @@ module PaperTrailDiff
|
|
|
18
49
|
# : (untyped, untyped, RecordSnapshot?, event: ActivityEvent) -> RecordSnapshot?
|
|
19
50
|
def advance_root: (untyped, untyped, RecordSnapshot?, event: ActivityEvent) -> RecordSnapshot?
|
|
20
51
|
|
|
21
|
-
#
|
|
22
|
-
|
|
52
|
+
# The branches a refresh rebuilds, with this root's history.
|
|
53
|
+
# : (untyped, untyped, tree: AssociationTree, normalizer: SnapshotNormalizer) -> RecordSnapshot?
|
|
54
|
+
def custom: (untyped, untyped, tree: AssociationTree, normalizer: SnapshotNormalizer) -> RecordSnapshot?
|
|
23
55
|
|
|
24
|
-
|
|
56
|
+
# : (untyped, habtm_version: untyped) -> untyped
|
|
57
|
+
def association_reader: (untyped, habtm_version: untyped) -> untyped
|
|
25
58
|
|
|
26
|
-
|
|
59
|
+
# : (untyped) -> [Hash[untyped, untyped], Hash[untyped, untyped]]?
|
|
60
|
+
def record_transition: (untyped) -> [ Hash[untyped, untyped], Hash[untyped, untyped] ]?
|
|
61
|
+
|
|
62
|
+
# : (untyped, ?direct: bool) -> [bool, untyped]
|
|
63
|
+
def record_after: (untyped, ?direct: bool) -> [ bool, untyped ]
|
|
27
64
|
|
|
28
65
|
@refresher: untyped
|
|
29
66
|
|
|
30
67
|
@snapshotter: untyped
|
|
68
|
+
|
|
69
|
+
@store: HistoricalSnapshotStore
|
|
31
70
|
end
|
|
32
71
|
|
|
33
72
|
# Builds chronological snapshots, refreshing only branches affected by prior events.
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
# Generated from lib/paper_trail_diff/activity_timeline_builder.rb with RBS::Inline
|
|
2
2
|
|
|
3
3
|
module PaperTrailDiff
|
|
4
|
-
# Compares adjacent root and selected-descendant activity boundaries
|
|
4
|
+
# Compares adjacent root and selected-descendant activity boundaries, between
|
|
5
|
+
# explicit endpoints or over a wall-clock window. Both replay the range's
|
|
6
|
+
# events into steps the same way, and close on the live row the same way.
|
|
7
|
+
# They differ in what they report and what closes them: explicit endpoints
|
|
8
|
+
# report every step between them and close on the endpoint asked for; a
|
|
9
|
+
# window reports only the events inside it, and closes on a final destroy,
|
|
10
|
+
# or on the live row when nothing recorded follows it.
|
|
5
11
|
class ActivityTimelineBuilder
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
# : (untyped, range: TimelineRange, tree: AssociationTree, snapshotter: untyped, snapshots: bool, group: Symbol?) -> void
|
|
9
|
-
def initialize: (untyped, range: TimelineRange, tree: AssociationTree, snapshotter: untyped, snapshots: bool, group: Symbol?) -> void
|
|
12
|
+
# : (untyped, range: TimelineRange, tree: AssociationTree, snapshotter: untyped, view: ActivityView) -> void
|
|
13
|
+
def initialize: (untyped, range: TimelineRange, tree: AssociationTree, snapshotter: untyped, view: ActivityView) -> void
|
|
10
14
|
|
|
11
15
|
# : () -> Array[ActivityStep]
|
|
12
16
|
def build: () -> Array[ActivityStep]
|
|
13
17
|
|
|
14
|
-
# Builds
|
|
18
|
+
# Builds the endpoint diff, the root timeline, and the activity from one
|
|
19
|
+
# activity snapshot pass.
|
|
15
20
|
# : () -> Analysis
|
|
16
21
|
def analyze: () -> Analysis
|
|
17
22
|
|
|
@@ -21,14 +26,14 @@ module PaperTrailDiff
|
|
|
21
26
|
|
|
22
27
|
@record: untyped
|
|
23
28
|
|
|
24
|
-
@snapshots: bool
|
|
25
|
-
|
|
26
29
|
@snapshotter: untyped
|
|
27
30
|
|
|
28
31
|
@to: untyped
|
|
29
32
|
|
|
30
33
|
@tree: AssociationTree
|
|
31
34
|
|
|
35
|
+
@view: ActivityView
|
|
36
|
+
|
|
32
37
|
# : () -> Array[ActivityStep]
|
|
33
38
|
def no_steps: () -> Array[ActivityStep]
|
|
34
39
|
|
|
@@ -40,6 +45,10 @@ module PaperTrailDiff
|
|
|
40
45
|
# : () -> Array[ActivityStep]
|
|
41
46
|
def build_between_versions: () -> Array[ActivityStep]
|
|
42
47
|
|
|
48
|
+
# Activity from the first to the last of the root versions.
|
|
49
|
+
# : (Array[untyped]) -> ActivityHistory
|
|
50
|
+
def version_history: (Array[untyped]) -> ActivityHistory
|
|
51
|
+
|
|
43
52
|
# : () -> Array[ActivityStep]
|
|
44
53
|
def build_to_current: () -> Array[ActivityStep]
|
|
45
54
|
|
|
@@ -48,14 +57,22 @@ module PaperTrailDiff
|
|
|
48
57
|
|
|
49
58
|
# The explicit live endpoint and a batch's live closing endpoint use the
|
|
50
59
|
# same selected plan. A version filter can close earlier, on its successor.
|
|
51
|
-
# : () -> [RootVersionPlan,
|
|
52
|
-
def current_history: () -> [ RootVersionPlan,
|
|
60
|
+
# : () -> [RootVersionPlan, ActivityHistory, RecordSnapshot?, ActivityBoundary?]
|
|
61
|
+
def current_history: () -> [ RootVersionPlan, ActivityHistory, RecordSnapshot?, ActivityBoundary? ]
|
|
62
|
+
|
|
63
|
+
# Events up to the instant the current record was read. A range that a
|
|
64
|
+
# version filter closes earlier ends at that version, with no snapshot.
|
|
65
|
+
# : (RootVersionPlan, RecordSnapshot?, untyped) -> ActivityHistory
|
|
66
|
+
def history_until: (RootVersionPlan, RecordSnapshot?, untyped) -> ActivityHistory
|
|
53
67
|
|
|
54
|
-
# Without a closing boundary nothing reads the
|
|
55
|
-
#
|
|
68
|
+
# Without a closing boundary nothing reads the closing pair, so its
|
|
69
|
+
# mutations cannot change an answer.
|
|
56
70
|
# mutant:disable
|
|
57
|
-
# : (RootVersionPlan) -> [RootVersionPlan,
|
|
58
|
-
def empty_history: (RootVersionPlan) -> [ RootVersionPlan,
|
|
71
|
+
# : (RootVersionPlan) -> [RootVersionPlan, ActivityHistory, RecordSnapshot?, ActivityBoundary?]
|
|
72
|
+
def empty_history: (RootVersionPlan) -> [ RootVersionPlan, ActivityHistory, RecordSnapshot?, ActivityBoundary? ]
|
|
73
|
+
|
|
74
|
+
# : (untyped) -> ActivityBoundary
|
|
75
|
+
def current_boundary: (untyped) -> ActivityBoundary
|
|
59
76
|
|
|
60
77
|
# : () -> [RecordSnapshot?, untyped]
|
|
61
78
|
def capture_current: () -> [ RecordSnapshot?, untyped ]
|
|
@@ -63,33 +80,120 @@ module PaperTrailDiff
|
|
|
63
80
|
# : () -> void
|
|
64
81
|
def validate_current_range!: () -> void
|
|
65
82
|
|
|
66
|
-
# : (Array[untyped], ?range_start: untyped, ?range_end: untyped) -> Array[ActivityEvent]
|
|
67
|
-
def collect_events: (Array[untyped], ?range_start: untyped, ?range_end: untyped) -> Array[ActivityEvent]
|
|
68
|
-
|
|
69
|
-
# : (Array[untyped], ?end_at: untyped) -> void
|
|
70
|
-
def prepare_history: (Array[untyped], ?end_at: untyped) -> void
|
|
71
|
-
|
|
72
83
|
# Appends the transition into an explicit closing boundary, which is either
|
|
73
84
|
# a requested current record or the absence a final root destroy leaves.
|
|
74
|
-
# Either follows the root versions, which are themselves events
|
|
75
|
-
#
|
|
76
|
-
|
|
85
|
+
# Either follows the root versions, which are themselves events, so the
|
|
86
|
+
# last boundary the history kept opens it.
|
|
87
|
+
# : (ActivityHistory, ActivityBoundary?, RecordSnapshot?) -> Array[ActivityStep]
|
|
88
|
+
def activity_steps: (ActivityHistory, ActivityBoundary?, RecordSnapshot?) -> Array[ActivityStep]
|
|
77
89
|
|
|
78
90
|
# A destroyed root has no later version, but its own event states that
|
|
79
91
|
# nothing follows it, so the removal can still close the timeline.
|
|
80
92
|
# : (Array[untyped]) -> ActivityBoundary?
|
|
81
93
|
def destroyed_boundary: (Array[untyped]) -> ActivityBoundary?
|
|
82
94
|
|
|
83
|
-
# : (Array[untyped], Array[ActivityEvent], ?current: untyped) -> ActivityHistory
|
|
84
|
-
def event_history: (Array[untyped], Array[ActivityEvent], ?current: untyped) -> ActivityHistory
|
|
85
|
-
|
|
86
95
|
# Only the activity view gains the closing removal. The endpoint diff and
|
|
87
96
|
# the root timeline keep their `compare` and `timeline` semantics, under
|
|
88
97
|
# which the state at a destroy version is the state before the deletion.
|
|
89
|
-
# : (RootVersionPlan,
|
|
90
|
-
def build_analysis: (RootVersionPlan,
|
|
98
|
+
# : (RootVersionPlan, ActivityHistory) -> Analysis
|
|
99
|
+
def build_analysis: (RootVersionPlan, ActivityHistory) -> Analysis
|
|
91
100
|
|
|
92
|
-
# : () ->
|
|
93
|
-
def
|
|
101
|
+
# : () -> Array[ActivityStep]
|
|
102
|
+
def window_steps: () -> Array[ActivityStep]
|
|
103
|
+
|
|
104
|
+
# : () -> Analysis
|
|
105
|
+
def analyze_window: () -> Analysis
|
|
106
|
+
|
|
107
|
+
# A window with a closing step ends at what closed it: the live row, or
|
|
108
|
+
# nothing after a destroy, where no live row is read. One that ends before
|
|
109
|
+
# a later event ends at the state that event found.
|
|
110
|
+
# : (ActivityHistory, ActivityStep?, RecordSnapshot?) -> RecordSnapshot?
|
|
111
|
+
def window_final_snapshot: (ActivityHistory, ActivityStep?, RecordSnapshot?) -> RecordSnapshot?
|
|
112
|
+
|
|
113
|
+
# : () -> [ActivityHistory, RootVersionPlan, ActivityStep?, RecordSnapshot?, untyped]
|
|
114
|
+
def window_history: () -> [ ActivityHistory, RootVersionPlan, ActivityStep?, RecordSnapshot?, untyped ]
|
|
115
|
+
|
|
116
|
+
# Nothing reads a window's closing step, live snapshot, or capture time
|
|
117
|
+
# when it reported nothing, so mutations of those cannot change an answer.
|
|
118
|
+
# mutant:disable
|
|
119
|
+
# : (RootVersionPlan) -> [ActivityHistory, RootVersionPlan, ActivityStep?, RecordSnapshot?, untyped]
|
|
120
|
+
def empty_window: (RootVersionPlan) -> [ ActivityHistory, RootVersionPlan, ActivityStep?, RecordSnapshot?, untyped ]
|
|
121
|
+
|
|
122
|
+
# A window with no selected event reports nothing. Any other has a
|
|
123
|
+
# boundary after its last one: the plan refuses a window that has no later
|
|
124
|
+
# version, ends on no destroy, and does not close on the live row.
|
|
125
|
+
# : (RootVersionPlan, untyped) -> [ActivityHistory, RootVersionPlan, ActivityStep?, RecordSnapshot?, untyped]
|
|
126
|
+
def window_replay: (RootVersionPlan, untyped) -> [ ActivityHistory, RootVersionPlan, ActivityStep?, RecordSnapshot?, untyped ]
|
|
127
|
+
|
|
128
|
+
# One live read serves both the closing activity step and the endpoint the
|
|
129
|
+
# analysis reports, which would otherwise reconstruct the graph twice.
|
|
130
|
+
# : (RootVersionPlan) -> RecordSnapshot?
|
|
131
|
+
def window_live_snapshot: (RootVersionPlan) -> RecordSnapshot?
|
|
132
|
+
|
|
133
|
+
# Root versions inside the window that the plan does not report are context
|
|
134
|
+
# rather than mutations: the version appended to reveal the last selected
|
|
135
|
+
# change, and anything a filter excluded but the replay still walks. Neither
|
|
136
|
+
# may be counted as a selected mutation. Descendant events are not filtered,
|
|
137
|
+
# so window membership is the whole test for them.
|
|
138
|
+
# : (Array[ActivityEvent], RootVersionPlan) -> Array[ActivityEvent]
|
|
139
|
+
def selected_events: (Array[ActivityEvent], RootVersionPlan) -> Array[ActivityEvent]
|
|
140
|
+
|
|
141
|
+
# A window either closes on the absence its final destruction leaves, or on
|
|
142
|
+
# current state when it reaches past everything recorded. Both are boundaries
|
|
143
|
+
# no version can supply.
|
|
144
|
+
#
|
|
145
|
+
# Everything recorded means on every requested path, not only the root's
|
|
146
|
+
# own versions. When an association changed after the window, its last
|
|
147
|
+
# step already ends at that change, at the state the window left; closing
|
|
148
|
+
# on current state would add the later change to a window it was not in.
|
|
149
|
+
# : (ActivityHistory, ActivityEvent, RootVersionPlan, untyped, RecordSnapshot?, Array[ActivityEvent]) -> ActivityStep?
|
|
150
|
+
def window_closing: (ActivityHistory, ActivityEvent, RootVersionPlan, untyped, RecordSnapshot?, Array[ActivityEvent]) -> ActivityStep?
|
|
151
|
+
|
|
152
|
+
# : (ActivityHistory, ActivityEvent) -> ActivityStep
|
|
153
|
+
def window_destroyed_step: (ActivityHistory, ActivityEvent) -> ActivityStep
|
|
154
|
+
|
|
155
|
+
# The last boundary reached is where current state is compared from, which
|
|
156
|
+
# is the final event rather than the final root version once descendants
|
|
157
|
+
# have moved since it. A selected event is a boundary the history kept.
|
|
158
|
+
# : (ActivityHistory, untyped, untyped, RecordSnapshot?) -> ActivityStep
|
|
159
|
+
def window_current_step: (ActivityHistory, untyped, untyped, RecordSnapshot?) -> ActivityStep
|
|
160
|
+
|
|
161
|
+
# : (ActivityEvent) -> bool
|
|
162
|
+
def terminal_destroy?: (ActivityEvent) -> bool
|
|
163
|
+
|
|
164
|
+
# : () -> void
|
|
165
|
+
def reject_live_habtm!: () -> void
|
|
166
|
+
|
|
167
|
+
# : () -> Array[String]?
|
|
168
|
+
def root_recorded: () -> Array[String]?
|
|
169
|
+
|
|
170
|
+
# A window prepares from its start, explicit endpoints from their first
|
|
171
|
+
# version.
|
|
172
|
+
# : (Array[untyped], ?end_at: untyped) -> untyped
|
|
173
|
+
def prepare_history: (Array[untyped], ?end_at: untyped) -> untyped
|
|
174
|
+
|
|
175
|
+
# A window collects from its start, explicit endpoints from their first
|
|
176
|
+
# version. Explicit endpoints also stop before the rest of the closing
|
|
177
|
+
# version's transaction (see ActivityTransactionGroups.before_closing); a
|
|
178
|
+
# window keeps every event it collected and reports only those inside it.
|
|
179
|
+
# : (Array[untyped], untyped, range_end: untyped) -> Array[ActivityEvent]
|
|
180
|
+
def collect_events: (Array[untyped], untyped, range_end: untyped) -> Array[ActivityEvent]
|
|
181
|
+
|
|
182
|
+
# Events after the last root version read the root from the live record
|
|
183
|
+
# when the range closes on it. Explicit endpoints report every step, as
|
|
184
|
+
# their range includes every version.
|
|
185
|
+
# : (Array[untyped], Array[ActivityEvent], untyped, ?current: untyped, ?closing: RecordSnapshot?) -> ActivityHistory
|
|
186
|
+
def replay: (Array[untyped], Array[ActivityEvent], untyped, ?current: untyped, ?closing: RecordSnapshot?) -> ActivityHistory
|
|
187
|
+
|
|
188
|
+
# The step from the last boundary the history reached to one that closes
|
|
189
|
+
# the range.
|
|
190
|
+
# : (ActivityHistory, ActivityBoundary, ActivityBoundary, RecordSnapshot?) -> ActivityStep
|
|
191
|
+
def step_from_last: (ActivityHistory, ActivityBoundary, ActivityBoundary, RecordSnapshot?) -> ActivityStep
|
|
192
|
+
|
|
193
|
+
# : (Array[ActivityStep]) -> Array[ActivityStep]
|
|
194
|
+
def present: (Array[ActivityStep]) -> Array[ActivityStep]
|
|
195
|
+
|
|
196
|
+
# : (RootVersionPlan, ActivityHistory, final: RecordSnapshot?, steps: Array[ActivityStep], ?closing_snapshot: RecordSnapshot?, ?captured_at: untyped) -> Analysis
|
|
197
|
+
def analysis: (RootVersionPlan, ActivityHistory, final: RecordSnapshot?, steps: Array[ActivityStep], ?closing_snapshot: RecordSnapshot?, ?captured_at: untyped) -> Analysis
|
|
94
198
|
end
|
|
95
199
|
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Generated from lib/paper_trail_diff/activity_tree_filter.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module PaperTrailDiff
|
|
4
|
+
# Leaves out the events of records that were outside the root's tree.
|
|
5
|
+
#
|
|
6
|
+
# A record found in the tree at one time in a range brings every version it
|
|
7
|
+
# saved in the range, including those it saved while it belonged elsewhere:
|
|
8
|
+
# a comment edited on another article before it moved to this one, or after
|
|
9
|
+
# it left a scope. Such a version changes nothing the root shows. As a
|
|
10
|
+
# boundary it would open a step of its own, and inside a transaction, where
|
|
11
|
+
# a change surfaces one event late, that step would take the credit for the
|
|
12
|
+
# root's own change.
|
|
13
|
+
#
|
|
14
|
+
# PT-AT reads associations as they were before a transaction, so a record
|
|
15
|
+
# is judged by two snapshots: the one at its transaction's first event, and
|
|
16
|
+
# the one after its last, which is the next event's or what the range
|
|
17
|
+
# closes on. A record in neither was outside the tree throughout.
|
|
18
|
+
#
|
|
19
|
+
# The root's own events are always kept, and so are the versions of a
|
|
20
|
+
# through's join rows, which a snapshot does not hold, and an event whose
|
|
21
|
+
# step is not reported, which only bounds one that is.
|
|
22
|
+
class ActivityTreeFilter
|
|
23
|
+
# `closing` is the snapshot after the last event: the current record's,
|
|
24
|
+
# or nil when nothing follows, as after the root's destruction.
|
|
25
|
+
# : (Array[ActivityEvent], reported: untyped, closing: RecordSnapshot?) -> void
|
|
26
|
+
def initialize: (Array[ActivityEvent], reported: untyped, closing: RecordSnapshot?) -> void
|
|
27
|
+
|
|
28
|
+
# Yields each event of the sequence with its snapshot, and whether to keep
|
|
29
|
+
# it, in order.
|
|
30
|
+
# : (untyped) { (ActivityEvent, RecordSnapshot?, bool) -> void } -> void
|
|
31
|
+
def call: (untyped) { (ActivityEvent, RecordSnapshot?, bool) -> void } -> void
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
@closing: RecordSnapshot?
|
|
36
|
+
|
|
37
|
+
@ends: Array[Integer]
|
|
38
|
+
|
|
39
|
+
@reported: untyped
|
|
40
|
+
|
|
41
|
+
@starts: Array[Integer]
|
|
42
|
+
|
|
43
|
+
@types: Hash[String, Array[String?]]
|
|
44
|
+
|
|
45
|
+
# : (ActivityEvent, Integer, Array[[ActivityEvent, RecordSnapshot?]]) -> bool
|
|
46
|
+
def keep?: (ActivityEvent, Integer, Array[[ ActivityEvent, RecordSnapshot? ]]) -> bool
|
|
47
|
+
|
|
48
|
+
# : (ActivityEvent) -> bool
|
|
49
|
+
def reported?: (ActivityEvent) -> bool
|
|
50
|
+
|
|
51
|
+
# Where each event's transaction starts, and the position just past its
|
|
52
|
+
# last event. Two transactions can interleave, so a transaction's events
|
|
53
|
+
# need not be adjacent.
|
|
54
|
+
# : (Array[ActivityEvent]) -> [Array[Integer], Array[Integer]]
|
|
55
|
+
def spans: (Array[ActivityEvent]) -> [ Array[Integer], Array[Integer] ]
|
|
56
|
+
|
|
57
|
+
# A version saved outside a transaction is a transaction of its own,
|
|
58
|
+
# keyed by its position.
|
|
59
|
+
# : (Array[ActivityEvent]) -> Array[Array[untyped] | Integer]
|
|
60
|
+
def transaction_keys: (Array[ActivityEvent]) -> Array[Array[untyped] | Integer]
|
|
61
|
+
|
|
62
|
+
# : (RecordSnapshot?, ActivityEvent) -> bool
|
|
63
|
+
def holds?: (RecordSnapshot?, ActivityEvent) -> bool
|
|
64
|
+
|
|
65
|
+
# : (AssociationSnapshot, Array[String?], untyped) -> bool
|
|
66
|
+
def contains?: (AssociationSnapshot, Array[String?], untyped) -> bool
|
|
67
|
+
|
|
68
|
+
# A version names its record's base class, and a snapshot the record's
|
|
69
|
+
# own class, which may be any subclass of it.
|
|
70
|
+
# : (String) -> Array[String?]
|
|
71
|
+
def types: (String) -> Array[String?]
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -6,6 +6,8 @@ module PaperTrailDiff
|
|
|
6
6
|
# : (untyped, root_versions: Array[untyped], tree: AssociationTree, ?range_start: untyped, ?range_end: untyped, ?prepared: PreparedActivityIndex?) -> void
|
|
7
7
|
def initialize: (untyped, root_versions: Array[untyped], tree: AssociationTree, ?range_start: untyped, ?range_end: untyped, ?prepared: PreparedActivityIndex?) -> void
|
|
8
8
|
|
|
9
|
+
# A tie between version tables, or between ids that do not count up,
|
|
10
|
+
# raises rather than building a timeline in an arbitrary order.
|
|
9
11
|
# : () -> Array[ActivityEvent]
|
|
10
12
|
def call: () -> Array[ActivityEvent]
|
|
11
13
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Generated from lib/paper_trail_diff/activity_view.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module PaperTrailDiff
|
|
4
|
+
# How a request presents its activity steps: whether they keep their
|
|
5
|
+
# snapshots, whether a transaction's steps merge into one, and which of
|
|
6
|
+
# their versions' recorded changes they carry. Built and checked once per
|
|
7
|
+
# request, and read the same way by both activity builders, or the same
|
|
8
|
+
# history would read differently depending on how it was asked for.
|
|
9
|
+
class ActivityView
|
|
10
|
+
# Options only an activity view uses are refused without one.
|
|
11
|
+
# : (activity: bool, snapshots: bool, group: Symbol?, recorded: IgnorePolicy?) -> ActivityView
|
|
12
|
+
def self.build: (activity: bool, snapshots: bool, group: Symbol?, recorded: IgnorePolicy?) -> ActivityView
|
|
13
|
+
|
|
14
|
+
# : (?snapshots: bool, ?group: Symbol?, ?recorded: IgnorePolicy?) -> void
|
|
15
|
+
def initialize: (?snapshots: bool, ?group: Symbol?, ?recorded: IgnorePolicy?) -> void
|
|
16
|
+
|
|
17
|
+
# Merging a group compares its outer states, so the snapshots must survive
|
|
18
|
+
# the build even when the caller did not ask to keep them.
|
|
19
|
+
# : () -> bool
|
|
20
|
+
def retain?: () -> bool
|
|
21
|
+
|
|
22
|
+
# The attributes a boundary's version recorded, when they were asked for.
|
|
23
|
+
# : (root: bool) -> Array[String]?
|
|
24
|
+
def recorded_attributes: (root: bool) -> Array[String]?
|
|
25
|
+
|
|
26
|
+
# Applied last, to finished steps, so grouping sees the same timeline the
|
|
27
|
+
# caller would otherwise have received.
|
|
28
|
+
# : (Array[ActivityStep]) -> Array[ActivityStep]
|
|
29
|
+
def present: (Array[ActivityStep]) -> Array[ActivityStep]
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
@group: Symbol?
|
|
34
|
+
|
|
35
|
+
@recorded: IgnorePolicy?
|
|
36
|
+
|
|
37
|
+
@snapshots: bool
|
|
38
|
+
|
|
39
|
+
# : () -> bool
|
|
40
|
+
def grouping?: () -> bool
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -14,7 +14,9 @@ module PaperTrailDiff
|
|
|
14
14
|
attr_reader to_snapshot: RecordSnapshot?
|
|
15
15
|
|
|
16
16
|
# The result for a record whose requested history contains no versions,
|
|
17
|
-
# which is an empty history rather than a failed request.
|
|
17
|
+
# which is an empty history rather than a failed request. Its snapshots
|
|
18
|
+
# are nil because no state was read, not because the record was absent:
|
|
19
|
+
# reading one would rebuild the whole graph, per record in a batch.
|
|
18
20
|
# : () -> Analysis
|
|
19
21
|
def self.empty: () -> Analysis
|
|
20
22
|
|
|
@@ -23,6 +25,11 @@ module PaperTrailDiff
|
|
|
23
25
|
# : (diff: Diff, timeline: Array[Step], ?activity_timeline: Array[ActivityStep]?, ?from_snapshot: RecordSnapshot?, ?to_snapshot: RecordSnapshot?) -> void
|
|
24
26
|
def initialize: (diff: Diff, timeline: Array[Step], ?activity_timeline: Array[ActivityStep]?, ?from_snapshot: RecordSnapshot?, ?to_snapshot: RecordSnapshot?) -> void
|
|
25
27
|
|
|
28
|
+
# Every activity step's rows, in time order. Only the activity timeline says
|
|
29
|
+
# who made each change, so an analysis built without it has no rows to give.
|
|
30
|
+
# : () -> Array[ChangeRow]
|
|
31
|
+
def change_rows: () -> Array[ChangeRow]
|
|
32
|
+
|
|
26
33
|
# Reconstructed endpoint states are opt-in, because they carry the whole
|
|
27
34
|
# selected graph whether or not anything changed, which dwarfs the rest of
|
|
28
35
|
# the payload for a wide graph.
|
|
@@ -5,8 +5,8 @@ module PaperTrailDiff
|
|
|
5
5
|
# versions and preparing their association history once for the whole batch
|
|
6
6
|
# rather than once per root.
|
|
7
7
|
class AnalysisBatch
|
|
8
|
-
# : (Array[untyped], time_range: TimeRange?, live_loader: untyped, history_preparer: untyped, analyzer: untyped, ?version_scope: untyped, ?
|
|
9
|
-
def initialize: (Array[untyped], time_range: TimeRange?, live_loader: untyped, history_preparer: untyped, analyzer: untyped, ?version_scope: untyped, ?
|
|
8
|
+
# : (Array[untyped], time_range: TimeRange?, live_loader: untyped, history_preparer: untyped, analyzer: untyped, ?version_scope: untyped, ?context_required: bool) -> void
|
|
9
|
+
def initialize: (Array[untyped], time_range: TimeRange?, live_loader: untyped, history_preparer: untyped, analyzer: untyped, ?version_scope: untyped, ?context_required: bool) -> void
|
|
10
10
|
|
|
11
11
|
# : () -> Hash[identity, Analysis]
|
|
12
12
|
def call: () -> Hash[identity, Analysis]
|
|
@@ -15,8 +15,6 @@ module PaperTrailDiff
|
|
|
15
15
|
|
|
16
16
|
@analyzer: untyped
|
|
17
17
|
|
|
18
|
-
@close_on_current: bool
|
|
19
|
-
|
|
20
18
|
@context_required: bool
|
|
21
19
|
|
|
22
20
|
@history_preparer: untyped
|
|
@@ -29,11 +27,6 @@ module PaperTrailDiff
|
|
|
29
27
|
|
|
30
28
|
@version_scope: untyped
|
|
31
29
|
|
|
32
|
-
# A filter is a callable that narrows the version relation, so it is checked
|
|
33
|
-
# up front rather than failing partway through a batch.
|
|
34
|
-
# : (untyped) -> untyped
|
|
35
|
-
def validated_scope: (untyped) -> untyped
|
|
36
|
-
|
|
37
30
|
# : () -> Array[untyped]
|
|
38
31
|
def validated_records: () -> Array[untyped]
|
|
39
32
|
|
|
@@ -42,21 +35,21 @@ module PaperTrailDiff
|
|
|
42
35
|
# The roots are preloaded first, because preparation reads their current
|
|
43
36
|
# association state as a fallback and would otherwise walk it one root at a
|
|
44
37
|
# time.
|
|
45
|
-
# : (Array[untyped], Hash[Array[String], RootVersionPlan], Hash[Array[String], untyped]) -> void
|
|
46
|
-
def prepare: (Array[untyped], Hash[Array[String], RootVersionPlan], Hash[Array[String], untyped]) -> void
|
|
38
|
+
# : (Array[untyped], Hash[Array[String], RootVersionPlan], Hash[Array[String], untyped], Hash[Array[String], TimeRange]) -> void
|
|
39
|
+
def prepare: (Array[untyped], Hash[Array[String], RootVersionPlan], Hash[Array[String], untyped], Hash[Array[String], TimeRange]) -> void
|
|
47
40
|
|
|
48
41
|
# : (Array[untyped], Hash[Array[String], RootVersionPlan]) -> bool
|
|
49
42
|
def closes_live?: (Array[untyped], Hash[Array[String], RootVersionPlan]) -> bool
|
|
50
43
|
|
|
51
44
|
# A plan closing on the live record reads history up to now; the others
|
|
52
45
|
# stop at the window, so a past window does not load everything since.
|
|
53
|
-
# : (Array[untyped],
|
|
54
|
-
def preparation_range: (Array[untyped],
|
|
46
|
+
# : (Array[untyped], Hash[Array[String], TimeRange], live: bool) -> Hash[Symbol, untyped]
|
|
47
|
+
def preparation_range: (Array[untyped], Hash[Array[String], TimeRange], live: bool) -> Hash[Symbol, untyped]
|
|
55
48
|
|
|
56
49
|
# A root with no versions in range has nothing to report, which is an empty
|
|
57
50
|
# result rather than a failed request -- unless an activity view closes it
|
|
58
51
|
# on current state, where its descendants may still have moved.
|
|
59
|
-
# : (untyped, RootVersionPlan) -> Analysis
|
|
60
|
-
def analysis_for: (untyped, RootVersionPlan) -> Analysis
|
|
52
|
+
# : (untyped, RootVersionPlan, TimeRange?) -> Analysis
|
|
53
|
+
def analysis_for: (untyped, RootVersionPlan, TimeRange?) -> Analysis
|
|
61
54
|
end
|
|
62
55
|
end
|