ldkit 2.1.1 → 2.3.0

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.
@@ -1,6 +1,6 @@
1
- import { fromRdf } from "./rdf.js";
2
1
  import { ldkit } from "../namespaces/ldkit.js";
3
2
  import { rdf } from "../namespaces/rdf.js";
3
+ import { translateFromRdf } from "./translator.js";
4
4
  export const decode = (graph, schema, options) => {
5
5
  return Decoder.decode(graph, schema, options);
6
6
  };
@@ -185,7 +185,7 @@ class Decoder {
185
185
  return term.value;
186
186
  }
187
187
  else if (term.termType === "Literal") {
188
- return fromRdf(term);
188
+ return translateFromRdf(term);
189
189
  }
190
190
  else {
191
191
  throw new Error(`Unsupported term type to resolve: ${term.termType}`);
@@ -1,7 +1,8 @@
1
- import { DataFactory, toRdf } from "./rdf.js";
1
+ import { DataFactory } from "./rdf.js";
2
2
  import { xsd } from "../namespaces/xsd.js";
3
3
  import { rdf } from "../namespaces/rdf.js";
4
4
  import { ldkit } from "../namespaces/ldkit.js";
5
+ import { translateToRdf } from "./translator.js";
5
6
  export const encode = (node, schema, options, includeType = true, variableInitCounter = 0) => {
6
7
  return Encoder.encode(node, schema, options, includeType, variableInitCounter);
7
8
  };
@@ -9,9 +10,7 @@ export const encodeValue = (value, datatype, df) => {
9
10
  if (datatype === ldkit.IRI) {
10
11
  return df.namedNode(value);
11
12
  }
12
- return toRdf(value, {
13
- datatype: df.namedNode(datatype),
14
- });
13
+ return translateToRdf(value, datatype);
15
14
  };
16
15
  class Encoder {
17
16
  constructor(options, includeType, variableInitCounter) {
@@ -41,21 +41,21 @@ export class QueryEngine {
41
41
  getFetch(context) {
42
42
  return context && context.fetch ? context.fetch : fetch;
43
43
  }
44
- query(body, responseType, context) {
44
+ query(body, requestType, responseType, context) {
45
45
  const endpoint = this.getSparqlEndpoint(context);
46
46
  const fetchFn = this.getFetch(context);
47
47
  return fetchFn(endpoint, {
48
48
  method: "POST",
49
49
  headers: {
50
50
  "accept": responseType,
51
- "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
51
+ "content-type": `${requestType}; charset=UTF-8`,
52
52
  },
53
- body: new URLSearchParams(body),
53
+ body,
54
54
  });
55
55
  }
56
56
  async queryAndResolve(type, query, context) {
57
57
  const responseType = getResponseTypes(type).join(", ");
58
- const response = await this.query({ query }, responseType, context);
58
+ const response = await this.query(query, "application/sparql-query", responseType, context);
59
59
  if (!response.ok) {
60
60
  await response.body?.cancel();
61
61
  throw new Error(`Invalid query response status '${response.status} ${response.statusText}'`);
@@ -100,6 +100,6 @@ export class QueryEngine {
100
100
  * @returns Nothing
101
101
  */
102
102
  async queryVoid(query, context) {
103
- await this.query({ update: query }, "application/sparql-results+json", context);
103
+ await this.query(query, "application/sparql-update", "application/sparql-results+json", context);
104
104
  }
105
105
  }
@@ -1,4 +1,4 @@
1
- import { N3, quadsToGraph } from "../rdf.js";
1
+ import { quadsToGraph } from "../rdf.js";
2
2
  export class QueryEngineProxy {
3
3
  constructor(engine, context) {
4
4
  Object.defineProperty(this, "engine", {
@@ -25,9 +25,7 @@ export class QueryEngineProxy {
25
25
  }
26
26
  async queryGraph(query) {
27
27
  const quadStream = await this.engine.queryQuads(query, this.context);
28
- const quads = await (quadStream.toArray());
29
- const store = new N3.Store(quads);
30
- return quadsToGraph(store);
28
+ return quadsToGraph(quadStream);
31
29
  }
32
30
  queryVoid(query) {
33
31
  return this.engine.queryVoid(query, this.context);
@@ -1,3 +1,4 @@
1
+ import { readableFromWeb } from "../utils.js";
1
2
  import { BindingsFactory, N3, QuadFactory } from "../rdf.js";
2
3
  import { ArrayIterator, MappingIterator, TreeIterator, } from "../asynciterator.js";
3
4
  class QueryResolver {
@@ -19,7 +20,6 @@ class BindingsJsonResolver extends QueryResolver {
19
20
  }
20
21
  const bindingsFactory = new BindingsFactory();
21
22
  const bindingsIterator = new ArrayIterator(json.results.bindings);
22
- // TODO: review the unknown type cast
23
23
  return new MappingIterator(bindingsIterator, (i) => bindingsFactory.fromJson(i));
24
24
  }
25
25
  }
@@ -31,15 +31,35 @@ class QuadsJsonResolver extends QueryResolver {
31
31
  }
32
32
  const quadFactory = new QuadFactory();
33
33
  const treeIterator = new TreeIterator(json);
34
- // TODO: review the unknown type cast
35
34
  return new MappingIterator(treeIterator, (i) => quadFactory.fromJson(i));
36
35
  }
37
36
  }
37
+ const createN3Stream = async (response, format) => {
38
+ if (response.body === null) {
39
+ throw new Error("Response body is null, but it should contain quads from the SPARQL query");
40
+ }
41
+ const stream = readableFromWeb(response.body);
42
+ const parser = new N3.StreamParser({ format });
43
+ return await parser.import(stream);
44
+ };
45
+ class QuadsNTriplesResolver extends QueryResolver {
46
+ resolve(response) {
47
+ return createN3Stream(response, "N-Triples");
48
+ }
49
+ }
50
+ class QuadsNQuadsResolver extends QueryResolver {
51
+ resolve(response) {
52
+ return createN3Stream(response, "N-Quads");
53
+ }
54
+ }
38
55
  class QuadsTurtleResolver extends QueryResolver {
39
- async resolve(response) {
40
- const text = await response.text();
41
- const quads = new N3.Parser({ format: "turtle" }).parse(text);
42
- return new ArrayIterator(quads);
56
+ resolve(response) {
57
+ return createN3Stream(response, "Turtle");
58
+ }
59
+ }
60
+ class QuadsTrigResolver extends QueryResolver {
61
+ resolve(response) {
62
+ return createN3Stream(response, "TriG");
43
63
  }
44
64
  }
45
65
  const resolvers = {
@@ -51,7 +71,10 @@ const resolvers = {
51
71
  },
52
72
  "quads": {
53
73
  "application/rdf+json": new QuadsJsonResolver(),
74
+ "application/n-triples": new QuadsNTriplesResolver(),
75
+ "application/n-quads": new QuadsNQuadsResolver(),
54
76
  "text/turtle": new QuadsTurtleResolver(),
77
+ "application/trig": new QuadsTrigResolver(),
55
78
  },
56
79
  };
57
80
  export const getResponseTypes = (resolverType) => Object.keys(resolvers[resolverType]);
@@ -1,17 +1,27 @@
1
1
  export { fromRdf, toRdf } from "rdf-literal";
2
+ import { quadToStringQuad } from "rdf-string";
2
3
  import { DataFactory, DefaultGraph } from "rdf-data-factory";
3
4
  export { DataFactory, DefaultGraph };
4
5
  export * as N3 from "n3";
5
- export const quadsToGraph = (quads) => {
6
- const graph = new Map();
7
- for (const quad of quads) {
8
- const s = quad.subject.value;
9
- const p = quad.predicate.value;
10
- const predicateMap = graph.get(s) || graph.set(s, new Map()).get(s);
11
- const termArray = predicateMap.get(p) || predicateMap.set(p, []).get(p);
12
- termArray.push(quad.object);
13
- }
14
- return graph;
6
+ export const quadsToGraph = (quadStream) => {
7
+ return new Promise((resolve, reject) => {
8
+ const graph = new Map();
9
+ const included = {};
10
+ quadStream.on("data", (quad) => {
11
+ const hash = Object.values(quadToStringQuad(quad)).join(" ");
12
+ if (included[hash]) {
13
+ return;
14
+ }
15
+ included[hash] = true;
16
+ const s = quad.subject.value;
17
+ const p = quad.predicate.value;
18
+ const predicateMap = graph.get(s) || graph.set(s, new Map()).get(s);
19
+ const termArray = predicateMap.get(p) || predicateMap.set(p, []).get(p);
20
+ termArray.push(quad.object);
21
+ });
22
+ quadStream.on("end", () => resolve(graph));
23
+ quadStream.on("error", reject);
24
+ });
15
25
  };
16
26
  export class TermFactory {
17
27
  constructor(dataFactory = new DataFactory()) {
@@ -0,0 +1,62 @@
1
+ import { DataFactory, fromRdf, toRdf } from "./rdf.js";
2
+ const df = new DataFactory();
3
+ const rdfToNativeHandlers = new Map();
4
+ const nativeToRdfHandlers = new Map();
5
+ /**
6
+ * Registers a data type handler for translating between RDF literals and JavaScript values.
7
+ *
8
+ * In order to register a custom data type handler, the custom data type TypeScript mapping needs
9
+ * to be added to the {@link CustomDataTypes} interface using module augmentation.
10
+ *
11
+ * Two handlers are required:
12
+ * 1) A function to translate from RDF literal value (string) to JavaScript value.
13
+ * 2) A function to translate from JavaScript value to RDF literal value (string).
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * import { registerDataHandler } from "ldkit";
18
+ *
19
+ * const customNumberDataType = "http://example.org/number";
20
+ *
21
+ * declare module "ldkit" {
22
+ * interface CustomDataTypes {
23
+ * [customNumberDataType]: number;
24
+ * }
25
+ * }
26
+ *
27
+ * registerDataHandler(
28
+ * customNumberDataType,
29
+ * (literalValue: string) => parseInt(literalValue),
30
+ * (nativeValue: number) => nativeValue.toString(),
31
+ * );
32
+ * ```
33
+ *
34
+ * @param dataType - The data type to register.
35
+ * @param translateFromRDF - Function to translate from RDF literal to JavaScript value.
36
+ * @param translateToRDF - Function to translate from JavaScript value to RDF literal.
37
+ */
38
+ export function registerDataHandler(dataType, translateFromRDF, translateToRDF) {
39
+ rdfToNativeHandlers.set(dataType, translateFromRDF);
40
+ nativeToRdfHandlers.set(dataType, translateToRDF);
41
+ }
42
+ export function translateFromRdf(literal) {
43
+ const dataType = literal.datatype.value;
44
+ const customHandler = rdfToNativeHandlers.get(dataType);
45
+ if (customHandler) {
46
+ return customHandler(literal.value);
47
+ }
48
+ else {
49
+ return fromRdf(literal);
50
+ }
51
+ }
52
+ export function translateToRdf(value, dataType) {
53
+ const customHandler = nativeToRdfHandlers.get(dataType);
54
+ if (customHandler) {
55
+ return df.literal(customHandler(value), df.namedNode(dataType));
56
+ }
57
+ else {
58
+ return toRdf(value, {
59
+ datatype: df.namedNode(dataType),
60
+ });
61
+ }
62
+ }
@@ -0,0 +1 @@
1
+ export { readableFromWeb } from "readable-from-web";
package/esm/mod.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { setGlobalOptions } from "./library/options.js";
2
+ export { registerDataHandler } from "./library/translator.js";
2
3
  export * from "./library/lens/mod.js";
3
4
  export * from "./library/namespace.js";
4
5
  export * from "./library/engine/mod.js";
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "main": "./script/mod.js",
4
4
  "types": "./types/mod.d.ts",
5
5
  "name": "ldkit",
6
- "version": "2.1.1",
6
+ "version": "2.3.0",
7
7
  "description": "LDkit, a Linked Data query toolkit for TypeScript developers",
8
8
  "homepage": "https://ldkit.io",
9
9
  "author": "Karel Klima <karelklima@gmail.com> (https://karelklima.com)",
@@ -70,6 +70,8 @@
70
70
  "asynciterator": "^3.9.0",
71
71
  "n3": "^1.23.1",
72
72
  "rdf-data-factory": "^2.0.2",
73
- "rdf-literal": "^2.0.0"
73
+ "rdf-literal": "^2.0.0",
74
+ "rdf-string": "^2.0.0",
75
+ "readable-from-web": "^0.0.4"
74
76
  }
75
77
  }
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.decode = void 0;
4
- const rdf_js_1 = require("./rdf.js");
5
4
  const ldkit_js_1 = require("../namespaces/ldkit.js");
6
- const rdf_js_2 = require("../namespaces/rdf.js");
5
+ const rdf_js_1 = require("../namespaces/rdf.js");
6
+ const translator_js_1 = require("./translator.js");
7
7
  const decode = (graph, schema, options) => {
8
8
  return Decoder.decode(graph, schema, options);
9
9
  };
@@ -56,8 +56,8 @@ class Decoder {
56
56
  decode() {
57
57
  const output = [];
58
58
  for (const [iri, properties] of this.graph) {
59
- if (properties.has(rdf_js_2.rdf.type)) {
60
- const types = properties.get(rdf_js_2.rdf.type);
59
+ if (properties.has(rdf_js_1.rdf.type)) {
60
+ const types = properties.get(rdf_js_1.rdf.type);
61
61
  for (const type of types) {
62
62
  if (type.termType === "NamedNode" && type.value === ldkit_js_1.ldkit.Resource) {
63
63
  output.push(this.decodeNode(iri, this.schema));
@@ -96,7 +96,7 @@ class Decoder {
96
96
  }
97
97
  decodeNodeProperty(nodeIri, node, propertyKey, property) {
98
98
  const allTerms = node.get(property["@id"]);
99
- const terms = property["@id"] !== rdf_js_2.rdf.type
99
+ const terms = property["@id"] !== rdf_js_1.rdf.type
100
100
  ? allTerms
101
101
  : allTerms?.filter((term) => term.value !== ldkit_js_1.ldkit.Resource);
102
102
  if (!terms) {
@@ -189,7 +189,7 @@ class Decoder {
189
189
  return term.value;
190
190
  }
191
191
  else if (term.termType === "Literal") {
192
- return (0, rdf_js_1.fromRdf)(term);
192
+ return (0, translator_js_1.translateFromRdf)(term);
193
193
  }
194
194
  else {
195
195
  throw new Error(`Unsupported term type to resolve: ${term.termType}`);
@@ -5,6 +5,7 @@ const rdf_js_1 = require("./rdf.js");
5
5
  const xsd_js_1 = require("../namespaces/xsd.js");
6
6
  const rdf_js_2 = require("../namespaces/rdf.js");
7
7
  const ldkit_js_1 = require("../namespaces/ldkit.js");
8
+ const translator_js_1 = require("./translator.js");
8
9
  const encode = (node, schema, options, includeType = true, variableInitCounter = 0) => {
9
10
  return Encoder.encode(node, schema, options, includeType, variableInitCounter);
10
11
  };
@@ -13,9 +14,7 @@ const encodeValue = (value, datatype, df) => {
13
14
  if (datatype === ldkit_js_1.ldkit.IRI) {
14
15
  return df.namedNode(value);
15
16
  }
16
- return (0, rdf_js_1.toRdf)(value, {
17
- datatype: df.namedNode(datatype),
18
- });
17
+ return (0, translator_js_1.translateToRdf)(value, datatype);
19
18
  };
20
19
  exports.encodeValue = encodeValue;
21
20
  class Encoder {
@@ -44,21 +44,21 @@ class QueryEngine {
44
44
  getFetch(context) {
45
45
  return context && context.fetch ? context.fetch : fetch;
46
46
  }
47
- query(body, responseType, context) {
47
+ query(body, requestType, responseType, context) {
48
48
  const endpoint = this.getSparqlEndpoint(context);
49
49
  const fetchFn = this.getFetch(context);
50
50
  return fetchFn(endpoint, {
51
51
  method: "POST",
52
52
  headers: {
53
53
  "accept": responseType,
54
- "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
54
+ "content-type": `${requestType}; charset=UTF-8`,
55
55
  },
56
- body: new URLSearchParams(body),
56
+ body,
57
57
  });
58
58
  }
59
59
  async queryAndResolve(type, query, context) {
60
60
  const responseType = (0, query_resolvers_js_1.getResponseTypes)(type).join(", ");
61
- const response = await this.query({ query }, responseType, context);
61
+ const response = await this.query(query, "application/sparql-query", responseType, context);
62
62
  if (!response.ok) {
63
63
  await response.body?.cancel();
64
64
  throw new Error(`Invalid query response status '${response.status} ${response.statusText}'`);
@@ -103,7 +103,7 @@ class QueryEngine {
103
103
  * @returns Nothing
104
104
  */
105
105
  async queryVoid(query, context) {
106
- await this.query({ update: query }, "application/sparql-results+json", context);
106
+ await this.query(query, "application/sparql-update", "application/sparql-results+json", context);
107
107
  }
108
108
  }
109
109
  exports.QueryEngine = QueryEngine;
@@ -28,9 +28,7 @@ class QueryEngineProxy {
28
28
  }
29
29
  async queryGraph(query) {
30
30
  const quadStream = await this.engine.queryQuads(query, this.context);
31
- const quads = await (quadStream.toArray());
32
- const store = new rdf_js_1.N3.Store(quads);
33
- return (0, rdf_js_1.quadsToGraph)(store);
31
+ return (0, rdf_js_1.quadsToGraph)(quadStream);
34
32
  }
35
33
  queryVoid(query) {
36
34
  return this.engine.queryVoid(query, this.context);
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resolve = exports.getResponseTypes = void 0;
4
+ const utils_js_1 = require("../utils.js");
4
5
  const rdf_js_1 = require("../rdf.js");
5
6
  const asynciterator_js_1 = require("../asynciterator.js");
6
7
  class QueryResolver {
@@ -22,7 +23,6 @@ class BindingsJsonResolver extends QueryResolver {
22
23
  }
23
24
  const bindingsFactory = new rdf_js_1.BindingsFactory();
24
25
  const bindingsIterator = new asynciterator_js_1.ArrayIterator(json.results.bindings);
25
- // TODO: review the unknown type cast
26
26
  return new asynciterator_js_1.MappingIterator(bindingsIterator, (i) => bindingsFactory.fromJson(i));
27
27
  }
28
28
  }
@@ -34,15 +34,35 @@ class QuadsJsonResolver extends QueryResolver {
34
34
  }
35
35
  const quadFactory = new rdf_js_1.QuadFactory();
36
36
  const treeIterator = new asynciterator_js_1.TreeIterator(json);
37
- // TODO: review the unknown type cast
38
37
  return new asynciterator_js_1.MappingIterator(treeIterator, (i) => quadFactory.fromJson(i));
39
38
  }
40
39
  }
40
+ const createN3Stream = async (response, format) => {
41
+ if (response.body === null) {
42
+ throw new Error("Response body is null, but it should contain quads from the SPARQL query");
43
+ }
44
+ const stream = (0, utils_js_1.readableFromWeb)(response.body);
45
+ const parser = new rdf_js_1.N3.StreamParser({ format });
46
+ return await parser.import(stream);
47
+ };
48
+ class QuadsNTriplesResolver extends QueryResolver {
49
+ resolve(response) {
50
+ return createN3Stream(response, "N-Triples");
51
+ }
52
+ }
53
+ class QuadsNQuadsResolver extends QueryResolver {
54
+ resolve(response) {
55
+ return createN3Stream(response, "N-Quads");
56
+ }
57
+ }
41
58
  class QuadsTurtleResolver extends QueryResolver {
42
- async resolve(response) {
43
- const text = await response.text();
44
- const quads = new rdf_js_1.N3.Parser({ format: "turtle" }).parse(text);
45
- return new asynciterator_js_1.ArrayIterator(quads);
59
+ resolve(response) {
60
+ return createN3Stream(response, "Turtle");
61
+ }
62
+ }
63
+ class QuadsTrigResolver extends QueryResolver {
64
+ resolve(response) {
65
+ return createN3Stream(response, "TriG");
46
66
  }
47
67
  }
48
68
  const resolvers = {
@@ -54,7 +74,10 @@ const resolvers = {
54
74
  },
55
75
  "quads": {
56
76
  "application/rdf+json": new QuadsJsonResolver(),
77
+ "application/n-triples": new QuadsNTriplesResolver(),
78
+ "application/n-quads": new QuadsNQuadsResolver(),
57
79
  "text/turtle": new QuadsTurtleResolver(),
80
+ "application/trig": new QuadsTrigResolver(),
58
81
  },
59
82
  };
60
83
  const getResponseTypes = (resolverType) => Object.keys(resolvers[resolverType]);
@@ -27,20 +27,30 @@ exports.QuadFactory = exports.BindingsFactory = exports.ReadOnlyBindings = expor
27
27
  var rdf_literal_1 = require("rdf-literal");
28
28
  Object.defineProperty(exports, "fromRdf", { enumerable: true, get: function () { return rdf_literal_1.fromRdf; } });
29
29
  Object.defineProperty(exports, "toRdf", { enumerable: true, get: function () { return rdf_literal_1.toRdf; } });
30
+ const rdf_string_1 = require("rdf-string");
30
31
  const rdf_data_factory_1 = require("rdf-data-factory");
31
32
  Object.defineProperty(exports, "DataFactory", { enumerable: true, get: function () { return rdf_data_factory_1.DataFactory; } });
32
33
  Object.defineProperty(exports, "DefaultGraph", { enumerable: true, get: function () { return rdf_data_factory_1.DefaultGraph; } });
33
34
  exports.N3 = __importStar(require("n3"));
34
- const quadsToGraph = (quads) => {
35
- const graph = new Map();
36
- for (const quad of quads) {
37
- const s = quad.subject.value;
38
- const p = quad.predicate.value;
39
- const predicateMap = graph.get(s) || graph.set(s, new Map()).get(s);
40
- const termArray = predicateMap.get(p) || predicateMap.set(p, []).get(p);
41
- termArray.push(quad.object);
42
- }
43
- return graph;
35
+ const quadsToGraph = (quadStream) => {
36
+ return new Promise((resolve, reject) => {
37
+ const graph = new Map();
38
+ const included = {};
39
+ quadStream.on("data", (quad) => {
40
+ const hash = Object.values((0, rdf_string_1.quadToStringQuad)(quad)).join(" ");
41
+ if (included[hash]) {
42
+ return;
43
+ }
44
+ included[hash] = true;
45
+ const s = quad.subject.value;
46
+ const p = quad.predicate.value;
47
+ const predicateMap = graph.get(s) || graph.set(s, new Map()).get(s);
48
+ const termArray = predicateMap.get(p) || predicateMap.set(p, []).get(p);
49
+ termArray.push(quad.object);
50
+ });
51
+ quadStream.on("end", () => resolve(graph));
52
+ quadStream.on("error", reject);
53
+ });
44
54
  };
45
55
  exports.quadsToGraph = quadsToGraph;
46
56
  class TermFactory {
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.translateToRdf = exports.translateFromRdf = exports.registerDataHandler = void 0;
4
+ const rdf_js_1 = require("./rdf.js");
5
+ const df = new rdf_js_1.DataFactory();
6
+ const rdfToNativeHandlers = new Map();
7
+ const nativeToRdfHandlers = new Map();
8
+ /**
9
+ * Registers a data type handler for translating between RDF literals and JavaScript values.
10
+ *
11
+ * In order to register a custom data type handler, the custom data type TypeScript mapping needs
12
+ * to be added to the {@link CustomDataTypes} interface using module augmentation.
13
+ *
14
+ * Two handlers are required:
15
+ * 1) A function to translate from RDF literal value (string) to JavaScript value.
16
+ * 2) A function to translate from JavaScript value to RDF literal value (string).
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * import { registerDataHandler } from "ldkit";
21
+ *
22
+ * const customNumberDataType = "http://example.org/number";
23
+ *
24
+ * declare module "ldkit" {
25
+ * interface CustomDataTypes {
26
+ * [customNumberDataType]: number;
27
+ * }
28
+ * }
29
+ *
30
+ * registerDataHandler(
31
+ * customNumberDataType,
32
+ * (literalValue: string) => parseInt(literalValue),
33
+ * (nativeValue: number) => nativeValue.toString(),
34
+ * );
35
+ * ```
36
+ *
37
+ * @param dataType - The data type to register.
38
+ * @param translateFromRDF - Function to translate from RDF literal to JavaScript value.
39
+ * @param translateToRDF - Function to translate from JavaScript value to RDF literal.
40
+ */
41
+ function registerDataHandler(dataType, translateFromRDF, translateToRDF) {
42
+ rdfToNativeHandlers.set(dataType, translateFromRDF);
43
+ nativeToRdfHandlers.set(dataType, translateToRDF);
44
+ }
45
+ exports.registerDataHandler = registerDataHandler;
46
+ function translateFromRdf(literal) {
47
+ const dataType = literal.datatype.value;
48
+ const customHandler = rdfToNativeHandlers.get(dataType);
49
+ if (customHandler) {
50
+ return customHandler(literal.value);
51
+ }
52
+ else {
53
+ return (0, rdf_js_1.fromRdf)(literal);
54
+ }
55
+ }
56
+ exports.translateFromRdf = translateFromRdf;
57
+ function translateToRdf(value, dataType) {
58
+ const customHandler = nativeToRdfHandlers.get(dataType);
59
+ if (customHandler) {
60
+ return df.literal(customHandler(value), df.namedNode(dataType));
61
+ }
62
+ else {
63
+ return (0, rdf_js_1.toRdf)(value, {
64
+ datatype: df.namedNode(dataType),
65
+ });
66
+ }
67
+ }
68
+ exports.translateToRdf = translateToRdf;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readableFromWeb = void 0;
4
+ var readable_from_web_1 = require("readable-from-web");
5
+ Object.defineProperty(exports, "readableFromWeb", { enumerable: true, get: function () { return readable_from_web_1.readableFromWeb; } });
package/script/mod.js CHANGED
@@ -14,9 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.setGlobalOptions = void 0;
17
+ exports.registerDataHandler = exports.setGlobalOptions = void 0;
18
18
  var options_js_1 = require("./library/options.js");
19
19
  Object.defineProperty(exports, "setGlobalOptions", { enumerable: true, get: function () { return options_js_1.setGlobalOptions; } });
20
+ var translator_js_1 = require("./library/translator.js");
21
+ Object.defineProperty(exports, "registerDataHandler", { enumerable: true, get: function () { return translator_js_1.registerDataHandler; } });
20
22
  __exportStar(require("./library/lens/mod.js"), exports);
21
23
  __exportStar(require("./library/namespace.js"), exports);
22
24
  __exportStar(require("./library/engine/mod.js"), exports);
@@ -3,5 +3,5 @@ import { DataFactory, type RDF } from "./rdf.js";
3
3
  import type { ExpandedSchema } from "./schema/mod.js";
4
4
  type DecodedNode = Record<string, unknown>;
5
5
  export declare const encode: (node: DecodedNode, schema: ExpandedSchema, options: Options, includeType?: boolean, variableInitCounter?: number) => RDF.Quad[];
6
- export declare const encodeValue: (value: unknown, datatype: string, df: DataFactory) => RDF.Literal | import("rdf-data-factory").NamedNode<string>;
6
+ export declare const encodeValue: (value: unknown, datatype: string, df: DataFactory) => RDF.Literal | import("rdf-data-factory").Literal | import("rdf-data-factory").NamedNode<string>;
7
7
  export {};
@@ -16,11 +16,7 @@ import { type ResolverType } from "./query_resolvers.js";
16
16
  export declare class QueryEngine implements IQueryEngine {
17
17
  protected getSparqlEndpoint(context?: QueryContext): string;
18
18
  protected getFetch(context?: QueryContext): typeof fetch;
19
- protected query(body: {
20
- query: string;
21
- } | {
22
- update: string;
23
- }, responseType: string, context?: QueryContext): Promise<Response>;
19
+ protected query(body: string, requestType: "application/sparql-query" | "application/sparql-update", responseType: string, context?: QueryContext): Promise<Response>;
24
20
  protected queryAndResolve<T extends ResolverType>(type: T, query: string, context?: QueryContext): Promise<{
25
21
  boolean: boolean;
26
22
  bindings: RDF.ResultStream<RDF.Bindings>;
@@ -66,5 +66,6 @@ export declare function resolveOptions(options?: Options): {
66
66
  extensionFunctions?: Record<string, (args: import("@rdfjs/types").Term[]) => Promise<import("@rdfjs/types").Term>> | undefined;
67
67
  explain?: import("@comunica/types").QueryExplainMode | undefined;
68
68
  recoverBrokenLinks?: boolean | undefined;
69
+ distinctConstruct?: boolean | undefined;
69
70
  };
70
71
  export declare function resolveQueryContext(options: Options): QueryContext;
@@ -7,7 +7,7 @@ export * as N3 from "n3";
7
7
  export type IRI = string;
8
8
  export type Node = Map<IRI, RDF.Term[]>;
9
9
  export type Graph = Map<IRI, Node>;
10
- export declare const quadsToGraph: (quads: Iterable<RDF.Quad>) => Graph;
10
+ export declare const quadsToGraph: (quadStream: RDF.ResultStream<RDF.Quad>) => Promise<Graph>;
11
11
  export declare namespace RDFJSON {
12
12
  type Term = {
13
13
  type: "uri" | "literal" | "bnode";
@@ -2,8 +2,8 @@ import { xsd } from "../../namespaces/xsd.js";
2
2
  import { rdf } from "../../namespaces/rdf.js";
3
3
  import { ldkit } from "../../namespaces/ldkit.js";
4
4
  import { type IRI } from "../rdf.js";
5
- /** Map of supported RDF data types and their JavaScript native counterparts */
6
- export type SupportedDataTypes = {
5
+ /** Map of default RDF data types and their JavaScript native counterparts */
6
+ type DefaultDataTypes = {
7
7
  [xsd.dateTime]: Date;
8
8
  [xsd.date]: Date;
9
9
  [xsd.gDay]: Date;
@@ -42,5 +42,15 @@ export type SupportedDataTypes = {
42
42
  [xsd.duration]: string;
43
43
  [ldkit.IRI]: IRI;
44
44
  };
45
+ /** Custom data types definition. Keys are type IRIs, values are JavaScript native types */
46
+ export interface CustomDataTypes {
47
+ }
48
+ /**
49
+ * Map of supported RDF data types and their JavaScript native counterparts,
50
+ * combines default data types with custom data types.
51
+ * The keys are the IRIs of the data types, and the values are the corresponding JavaScript types.
52
+ */
53
+ export type SupportedDataTypes = Omit<DefaultDataTypes, keyof CustomDataTypes> & CustomDataTypes;
45
54
  /** List of supported native JavaScript types */
46
55
  export type SupportedNativeTypes = SupportedDataTypes[keyof SupportedDataTypes];
56
+ export {};
@@ -1,4 +1,4 @@
1
- export type { SupportedDataTypes, SupportedNativeTypes } from "./data_types.js";
1
+ export type { CustomDataTypes, SupportedDataTypes, SupportedNativeTypes, } from "./data_types.js";
2
2
  export type { Identity, SchemaInterface, SchemaSearchInterface, SchemaUpdateInterface, } from "./interface.js";
3
3
  export type { ExpandedProperty, ExpandedSchema, Property, Schema, } from "./schema.js";
4
4
  export type { SearchFilters, SearchSchema } from "./search.js";
@@ -0,0 +1,38 @@
1
+ import { RDF } from "./rdf.js";
2
+ import { SupportedDataTypes } from "./schema/mod.js";
3
+ /**
4
+ * Registers a data type handler for translating between RDF literals and JavaScript values.
5
+ *
6
+ * In order to register a custom data type handler, the custom data type TypeScript mapping needs
7
+ * to be added to the {@link CustomDataTypes} interface using module augmentation.
8
+ *
9
+ * Two handlers are required:
10
+ * 1) A function to translate from RDF literal value (string) to JavaScript value.
11
+ * 2) A function to translate from JavaScript value to RDF literal value (string).
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { registerDataHandler } from "ldkit";
16
+ *
17
+ * const customNumberDataType = "http://example.org/number";
18
+ *
19
+ * declare module "ldkit" {
20
+ * interface CustomDataTypes {
21
+ * [customNumberDataType]: number;
22
+ * }
23
+ * }
24
+ *
25
+ * registerDataHandler(
26
+ * customNumberDataType,
27
+ * (literalValue: string) => parseInt(literalValue),
28
+ * (nativeValue: number) => nativeValue.toString(),
29
+ * );
30
+ * ```
31
+ *
32
+ * @param dataType - The data type to register.
33
+ * @param translateFromRDF - Function to translate from RDF literal to JavaScript value.
34
+ * @param translateToRDF - Function to translate from JavaScript value to RDF literal.
35
+ */
36
+ export declare function registerDataHandler<T extends keyof SupportedDataTypes>(dataType: T, translateFromRDF: (literalValue: string) => SupportedDataTypes[T], translateToRDF: (nativeValue: SupportedDataTypes[T]) => string): void;
37
+ export declare function translateFromRdf(literal: RDF.Literal): any;
38
+ export declare function translateToRdf(value: unknown, dataType: keyof SupportedDataTypes | string): RDF.Literal | import("rdf-data-factory").Literal;
@@ -0,0 +1 @@
1
+ export { readableFromWeb } from "readable-from-web";
package/types/mod.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { type Options, setGlobalOptions } from "./library/options.js";
2
- export type { Identity, Property, Schema, SchemaInterface, SchemaSearchInterface, SchemaUpdateInterface, SupportedDataTypes, } from "./library/schema/mod.js";
2
+ export type { CustomDataTypes, Identity, Property, Schema, SchemaInterface, SchemaSearchInterface, SchemaUpdateInterface, SupportedDataTypes, } from "./library/schema/mod.js";
3
+ export { registerDataHandler } from "./library/translator.js";
3
4
  export * from "./library/lens/mod.js";
4
5
  export * from "./library/namespace.js";
5
6
  export * from "./library/engine/mod.js";