json-ld 3.1.2 → 3.1.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  # frozen_string_literal: true
3
3
  $:.unshift(File.expand_path("../ld", __FILE__))
4
- require 'rdf' # @see http://rubygems.org/gems/rdf
4
+ require 'rdf' # @see https://rubygems.org/gems/rdf
5
5
  require 'multi_json'
6
6
  require 'set'
7
7
 
@@ -19,7 +19,7 @@ module JSON
19
19
  # end
20
20
  # end
21
21
  #
22
- # @see http://rubygems.org/gems/rdf
22
+ # @see https://rubygems.org/gems/rdf
23
23
  # @see http://www.w3.org/TR/REC-rdf-syntax/
24
24
  #
25
25
  # @author [Gregg Kellogg](http://greggkellogg.net/)
@@ -34,6 +34,8 @@ module JSON
34
34
  autoload :Normalize, 'json/ld/normalize'
35
35
  autoload :Reader, 'json/ld/reader'
36
36
  autoload :Resource, 'json/ld/resource'
37
+ autoload :StreamingReader, 'json/ld/streaming_reader'
38
+ autoload :StreamingWriter, 'json/ld/streaming_writer'
37
39
  autoload :VERSION, 'json/ld/version'
38
40
  autoload :Writer, 'json/ld/writer'
39
41
 
@@ -135,6 +137,7 @@ module JSON
135
137
  class InvalidNestValue < JsonLdError; @code = "invalid @nest value"; end
136
138
  class InvalidPrefixValue < JsonLdError; @code = "invalid @prefix value"; end
137
139
  class InvalidPropagateValue < JsonLdError; @code = "invalid @propagate value"; end
140
+ class InvalidEmbeddedNode < JsonLdError; @code = "invalid reified node"; end
138
141
  class InvalidRemoteContext < JsonLdError; @code = "invalid remote context"; end
139
142
  class InvalidReverseProperty < JsonLdError; @code = "invalid reverse property"; end
140
143
  class InvalidReversePropertyMap < JsonLdError; @code = "invalid reverse property map"; end
@@ -143,6 +146,7 @@ module JSON
143
146
  class InvalidScopedContext < JsonLdError; @code = "invalid scoped context"; end
144
147
  class InvalidScriptElement < JsonLdError; @code = "invalid script element"; end
145
148
  class InvalidSetOrListObject < JsonLdError; @code = "invalid set or list object"; end
149
+ class InvalidStreamingKeyOrder < JsonLdError; @code = 'invalid streaming key order' end
146
150
  class InvalidTermDefinition < JsonLdError; @code = "invalid term definition"; end
147
151
  class InvalidBaseDirection < JsonLdError; @code = "invalid base direction"; end
148
152
  class InvalidTypedValue < JsonLdError; @code = "invalid typed value"; end
@@ -66,7 +66,7 @@ module JSON::LD
66
66
  # @param [String, #read, Hash, Array, JSON::LD::Context] context
67
67
  # An external context to use additionally to the context embedded in input when expanding the input.
68
68
  # @param [Hash{Symbol => Object}] options
69
- # @option options [String, #to_s] :base
69
+ # @option options [RDF::URI, String, #to_s] :base
70
70
  # The Base IRI to use when expanding the document. This overrides the value of `input` if it is a _IRI_. If not specified and `input` is not an _IRI_, the base IRI defaults to the current document IRI if in a browser context, or the empty string if there is no document context. If not specified, and a base IRI is found from `input`, options[:base] will be modified with this value.
71
71
  # @option options [Boolean] :compactArrays (true)
72
72
  # If set to `true`, the JSON-LD processor replaces arrays with just one element with that element during compaction. If set to `false`, all arrays will remain arrays even if they have just one element.
@@ -89,6 +89,8 @@ module JSON::LD
89
89
  # @option options [String] :processingMode
90
90
  # Processing mode, json-ld-1.0 or json-ld-1.1.
91
91
  # If `processingMode` is not specified, a mode of `json-ld-1.0` or `json-ld-1.1` is set, the context used for `expansion` or `compaction`.
92
+ # @option options [Boolean] rdfstar (false)
93
+ # support parsing JSON-LD* statement resources.
92
94
  # @option options [Boolean] :rename_bnodes (true)
93
95
  # Rename bnodes as part of expansion, or keep them the same.
94
96
  # @option options [Boolean] :unique_bnodes (false)
@@ -108,6 +110,7 @@ module JSON::LD
108
110
  }.merge(options)
109
111
  @namer = unique_bnodes ? BlankNodeUniqer.new : (rename_bnodes ? BlankNodeNamer.new("b") : BlankNodeMapper.new)
110
112
 
113
+ @options[:base] = RDF::URI(@options[:base]) if @options[:base] && !@options[:base].is_a?(RDF::URI)
111
114
  # For context via Link header
112
115
  _, context_ref = nil, nil
113
116
 
@@ -117,7 +120,7 @@ module JSON::LD
117
120
  remote_doc = self.class.loadRemoteDocument(input, **@options)
118
121
 
119
122
  context_ref = remote_doc.contextUrl
120
- @options[:base] = remote_doc.documentUrl if remote_doc.documentUrl && !@options[:no_default_base]
123
+ @options[:base] = RDF::URI(remote_doc.documentUrl) if remote_doc.documentUrl && !@options[:no_default_base]
121
124
 
122
125
  case remote_doc.document
123
126
  when String
@@ -130,7 +133,7 @@ module JSON::LD
130
133
 
131
134
  # If not provided, first use context from document, or from a Link header
132
135
  context ||= context_ref || {}
133
- @context = Context.parse(context || {}, **@options)
136
+ @context = Context.parse(context, **@options)
134
137
 
135
138
  if block_given?
136
139
  case block.arity
@@ -163,10 +166,9 @@ module JSON::LD
163
166
  # If a block is given, the result of evaluating the block is returned, otherwise, the expanded JSON-LD document
164
167
  # @see https://www.w3.org/TR/json-ld11-api/#expansion-algorithm
165
168
  def self.expand(input, framing: false, **options, &block)
166
- result, doc_base = nil
169
+ result = doc_base = nil
167
170
  API.new(input, options[:expandContext], **options) do
168
171
  result = self.expand(self.value, nil, self.context,
169
- ordered: @options[:ordered],
170
172
  framing: framing)
171
173
  doc_base = @options[:base]
172
174
  end
@@ -218,21 +220,21 @@ module JSON::LD
218
220
  # 1) Perform the Expansion Algorithm on the JSON-LD input.
219
221
  # This removes any existing context to allow the given context to be cleanly applied.
220
222
  expanded_input = expanded ? input : API.expand(input, ordered: false, **options) do |res, base_iri|
221
- options[:base] ||= base_iri if options[:compactToRelative]
223
+ options[:base] ||= RDF::URI(base_iri) if base_iri && options[:compactToRelative]
222
224
  res
223
225
  end
224
226
 
225
227
  API.new(expanded_input, context, no_default_base: true, **options) do
226
228
  log_debug(".compact") {"expanded input: #{expanded_input.to_json(JSON_STATE) rescue 'malformed json'}"}
227
- result = compact(value, ordered: @options[:ordered])
229
+ result = compact(value)
228
230
 
229
231
  # xxx) Add the given context to the output
230
- ctx = self.context.serialize
232
+ ctx = self.context.serialize(provided_context: context)
231
233
  if result.is_a?(Array)
232
234
  kwgraph = self.context.compact_iri('@graph', vocab: true)
233
235
  result = result.empty? ? {} : {kwgraph => result}
234
236
  end
235
- result = ctx.merge(result) unless ctx.empty?
237
+ result = ctx.merge(result) unless ctx.fetch('@context', {}).empty?
236
238
  end
237
239
  block_given? ? yield(result) : result
238
240
  end
@@ -265,7 +267,7 @@ module JSON::LD
265
267
 
266
268
  # Expand input to simplify processing
267
269
  expanded_input = expanded ? input : API.expand(input, **options) do |result, base_iri|
268
- options[:base] ||= base_iri if options[:compactToRelative]
270
+ options[:base] ||= RDF::URI(base_iri) if base_iri && options[:compactToRelative]
269
271
  result
270
272
  end
271
273
 
@@ -294,9 +296,11 @@ module JSON::LD
294
296
 
295
297
  if context && !flattened.empty?
296
298
  # Otherwise, return the result of compacting flattened according the Compaction algorithm passing context ensuring that the compaction result uses the @graph keyword (or its alias) at the top-level, even if the context is empty or if there is only one element to put in the @graph array. This ensures that the returned document has a deterministic structure.
297
- compacted = as_array(compact(flattened, ordered: @options[:ordered]))
299
+ compacted = as_array(compact(flattened))
298
300
  kwgraph = self.context.compact_iri('@graph')
299
- flattened = self.context.serialize.merge(kwgraph => compacted)
301
+ flattened = self.context.
302
+ serialize(provided_context: context).
303
+ merge(kwgraph => compacted)
300
304
  end
301
305
  end
302
306
 
@@ -335,7 +339,7 @@ module JSON::LD
335
339
  def self.frame(input, frame, expanded: false, **options)
336
340
  result = nil
337
341
  options = {
338
- base: (input if input.is_a?(String)),
342
+ base: (RDF::URI(input) if input.is_a?(String)),
339
343
  compactArrays: true,
340
344
  compactToRelative: true,
341
345
  embed: '@once',
@@ -369,7 +373,7 @@ module JSON::LD
369
373
 
370
374
  # Expand input to simplify processing
371
375
  expanded_input = expanded ? input : API.expand(input, ordered: false, **options) do |res, base_iri|
372
- options[:base] ||= base_iri if options[:compactToRelative]
376
+ options[:base] ||= RDF::URI(base_iri) if base_iri && options[:compactToRelative]
373
377
  res
374
378
  end
375
379
 
@@ -426,7 +430,7 @@ module JSON::LD
426
430
  log_debug(".frame") {"expanded result: #{result.to_json(JSON_STATE) rescue 'malformed json'}"}
427
431
 
428
432
  # Compact result
429
- compacted = compact(result, ordered: @options[:ordered])
433
+ compacted = compact(result)
430
434
 
431
435
  # @replace `@null` with nil, compacting arrays
432
436
  compacted = cleanup_null(compacted)
@@ -434,11 +438,14 @@ module JSON::LD
434
438
 
435
439
  # Add the given context to the output
436
440
  result = if !compacted.is_a?(Array)
437
- context.serialize.merge(compacted)
441
+ compacted
438
442
  else
439
443
  kwgraph = context.compact_iri('@graph')
440
- context.serialize.merge({kwgraph => compacted})
444
+ {kwgraph => compacted}
441
445
  end
446
+ # Only add context if one was provided
447
+ result = context.serialize(provided_context: frame).merge(result) if frame['@context']
448
+
442
449
  log_debug(".frame") {"after compact: #{result.to_json(JSON_STATE) rescue 'malformed json'}"}
443
450
  result
444
451
  end
@@ -521,8 +528,7 @@ module JSON::LD
521
528
  API.new(nil, nil, **options) do
522
529
  result = from_statements(input,
523
530
  useRdfType: useRdfType,
524
- useNativeTypes: useNativeTypes,
525
- ordered: @options[:ordered])
531
+ useNativeTypes: useNativeTypes)
526
532
  end
527
533
 
528
534
  block_given? ? yield(result) : result
@@ -532,16 +538,18 @@ module JSON::LD
532
538
  # Uses built-in or provided documentLoader to retrieve a parsed document.
533
539
  #
534
540
  # @param [RDF::URI, String] url
541
+ # @param [String, RDF::URI] base
542
+ # Location to use as documentUrl instead of `url`.
543
+ # @option options [Proc] :documentLoader
544
+ # The callback of the loader to be used to retrieve remote documents and contexts.
535
545
  # @param [Boolean] extractAllScripts
536
546
  # If set to `true`, when extracting JSON-LD script elements from HTML, unless a specific fragment identifier is targeted, extracts all encountered JSON-LD script elements using an array form, if necessary.
537
547
  # @param [String] profile
538
548
  # When the resulting `contentType` is `text/html` or `application/xhtml+xml`, this option determines the profile to use for selecting a JSON-LD script elements.
539
549
  # @param [String] requestProfile
540
550
  # One or more IRIs to use in the request as a profile parameter.
541
- # @param [Boolean] validate
551
+ # @param [Boolean] validate (false)
542
552
  # Allow only appropriate content types
543
- # @param [String, RDF::URI] base
544
- # Location to use as documentUrl instead of `url`.
545
553
  # @param [Hash<Symbol => Object>] options
546
554
  # @yield remote_document
547
555
  # @yieldparam [RemoteDocumentRemoteDocument, RDF::Util::File::RemoteDocument] remote_document
@@ -550,13 +558,14 @@ module JSON::LD
550
558
  # If a block is given, the result of evaluating the block is returned, otherwise, the retrieved remote document and context information unless block given
551
559
  # @raise [JsonLdError]
552
560
  def self.loadRemoteDocument(url,
561
+ base: nil,
562
+ documentLoader: nil,
553
563
  extractAllScripts: false,
554
564
  profile: nil,
555
565
  requestProfile: nil,
556
566
  validate: false,
557
- base: nil,
558
567
  **options)
559
- documentLoader = options.fetch(:documentLoader, self.method(:documentLoader))
568
+ documentLoader ||= self.method(:documentLoader)
560
569
  options = OPEN_OPTS.merge(options)
561
570
  if requestProfile
562
571
  # Add any request profile
@@ -12,16 +12,16 @@ module JSON::LD
12
12
  # This algorithm compacts a JSON-LD document, such that the given context is applied. This must result in shortening any applicable IRIs to terms or compact IRIs, any applicable keywords to keyword aliases, and any applicable JSON-LD values expressed in expanded form to simple values such as strings or numbers.
13
13
  #
14
14
  # @param [Array, Hash] element
15
- # @param [String] property (nil)
16
- # @param [Boolean] ordered (true)
15
+ # @param [String, RDF::URI] base (nil)
17
16
  # Ensure output objects have keys ordered properly
17
+ # @param [String] property (nil)
18
+ # Extra validatation
18
19
  # @return [Array, Hash]
19
- def compact(element, property: nil, ordered: false)
20
- #if property.nil?
21
- # log_debug("compact") {"element: #{element.inspect}, ec: #{context.inspect}"}
22
- #else
23
- # log_debug("compact") {"property: #{property.inspect}"}
24
- #end
20
+ def compact(element,
21
+ base: nil,
22
+ property: nil,
23
+ log_depth: nil)
24
+ log_debug("compact", depth: log_depth.to_i) {"element: #{element.inspect}, ec: #{context.inspect}"}
25
25
 
26
26
  # If the term definition for active property itself contains a context, use that for compacting values.
27
27
  input_context = self.context
@@ -29,17 +29,19 @@ module JSON::LD
29
29
  case element
30
30
  when Array
31
31
  #log_debug("") {"Array #{element.inspect}"}
32
- result = element.map {|item| compact(item, property: property, ordered: ordered)}.compact
32
+ result = element.map do |item|
33
+ compact(item, base: base, property: property, log_depth: log_depth.to_i + 1)
34
+ end.compact
33
35
 
34
36
  # If element has a single member and the active property has no
35
37
  # @container mapping to @list or @set, the compacted value is that
36
38
  # member; otherwise the compacted value is element
37
39
  if result.length == 1 &&
38
40
  !context.as_array?(property) && @options[:compactArrays]
39
- #log_debug("=> extract single element: #{result.first.inspect}")
41
+ log_debug("=> extract single element", depth: log_depth.to_i) {result.first.inspect}
40
42
  result.first
41
43
  else
42
- #log_debug("=> array result: #{result.inspect}")
44
+ log_debug("=> array result", depth: log_depth.to_i) {result.inspect}
43
45
  result
44
46
  end
45
47
  when Hash
@@ -50,24 +52,31 @@ module JSON::LD
50
52
 
51
53
  # Revert any previously type-scoped (non-preserved) context
52
54
  if context.previous_context && !element.key?('@value') && element.keys != %w(@id)
55
+ log_debug("revert ec", depth: log_depth.to_i) {"previous context: #{context.previous_context.inspect}"}
53
56
  self.context = context.previous_context
54
57
  end
55
58
 
56
59
  # Look up term definintions from property using the original type-scoped context, if it exists, but apply them to the now current previous context
57
60
  td = input_context.term_definitions[property] if property
58
- self.context = context.parse(td.context, override_protected: true) if td && td.context
61
+ if td && !td.context.nil?
62
+ self.context = context.parse(td.context,
63
+ override_protected: true)
64
+ log_debug("prop-scoped", depth: log_depth.to_i) {"context: #{self.context.inspect}"}
65
+ end
59
66
 
60
67
  if element.key?('@id') || element.key?('@value')
61
- result = context.compact_value(property, element, log_depth: @options[:log_depth])
68
+ result = context.compact_value(property, element, base: @options[:base])
62
69
  if !result.is_a?(Hash) || context.coerce(property) == '@json'
63
- #log_debug("") {"=> scalar result: #{result.inspect}"}
70
+ log_debug("", depth: log_depth.to_i) {"=> scalar result: #{result.inspect}"}
64
71
  return result
65
72
  end
66
73
  end
67
74
 
68
75
  # If expanded property is @list and we're contained within a list container, recursively compact this item to an array
69
76
  if list?(element) && context.container(property).include?('@list')
70
- return compact(element['@list'], property: property, ordered: ordered)
77
+ return compact(element['@list'], base: base,
78
+ property: property,
79
+ log_depth: log_depth.to_i + 1)
71
80
  end
72
81
 
73
82
  inside_reverse = property == '@reverse'
@@ -80,15 +89,25 @@ module JSON::LD
80
89
  sort.
81
90
  each do |term|
82
91
  term_context = input_context.term_definitions[term].context if input_context.term_definitions[term]
83
- self.context = context.parse(term_context, propagate: false) if term_context
92
+ self.context = context.parse(term_context, propagate: false) unless term_context.nil?
93
+ log_debug("type-scoped", depth: log_depth.to_i) {"context: #{self.context.inspect}"}
84
94
  end
85
95
 
86
- element.keys.opt_sort(ordered: ordered).each do |expanded_property|
96
+ element.keys.opt_sort(ordered: @options[:ordered]).each do |expanded_property|
87
97
  expanded_value = element[expanded_property]
88
- #log_debug("") {"#{expanded_property}: #{expanded_value.inspect}"}
98
+ log_debug("", depth: log_depth.to_i) {"#{expanded_property}: #{expanded_value.inspect}"}
89
99
 
90
100
  if expanded_property == '@id'
91
- compacted_value = Array(expanded_value).map {|expanded_id| context.compact_iri(expanded_id)}
101
+ compacted_value = as_array(expanded_value).map do |expanded_id|
102
+ if node?(expanded_id) && @options[:rdfstar]
103
+ # This can only really happen for valid RDF*
104
+ compact(expanded_id, base: base,
105
+ property: '@id',
106
+ log_depth: log_depth.to_i + 1)
107
+ else
108
+ context.compact_iri(expanded_id, base: @options[:base])
109
+ end
110
+ end
92
111
 
93
112
  kw_alias = context.compact_iri('@id', vocab: true)
94
113
  as_array = compacted_value.length > 1
@@ -98,7 +117,9 @@ module JSON::LD
98
117
  end
99
118
 
100
119
  if expanded_property == '@type'
101
- compacted_value = Array(expanded_value).map {|expanded_type| input_context.compact_iri(expanded_type, vocab: true)}
120
+ compacted_value = Array(expanded_value).map do |expanded_type|
121
+ input_context.compact_iri(expanded_type, vocab: true)
122
+ end
102
123
 
103
124
  kw_alias = context.compact_iri('@type', vocab: true)
104
125
  as_array = compacted_value.length > 1 ||
@@ -110,8 +131,10 @@ module JSON::LD
110
131
  end
111
132
 
112
133
  if expanded_property == '@reverse'
113
- compacted_value = compact(expanded_value, property: '@reverse', ordered: ordered)
114
- #log_debug("@reverse") {"compacted_value: #{compacted_value.inspect}"}
134
+ compacted_value = compact(expanded_value, base: base,
135
+ property: '@reverse',
136
+ log_depth: log_depth.to_i + 1)
137
+ log_debug("@reverse", depth: log_depth.to_i) {"compacted_value: #{compacted_value.inspect}"}
115
138
  # handle double-reversed properties
116
139
  compacted_value.each do |prop, value|
117
140
  if context.reverse?(prop)
@@ -123,7 +146,7 @@ module JSON::LD
123
146
 
124
147
  unless compacted_value.empty?
125
148
  al = context.compact_iri('@reverse')
126
- #log_debug("") {"remainder: #{al} => #{compacted_value.inspect}"}
149
+ log_debug("", depth: log_depth.to_i) {"remainder: #{al} => #{compacted_value.inspect}"}
127
150
  result[al] = compacted_value
128
151
  end
129
152
  next
@@ -131,8 +154,10 @@ module JSON::LD
131
154
 
132
155
  if expanded_property == '@preserve'
133
156
  # Compact using `property`
134
- compacted_value = compact(expanded_value, property: property, ordered: ordered)
135
- #log_debug("@preserve") {"compacted_value: #{compacted_value.inspect}"}
157
+ compacted_value = compact(expanded_value, base: base,
158
+ property: property,
159
+ log_depth: log_depth.to_i + 1)
160
+ log_debug("@preserve", depth: log_depth.to_i) {"compacted_value: #{compacted_value.inspect}"}
136
161
 
137
162
  unless compacted_value.is_a?(Array) && compacted_value.empty?
138
163
  result['@preserve'] = compacted_value
@@ -141,14 +166,14 @@ module JSON::LD
141
166
  end
142
167
 
143
168
  if expanded_property == '@index' && context.container(property).include?('@index')
144
- #log_debug("@index") {"drop @index"}
169
+ log_debug("@index", depth: log_depth.to_i) {"drop @index"}
145
170
  next
146
171
  end
147
172
 
148
173
  # Otherwise, if expanded property is @direction, @index, @value, or @language:
149
174
  if EXPANDED_PROPERTY_DIRECTION_INDEX_LANGUAGE_VALUE.include?(expanded_property)
150
175
  al = context.compact_iri(expanded_property, vocab: true)
151
- #log_debug(expanded_property) {"#{al} => #{expanded_value.inspect}"}
176
+ log_debug(expanded_property, depth: log_depth.to_i) {"#{al} => #{expanded_value.inspect}"}
152
177
  result[al] = expanded_value
153
178
  next
154
179
  end
@@ -158,8 +183,7 @@ module JSON::LD
158
183
  context.compact_iri(expanded_property,
159
184
  value: expanded_value,
160
185
  vocab: true,
161
- reverse: inside_reverse,
162
- log_depth: @options[:log_depth])
186
+ reverse: inside_reverse)
163
187
 
164
188
  if nest_prop = context.nest(item_active_property)
165
189
  result[nest_prop] ||= {}
@@ -177,8 +201,7 @@ module JSON::LD
177
201
  context.compact_iri(expanded_property,
178
202
  value: expanded_item,
179
203
  vocab: true,
180
- reverse: inside_reverse,
181
- log_depth: @options[:log_depth])
204
+ reverse: inside_reverse)
182
205
 
183
206
 
184
207
  nest_result = if nest_prop = context.nest(item_active_property)
@@ -197,8 +220,10 @@ module JSON::LD
197
220
  else expanded_item
198
221
  end
199
222
 
200
- compacted_item = compact(value, property: item_active_property, ordered: ordered)
201
- #log_debug("") {" => compacted key: #{item_active_property.inspect} for #{compacted_item.inspect}"}
223
+ compacted_item = compact(value, base: base,
224
+ property: item_active_property,
225
+ log_depth: log_depth.to_i + 1)
226
+ log_debug("", depth: log_depth.to_i) {" => compacted key: #{item_active_property.inspect} for #{compacted_item.inspect}"}
202
227
 
203
228
  # handle @list
204
229
  if list?(expanded_item)
@@ -225,9 +250,9 @@ module JSON::LD
225
250
  map_object = nest_result[item_active_property] ||= {}
226
251
  # If there is no @id, create a blank node identifier to use as an index
227
252
  map_key = if container.include?('@id') && expanded_item['@id']
228
- context.compact_iri(expanded_item['@id'])
253
+ context.compact_iri(expanded_item['@id'], base: @options[:base])
229
254
  elsif container.include?('@index') && expanded_item['@index']
230
- context.compact_iri(expanded_item['@index'])
255
+ context.compact_iri(expanded_item['@index'], vocab: true)
231
256
  else
232
257
  context.compact_iri('@none', vocab: true)
233
258
  end
@@ -299,7 +324,10 @@ module JSON::LD
299
324
 
300
325
  # if compacted_item contains a single entry who's key maps to @id, then recompact the item without @type
301
326
  if compacted_item.keys.length == 1 && expanded_item.keys.include?('@id')
302
- compacted_item = compact({'@id' => expanded_item['@id']}, property: item_active_property)
327
+ compacted_item = compact({'@id' => expanded_item['@id']},
328
+ base: base,
329
+ property: item_active_property,
330
+ log_depth: log_depth.to_i + 1)
303
331
  end
304
332
  compacted_item
305
333
  end
@@ -316,7 +344,7 @@ module JSON::LD
316
344
  result
317
345
  else
318
346
  # For other types, the compacted value is the element value
319
- #log_debug("compact") {element.class.to_s}
347
+ log_debug("compact", depth: log_depth.to_i) {element.class.to_s}
320
348
  element
321
349
  end
322
350