jekyll-relationships 0.1.0.alpha → 0.2.0.alpha

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/lib/jekyll-relationships/configuration/debug_setting.rb +72 -12
  3. data/lib/jekyll-relationships/configuration/defaults.rb +3 -1
  4. data/lib/jekyll-relationships/configuration/frontmatter.rb +28 -1
  5. data/lib/jekyll-relationships/configuration/parser.rb +20 -3
  6. data/lib/jekyll-relationships/configuration/prune_rule_settings.rb +33 -5
  7. data/lib/jekyll-relationships/configuration/tree_frontmatter.rb +8 -2
  8. data/lib/jekyll-relationships/configuration.rb +43 -8
  9. data/lib/jekyll-relationships/debug_logger.rb +94 -3
  10. data/lib/jekyll-relationships/definitions/normal_relationship.rb +13 -2
  11. data/lib/jekyll-relationships/definitions/prune_rule.rb +19 -3
  12. data/lib/jekyll-relationships/definitions/tree_relationship.rb +8 -2
  13. data/lib/jekyll-relationships/documents/registry.rb +182 -33
  14. data/lib/jekyll-relationships/engine/normal_seed.rb +222 -0
  15. data/lib/jekyll-relationships/engine/persisted_links.rb +365 -0
  16. data/lib/jekyll-relationships/engine/raw_path_state.rb +46 -116
  17. data/lib/jekyll-relationships/engine/relationship_state.rb +67 -56
  18. data/lib/jekyll-relationships/engine/session.rb +159 -19
  19. data/lib/jekyll-relationships/engine/write_back.rb +3 -42
  20. data/lib/jekyll-relationships/engine.rb +168 -46
  21. data/lib/jekyll-relationships/pruning/rule_pruner.rb +7 -7
  22. data/lib/jekyll-relationships/pruning/tree_phase.rb +128 -124
  23. data/lib/jekyll-relationships/pruning/tree_provenance.rb +1 -1
  24. data/lib/jekyll-relationships/references/accumulator.rb +87 -9
  25. data/lib/jekyll-relationships/references/template.rb +46 -11
  26. data/lib/jekyll-relationships/resolvers/base.rb +59 -2
  27. data/lib/jekyll-relationships/support/frontmatter_matcher.rb +76 -0
  28. data/lib/jekyll-relationships/support/placeholders.rb +1 -0
  29. data/lib/jekyll-relationships/trees/edge_builder.rb +43 -11
  30. data/lib/jekyll-relationships/trees/graph.rb +135 -17
  31. data/lib/jekyll-relationships/trees/root_distances.rb +44 -0
  32. data/lib/jekyll-relationships/version.rb +1 -1
  33. data/lib/jekyll-relationships.rb +1 -0
  34. data/readme.md +185 -26
  35. metadata +6 -2
@@ -0,0 +1,365 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Jekyll
6
+ module Plugins
7
+
8
+ module Relationships
9
+
10
+ class Engine
11
+
12
+ # Stores resolver-promoted links that may be restored in later rounds.
13
+ #
14
+ # Persisted links are a fallback overlay, not part of the source-derived
15
+ # seeds. A later round only reapplies them after resolvers have had their own
16
+ # chance to recreate the same links naturally.
17
+ class PersistedLinks
18
+ # Builds one persisted-link store with the active duplicate-handling rules.
19
+ def initialize(engine:)
20
+ @engine = engine
21
+ @configuration = engine.configuration
22
+ @registry = engine.registry
23
+ @entries_by_state = Hash.new { |hash, key| hash[key] = [] }
24
+ @next_order = 0
25
+ @round_identifier = 0
26
+ end
27
+
28
+ # Marks the start of one new resolution round.
29
+ def start_round!
30
+ @round_identifier += 1
31
+ end
32
+
33
+ # Records one persisted link for the given directional relationship pair.
34
+ def persist_link(source_state:, target_document:, metadata:, count:)
35
+ persist_directional_link(
36
+ document: source_state.document,
37
+ to_collection: source_state.definition.to_collection,
38
+ target_document: target_document,
39
+ key: @registry.key_for(target_document, primary_path: source_state.definition.primary_path),
40
+ metadata: metadata,
41
+ count: count
42
+ )
43
+
44
+ return unless source_state.definition.bidirectional
45
+
46
+ persist_directional_link(
47
+ document: target_document,
48
+ to_collection: source_state.definition.from_collection,
49
+ target_document: source_state.document,
50
+ key: @registry.key_for(source_state.document, primary_path: source_state.definition.primary_path),
51
+ metadata: metadata,
52
+ count: count
53
+ )
54
+ end
55
+
56
+ # Removes one persisted link from the given directional pair.
57
+ def clear_link(source_state:, target_document:)
58
+ clear_directional_link(
59
+ document: source_state.document,
60
+ to_collection: source_state.definition.to_collection,
61
+ target_document: target_document
62
+ )
63
+
64
+ return unless source_state.definition.bidirectional
65
+
66
+ clear_directional_link(
67
+ document: target_document,
68
+ to_collection: source_state.definition.from_collection,
69
+ target_document: source_state.document
70
+ )
71
+ end
72
+
73
+ # Removes every persisted link for the given directional pair.
74
+ def clear_all(source_state:)
75
+ state_entries = @entries_by_state[[source_state.document.object_id, source_state.definition.to_collection]].dup
76
+ clear_directional_state(
77
+ document: source_state.document,
78
+ to_collection: source_state.definition.to_collection
79
+ )
80
+
81
+ return unless source_state.definition.bidirectional
82
+
83
+ state_entries.each do |entry|
84
+ clear_directional_link(
85
+ document: entry.fetch(:document),
86
+ to_collection: source_state.definition.from_collection,
87
+ target_document: source_state.document
88
+ )
89
+ end
90
+ end
91
+
92
+ # Drops any persisted links whose source or target documents no longer survive.
93
+ def remove_documents!(documents)
94
+ removed_document_ids = Array(documents).each_with_object({}) do |document, lookup|
95
+ lookup[document.object_id] = true
96
+ end
97
+ return if removed_document_ids.empty?
98
+
99
+ @entries_by_state.delete_if do |(source_document_id, _to_collection), _entries|
100
+ removed_document_ids.key?(source_document_id)
101
+ end
102
+ @entries_by_state.each_value do |entries|
103
+ entries.reject! do |entry|
104
+ removed_document_ids.key?(entry.fetch(:document).object_id)
105
+ end
106
+ end
107
+ end
108
+
109
+ # Restores any still-valid persisted links that resolvers did not recreate.
110
+ def reapply_missing_links(state:)
111
+ state_entries = @entries_by_state[[state.document.object_id, state.definition.to_collection]]
112
+ return if state_entries.empty?
113
+
114
+ cleanup_dead_entries!(
115
+ state: state,
116
+ state_entries: state_entries
117
+ )
118
+ return if state_entries.empty?
119
+
120
+ missing_entries = missing_entries_for(state_entries: state_entries, current_entries: state.current_link_entries)
121
+ return if missing_entries.empty?
122
+
123
+ base_count = state.current_link_entries.length
124
+ reinsertions = []
125
+ missing_entries.each do |entry|
126
+ result = state.link(
127
+ entry.fetch(:document),
128
+ metadata: entry.fetch(:metadata),
129
+ count: entry.fetch(:count),
130
+ reflect: true,
131
+ origin: 'persisted overlay',
132
+ persist: false
133
+ )
134
+ next unless result.fetch(:action) == :added
135
+
136
+ reinsertions << {
137
+ entry: result.fetch(:entry),
138
+ position_ratio: entry.fetch(:position_ratio),
139
+ order: entry.fetch(:order)
140
+ }
141
+ end
142
+
143
+ state.reposition_entries!(reinsertions: reinsertions, base_count: base_count) unless reinsertions.empty?
144
+ end
145
+
146
+ # Refreshes stored position hints from the latest resolved ordering.
147
+ def refresh_positions(state:)
148
+ state_entries = @entries_by_state[[state.document.object_id, state.definition.to_collection]]
149
+ return if state_entries.empty?
150
+
151
+ current_entries = state.current_link_entries
152
+ return if current_entries.empty?
153
+
154
+ if @configuration.multiple_settings.keep?
155
+ update_keep_positions!(
156
+ state_entries: state_entries,
157
+ current_entries: current_entries
158
+ )
159
+ return
160
+ end
161
+
162
+ current_indexes = current_entries.each_with_index.each_with_object({}) do |(entry, index), indexes|
163
+ indexes[entry.fetch(:document).object_id] = {
164
+ index: index,
165
+ entry: entry
166
+ }
167
+ end
168
+ state_entries.each do |entry|
169
+ match = current_indexes[entry.fetch(:document).object_id]
170
+ next unless match
171
+
172
+ entry[:position_ratio] = position_ratio(index: match.fetch(:index), length: current_entries.length)
173
+ end
174
+ end
175
+
176
+ private
177
+
178
+ # Stores one directional persisted entry under the active duplicate mode.
179
+ def persist_directional_link(document:, to_collection:, target_document:, key:, metadata:, count:)
180
+ state_entries = @entries_by_state[[document.object_id, to_collection]]
181
+ if @configuration.multiple_settings.keep?
182
+ existing_entry = state_entries.find do |entry|
183
+ entry_signature(entry) == signature_for(document: target_document, metadata: metadata) &&
184
+ entry.fetch(:last_seen_round) != @round_identifier
185
+ end
186
+ if existing_entry
187
+ existing_entry[:last_seen_round] = @round_identifier
188
+ return
189
+ end
190
+
191
+ state_entries << build_entry(
192
+ document: target_document,
193
+ key: key,
194
+ metadata: metadata,
195
+ count: 1
196
+ )
197
+ return
198
+ end
199
+
200
+ existing_entry = state_entries.find do |entry|
201
+ entry.fetch(:document) == target_document
202
+ end
203
+ if existing_entry
204
+ return if @configuration.multiple_settings.drop?
205
+
206
+ existing_entry[:count] += normalise_count(count)
207
+ existing_entry[:metadata] = merge_metadata_under(
208
+ existing_metadata: existing_entry.fetch(:metadata),
209
+ incoming_metadata: metadata
210
+ )
211
+ return
212
+ end
213
+
214
+ state_entries << build_entry(
215
+ document: target_document,
216
+ key: key,
217
+ metadata: metadata,
218
+ count: @configuration.multiple_settings.count? ? normalise_count(count) : 1
219
+ )
220
+ end
221
+
222
+ # Removes one directional persisted entry.
223
+ def clear_directional_link(document:, to_collection:, target_document:)
224
+ state_entries = @entries_by_state[[document.object_id, to_collection]]
225
+ state_entries.reject! do |entry|
226
+ entry.fetch(:document) == target_document
227
+ end
228
+ end
229
+
230
+ # Removes every directional persisted entry for one pair.
231
+ def clear_directional_state(document:, to_collection:)
232
+ @entries_by_state.delete([document.object_id, to_collection])
233
+ end
234
+
235
+ # Builds one new persisted entry record.
236
+ def build_entry(document:, key:, metadata:, count:)
237
+ entry = {
238
+ document: document,
239
+ key: key,
240
+ metadata: normalise_metadata(metadata),
241
+ count: count,
242
+ position_ratio: nil,
243
+ order: @next_order,
244
+ last_seen_round: @round_identifier
245
+ }
246
+ @next_order += 1
247
+ entry
248
+ end
249
+
250
+ # Removes dead-source or dead-target entries before reuse.
251
+ def cleanup_dead_entries!(state:, state_entries:)
252
+ state_entries.reject! do |entry|
253
+ !state.active_document?(state.document) || !state.active_document?(entry.fetch(:document))
254
+ end
255
+ end
256
+
257
+ # Returns the subset of persisted entries that are still missing this round.
258
+ def missing_entries_for(state_entries:, current_entries:)
259
+ if @configuration.multiple_settings.keep?
260
+ return missing_keep_entries(state_entries: state_entries, current_entries: current_entries)
261
+ end
262
+
263
+ current_entries_by_document = current_entries.each_with_object({}) do |entry, grouped_entries|
264
+ grouped_entries[entry.fetch(:document).object_id] = entry
265
+ end
266
+ state_entries.each_with_object([]) do |entry, missing_entries|
267
+ current_entry = current_entries_by_document[entry.fetch(:document).object_id]
268
+ if current_entry.nil?
269
+ missing_entries << entry
270
+ next
271
+ end
272
+ next unless @configuration.multiple_settings.count?
273
+ next unless current_entry.fetch(:count) < entry.fetch(:count)
274
+
275
+ missing_entries << entry.merge(
276
+ count: entry.fetch(:count) - current_entry.fetch(:count)
277
+ )
278
+ end
279
+ end
280
+
281
+ # Returns the missing persisted occurrences for keep mode.
282
+ def missing_keep_entries(state_entries:, current_entries:)
283
+ current_counts_by_signature = current_entries.each_with_object(Hash.new(0)) do |entry, counts|
284
+ counts[entry_signature(entry)] += 1
285
+ end
286
+ state_entries.each_with_object([]) do |entry, missing_entries|
287
+ signature = entry_signature(entry)
288
+ if current_counts_by_signature[signature].positive?
289
+ current_counts_by_signature[signature] -= 1
290
+ next
291
+ end
292
+
293
+ missing_entries << entry
294
+ end
295
+ end
296
+
297
+ # Updates keep-mode persisted positions by consuming current occurrences in order.
298
+ def update_keep_positions!(state_entries:, current_entries:)
299
+ current_indexes_by_signature = current_entries.each_with_index.each_with_object(Hash.new { |hash, key| hash[key] = [] }) do |(entry, index), indexes|
300
+ indexes[entry_signature(entry)] << index
301
+ end
302
+ state_entries.each do |entry|
303
+ indexes = current_indexes_by_signature[entry_signature(entry)]
304
+ next if indexes.empty?
305
+
306
+ entry[:position_ratio] = position_ratio(index: indexes.shift, length: current_entries.length)
307
+ end
308
+ end
309
+
310
+ # Builds one stable signature for keep-mode matching.
311
+ def entry_signature(entry)
312
+ signature_for(
313
+ document: entry.fetch(:document),
314
+ metadata: entry.fetch(:metadata)
315
+ )
316
+ end
317
+
318
+ # Builds one stable signature for one persisted keep-mode occurrence.
319
+ def signature_for(document:, metadata:)
320
+ [
321
+ document.object_id,
322
+ JSON.generate(normalise_metadata(metadata))
323
+ ]
324
+ end
325
+
326
+ # Converts one final list index into a proportional reinsertion hint.
327
+ def position_ratio(index:, length:)
328
+ return 1.0 if length <= 1
329
+
330
+ index.to_f / (length - 1)
331
+ end
332
+
333
+ # Merges later metadata under the first-seen persisted metadata.
334
+ def merge_metadata_under(existing_metadata:, incoming_metadata:)
335
+ Jekyll::Plugins::Relationships::Support.hash_deep_merge(
336
+ normalise_metadata(incoming_metadata),
337
+ normalise_metadata(existing_metadata)
338
+ )
339
+ end
340
+
341
+ # Normalises metadata into a string-keyed hash.
342
+ def normalise_metadata(metadata)
343
+ Jekyll::Plugins::Relationships::Support.stringify_hash(metadata)
344
+ end
345
+
346
+ # Validates and normalises an incoming counted multiplicity.
347
+ def normalise_count(count)
348
+ integer_count = if count.is_a?(Integer)
349
+ count
350
+ elsif count.is_a?(String) && count.strip.match?(/\A\d+\z/)
351
+ count.to_i
352
+ else
353
+ raise ResolutionError, "Relationship count `#{count.inspect}` must be a positive integer."
354
+ end
355
+ raise ResolutionError, "Relationship count `#{count.inspect}` must be a positive integer." if integer_count < 1
356
+
357
+ integer_count
358
+ end
359
+ end
360
+ end
361
+
362
+ end
363
+
364
+ end
365
+ end
@@ -14,94 +14,50 @@ class Engine
14
14
  class RawPathState
15
15
  # Caches the parsed contents of one concrete leaf under a raw path.
16
16
  #
17
- # Each location keeps its own singular/array shape so write-back can
18
- # upgrade that exact leaf without leaking links across sibling array items.
17
+ # Each location keeps its own parsed entries so repeated resolution can
18
+ # reuse them without reparsing frontmatter.
19
19
  class LocationState
20
20
  # Builds one concrete-location cache.
21
- def initialize(match:, string_array:, reference_template:, multiple_settings:)
22
- @match = match
21
+ def initialize(match:, string_array:, reference_template:, reference_context: nil)
23
22
  @string_array = string_array
24
23
  @reference_template = reference_template
25
- @multiple_settings = multiple_settings
26
- @shape = infer_shape(@match.value)
27
- @entries = parse_entries(@match.value)
24
+ @reference_context = reference_context
25
+ @entries = parse_entries(match.value)
28
26
  @resolution_cache = {}
29
- @upgraded_value_cache = {}
30
27
  end
31
28
 
32
- # Resolves every parsed entry for one primary-key scheme.
33
- def resolved_entries_for(primary_path:, &resolver)
34
- signature = primary_signature(primary_path)
29
+ # Resolves every parsed entry for one complete identity scheme.
30
+ def resolved_entries_for(primary_path:, scope_fields:, &resolver)
31
+ signature = identity_signature(primary_path: primary_path, scope_fields: scope_fields)
35
32
  @resolution_cache[signature] ||= @entries.map do |entry|
36
33
  resolver.call(entry)
37
34
  end
38
35
  end
39
36
 
40
- # Builds the upgraded value for this exact location.
41
- def upgraded_value(primary_path:, &resolver)
42
- signature = primary_signature(primary_path)
43
- @upgraded_value_cache[signature] ||= begin
44
- accumulator = build_accumulator
45
-
46
- resolved_entries_for(primary_path: primary_path, &resolver).each do |resolved_entry|
47
- next unless resolved_entry
48
-
49
- accumulator.add(
50
- document: resolved_entry.fetch(:document),
51
- key: resolved_entry.fetch(:key),
52
- metadata: resolved_entry.fetch(:metadata),
53
- count: resolved_entry.fetch(:count)
54
- )
55
- end
56
- values = accumulator.references
57
-
58
- (@shape == :array || values.length != 1) ? values : values.first
59
- end
60
- end
61
-
62
- # Writes the upgraded value back onto the exact matched location.
63
- def write_upgraded_value(primary_path:, &resolver)
64
- @match.write(upgraded_value(primary_path: primary_path, &resolver))
65
- end
66
-
67
37
  private
68
38
 
69
39
  # Parses one concrete raw value into individual reference entries.
70
40
  def parse_entries(raw_value)
71
41
  @string_array.interpret(raw_value, split: -1, flatten: true).map do |entry|
72
- @reference_template.parse(entry)
42
+ @reference_template.parse(entry, context: @reference_context)
73
43
  end.compact
74
44
  end
75
45
 
76
- # Builds one new accumulator with the active duplicate-handling settings.
77
- def build_accumulator
78
- Jekyll::Plugins::Relationships::References::Accumulator.new(
79
- reference_template: @reference_template,
80
- multiple_settings: @multiple_settings
81
- )
82
- end
83
-
84
- # Normalises the cache key for one primary-key scheme.
85
- def primary_signature(primary_path)
86
- primary_path.nil? ? '__relative_path__' : primary_path
87
- end
88
-
89
- # Tracks the original top-level shape of this concrete raw value.
90
- def infer_shape(raw_value)
91
- raw_value.is_a?(Array) ? :array : :single
46
+ # Normalises the cache key for one primary-key and scope scheme.
47
+ def identity_signature(primary_path:, scope_fields:)
48
+ [primary_path.nil? ? '__relative_path__' : primary_path, scope_fields.map(&:signature)]
92
49
  end
93
50
  end
94
51
 
95
52
  attr_reader :document, :path, :raw_value
96
53
 
97
54
  # Builds one raw-path cache for one document and path.
98
- def initialize(document:, path:, data_path:, string_array:, reference_template:, multiple_settings:)
55
+ def initialize(document:, path:, data_path:, string_array:, reference_template:, reference_context: nil)
99
56
  @document = document
100
57
  @path = path
101
58
  @data_path = data_path
102
59
  @string_array = string_array
103
60
  @reference_template = reference_template
104
- @multiple_settings = multiple_settings
105
61
  @read_result = @data_path.read_result(@document.data, @path)
106
62
  @raw_value = @read_result.value
107
63
  @present = @read_result.present?
@@ -110,10 +66,9 @@ class Engine
110
66
  match: match,
111
67
  string_array: @string_array,
112
68
  reference_template: @reference_template,
113
- multiple_settings: @multiple_settings
69
+ reference_context: reference_context
114
70
  )
115
71
  end
116
- @preferred_primary_path = nil
117
72
  end
118
73
 
119
74
  # Returns true when the source path existed in frontmatter.
@@ -126,46 +81,16 @@ class Engine
126
81
  @read_result.array_traversed?
127
82
  end
128
83
 
129
- # Resolves every parsed entry for one primary-key scheme.
130
- def resolved_entries_for(primary_path:, registry:, active_document_checker: nil)
131
- @preferred_primary_path ||= primary_path
84
+ # Resolves every parsed entry for one complete identity scheme.
85
+ def resolved_entries_for(primary_path:, scope_fields: [], registry:, relationship: nil, active_document_checker: nil)
132
86
  @location_states.flat_map do |location_state|
133
- location_state.resolved_entries_for(primary_path: primary_path) do |entry|
87
+ location_state.resolved_entries_for(primary_path: primary_path, scope_fields: scope_fields) do |entry|
134
88
  resolve_entry(
135
89
  entry: entry,
136
90
  primary_path: primary_path,
91
+ scope_fields: scope_fields,
137
92
  registry: registry,
138
- active_document_checker: active_document_checker
139
- )
140
- end
141
- end
142
- end
143
-
144
- # Builds the upgraded path value while preserving its concrete locations.
145
- def upgraded_raw_value(registry:, active_document_checker: nil)
146
- return nil unless present?
147
-
148
- upgraded_values = upgraded_location_values(
149
- registry: registry,
150
- active_document_checker: active_document_checker
151
- )
152
- return upgraded_values.first if upgraded_values.length == 1
153
-
154
- upgraded_values
155
- end
156
-
157
- # Writes upgraded values back onto the exact matched locations.
158
- def write_upgraded_input!(registry:, active_document_checker: nil)
159
- upgraded_location_values(
160
- registry: registry,
161
- active_document_checker: active_document_checker
162
- )
163
- @location_states.each do |location_state|
164
- location_state.write_upgraded_value(primary_path: @preferred_primary_path) do |entry|
165
- resolve_entry(
166
- entry: entry,
167
- primary_path: @preferred_primary_path,
168
- registry: registry,
93
+ relationship: relationship,
169
94
  active_document_checker: active_document_checker
170
95
  )
171
96
  end
@@ -175,39 +100,44 @@ class Engine
175
100
  private
176
101
 
177
102
  # Resolves one parsed entry to a document and canonical key.
178
- def resolve_entry(entry:, primary_path:, registry:, active_document_checker:)
103
+ def resolve_entry(entry:, primary_path:, scope_fields:, registry:, relationship:, active_document_checker:)
104
+ effective_scope = registry.effective_scope_for(
105
+ reference_scope: entry.scope,
106
+ referring_document: @document,
107
+ scope_fields: scope_fields,
108
+ relationship: relationship
109
+ )
179
110
  document = if entry.document?
180
- entry.page
181
- else
182
- registry.lookup(
183
- key: entry.key,
184
- primary_path: primary_path,
185
- collection: entry.collection.nil? ? nil : entry.collection.to_s
186
- )
187
- end
111
+ registry.validate_scope_match!(
112
+ document: entry.page,
113
+ scope: effective_scope,
114
+ scope_fields: scope_fields,
115
+ relationship: relationship,
116
+ referring_document: @document
117
+ )
118
+ entry.page
119
+ else
120
+ registry.lookup(
121
+ key: entry.key,
122
+ primary_path: primary_path,
123
+ collection: entry.collection.nil? ? nil : entry.collection.to_s,
124
+ scope_fields: scope_fields,
125
+ scope: effective_scope,
126
+ relationship: relationship,
127
+ referring_document: @document
128
+ )
129
+ end
188
130
  return nil if active_document_checker && !active_document_checker.call(document)
189
131
 
190
132
  {
191
133
  document: document,
192
134
  key: registry.key_for(document, primary_path: primary_path),
135
+ scope: effective_scope,
193
136
  metadata: entry.metadata,
194
137
  count: entry.count
195
138
  }
196
139
  end
197
140
 
198
- # Builds upgraded values for every concrete location under this raw path.
199
- def upgraded_location_values(registry:, active_document_checker:)
200
- @location_states.map do |location_state|
201
- location_state.upgraded_value(primary_path: @preferred_primary_path) do |entry|
202
- resolve_entry(
203
- entry: entry,
204
- primary_path: @preferred_primary_path,
205
- registry: registry,
206
- active_document_checker: active_document_checker
207
- )
208
- end
209
- end
210
- end
211
141
  end
212
142
  end
213
143