Skip to content

Commit b7adb33

Browse files
author
Thom van Kalkeren
committed
Extract hextuple processor from Libro
1 parent ff958fc commit b7adb33

File tree

5 files changed

+151
-0
lines changed

5 files changed

+151
-0
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"@ontologies/schema": ">=1.0.0",
4444
"@ontologies/shacl": ">=1.0.0",
4545
"@ontologies/xsd": ">=1.0.0",
46+
"can-ndjson-stream": "^1.0.2",
4647
"http-status-codes": ">= 1.x",
4748
"n-quads-parser": "^2.1.0-3"
4849
},

src/transformers/hextuples.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Quad } from "@ontologies/core";
2+
3+
import { LinkedRenderStore } from "../LinkedRenderStore";
4+
import {
5+
ResponseAndFallbacks,
6+
ResponseTransformer,
7+
} from "../types";
8+
import { hextupleTransformer } from "../utilities/hextupleProcessor";
9+
10+
export const hextupleProcessor = {
11+
acceptValue: 1.0,
12+
mediaTypes: ["application/hex+x-ndjson"],
13+
14+
transformer: (store: LinkedRenderStore<any>): ResponseTransformer => (res: ResponseAndFallbacks): Promise<Quad[]> => {
15+
const isExpedited = res.hasOwnProperty("expedite")
16+
? (res as any).expedite
17+
: false;
18+
19+
return hextupleTransformer(res)
20+
.then((delta) => store.queueDelta(delta, isExpedited))
21+
.then(() => []);
22+
},
23+
};

src/transformers/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import { hextupleProcessor } from "./hextuples";
12
import { linkedDeltaProcessor } from "./linked-delta";
23
import { createProcessRDF } from "./rdf-formats-common";
34

45
export const transformers = {
56
createProcessRDF,
7+
hextupleProcessor,
68
linkedDeltaProcessor,
79
};

src/utilities/hextupleProcessor.ts

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import rdf, { BlankNode, Quad, SomeTerm } from "@ontologies/core";
2+
import * as rdfx from "@ontologies/rdf";
3+
// @ts-ignore
4+
import NdjsonStream from "can-ndjson-stream";
5+
6+
import {
7+
ExtensionResponse,
8+
RDFLibFetcherResponse,
9+
ResponseAndFallbacks,
10+
ResponseTransformer,
11+
} from "../types";
12+
13+
enum HexPosition {
14+
Subject = 0,
15+
Predicate,
16+
Value,
17+
Datatype,
18+
Language,
19+
Graph,
20+
}
21+
22+
let hasReadableStreamConstructor = false;
23+
24+
try {
25+
// tslint:disable-next-line:typedef no-empty no-unused-expression
26+
new ReadableStream({ start() {} });
27+
hasReadableStreamConstructor = true;
28+
} catch (e) {
29+
// ignore
30+
}
31+
32+
export const hextupleTransformer: ResponseTransformer = async (res: ResponseAndFallbacks): Promise<Quad[]> => {
33+
const bnMap: { [s: string]: BlankNode } = {};
34+
// Skip the (expensive) proxy object when parsing
35+
const quad = rdf.quad.bind(rdf);
36+
const literal = rdf.literal.bind(rdf);
37+
const namedNode = rdf.namedNode.bind(rdf);
38+
const blankNodeF = rdf.blankNode.bind(rdf);
39+
const defaultGraph = rdf.defaultGraph.bind(rdf);
40+
41+
const blankNode = (v: string): BlankNode => {
42+
if (!bnMap[v]) {
43+
bnMap[v] = blankNodeF();
44+
}
45+
46+
return bnMap[v];
47+
};
48+
49+
const object = (v: string, dt: string, l: string): SomeTerm => {
50+
if (l) {
51+
return literal(v, l);
52+
} else if (dt === rdfx.ns("namedNode").value) {
53+
return namedNode(v);
54+
} else if (dt === rdfx.ns("blankNode").value) {
55+
return blankNode(v);
56+
}
57+
58+
return literal(v, namedNode(dt));
59+
};
60+
61+
const lineToQuad = (h: string[]): Quad => quad(
62+
h[HexPosition.Subject].startsWith("_:") ? blankNode(h[HexPosition.Subject]) : namedNode(h[HexPosition.Subject]),
63+
namedNode(h[HexPosition.Predicate]),
64+
object(h[HexPosition.Value], h[HexPosition.Datatype], h[HexPosition.Language]),
65+
h[HexPosition.Graph] ? namedNode(h[HexPosition.Graph]) : defaultGraph(),
66+
);
67+
68+
const delta: Quad[] = [];
69+
let parse;
70+
71+
if (res instanceof Response && hasReadableStreamConstructor) {
72+
const stream = new NdjsonStream(res.body);
73+
const reader = stream.getReader();
74+
75+
let read: any;
76+
parse = reader
77+
.read()
78+
.then(read = (result: { done: boolean, value: string[] }): undefined => {
79+
if (result.done) {
80+
return;
81+
}
82+
83+
delta.push(lineToQuad(result.value));
84+
85+
return reader.read().then(read);
86+
});
87+
} else {
88+
let body;
89+
90+
if (res instanceof Response) {
91+
body = res.text();
92+
} else if (typeof XMLHttpRequest !== "undefined"
93+
&& res instanceof XMLHttpRequest
94+
|| typeof (res as any).responseText === "string") {
95+
body = Promise.resolve((res as XMLHttpRequest | RDFLibFetcherResponse).responseText);
96+
} else {
97+
body = Promise.resolve((res as ExtensionResponse).body);
98+
}
99+
100+
parse = body
101+
.then((text) => {
102+
for (const line of text.split("\n")) {
103+
if (line.length > 0) {
104+
delta.push(lineToQuad(JSON.parse(line)));
105+
}
106+
}
107+
});
108+
}
109+
110+
await parse;
111+
112+
return delta;
113+
};

yarn.lock

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2219,6 +2219,18 @@ camelcase@^6.2.0:
22192219
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
22202220
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
22212221

2222+
can-namespace@^1.0.0:
2223+
version "1.0.0"
2224+
resolved "https://registry.yarnpkg.com/can-namespace/-/can-namespace-1.0.0.tgz#0b8fafafbb11352b9ead4222ffe3822405b43e99"
2225+
integrity sha1-C4+vr7sRNSuerUIi/+OCJAW0Ppk=
2226+
2227+
can-ndjson-stream@^1.0.2:
2228+
version "1.0.2"
2229+
resolved "https://registry.yarnpkg.com/can-ndjson-stream/-/can-ndjson-stream-1.0.2.tgz#6a8131f9c8c697215163b3fe49a0c02e4439cb47"
2230+
integrity sha512-//tM8wcTV42SyD1JGua7WMVftZEeTwapcHJTTe3vJwuVywXD01CJbdEkgwRYjy2evIByVJV21ZKBdSv5ygIw1w==
2231+
dependencies:
2232+
can-namespace "^1.0.0"
2233+
22222234
caniuse-lite@^1.0.30001173:
22232235
version "1.0.30001180"
22242236
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001180.tgz#67abcd6d1edf48fa5e7d1e84091d1d65ab76e33b"

0 commit comments

Comments
 (0)