forked from rdf-ext/sparql-http-client
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathResultParser.js
More file actions
70 lines (55 loc) · 1.56 KB
/
ResultParser.js
File metadata and controls
70 lines (55 loc) · 1.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
const jsonStream = require('jsonstream2')
const delay = require('promise-the-world/delay')
const rdf = require('@rdfjs/data-model')
const { Duplex, finished } = require('readable-stream')
/**
* A stream which parses SPARQL SELECT bindings
*/
class ResultParser extends Duplex {
constructor ({ factory = rdf } = {}) {
super({
readableObjectMode: true
})
this.factory = factory
this.jsonParser = jsonStream.parse('results.bindings.*')
finished(this.jsonParser, err => {
this.destroy(err)
})
}
_write (chunk, encoding, callback) {
this.jsonParser.write(chunk, encoding, callback)
}
async _read () {
while (true) {
const raw = this.jsonParser.read()
if (!raw || Object.keys(raw).length === 0) {
if (!this.writable) {
return this.push(null)
}
await delay(0)
} else {
const row = Object.entries(raw).reduce((row, [key, value]) => {
row[key] = this.valueToTerm(value)
return row
}, {})
if (!this.push(row)) {
return
}
}
}
}
valueToTerm (value) {
if (value.type === 'uri') {
return this.factory.namedNode(value.value)
}
if (value.type === 'bnode') {
return this.factory.blankNode(value.value)
}
if (value.type === 'literal' || value.type === 'typed-literal') {
const datatype = (value.datatype && this.factory.namedNode(value.datatype))
return this.factory.literal(value.value, datatype || value['xml:lang'])
}
return null
}
}
module.exports = ResultParser