Class: PaperTrailDiff::RootVersionPlan

Inherits:
Object
  • Object
show all
Defined in:
lib/paper_trail_diff/root_version_plan.rb,
sig/generated/paper_trail_diff/root_version_plan.rbs

Overview

Which versions a range reconstructs, and which pairs of them become steps.

Without a filter those are the same thing: every selected version is a boundary and adjacent ones bound each other. A filter separates them, because each selected mutation then has to be bounded by the version that actually reveals it rather than by the next mutation that happened to be selected.

A filter also separates what is reported from what has to be replayed. The activity view rebuilds state by carrying one snapshot forward across every event in order, so skipping a filtered-out version would leave that snapshot holding a state the record had already moved past. versions are the boundaries the steps refer to; reconstruction_versions are every root version the span passes through, which is what any forward replay must walk.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(versions:, steps:, context_version: nil, reconstruction_versions: nil, mutations: nil, closing_record: nil) ⇒ RootVersionPlan

: (versions: Array, steps: Array[[untyped, untyped]], ?context_version: untyped, ?reconstruction_versions: Array?, ?mutations: Array?, ?closing_record: untyped) -> void

Parameters:

  • versions: (Array[untyped])
  • steps: (Array[[ untyped, untyped ]])
  • context_version: (Object) (defaults to: nil)
  • reconstruction_versions: (Array[untyped], nil) (defaults to: nil)
  • mutations: (Array[untyped], nil) (defaults to: nil)
  • closing_record: (Object) (defaults to: nil)


51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/paper_trail_diff/root_version_plan.rb', line 51

def initialize( # rubocop:disable Metrics/ParameterLists
  versions:, steps:, context_version: nil, reconstruction_versions: nil, mutations: nil,
  closing_record: nil
)
  @closing_record = closing_record
  @versions = versions.freeze
  @reconstruction_versions = (reconstruction_versions || versions).freeze
  @steps = steps.freeze
  @context_version = context_version
  @mutations = (mutations || default_mutations).freeze
  @mutation_keys = Set.new(@mutations.map { |version| key(version) }).freeze
  freeze
end

Instance Attribute Details

#closing_recordObject (readonly)

The live record a window closes on when no later version can reveal its final mutation. It is a boundary, never a version, so it stays out of versions and out of anything that reconstructs from version history.

Returns:

  • (Object)


26
27
28
# File 'lib/paper_trail_diff/root_version_plan.rb', line 26

def closing_record
  @closing_record
end

#context_versionObject (readonly)

Signature:

  • untyped

Returns:

  • (Object)


22
23
24
# File 'lib/paper_trail_diff/root_version_plan.rb', line 22

def context_version
  @context_version
end

#mutationsArray[untyped] (readonly)

The root versions this plan reports as mutations, which excludes any version present only to reveal what the last of them produced.

Returns:

  • (Array[untyped])


29
30
31
# File 'lib/paper_trail_diff/root_version_plan.rb', line 29

def mutations
  @mutations
end

#reconstruction_versionsArray[untyped] (readonly)

Signature:

  • Array[untyped]

Returns:

  • (Array[untyped])


20
21
22
# File 'lib/paper_trail_diff/root_version_plan.rb', line 20

def reconstruction_versions
  @reconstruction_versions
end

#stepsArray[[ untyped, untyped ]] (readonly)

Signature:

  • Array[[untyped, untyped]]

Returns:

  • (Array[[ untyped, untyped ]])


21
22
23
# File 'lib/paper_trail_diff/root_version_plan.rb', line 21

def steps
  @steps
end

#versionsArray[untyped] (readonly)

Signature:

  • Array[untyped]

Returns:

  • (Array[untyped])


19
20
21
# File 'lib/paper_trail_diff/root_version_plan.rb', line 19

def versions
  @versions
end

Class Method Details

.contiguous(versions, context_version: nil) ⇒ RootVersionPlan

Adjacent boundaries, which is what an unfiltered range reports. : (Array, ?context_version: untyped) -> RootVersionPlan

Parameters:

  • (Array[untyped])
  • context_version: (Object) (defaults to: nil)

Returns:



34
35
36
37
38
39
40
# File 'lib/paper_trail_diff/root_version_plan.rb', line 34

def contiguous(versions, context_version: nil)
  new(
    versions: versions,
    steps: versions.each_cons(2).map { |from, to| [from, to] },
    context_version: context_version
  )
end

.emptyRootVersionPlan

: () -> RootVersionPlan

Returns:



43
44
45
46
47
# File 'lib/paper_trail_diff/root_version_plan.rb', line 43

def empty
  versions = [] #: Array[untyped]
  steps = [] #: Array[[untyped, untyped]]
  new(versions: versions, steps: steps)
end

Instance Method Details

#default_mutationsArray[untyped]

: () -> Array

Returns:

  • (Array[untyped])


87
88
89
90
91
92
# File 'lib/paper_trail_diff/root_version_plan.rb', line 87

def default_mutations
  return @versions unless @context_version

  context = key(@context_version)
  @versions.reject { |version| key(version) == context }
end

#empty?Boolean

: () -> bool

Returns:

  • (Boolean)


66
67
68
# File 'lib/paper_trail_diff/root_version_plan.rb', line 66

def empty?
  versions.empty?
end

#final_endpointObject

What the range's final state is read from, which is the live record when the window closes on current state and the last version otherwise. : () -> untyped

Returns:

  • (Object)


73
74
75
# File 'lib/paper_trail_diff/root_version_plan.rb', line 73

def final_endpoint
  @closing_record || @versions.last
end

#key(version) ⇒ Array[untyped]

: (untyped) -> Array

Parameters:

  • (Object)

Returns:

  • (Array[untyped])


95
96
97
# File 'lib/paper_trail_diff/root_version_plan.rb', line 95

def key(version)
  [version.class.name, version.id]
end

#mutation?(version) ⇒ Boolean

: (untyped) -> bool

Parameters:

  • (Object)

Returns:

  • (Boolean)


78
79
80
# File 'lib/paper_trail_diff/root_version_plan.rb', line 78

def mutation?(version)
  @mutation_keys.include?(key(version))
end