@lde/pipeline 0.6.28 → 0.6.30

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
@@ -86,9 +86,7 @@ import {
86
86
  } from '@lde/pipeline';
87
87
 
88
88
  const pipeline = new Pipeline({
89
- name: 'example',
90
89
  datasetSelector: new ManualDatasetSelection([dataset]),
91
- distributionResolver: new SparqlDistributionResolver(),
92
90
  stages: [
93
91
  new Stage({
94
92
  name: 'per-class',
@@ -101,7 +99,7 @@ const pipeline = new Pipeline({
101
99
  }),
102
100
  }),
103
101
  ],
104
- writer: new SparqlUpdateWriter({
102
+ writers: new SparqlUpdateWriter({
105
103
  endpoint: new URL('http://localhost:7200/repositories/lde/statements'),
106
104
  }),
107
105
  });
@@ -31,7 +31,9 @@ export declare class SparqlProbeResult extends ProbeResult {
31
31
  */
32
32
  export declare class DataDumpProbeResult extends ProbeResult {
33
33
  readonly contentSize: number | null;
34
- constructor(url: string, response: Response);
34
+ readonly failureReason: string | null;
35
+ constructor(url: string, response: Response, failureReason?: string | null);
36
+ isSuccess(): boolean;
35
37
  }
36
38
  export type ProbeResultType = SparqlProbeResult | DataDumpProbeResult | NetworkError;
37
39
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../../src/distribution/probe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C;;GAEG;AACH,qBAAa,YAAY;aACK,GAAG,EAAE,MAAM;aAAkB,OAAO,EAAE,MAAM;gBAA5C,GAAG,EAAE,MAAM,EAAkB,OAAO,EAAE,MAAM;CACzE;AAED;;GAEG;AACH,uBAAe,WAAW;aAMI,GAAG,EAAE,MAAM;IALvC,SAAgB,UAAU,EAAE,MAAM,CAAC;IACnC,SAAgB,UAAU,EAAE,MAAM,CAAC;IACnC,SAAgB,YAAY,EAAE,IAAI,GAAG,IAAI,CAAQ;IACjD,SAAgB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;gBAEf,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ;IAUpD,SAAS,IAAI,OAAO;CAG5B;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,WAAW;IAChD,SAAgB,mBAAmB,qCAAqC;IAE/D,SAAS,IAAI,OAAO;CAM9B;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,WAAW;IAClD,SAAgB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;gBAEtC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ;CAO5C;AAED,MAAM,MAAM,eAAe,GACvB,iBAAiB,GACjB,mBAAmB,GACnB,YAAY,CAAC;AAEjB;;;;;;;GAOG;AACH,wBAAsB,KAAK,CACzB,YAAY,EAAE,YAAY,EAC1B,OAAO,SAAO,GACb,OAAO,CAAC,eAAe,CAAC,CAY1B"}
1
+ {"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../../src/distribution/probe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C;;GAEG;AACH,qBAAa,YAAY;aAEL,GAAG,EAAE,MAAM;aACX,OAAO,EAAE,MAAM;gBADf,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM;CAElC;AAED;;GAEG;AACH,uBAAe,WAAW;aAON,GAAG,EAAE,MAAM;IAN7B,SAAgB,UAAU,EAAE,MAAM,CAAC;IACnC,SAAgB,UAAU,EAAE,MAAM,CAAC;IACnC,SAAgB,YAAY,EAAE,IAAI,GAAG,IAAI,CAAQ;IACjD,SAAgB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;gBAGzB,GAAG,EAAE,MAAM,EAC3B,QAAQ,EAAE,QAAQ;IAWb,SAAS,IAAI,OAAO;CAG5B;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,WAAW;IAChD,SAAgB,mBAAmB,qCAAqC;IAE/D,SAAS,IAAI,OAAO;CAM9B;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,WAAW;IAClD,SAAgB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;IAClD,SAAgB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;gBAG3C,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,QAAQ,EAClB,aAAa,GAAE,MAAM,GAAG,IAAW;IAU5B,SAAS,IAAI,OAAO;CAG9B;AAED,MAAM,MAAM,eAAe,GACvB,iBAAiB,GACjB,mBAAmB,GACnB,YAAY,CAAC;AAEjB;;;;;;;GAOG;AACH,wBAAsB,KAAK,CACzB,YAAY,EAAE,YAAY,EAC1B,OAAO,SAAO,GACb,OAAO,CAAC,eAAe,CAAC,CAY1B"}
@@ -1,3 +1,4 @@
1
+ import { Parser } from 'n3';
1
2
  /**
2
3
  * Result of a network error during probing.
3
4
  */
@@ -47,13 +48,18 @@ export class SparqlProbeResult extends ProbeResult {
47
48
  */
48
49
  export class DataDumpProbeResult extends ProbeResult {
49
50
  contentSize = null;
50
- constructor(url, response) {
51
+ failureReason;
52
+ constructor(url, response, failureReason = null) {
51
53
  super(url, response);
54
+ this.failureReason = failureReason;
52
55
  const contentLengthHeader = response.headers.get('Content-Length');
53
56
  if (contentLengthHeader) {
54
57
  this.contentSize = parseInt(contentLengthHeader);
55
58
  }
56
59
  }
60
+ isSuccess() {
61
+ return super.isSuccess() && this.failureReason === null;
62
+ }
57
63
  }
58
64
  /**
59
65
  * Probe a distribution to check availability and gather metadata.
@@ -96,19 +102,48 @@ async function probeDataDump(distribution, timeout) {
96
102
  'Accept-Encoding': 'identity', // Return uncompressed responses.
97
103
  },
98
104
  };
99
- let response = await fetch(url, {
105
+ const headResponse = await fetch(url, {
100
106
  method: 'HEAD',
101
107
  ...requestOptions,
102
108
  });
103
- const contentLength = response.headers.get('Content-Length');
104
- if (contentLength === null || contentLength === '0') {
105
- // Retry as GET request for servers incorrectly returning HEAD request Content-Length,
106
- // which *should* be the size of the response body when issuing a GET, not that of
107
- // the response to a HEAD request, which is intentionally 0.
108
- response = await fetch(url, {
109
+ const contentLength = headResponse.headers.get('Content-Length');
110
+ const contentLengthBytes = contentLength ? parseInt(contentLength) : 0;
111
+ // For small or unknown-size files, do a GET to validate body content.
112
+ // This also handles servers that incorrectly return 0 Content-Length for HEAD.
113
+ if (contentLengthBytes <= 10_240) {
114
+ const getResponse = await fetch(url, {
109
115
  method: 'GET',
110
116
  ...requestOptions,
111
117
  });
118
+ const body = await getResponse.text();
119
+ const isHttpSuccess = getResponse.status >= 200 && getResponse.status < 400;
120
+ const failureReason = isHttpSuccess
121
+ ? validateBody(body, getResponse.headers.get('Content-Type'))
122
+ : null;
123
+ return new DataDumpProbeResult(url, getResponse, failureReason);
124
+ }
125
+ return new DataDumpProbeResult(url, headResponse);
126
+ }
127
+ const rdfContentTypes = [
128
+ 'text/turtle',
129
+ 'application/n-triples',
130
+ 'application/n-quads',
131
+ ];
132
+ function validateBody(body, contentType) {
133
+ if (body.length === 0) {
134
+ return 'Distribution is empty';
135
+ }
136
+ if (contentType && rdfContentTypes.some((t) => contentType.startsWith(t))) {
137
+ try {
138
+ const parser = new Parser();
139
+ const quads = parser.parse(body);
140
+ if (quads.length === 0) {
141
+ return 'Distribution contains no RDF triples';
142
+ }
143
+ }
144
+ catch (e) {
145
+ return e instanceof Error ? e.message : String(e);
146
+ }
112
147
  }
113
- return new DataDumpProbeResult(url, response);
148
+ return null;
114
149
  }
@@ -1 +1 @@
1
- {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/distribution/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAe,KAAK,IAAI,EAAE,MAAM,IAAI,CAAC;AAC5C,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,YAAY,CAAC;AAUpB;;;;;;;;;GASG;AACH,wBAAuB,mBAAmB,CACxC,YAAY,EAAE,eAAe,EAAE,EAC/B,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,YAAY,GAC1B,aAAa,CAAC,IAAI,CAAC,CAkCrB"}
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/distribution/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAe,KAAK,IAAI,EAAE,MAAM,IAAI,CAAC;AAC5C,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,YAAY,CAAC;AAUpB;;;;;;;;;GASG;AACH,wBAAuB,mBAAmB,CACxC,YAAY,EAAE,eAAe,EAAE,EAC/B,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,YAAY,GAC1B,aAAa,CAAC,IAAI,CAAC,CAwCrB"}
@@ -1,5 +1,5 @@
1
1
  import { DataFactory } from 'n3';
2
- import { NetworkError, SparqlProbeResult, } from './probe.js';
2
+ import { NetworkError, SparqlProbeResult, DataDumpProbeResult, } from './probe.js';
3
3
  const { quad, namedNode, blankNode, literal } = DataFactory;
4
4
  const RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
5
5
  const SCHEMA = 'https://schema.org/';
@@ -30,6 +30,9 @@ export async function* probeResultsToQuads(probeResults, datasetIri, importResul
30
30
  else if (result.isSuccess()) {
31
31
  yield* successQuads(action, result, datasetIri);
32
32
  }
33
+ else if (result instanceof DataDumpProbeResult && result.failureReason) {
34
+ yield quad(action, namedNode(`${SCHEMA}error`), literal(result.failureReason));
35
+ }
33
36
  else {
34
37
  // HTTP error
35
38
  const statusUri = `${HTTP_STATUS}${result.statusText.replace(/ /g, '')}`;
@@ -5,18 +5,26 @@ import { type DistributionResolver } from './distribution/resolver.js';
5
5
  import type { StageOutputResolver } from './stageOutputResolver.js';
6
6
  import type { ProgressReporter } from './progressReporter.js';
7
7
  export interface PipelineOptions {
8
- name: string;
9
8
  datasetSelector: DatasetSelector;
10
9
  stages: Stage[];
11
- writer: Writer;
12
- distributionResolver: DistributionResolver;
13
- stageOutputResolver?: StageOutputResolver;
14
- outputDir?: string;
15
- outputFormat?: 'turtle' | 'n-triples' | 'n-quads';
10
+ writers: Writer | Writer[];
11
+ name?: string;
12
+ distributionResolver?: DistributionResolver;
13
+ chaining?: {
14
+ stageOutputResolver: StageOutputResolver;
15
+ outputDir: string;
16
+ outputFormat?: 'turtle' | 'n-triples' | 'n-quads';
17
+ };
16
18
  reporter?: ProgressReporter;
17
19
  }
18
20
  export declare class Pipeline {
19
- private readonly options;
21
+ private readonly name;
22
+ private readonly datasetSelector;
23
+ private readonly stages;
24
+ private readonly writer;
25
+ private readonly distributionResolver;
26
+ private readonly chaining?;
27
+ private readonly reporter?;
20
28
  constructor(options: PipelineOptions);
21
29
  run(): Promise<void>;
22
30
  private processDataset;
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EACL,KAAK,oBAAoB,EAE1B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,eAAe,CAAC;IACjC,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;IAClD,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;gBAE9B,OAAO,EAAE,eAAe;IAe9B,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAcZ,cAAc;YA2Bd,QAAQ;YAgCR,QAAQ;YAoDR,eAAe;YAoCd,SAAS;CAUzB"}
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EACL,KAAK,oBAAoB,EAE1B,MAAM,4BAA4B,CAAC;AAGpC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC9B,eAAe,EAAE,eAAe,CAAC;IACjC,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,QAAQ,CAAC,EAAE;QACT,mBAAmB,EAAE,mBAAmB,CAAC;QACzC,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;KACnD,CAAC;IACF,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AAmBD,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAuB;IAC5D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAA8B;IACxD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAmB;gBAEjC,OAAO,EAAE,eAAe;IAoB9B,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAaZ,cAAc;YA0Bd,QAAQ;YA8BR,QAAQ;YAmDR,eAAe;YAkCd,SAAS;CAUzB"}
package/dist/pipeline.js CHANGED
@@ -2,40 +2,67 @@ import { createReadStream } from 'node:fs';
2
2
  import { StreamParser } from 'n3';
3
3
  import { FileWriter } from './writer/fileWriter.js';
4
4
  import { NoDistributionAvailable, } from './distribution/resolver.js';
5
+ import { SparqlDistributionResolver } from './distribution/index.js';
5
6
  import { NotSupported } from './sparql/executor.js';
7
+ class FanOutWriter {
8
+ writers;
9
+ constructor(writers) {
10
+ this.writers = writers;
11
+ }
12
+ async write(dataset, quads) {
13
+ const collected = [];
14
+ for await (const quad of quads)
15
+ collected.push(quad);
16
+ for (const w of this.writers) {
17
+ await w.write(dataset, (async function* () {
18
+ yield* collected;
19
+ })());
20
+ }
21
+ }
22
+ }
6
23
  export class Pipeline {
7
- options;
24
+ name;
25
+ datasetSelector;
26
+ stages;
27
+ writer;
28
+ distributionResolver;
29
+ chaining;
30
+ reporter;
8
31
  constructor(options) {
9
32
  const hasSubStages = options.stages.some((stage) => stage.stages.length > 0);
10
- if (hasSubStages && !options.stageOutputResolver) {
11
- throw new Error('stageOutputResolver is required when any stage has sub-stages');
12
- }
13
- if (hasSubStages && !options.outputDir) {
14
- throw new Error('outputDir is required when any stage has sub-stages');
33
+ if (hasSubStages && !options.chaining) {
34
+ throw new Error('chaining is required when any stage has sub-stages');
15
35
  }
16
- this.options = options;
36
+ this.name = options.name ?? '';
37
+ this.datasetSelector = options.datasetSelector;
38
+ this.stages = options.stages;
39
+ this.writer = Array.isArray(options.writers)
40
+ ? new FanOutWriter(options.writers)
41
+ : options.writers;
42
+ this.distributionResolver =
43
+ options.distributionResolver ?? new SparqlDistributionResolver();
44
+ this.chaining = options.chaining;
45
+ this.reporter = options.reporter;
17
46
  }
18
47
  async run() {
19
- const { datasetSelector, reporter, name } = this.options;
20
48
  const start = Date.now();
21
- reporter?.pipelineStart(name);
22
- const datasets = await datasetSelector.select();
49
+ this.reporter?.pipelineStart(this.name);
50
+ const datasets = await this.datasetSelector.select();
23
51
  for await (const dataset of datasets) {
24
52
  await this.processDataset(dataset);
25
53
  }
26
- reporter?.pipelineComplete({ duration: Date.now() - start });
54
+ this.reporter?.pipelineComplete({ duration: Date.now() - start });
27
55
  }
28
56
  async processDataset(dataset) {
29
- const { distributionResolver, reporter } = this.options;
30
57
  const datasetIri = dataset.iri.toString();
31
- reporter?.datasetStart(datasetIri);
32
- const resolved = await distributionResolver.resolve(dataset);
58
+ this.reporter?.datasetStart(datasetIri);
59
+ const resolved = await this.distributionResolver.resolve(dataset);
33
60
  if (resolved instanceof NoDistributionAvailable) {
34
- reporter?.datasetSkipped(datasetIri, resolved.message);
61
+ this.reporter?.datasetSkipped(datasetIri, resolved.message);
35
62
  return;
36
63
  }
37
64
  try {
38
- for (const stage of this.options.stages) {
65
+ for (const stage of this.stages) {
39
66
  if (stage.stages.length > 0) {
40
67
  await this.runChain(dataset, resolved.distribution, stage);
41
68
  }
@@ -47,26 +74,25 @@ export class Pipeline {
47
74
  catch {
48
75
  // Stage error for this dataset; continue to next dataset.
49
76
  }
50
- reporter?.datasetComplete(datasetIri);
77
+ this.reporter?.datasetComplete(datasetIri);
51
78
  }
52
79
  async runStage(dataset, distribution, stage) {
53
- const { writer, reporter } = this.options;
54
- reporter?.stageStart(stage.name);
80
+ this.reporter?.stageStart(stage.name);
55
81
  const stageStart = Date.now();
56
82
  let elementsProcessed = 0;
57
83
  let quadsGenerated = 0;
58
- const result = await stage.run(dataset, distribution, writer, {
84
+ const result = await stage.run(dataset, distribution, this.writer, {
59
85
  onProgress: (elements, quads) => {
60
86
  elementsProcessed = elements;
61
87
  quadsGenerated = quads;
62
- reporter?.stageProgress({ elementsProcessed, quadsGenerated });
88
+ this.reporter?.stageProgress({ elementsProcessed, quadsGenerated });
63
89
  },
64
90
  });
65
91
  if (result instanceof NotSupported) {
66
- reporter?.stageSkipped(stage.name, result.message);
92
+ this.reporter?.stageSkipped(stage.name, result.message);
67
93
  }
68
94
  else {
69
- reporter?.stageComplete(stage.name, {
95
+ this.reporter?.stageComplete(stage.name, {
70
96
  elementsProcessed,
71
97
  quadsGenerated,
72
98
  duration: Date.now() - stageStart,
@@ -74,7 +100,7 @@ export class Pipeline {
74
100
  }
75
101
  }
76
102
  async runChain(dataset, distribution, stage) {
77
- const { writer, stageOutputResolver, outputDir, outputFormat } = this.options;
103
+ const { stageOutputResolver, outputDir, outputFormat } = this.chaining;
78
104
  const outputFiles = [];
79
105
  try {
80
106
  // 1. Run parent stage → FileWriter.
@@ -99,15 +125,14 @@ export class Pipeline {
99
125
  }
100
126
  }
101
127
  // 3. Concatenate all output files → user writer.
102
- await writer.write(dataset, this.readFiles(outputFiles));
128
+ await this.writer.write(dataset, this.readFiles(outputFiles));
103
129
  }
104
130
  finally {
105
131
  await stageOutputResolver.cleanup();
106
132
  }
107
133
  }
108
134
  async runChainedStage(dataset, distribution, stage, stageWriter) {
109
- const { reporter } = this.options;
110
- reporter?.stageStart(stage.name);
135
+ this.reporter?.stageStart(stage.name);
111
136
  const stageStart = Date.now();
112
137
  let elementsProcessed = 0;
113
138
  let quadsGenerated = 0;
@@ -115,14 +140,14 @@ export class Pipeline {
115
140
  onProgress: (elements, quads) => {
116
141
  elementsProcessed = elements;
117
142
  quadsGenerated = quads;
118
- reporter?.stageProgress({ elementsProcessed, quadsGenerated });
143
+ this.reporter?.stageProgress({ elementsProcessed, quadsGenerated });
119
144
  },
120
145
  });
121
146
  if (result instanceof NotSupported) {
122
- reporter?.stageSkipped(stage.name, result.message);
147
+ this.reporter?.stageSkipped(stage.name, result.message);
123
148
  throw new Error(`Stage '${stage.name}' returned NotSupported in chained mode`);
124
149
  }
125
- reporter?.stageComplete(stage.name, {
150
+ this.reporter?.stageComplete(stage.name, {
126
151
  elementsProcessed,
127
152
  quadsGenerated,
128
153
  duration: Date.now() - stageStart,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lde/pipeline",
3
- "version": "0.6.28",
3
+ "version": "0.6.30",
4
4
  "repository": {
5
5
  "url": "https://github.com/ldengine/lde",
6
6
  "directory": "packages/pipeline"