Skip to content

Commit 514172e

Browse files
authored
Merge pull request #57 from iilab/master
Fix blank node problem
2 parents 43e91d9 + d1a97de commit 514172e

8 files changed

Lines changed: 8071 additions & 7972 deletions

File tree

build/levelgraph-jsonld.js

Lines changed: 7813 additions & 7884 deletions
Large diffs are not rendered by default.

build/levelgraph-jsonld.min.js

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

index.js

Lines changed: 56 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -45,42 +45,47 @@ function levelgraphJSONLD(db, jsonldOpts) {
4545

4646
stream.on('error', callback);
4747
stream.on('close', function() {
48+
if (options.blank_ids) {
49+
// return rdf store scoped blank nodes
50+
51+
var blank_keys = Object.keys(blanks);
52+
var clone_obj = Object.assign({}, obj)
53+
var frame;
54+
frame = (function framify(o) {
55+
Object.keys(o).map(function(key) {
56+
if (Array.isArray(o[key]) && key != "@type") {
57+
o[key] = o[key][0];
58+
} else if (typeof o[key] === "object") {
59+
o[key] = framify(o[key]);
60+
}
61+
})
62+
return o;
63+
})(clone_obj)
4864

49-
var blank_keys = Object.keys(blanks);
50-
var clone_obj = Object.assign({}, obj)
51-
var frame;
52-
frame = (function framify(o) {
53-
Object.keys(o).map(function(key) {
54-
if (Array.isArray(o[key]) && key != "@type") {
55-
o[key] = o[key][0];
56-
} else if (typeof o[key] === "object") {
57-
o[key] = framify(o[key]);
58-
}
59-
})
60-
return o;
61-
})(clone_obj)
62-
63-
if (blank_keys.length != 0) {
64-
jsonld.frame(obj, frame, function(err, framed) {
65-
if (err) {
66-
return callback(err, null);
67-
}
68-
var framed_string = JSON.stringify(framed);
69-
70-
blank_keys.forEach(function(blank) {
71-
framed_string = framed_string.replace(blank,blanks[blank])
65+
if (blank_keys.length != 0) {
66+
jsonld.frame(obj, frame, function(err, framed) {
67+
if (err) {
68+
return callback(err, null);
69+
}
70+
var framed_string = JSON.stringify(framed);
71+
72+
blank_keys.forEach(function(blank) {
73+
framed_string = framed_string.replace(blank,blanks[blank])
74+
})
75+
var ided = JSON.parse(framed_string);
76+
if (ided["@graph"].length == 1) {
77+
var clean_reframe = Object.assign({}, { "@context": ided["@context"]}, ided["@graph"][0]);
78+
return callback(null, clean_reframe);
79+
} else if (ided["@graph"].length > 1) {
80+
return callback(null, ided);
81+
} else {
82+
// Could not reframe the input, returning the original object
83+
return callback(null, obj);
84+
}
7285
})
73-
var ided = JSON.parse(framed_string);
74-
if (ided["@graph"].length == 1) {
75-
var clean_reframe = Object.assign({}, { "@context": ided["@context"]}, ided["@graph"][0]);
76-
return callback(null, clean_reframe);
77-
} else if (ided["@graph"].length > 1) {
78-
return callback(null, ided);
79-
} else {
80-
// Could not reframe the input, returning the original object
81-
return callback(null, obj);
82-
}
83-
})
86+
} else {
87+
return callback(null, obj);
88+
}
8489
} else {
8590
return callback(null, obj);
8691
}
@@ -344,16 +349,18 @@ function levelgraphJSONLD(db, jsonldOpts) {
344349
async.reduce(triples, memo, function(acc, triple, cb) {
345350
var key;
346351

347-
if (!acc[triple.subject]) {
352+
if (!acc[triple.subject] && !N3Util.isBlank(triple.subject)) {
348353
acc[triple.subject] = { '@id': triple.subject };
354+
} else if (N3Util.isBlank(triple.subject) && !acc[triple.subject]) {
355+
acc[triple.subject] = {};
349356
}
350357
if (triple.predicate === RDFTYPE) {
351358
if (acc[triple.subject]['@type']) {
352359
acc[triple.subject]['@type'].push(triple.object);
353360
} else {
354361
acc[triple.subject]['@type'] = [triple.object];
355362
}
356-
cb(null, acc);
363+
return cb(null, acc);
357364
} else if (!N3Util.isBlank(triple.object)) {
358365
var object = {};
359366
if (N3Util.isIRI(triple.object)) {
@@ -362,42 +369,34 @@ function levelgraphJSONLD(db, jsonldOpts) {
362369
object = getCoercedObject(triple.object);
363370
}
364371
if(object['@id']) {
372+
// expanding object iri
365373
fetchExpandedTriples(triple.object, function(err, expanded) {
366-
if (expanded !== null && !acc[triple.subject][triple.predicate]) {
367-
acc[triple.subject][triple.predicate] = expanded[triple.object];
368-
} else if (expanded !== null) {
369-
if (!acc[triple.subject][triple.predicate].push) {
370-
acc[triple.subject][triple.predicate] = [acc[triple.subject][triple.predicate]];
371-
}
374+
if (!acc[triple.subject][triple.predicate]) acc[triple.subject][triple.predicate] = [];
375+
if (expanded !== null) {
372376
acc[triple.subject][triple.predicate].push(expanded[triple.object]);
373377
} else {
374-
if (Array.isArray(acc[triple.subject][triple.predicate])){
375-
acc[triple.subject][triple.predicate].push(object);
376-
} else {
377-
acc[triple.subject][triple.predicate] = [object];
378-
}
378+
acc[triple.subject][triple.predicate].push(object);
379379
}
380-
cb(err, acc);
380+
return cb(err, acc);
381381
});
382382
}
383383
else if (Array.isArray(acc[triple.subject][triple.predicate])){
384384
acc[triple.subject][triple.predicate].push(object);
385-
cb(err, acc);
385+
return cb(err, acc);
386386
} else {
387387
acc[triple.subject][triple.predicate] = [object];
388-
cb(err, acc);
388+
return cb(err, acc);
389389
}
390390
} else {
391+
// deal with blanks
391392
fetchExpandedTriples(triple.object, function(err, expanded) {
392-
if (expanded !== null && !acc[triple.subject][triple.predicate]) {
393-
acc[triple.subject][triple.predicate] = expanded[triple.object];
394-
} else if (expanded !== null) {
395-
if (!Array.isArray(acc[triple.subject][triple.predicate])) {
396-
acc[triple.subject][triple.predicate] = [acc[triple.subject][triple.predicate]];
397-
}
393+
if (!acc[triple.subject][triple.predicate]) acc[triple.subject][triple.predicate] = [];
394+
if (expanded !== null) {
398395
acc[triple.subject][triple.predicate].push(expanded[triple.object]);
396+
} else {
397+
acc[triple.subject][triple.predicate].push(object);
399398
}
400-
cb(err, acc);
399+
return cb(err, acc);
401400
});
402401
}
403402
}, callback);

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "levelgraph-jsonld",
3-
"version": "1.0.2",
3+
"version": "1.0.3",
44
"description": "The Object Document Mapper for LevelGraph based on JSON-LD",
55
"main": "index.js",
66
"scripts": {
@@ -34,7 +34,7 @@
3434
"license": "MIT",
3535
"dependencies": {
3636
"async": "^2.1.4",
37-
"jsonld": "~0.4.6",
37+
"jsonld": "0.4.9",
3838
"memdb": "^1.3.1",
3939
"n3": "iilab/N3.js#fix/object-is-not-IRI",
4040
"uuid": "^3.0.1"

test/get_spec.js

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,30 @@ describe('jsonld.get', function() {
3535
});
3636

3737
describe('with an object with blank nodes', function() {
38-
var tesla;
38+
var tesla, annotation;
3939

4040
beforeEach(function(done) {
4141
tesla = helper.getFixture('tesla.json');
42-
db.jsonld.put(tesla, done);
42+
annotation = helper.getFixture('annotation.json');
43+
done();
4344
});
4445

4546
it('should load it properly', function(done) {
46-
db.jsonld.get(tesla['@id'], { '@context': tesla['@context'] }, function(err, obj) {
47-
tesla['gr:hasPriceSpecification']['@id'] = obj['gr:hasPriceSpecification']['@id'];
48-
tesla['gr:includes']['@id'] = obj['gr:includes']['@id'];
49-
expect(obj).to.eql(tesla);
50-
done();
47+
db.jsonld.put(tesla, function() {
48+
db.jsonld.get(tesla['@id'], { '@context': tesla['@context'] }, function(err, obj) {
49+
expect(obj).to.eql(tesla);
50+
done();
51+
});
52+
});
53+
});
54+
55+
it('should load a context with mapped ids', function(done) {
56+
db.jsonld.put(annotation, function() {
57+
db.jsonld.get(annotation['id'], { '@context': annotation['@context'] }, function(err, obj) {
58+
expect(obj['body']).to.deep.have.members(annotation['body']);
59+
expect(obj['target']).to.deep.have.members(annotation['target']);
60+
done();
61+
});
5162
});
5263
});
5364
});

test/helper.js

Lines changed: 160 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,13 +260,172 @@ var getFixture = function(name) {
260260
"id": "http://bigbluehat.com/#",
261261
"name": "BigBlueHat",
262262
"knows": [
263-
264263
{
265264
"id": "http://manu.sporny.org#person",
266265
"name": "Manu Sporny",
267266
"homepage": "http://manu.sporny.org/"
268267
}
269268
]
269+
},
270+
"annotation_remote.json": {
271+
"@context": "http://www.w3.org/ns/anno.jsonld",
272+
"id": "http://example.org/anno9",
273+
"type": "Annotation",
274+
"body": [
275+
"http://example.org/description1",
276+
{
277+
"type": "TextualBody",
278+
"value": "tag1"
279+
}
280+
],
281+
"target": [
282+
"http://example.org/image1",
283+
"http://example.org/image2",
284+
{
285+
"source": "http://example.org/"
286+
}
287+
]
288+
},
289+
"annotation.json": {
290+
"@context": {
291+
"oa": "http://www.w3.org/ns/oa#",
292+
"dc": "http://purl.org/dc/elements/1.1/",
293+
"dcterms": "http://purl.org/dc/terms/",
294+
"dctypes": "http://purl.org/dc/dcmitype/",
295+
"foaf": "http://xmlns.com/foaf/0.1/",
296+
"rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
297+
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
298+
"skos": "http://www.w3.org/2004/02/skos/core#",
299+
"xsd": "http://www.w3.org/2001/XMLSchema#",
300+
"iana": "http://www.iana.org/assignments/relation/",
301+
"owl": "http://www.w3.org/2002/07/owl#",
302+
"as": "http://www.w3.org/ns/activitystreams#",
303+
"schema": "http://schema.org/",
304+
305+
"id": {"@type": "@id", "@id": "@id"},
306+
"type": {"@type": "@id", "@id": "@type"},
307+
308+
"Annotation": "oa:Annotation",
309+
"Dataset": "dctypes:Dataset",
310+
"Image": "dctypes:StillImage",
311+
"Video": "dctypes:MovingImage",
312+
"Audio": "dctypes:Sound",
313+
"Text": "dctypes:Text",
314+
"TextualBody": "oa:TextualBody",
315+
"ResourceSelection": "oa:ResourceSelection",
316+
"SpecificResource": "oa:SpecificResource",
317+
"FragmentSelector": "oa:FragmentSelector",
318+
"CssSelector": "oa:CssSelector",
319+
"XPathSelector": "oa:XPathSelector",
320+
"TextQuoteSelector": "oa:TextQuoteSelector",
321+
"TextPositionSelector": "oa:TextPositionSelector",
322+
"DataPositionSelector": "oa:DataPositionSelector",
323+
"SvgSelector": "oa:SvgSelector",
324+
"RangeSelector": "oa:RangeSelector",
325+
"TimeState": "oa:TimeState",
326+
"HttpRequestState": "oa:HttpRequestState",
327+
"CssStylesheet": "oa:CssStyle",
328+
"Choice": "oa:Choice",
329+
"Person": "foaf:Person",
330+
"Software": "as:Application",
331+
"Organization": "foaf:Organization",
332+
"AnnotationCollection": "as:OrderedCollection",
333+
"AnnotationPage": "as:OrderedCollectionPage",
334+
"Audience": "schema:Audience",
335+
336+
"Motivation": "oa:Motivation",
337+
"bookmarking": "oa:bookmarking",
338+
"classifying": "oa:classifying",
339+
"commenting": "oa:commenting",
340+
"describing": "oa:describing",
341+
"editing": "oa:editing",
342+
"highlighting": "oa:highlighting",
343+
"identifying": "oa:identifying",
344+
"linking": "oa:linking",
345+
"moderating": "oa:moderating",
346+
"questioning": "oa:questioning",
347+
"replying": "oa:replying",
348+
"reviewing": "oa:reviewing",
349+
"tagging": "oa:tagging",
350+
351+
"auto": "oa:autoDirection",
352+
"ltr": "oa:ltrDirection",
353+
"rtl": "oa:rtlDirection",
354+
355+
"body": {"@type": "@id", "@id": "oa:hasBody"},
356+
"target": {"@type": "@id", "@id": "oa:hasTarget"},
357+
"source": {"@type": "@id", "@id": "oa:hasSource"},
358+
"selector": {"@type": "@id", "@id": "oa:hasSelector"},
359+
"state": {"@type": "@id", "@id": "oa:hasState"},
360+
"scope": {"@type": "@id", "@id": "oa:hasScope"},
361+
"refinedBy": {"@type": "@id", "@id": "oa:refinedBy"},
362+
"startSelector": {"@type": "@id", "@id": "oa:hasStartSelector"},
363+
"endSelector": {"@type": "@id", "@id": "oa:hasEndSelector"},
364+
"renderedVia": {"@type": "@id", "@id": "oa:renderedVia"},
365+
"creator": {"@type": "@id", "@id": "dcterms:creator"},
366+
"generator": {"@type": "@id", "@id": "as:generator"},
367+
"rights": {"@type": "@id", "@id": "dcterms:rights"},
368+
"homepage": {"@type": "@id", "@id": "foaf:homepage"},
369+
"via": {"@type": "@id", "@id": "oa:via"},
370+
"canonical": {"@type": "@id", "@id": "oa:canonical"},
371+
"stylesheet": {"@type": "@id", "@id": "oa:styledBy"},
372+
"cached": {"@type": "@id", "@id": "oa:cachedSource"},
373+
"conformsTo": {"@type": "@id", "@id": "dcterms:conformsTo"},
374+
"items": {"@type": "@id", "@id": "as:items", "@container": "@list"},
375+
"partOf": {"@type": "@id", "@id": "as:partOf"},
376+
"first": {"@type": "@id", "@id": "as:first"},
377+
"last": {"@type": "@id", "@id": "as:last"},
378+
"next": {"@type": "@id", "@id": "as:next"},
379+
"prev": {"@type": "@id", "@id": "as:prev"},
380+
"audience": {"@type": "@id", "@id": "schema:audience"},
381+
"motivation": {"@type": "@vocab", "@id": "oa:motivatedBy"},
382+
"purpose": {"@type": "@vocab", "@id": "oa:hasPurpose"},
383+
"textDirection": {"@type": "@vocab", "@id": "oa:textDirection"},
384+
385+
"accessibility": "schema:accessibilityFeature",
386+
"bodyValue": "oa:bodyValue",
387+
"format": "dc:format",
388+
"language": "dc:language",
389+
"processingLanguage": "oa:processingLanguage",
390+
"value": "rdf:value",
391+
"exact": "oa:exact",
392+
"prefix": "oa:prefix",
393+
"suffix": "oa:suffix",
394+
"styleClass": "oa:styleClass",
395+
"name": "foaf:name",
396+
"email": "foaf:mbox",
397+
"email_sha1": "foaf:mbox_sha1sum",
398+
"nickname": "foaf:nick",
399+
"label": "rdfs:label",
400+
401+
"created": {"@id": "dcterms:created", "@type": "xsd:dateTime"},
402+
"modified": {"@id": "dcterms:modified", "@type": "xsd:dateTime"},
403+
"generated": {"@id": "dcterms:issued", "@type": "xsd:dateTime"},
404+
"sourceDate": {"@id": "oa:sourceDate", "@type": "xsd:dateTime"},
405+
"sourceDateStart": {"@id": "oa:sourceDateStart", "@type": "xsd:dateTime"},
406+
"sourceDateEnd": {"@id": "oa:sourceDateEnd", "@type": "xsd:dateTime"},
407+
408+
"start": {"@id": "oa:start", "@type": "xsd:nonNegativeInteger"},
409+
"end": {"@id": "oa:end", "@type": "xsd:nonNegativeInteger"},
410+
"total": {"@id": "as:totalItems", "@type": "xsd:nonNegativeInteger"},
411+
"startIndex": {"@id": "as:startIndex", "@type": "xsd:nonNegativeInteger"}
412+
},
413+
"id": "http://example.org/anno9",
414+
"type": "Annotation",
415+
"body": [
416+
"http://example.org/description1",
417+
{
418+
"type": "TextualBody",
419+
"value": "tag1"
420+
}
421+
],
422+
"target": [
423+
"http://example.org/image1",
424+
"http://example.org/image2",
425+
{
426+
"source": "http://example.org/"
427+
}
428+
]
270429
}
271430
};
272431
return fixtures[name];

test/mocha.opts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
--reporter dot
21
--ui bdd
32
--growl
43
--colors

0 commit comments

Comments
 (0)