@lde/sparql-qlever 0.18.1 → 0.18.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/createQlever.d.ts +3 -1
- package/dist/createQlever.d.ts.map +1 -1
- package/dist/createQlever.js +2 -1
- package/dist/importer.d.ts +9 -0
- package/dist/importer.d.ts.map +1 -1
- package/dist/importer.js +1 -1
- package/dist/preprocess.d.ts +12 -2
- package/dist/preprocess.d.ts.map +1 -1
- package/dist/preprocess.js +35 -10
- package/package.json +3 -2
package/dist/createQlever.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Downloader } from '@lde/distribution-downloader';
|
|
2
|
-
import { Importer, QleverIndexOptions } from './importer.js';
|
|
2
|
+
import { Importer, QleverImporterOptions, QleverIndexOptions } from './importer.js';
|
|
3
3
|
import { QleverServerOptions, Server } from './server.js';
|
|
4
4
|
export type QleverOptions = {
|
|
5
5
|
/** Directory where downloaded data files are stored. */
|
|
@@ -12,6 +12,8 @@ export type QleverOptions = {
|
|
|
12
12
|
cacheIndex?: boolean;
|
|
13
13
|
/** Options for `qlever-index` (index building). */
|
|
14
14
|
indexOptions?: QleverIndexOptions;
|
|
15
|
+
/** See {@link QleverImporterOptions.replaceJsonLdContext}. */
|
|
16
|
+
replaceJsonLdContext?: QleverImporterOptions['replaceJsonLdContext'];
|
|
15
17
|
/** Options for `qlever-server` (query processing). */
|
|
16
18
|
serverOptions?: QleverServerOptions;
|
|
17
19
|
} & ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createQlever.d.ts","sourceRoot":"","sources":["../src/createQlever.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,UAAU,EAEX,MAAM,8BAA8B,CAAC;AACtC,OAAO,
|
|
1
|
+
{"version":3,"file":"createQlever.d.ts","sourceRoot":"","sources":["../src/createQlever.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,UAAU,EAEX,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,QAAQ,EACR,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,MAAM,aAAa,GAAG;IAC1B,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,6FAA6F;IAC7F,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mDAAmD;IACnD,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,8DAA8D;IAC9D,oBAAoB,CAAC,EAAE,qBAAqB,CAAC,sBAAsB,CAAC,CAAC;IACrE,sDAAsD;IACtD,aAAa,CAAC,EAAE,mBAAmB,CAAC;CACrC,GAAG,CACA;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,KAAK,CAAC;CACjB,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;;OAQG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,aAAa,EAAE,MAAM,CAAC;CACvB,GACD;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IACE;;;;;OAKG;IACH,IAAI,EAAE,QAAQ,CAAC;IACf,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC;CACjB,CACJ,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa;;;EAuClD"}
|
package/dist/createQlever.js
CHANGED
|
@@ -2,7 +2,7 @@ import { DockerTaskRunner } from '@lde/task-runner-docker';
|
|
|
2
2
|
import { HttpTaskRunner } from '@lde/task-runner-http';
|
|
3
3
|
import { NativeTaskRunner } from '@lde/task-runner-native';
|
|
4
4
|
import { LastModifiedDownloader, } from '@lde/distribution-downloader';
|
|
5
|
-
import { Importer } from './importer.js';
|
|
5
|
+
import { Importer, } from './importer.js';
|
|
6
6
|
import { Server } from './server.js';
|
|
7
7
|
/**
|
|
8
8
|
* Create a paired QLever {@link Importer} and {@link Server} that share a
|
|
@@ -35,6 +35,7 @@ export function createQlever(options) {
|
|
|
35
35
|
downloader: options.downloader ?? new LastModifiedDownloader(options.dataDir),
|
|
36
36
|
cacheIndex: options.cacheIndex,
|
|
37
37
|
qleverOptions: options.indexOptions,
|
|
38
|
+
replaceJsonLdContext: options.replaceJsonLdContext,
|
|
38
39
|
}),
|
|
39
40
|
server: new Server({
|
|
40
41
|
taskRunner,
|
package/dist/importer.d.ts
CHANGED
|
@@ -16,6 +16,15 @@ export interface QleverImporterOptions extends ImporterOptions {
|
|
|
16
16
|
/** @default 'data' */
|
|
17
17
|
indexName?: string;
|
|
18
18
|
qleverOptions?: QleverIndexOptions;
|
|
19
|
+
/**
|
|
20
|
+
* Replace remote JSON-LD contexts when converting a JSON-LD distribution.
|
|
21
|
+
* Called with the URL of each remote `@context`; return the parsed document
|
|
22
|
+
* to use instead (shaped like what the URL serves, so
|
|
23
|
+
* `{ '@context': { … } }`), or `undefined` to fetch it as usual. A matching
|
|
24
|
+
* function rather than a fixed list, because one context is often served
|
|
25
|
+
* from several URLs.
|
|
26
|
+
*/
|
|
27
|
+
replaceJsonLdContext?: (url: string) => object | undefined;
|
|
19
28
|
}
|
|
20
29
|
export declare class Importer implements ImporterInterface {
|
|
21
30
|
private readonly options;
|
package/dist/importer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../src/importer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,IAAI,iBAAiB,EAC7B,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAyB,YAAY,EAAE,MAAM,cAAc,CAAC;AAOnE,MAAM,WAAW,kBAAkB;IACjC,oBAAoB;IACpB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,yBAAyB;IACzB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB;IACpB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,yJAAyJ;IACzJ,+BAA+B,CAAC,EAAE,OAAO,CAAC;CAC3C;AAED,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAC5D,sBAAsB;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../src/importer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,IAAI,iBAAiB,EAC7B,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAyB,YAAY,EAAE,MAAM,cAAc,CAAC;AAOnE,MAAM,WAAW,kBAAkB;IACjC,oBAAoB;IACpB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,yBAAyB;IACzB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB;IACpB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,yJAAyJ;IACzJ,+BAA+B,CAAC,EAAE,OAAO,CAAC;CAC3C;AAED,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAC5D,sBAAsB;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CAC5D;AAcD,qBAAa,QAAS,YAAW,iBAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;gBAE9B,OAAO,EAAE,qBAAqB;IAa7B,MAAM,CACjB,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,YAAY,GAAG,gBAAgB,GAAG,YAAY,CAAC;YAqC5C,QAAQ;IA8EtB,OAAO,CAAC,gBAAgB;IAQxB;gEAC4D;IAC5D,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,aAAa;IAIrB;;OAEG;YACW,eAAe;IA0B7B,0EAA0E;YAC5D,YAAY;YAYZ,cAAc;YAKd,KAAK;CA8CpB"}
|
package/dist/importer.js
CHANGED
|
@@ -63,7 +63,7 @@ export class Importer {
|
|
|
63
63
|
let format;
|
|
64
64
|
const warnings = [];
|
|
65
65
|
if (needsPreprocessing(distribution)) {
|
|
66
|
-
const result = await preprocess(localFile, distribution);
|
|
66
|
+
const result = await preprocess(localFile, distribution, this.options.replaceJsonLdContext);
|
|
67
67
|
indexFile = result.path;
|
|
68
68
|
format = result.format;
|
|
69
69
|
warnings.push(...result.warnings);
|
package/dist/preprocess.d.ts
CHANGED
|
@@ -5,6 +5,11 @@ export interface PreprocessResult {
|
|
|
5
5
|
format: 'nq';
|
|
6
6
|
warnings: string[];
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Called with the URL of each remote JSON-LD `@context`; returns the document
|
|
10
|
+
* to use instead, or `undefined` to fetch it.
|
|
11
|
+
*/
|
|
12
|
+
type ReplaceJsonLdContext = (url: string) => object | undefined;
|
|
8
13
|
/**
|
|
9
14
|
* Whether a distribution needs Node-side preprocessing before `qlever-index`
|
|
10
15
|
* can read it.
|
|
@@ -28,7 +33,12 @@ export declare function needsPreprocessing(distribution: Distribution): boolean;
|
|
|
28
33
|
* (detected from the file’s magic bytes, not from declared metadata) and zip
|
|
29
34
|
* containers (folds every parseable entry into the output stream in order).
|
|
30
35
|
*
|
|
31
|
-
*
|
|
36
|
+
* `replaceJsonLdContext` answers remote JSON-LD contexts locally; see
|
|
37
|
+
* {@link ReplaceJsonLdContext}.
|
|
38
|
+
*
|
|
39
|
+
* Cached: if the output is newer than the input, it is reused as-is – also
|
|
40
|
+
* when it was converted without the current `replaceJsonLdContext`.
|
|
32
41
|
*/
|
|
33
|
-
export declare function preprocess(localFile: string, distribution: Distribution): Promise<PreprocessResult>;
|
|
42
|
+
export declare function preprocess(localFile: string, distribution: Distribution, replaceJsonLdContext?: ReplaceJsonLdContext): Promise<PreprocessResult>;
|
|
43
|
+
export {};
|
|
34
44
|
//# sourceMappingURL=preprocess.d.ts.map
|
package/dist/preprocess.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preprocess.d.ts","sourceRoot":"","sources":["../src/preprocess.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"preprocess.d.ts","sourceRoot":"","sources":["../src/preprocess.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AA+B5C,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,IAAI,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,KAAK,oBAAoB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;AAEhE;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAKtE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,YAAY,EAC1B,oBAAoB,CAAC,EAAE,oBAAoB,GAC1C,OAAO,CAAC,gBAAgB,CAAC,CAqC3B"}
|
package/dist/preprocess.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { rdfParser } from 'rdf-parse';
|
|
2
|
+
import { FetchDocumentLoader, } from 'jsonld-context-parser';
|
|
2
3
|
import { rdfSerializer } from 'rdf-serialize';
|
|
3
4
|
import { createGunzip } from 'node:zlib';
|
|
4
5
|
import { createReadStream, createWriteStream } from 'node:fs';
|
|
@@ -46,9 +47,13 @@ export function needsPreprocessing(distribution) {
|
|
|
46
47
|
* (detected from the file’s magic bytes, not from declared metadata) and zip
|
|
47
48
|
* containers (folds every parseable entry into the output stream in order).
|
|
48
49
|
*
|
|
49
|
-
*
|
|
50
|
+
* `replaceJsonLdContext` answers remote JSON-LD contexts locally; see
|
|
51
|
+
* {@link ReplaceJsonLdContext}.
|
|
52
|
+
*
|
|
53
|
+
* Cached: if the output is newer than the input, it is reused as-is – also
|
|
54
|
+
* when it was converted without the current `replaceJsonLdContext`.
|
|
50
55
|
*/
|
|
51
|
-
export async function preprocess(localFile, distribution) {
|
|
56
|
+
export async function preprocess(localFile, distribution, replaceJsonLdContext) {
|
|
52
57
|
const contentType = distribution.mimeType;
|
|
53
58
|
const label = contentType === undefined ? undefined : preprocessFormats.get(contentType);
|
|
54
59
|
if (contentType === undefined || label === undefined) {
|
|
@@ -61,10 +66,10 @@ export async function preprocess(localFile, distribution) {
|
|
|
61
66
|
await rm(outputFile, { force: true });
|
|
62
67
|
const warnings = [];
|
|
63
68
|
if (distribution.compressMimeType === ZIP_MIME) {
|
|
64
|
-
await streamRdfZip(localFile, outputFile, contentType, label, warnings);
|
|
69
|
+
await streamRdfZip(localFile, outputFile, contentType, label, warnings, replaceJsonLdContext);
|
|
65
70
|
}
|
|
66
71
|
else {
|
|
67
|
-
await streamRdfFile(localFile, outputFile, contentType);
|
|
72
|
+
await streamRdfFile(localFile, outputFile, contentType, replaceJsonLdContext);
|
|
68
73
|
}
|
|
69
74
|
return { path: outputFile, format: 'nq', warnings };
|
|
70
75
|
}
|
|
@@ -85,14 +90,34 @@ async function outputIsUpToDate(inputFile, outputFile) {
|
|
|
85
90
|
* open writable, without closing it. Back-pressure is handled by Node's
|
|
86
91
|
* built-in `.pipe()`; the caller manages `output`'s lifecycle.
|
|
87
92
|
*/
|
|
88
|
-
async function pipeRdfToWritable(input, output, contentType) {
|
|
89
|
-
const quads = rdfParser.parse(input, {
|
|
93
|
+
async function pipeRdfToWritable(input, output, contentType, replaceJsonLdContext) {
|
|
94
|
+
const quads = rdfParser.parse(input, {
|
|
95
|
+
contentType,
|
|
96
|
+
...jsonLdParseContext(replaceJsonLdContext),
|
|
97
|
+
});
|
|
90
98
|
const bytes = rdfSerializer.serialize(quads, {
|
|
91
99
|
contentType: 'application/n-quads',
|
|
92
100
|
});
|
|
93
101
|
bytes.pipe(output, { end: false });
|
|
94
102
|
await finished(bytes);
|
|
95
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* `rdf-parse` context that answers replaced JSON-LD contexts locally and
|
|
106
|
+
* fetches the rest. rdf-parse only routes context requests through a document
|
|
107
|
+
* loader set under this Comunica context key. Empty without a replacement, so
|
|
108
|
+
* the parser keeps its own loader.
|
|
109
|
+
*/
|
|
110
|
+
function jsonLdParseContext(replaceJsonLdContext) {
|
|
111
|
+
if (replaceJsonLdContext === undefined)
|
|
112
|
+
return {};
|
|
113
|
+
const fetchLoader = new FetchDocumentLoader(fetch);
|
|
114
|
+
return {
|
|
115
|
+
'@comunica/actor-rdf-parse-jsonld:documentLoader': {
|
|
116
|
+
load: async (url) => replaceJsonLdContext(url) ??
|
|
117
|
+
fetchLoader.load(url),
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
96
121
|
async function closeWritable(output) {
|
|
97
122
|
await new Promise((resolve, reject) => {
|
|
98
123
|
output.once('close', resolve);
|
|
@@ -100,14 +125,14 @@ async function closeWritable(output) {
|
|
|
100
125
|
output.end();
|
|
101
126
|
});
|
|
102
127
|
}
|
|
103
|
-
async function streamRdfFile(localFile, outputFile, contentType) {
|
|
128
|
+
async function streamRdfFile(localFile, outputFile, contentType, replaceJsonLdContext) {
|
|
104
129
|
const source = createReadStream(localFile);
|
|
105
130
|
const input = (await isGzipFile(localFile))
|
|
106
131
|
? source.pipe(createGunzip())
|
|
107
132
|
: source;
|
|
108
133
|
const output = createWriteStream(outputFile);
|
|
109
134
|
try {
|
|
110
|
-
await pipeRdfToWritable(input, output, contentType);
|
|
135
|
+
await pipeRdfToWritable(input, output, contentType, replaceJsonLdContext);
|
|
111
136
|
}
|
|
112
137
|
finally {
|
|
113
138
|
await closeWritable(output);
|
|
@@ -138,7 +163,7 @@ const openZip = promisify(yauzl.open);
|
|
|
138
163
|
* declared `contentType` drives the parser; an entry that fails to parse (a
|
|
139
164
|
* sidecar, OS metadata) is skipped with a warning. Throws if nothing parses.
|
|
140
165
|
*/
|
|
141
|
-
async function streamRdfZip(zipFile, outputFile, contentType, label, warnings) {
|
|
166
|
+
async function streamRdfZip(zipFile, outputFile, contentType, label, warnings, replaceJsonLdContext) {
|
|
142
167
|
const zip = await openZip(zipFile, { lazyEntries: true });
|
|
143
168
|
const output = createWriteStream(outputFile);
|
|
144
169
|
let entriesProcessed = 0;
|
|
@@ -155,7 +180,7 @@ async function streamRdfZip(zipFile, outputFile, contentType, label, warnings) {
|
|
|
155
180
|
try {
|
|
156
181
|
const stream = await openZipEntry(zip, entry);
|
|
157
182
|
try {
|
|
158
|
-
await pipeRdfToWritable(stream, output, contentType);
|
|
183
|
+
await pipeRdfToWritable(stream, output, contentType, replaceJsonLdContext);
|
|
159
184
|
entriesProcessed++;
|
|
160
185
|
}
|
|
161
186
|
finally {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lde/sparql-qlever",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.3",
|
|
4
4
|
"repository": {
|
|
5
5
|
"url": "git+https://github.com/ldelements/lde.git",
|
|
6
6
|
"directory": "packages/sparql-qlever"
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
"@lde/task-runner-docker": "^0.4.0",
|
|
33
33
|
"@lde/task-runner-http": "^0.1.0",
|
|
34
34
|
"@lde/task-runner-native": "^0.3.0",
|
|
35
|
-
"@lde/wait-for-sparql": "^0.3.
|
|
35
|
+
"@lde/wait-for-sparql": "^0.3.1",
|
|
36
|
+
"jsonld-context-parser": "^3.1.0",
|
|
36
37
|
"rdf-parse": "^5.0.0",
|
|
37
38
|
"rdf-serialize": "^5.1.0",
|
|
38
39
|
"tslib": "^2.3.0",
|