@rdfc/sparql-ingest-processor-ts 2.1.0 → 2.1.2

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/README.md CHANGED
@@ -46,6 +46,8 @@ npm install @rdfc/sparql-ingest-processor-ts
46
46
  <ingester> a rdfc:SPARQLIngest;
47
47
  rdfc:memberStream <in>;
48
48
  rdfc:ingestConfig [
49
+ rdfc:operationMode "Replication";
50
+ rdfc:memberBatchSize 500;
49
51
  rdfc:memberShape "http://ex.org/Shape";
50
52
  rdfc:changeSemantics [
51
53
  rdfc:changeTypePath "http://ex.org/changeType";
@@ -83,6 +85,8 @@ npm install @rdfc/sparql-ingest-processor-ts
83
85
  ---
84
86
 
85
87
  ### Parameters of `rdfc:IngestConfig`:
88
+ - `rdfc:operationMode` (**string**, optional): Operation mode of the processor. Can be `Replication` or `Sync`. `Replication` mode uses the [SPARQL Graph Store Protocol](https://www.w3.org/TR/sparql11-http-rdf-update/) to ingest data directly into a triple store, which assumes that all received data is meant to be added. `Sync` mode uses the [SPARQL UPDATE specification](https://www.w3.org/TR/sparql11-update/) to ingest data via SPARQL queries, which allows for all CRUD operations.
89
+ - `rdfc:memberBatchSize` (**integer**, optional): Number of input records to batch together for ingestion when running in `Replication` mode.
86
90
  - `rdfc:memberShape` (**string**, optional): SHACL shape used to guide query construction when payloads are incomplete.
87
91
  - `rdfc:changeSemantics` (**rdfc:ChangeSemantics**, optional): Configures mapping between change types (create/update/delete) and SPARQL operations.
88
92
  - `rdfc:targetNamedGraph` (**string**, optional): Force all operations into a specific named graph.
@@ -132,7 +136,6 @@ npm install @rdfc/sparql-ingest-processor-ts
132
136
 
133
137
  ## Notes
134
138
 
135
- - Delete operations can be handled differently depending on how complete the input record is.
139
+ - Delete operations can be handled differently depending on how complete the input record is. A SHACL shape (`rdfc:memberShape`) can be provided to help identify deletion targets when payloads are incomplete.
136
140
  - Transactions can buffer multiple input records and commit them together using `rdfc:transactionConfig`.
137
- - A SHACL shape (`rdfc:memberShape`) can be provided to help identify deletion targets when payloads are incomplete.
138
141
 
@@ -34,6 +34,7 @@ export class SPARQLIngest extends Processor {
34
34
  }
35
35
  async transform() {
36
36
  for await (const rawQuads of this.memberStream.strings()) {
37
+ this.logger.debug(`Raw member data received: \n${rawQuads}`);
37
38
  const quads = new Parser().parse(rawQuads);
38
39
  this.logger.verbose(`Parsed ${quads.length} quads from received member data`);
39
40
  const store = RdfStore.createDefault();
@@ -45,6 +46,7 @@ export class SPARQLIngest extends Processor {
45
46
  store.addQuad(q);
46
47
  }
47
48
  });
49
+ sanitizeQuads(store);
48
50
  let query;
49
51
  const memberIRI = getObjects(store, null, SDS.terms.payload, SDS.terms.custom("DataDescription"))[0];
50
52
  if (memberIRI) {
@@ -99,7 +101,6 @@ export class SPARQLIngest extends Processor {
99
101
  }
100
102
  else {
101
103
  const ctv = store.getQuads(null, df.namedNode(this.config.changeSemantics.changeTypePath))[0];
102
- sanitizeQuads(store);
103
104
  if (ctv.object.value === this.config.changeSemantics.createValue) {
104
105
  this.logger.info(`Preparing 'INSERT DATA {}' SPARQL query for member ${memberIRI.value}`);
105
106
  query = CREATE(store, this.config.forVirtuoso);
@@ -128,12 +129,7 @@ export class SPARQLIngest extends Processor {
128
129
  }
129
130
  else {
130
131
  if (this.config.operationMode === OperationMode.REPLICATION) {
131
- this.memberBatch.push(...store.getQuads().map(q => {
132
- if (q.graph.equals(df.defaultGraph()) && this.config.targetNamedGraph) {
133
- q.graph = df.namedNode(this.config.targetNamedGraph);
134
- }
135
- return q;
136
- }));
132
+ this.memberBatch.push(...store.getQuads());
137
133
  this.batchCount++;
138
134
  if (this.batchCount < this.config.memberBatchSize) {
139
135
  continue;
package/lib/Utils.js CHANGED
@@ -81,13 +81,14 @@ export async function doSPARQLRequest(query, config, logger) {
81
81
  const timeout = config.measurePerformance?.queryTimeout || 1800;
82
82
  if (query.length > 0 && typeof query[0] !== 'string') {
83
83
  const quads = query;
84
- const writer = new N3Writer();
84
+ const writer = new N3Writer({ format: "N-Quads" });
85
85
  const serialized = writer.quadsToString(quads);
86
86
  const url = new URL(config.graphStoreUrl);
87
87
  if (config.accessToken) {
88
88
  url.searchParams.append("access-token", config.accessToken);
89
89
  }
90
- logger.debug(`Executing SPARQL Graph Store request (POST) with ${quads.length} quads.`);
90
+ logger.verbose(`[doSPARQLRequest] Executing SPARQL Graph Store request (POST) with ${quads.length} quads.`);
91
+ logger.debug(`[doSPARQLRequest] POSTing the following RDF quads:\n${serialized}`);
91
92
  const res = await fetch(url.toString(), {
92
93
  method: "POST",
93
94
  headers: {
@@ -113,6 +114,7 @@ export async function doSPARQLRequest(query, config, logger) {
113
114
  queries.push(jointQuery);
114
115
  }
115
116
  for (const q of queries) {
117
+ logger.debug(`[doSPARQLRequest] Executing SPARQL query: \n${q}`);
116
118
  const res = await fetch(config.graphStoreUrl, {
117
119
  method: "POST",
118
120
  headers: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rdfc/sparql-ingest-processor-ts",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "description": "SPARQL Update function to be within RDF-Connect pipelines",
5
5
  "author": "Julián Rojas",
6
6
  "contributors": [
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "@treecg/types": "^0.4.6",
31
- "n3": "^2.0.1",
31
+ "n3": "^1.26.0",
32
32
  "rdf-data-factory": "^2.0.2",
33
33
  "rdf-stores": "^2.1.1",
34
34
  "undici": "^7.21.0",
@@ -39,7 +39,7 @@
39
39
  "@rdfc/js-runner": "^3.0.2",
40
40
  "@rdfjs/types": "^2.0.1",
41
41
  "@types/n3": "^1.26.1",
42
- "@types/node": "^25.2.1",
42
+ "@types/node": "^25.2.2",
43
43
  "@typescript-eslint/eslint-plugin": "^8.54.0",
44
44
  "@typescript-eslint/parser": "^8.54.0",
45
45
  "@vitest/coverage-v8": "^4.0.18",