Skip to content

Commit 8ba5954

Browse files
committed
Compact graphs with @container: @graph and @id or @index.
- adds a BNode issuer to compact to generate identifiers, if necessary.
1 parent 13e2eaa commit 8ba5954

File tree

3 files changed

+71
-22
lines changed

3 files changed

+71
-22
lines changed

lib/compact.js

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ module.exports = api;
4545
* @param activeProperty the compacted property associated with the element
4646
* to compact, null for none.
4747
* @param element the element to compact.
48-
* @param options the compaction options.
48+
* @param options the compaction options:
49+
* [issuer] a jsonld.IdentifierIssuer to use to label blank nodes.
4950
* @param compactionMap the compaction map to use.
5051
*
5152
* @return the compacted value.
@@ -126,6 +127,9 @@ api.compact = ({
126127

127128
const rval = {};
128129

130+
// produce a map of all subjects and name each bnode
131+
const issuer = options.issuer || new util.IdentifierIssuer('_:b');
132+
129133
if(options.link && '@id' in element) {
130134
// store linked element
131135
if(!(element['@id'] in options.link)) {
@@ -262,20 +266,20 @@ api.compact = ({
262266
activeCtx, itemActiveProperty, '@container') || [];
263267

264268
// get simple @graph or @list value if appropriate
265-
const isSimpleGraph = _isSimpleGraph(expandedItem);
269+
const isGraph = _isGraph(expandedItem);
266270
const isList = _isList(expandedItem);
267271
let inner;
268272
if(isList) {
269273
inner = expandedItem['@list'];
270-
} else if(isSimpleGraph) {
274+
} else if(isGraph) {
271275
inner = expandedItem['@graph'];
272276
}
273277

274278
// recursively compact expanded item
275279
let compactedItem = api.compact({
276280
activeCtx,
277281
activeProperty: itemActiveProperty,
278-
element: (isList || isSimpleGraph) ? inner : expandedItem,
282+
element: (isList || isGraph) ? inner : expandedItem,
279283
options,
280284
compactionMap
281285
});
@@ -309,22 +313,63 @@ api.compact = ({
309313
}
310314
}
311315

312-
// handle simple @graph
313-
if(isSimpleGraph && !container.includes('@graph')) {
314-
// wrap using @graph alias
315-
compactedItem = {
316-
[api.compactIri({activeCtx, iri: '@graph'})]: compactedItem
317-
};
318-
319-
// include @index from expanded @graph, if any
320-
if('@index' in expandedItem) {
321-
compactedItem[api.compactIri({activeCtx, iri: '@index'})] =
322-
expandedItem['@index'];
323-
}
324-
}
316+
// Graph object compaction cases
317+
if(isGraph) {
318+
if(container.includes('@graph') && container.includes('@id')) {
319+
// container includes @graph and @id
320+
// get or create the map object
321+
let mapObject;
322+
if(itemActiveProperty in rval) {
323+
mapObject = rval[itemActiveProperty];
324+
} else {
325+
rval[itemActiveProperty] = mapObject = {};
326+
}
327+
// add compactedItem to map, using value of `@id` or a new blank node identifier
328+
_addValue(
329+
mapObject, (expandedItem['@id'] || issuer.getId(null)), compactedItem,
330+
{propertyIsArray: (!options.compactArrays || container.includes('@set'))});
331+
} else if(container.includes('@graph') && container.includes('@index') && _isSimpleGraph(expandedItem)) {
332+
// container includes @graph and @index and item is a simple graph
333+
// get or create the map object
334+
let mapObject;
335+
if(itemActiveProperty in rval) {
336+
mapObject = rval[itemActiveProperty];
337+
} else {
338+
rval[itemActiveProperty] = mapObject = {};
339+
}
340+
// add compactedItem to map, using value of `@index` or `@none`
341+
_addValue(
342+
mapObject, (expandedItem['@index'] || '@none'), compactedItem,
343+
{propertyIsArray: (!options.compactArrays || container.includes('@set'))});
344+
} else if(container.includes('@graph') && _isSimpleGraph(expandedItem)) {
345+
// container includes @graph but not @id or @index and value is a simple graph object
346+
// add compact value
347+
_addValue(
348+
rval, itemActiveProperty, compactedItem,
349+
{propertyIsArray: (!options.compactArrays || container.includes('@set'))});
350+
} else {
351+
// wrap using @graph alias
352+
compactedItem = {
353+
[api.compactIri({activeCtx, iri: '@graph'})]: compactedItem
354+
};
325355

356+
// include @id from expanded graph, if any
357+
if('@id' in expandedItem) {
358+
compactedItem[api.compactIri({activeCtx, iri: '@id'})] =
359+
expandedItem['@id'];
360+
}
361+
362+
// include @index from expanded graph, if any
363+
if('@index' in expandedItem) {
364+
compactedItem[api.compactIri({activeCtx, iri: '@index'})] =
365+
expandedItem['@index'];
366+
}
367+
_addValue(
368+
rval, itemActiveProperty, compactedItem,
369+
{propertyIsArray: (!options.compactArrays || container.includes('@set'))});
370+
}
371+
} else if(container.includes('@language') || container.includes('@index')) {
326372
// handle language and index maps
327-
if(container.includes('@language') || container.includes('@index')) {
328373
// get or create the map object
329374
let mapObject;
330375
if(itemActiveProperty in rval) {
@@ -412,9 +457,12 @@ api.compactIri = ({
412457
containers.push('@index');
413458
}
414459

415-
// prefer `['@graph', '@set']` and then `@graph` if value is a simple graph
416-
// TODO: support `@graphId`?
460+
// prefer most specific container including @graph, prefering @set variations
417461
if(_isGraph(value)) {
462+
containers.push('@graph@index@set');
463+
containers.push('@graph@index');
464+
containers.push('@graph@id@set');
465+
containers.push('@graph@id');
418466
containers.push('@graph@set');
419467
containers.push('@graph');
420468
}

lib/jsonld.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ jsonld.compact = util.callbackify(async function(input, ctx, options) {
136136
compactArrays: true,
137137
graph: false,
138138
skipExpansion: false,
139-
link: false
139+
link: false,
140+
issuer: new IdentifierIssuer('_:b')
140141
});
141142
if(options.link) {
142143
// force skip expansion when linking, "link" is not part of the public

tests/test-common.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const manifest = options.manifest || {
2929
const TEST_TYPES = {
3030
'jld:CompactTest': {
3131
skip: {
32-
regex: [/#t0073/, /#t[acmnps]/, /#t008[1-8]/]
32+
regex: [/#t0073/, /#t[acmnps]/]
3333
},
3434
fn: 'compact',
3535
params: [

0 commit comments

Comments
 (0)