@lde/pipeline 0.28.9 → 0.28.12

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 +1 @@
1
- {"version":3,"file":"importResolver.d.ts","sourceRoot":"","sources":["../../src/distribution/importResolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAMrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EACL,KAAK,oBAAoB,EAEzB,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,eAAe,CAAC;AAGvB,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,qBAAa,cAAe,YAAW,oBAAoB;IAEvD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBADP,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,qBAAqB;IAG3C,OAAO,CACX,GAAG,IAAI,EAAE,UAAU,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,GACnD,OAAO,CAAC,oBAAoB,GAAG,uBAAuB,CAAC;YAgB5C,aAAa;IAqFrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAG/B"}
1
+ {"version":3,"file":"importResolver.d.ts","sourceRoot":"","sources":["../../src/distribution/importResolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAMrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EACL,KAAK,oBAAoB,EAEzB,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,eAAe,CAAC;AAGvB,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,qBAAa,cAAe,YAAW,oBAAoB;IAEvD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBADP,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,qBAAqB;IAG3C,OAAO,CACX,GAAG,IAAI,EAAE,UAAU,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,GACnD,OAAO,CAAC,oBAAoB,GAAG,uBAAuB,CAAC;YAgB5C,aAAa;IAqGrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAG/B"}
@@ -1,7 +1,7 @@
1
1
  import { Distribution } from '@lde/dataset';
2
2
  import { ImportFailed, ImportSuccessful, NotSupported, } from '@lde/sparql-importer';
3
3
  import { NoDistributionAvailable, ResolvedDistribution, } from './resolver.js';
4
- import { NetworkError } from './probe.js';
4
+ import { NetworkError } from '@lde/distribution-probe';
5
5
  /**
6
6
  * A {@link DistributionResolver} decorator that adds data-dump import logic.
7
7
  *
@@ -35,6 +35,18 @@ export class ImportResolver {
35
35
  const candidates = dataset
36
36
  .getDownloadDistributions()
37
37
  .filter((d) => d.accessUrl && successfulUrls.has(d.accessUrl.toString()));
38
+ // Propagate Last-Modified from probe to candidate so the downloader can
39
+ // skip redundant downloads (and preserve the QLever index cache).
40
+ for (const candidate of candidates) {
41
+ if (candidate.lastModified)
42
+ continue;
43
+ const probeResult = probeResults.find((r) => r.url === candidate.accessUrl.toString());
44
+ if (probeResult &&
45
+ !(probeResult instanceof NetworkError) &&
46
+ probeResult.lastModified) {
47
+ candidate.lastModified = probeResult.lastModified;
48
+ }
49
+ }
38
50
  if (candidates.length === 0) {
39
51
  return new NoDistributionAvailable(dataset, 'No importable distributions passed probing', probeResults);
40
52
  }
@@ -1,4 +1,4 @@
1
- export { probe, NetworkError, SparqlProbeResult, DataDumpProbeResult, type ProbeResultType, } from './probe.js';
1
+ export { probe, NetworkError, SparqlProbeResult, DataDumpProbeResult, type ProbeResultType, } from '@lde/distribution-probe';
2
2
  export { probeResultsToQuads } from './report.js';
3
3
  export { ImportResolver, type ImportResolverOptions, } from './importResolver.js';
4
4
  export { ResolvedDistribution, NoDistributionAvailable, SparqlDistributionResolver, type DistributionResolver, type ResolveCallbacks, type SparqlDistributionResolverOptions, } from './resolver.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/distribution/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EACL,cAAc,EACd,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,0BAA0B,EAC1B,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,iCAAiC,GACvC,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,oBAAoB,EACpB,KAAK,uBAAuB,GAC7B,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/distribution/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,eAAe,GACrB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EACL,cAAc,EACd,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,0BAA0B,EAC1B,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,iCAAiC,GACvC,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,oBAAoB,EACpB,KAAK,uBAAuB,GAC7B,MAAM,2BAA2B,CAAC"}
@@ -1,4 +1,4 @@
1
- export { probe, NetworkError, SparqlProbeResult, DataDumpProbeResult, } from './probe.js';
1
+ export { probe, NetworkError, SparqlProbeResult, DataDumpProbeResult, } from '@lde/distribution-probe';
2
2
  export { probeResultsToQuads } from './report.js';
3
3
  export { ImportResolver, } from './importResolver.js';
4
4
  export { ResolvedDistribution, NoDistributionAvailable, SparqlDistributionResolver, } from './resolver.js';
@@ -1,6 +1,6 @@
1
1
  import type { ImportFailed } from '@lde/sparql-importer';
2
2
  import { type Quad } from 'n3';
3
- import { type ProbeResultType } from './probe.js';
3
+ import { type ProbeResultType } from '@lde/distribution-probe';
4
4
  /**
5
5
  * Convert probe results into RDF quads describing each probe as a `schema:Action`.
6
6
  *
@@ -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,CA2CrB"}
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,yBAAyB,CAAC;AAUjC;;;;;;;;;GASG;AACH,wBAAuB,mBAAmB,CACxC,YAAY,EAAE,eAAe,EAAE,EAC/B,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,YAAY,GAC1B,aAAa,CAAC,IAAI,CAAC,CA2CrB"}
@@ -1,5 +1,5 @@
1
1
  import { DataFactory } from 'n3';
2
- import { NetworkError, SparqlProbeResult, } from './probe.js';
2
+ import { NetworkError, SparqlProbeResult, } from '@lde/distribution-probe';
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/';
@@ -1,6 +1,6 @@
1
1
  import { type Distribution, type Dataset } from '@lde/dataset';
2
2
  import type { Quad } from 'n3';
3
- import type { ProbeResultType } from './probe.js';
3
+ import type { ProbeResultType } from '@lde/distribution-probe';
4
4
  import { type DistributionResolver } from './resolver.js';
5
5
  export interface DistributionStageResult {
6
6
  distribution: Distribution | null;
@@ -1 +1 @@
1
- {"version":3,"file":"resolveDistributions.d.ts","sourceRoot":"","sources":["../../src/distribution/resolveDistributions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,OAAO,EACL,KAAK,oBAAoB,EAE1B,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,uBAAuB,CAAC,CAoBlC"}
1
+ {"version":3,"file":"resolveDistributions.d.ts","sourceRoot":"","sources":["../../src/distribution/resolveDistributions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EACL,KAAK,oBAAoB,EAE1B,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,uBAAuB,CAAC,CAoBlC"}
@@ -1,6 +1,6 @@
1
1
  import { Dataset, Distribution } from '@lde/dataset';
2
2
  import type { ImportFailed } from '@lde/sparql-importer';
3
- import { type ProbeResultType } from './probe.js';
3
+ import { type ProbeResultType } from '@lde/distribution-probe';
4
4
  export declare class ResolvedDistribution {
5
5
  readonly distribution: Distribution;
6
6
  readonly probeResults: ProbeResultType[];
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/distribution/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAA4B,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAE5E,qBAAa,oBAAoB;IAE7B,QAAQ,CAAC,YAAY,EAAE,YAAY;IACnC,QAAQ,CAAC,YAAY,EAAE,eAAe,EAAE;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY;IACpC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM;IAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM;gBAJpB,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,eAAe,EAAE,EAC/B,YAAY,CAAC,EAAE,YAAY,YAAA,EAC3B,cAAc,CAAC,EAAE,MAAM,YAAA,EACvB,WAAW,CAAC,EAAE,MAAM,YAAA;CAEhC;AAED,qBAAa,uBAAuB;IAEhC,QAAQ,CAAC,OAAO,EAAE,OAAO;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,QAAQ,CAAC,YAAY,EAAE,eAAe,EAAE;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY;gBAH3B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,eAAe,EAAE,EAC/B,YAAY,CAAC,EAAE,YAAY,YAAA;CAEvC;AAED,sDAAsD;AACtD,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IACxE,6CAA6C;IAC7C,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,kDAAkD;IAClD,cAAc,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACtE;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CACL,OAAO,EAAE,OAAO,EAChB,SAAS,CAAC,EAAE,gBAAgB,GAC3B,OAAO,CAAC,oBAAoB,GAAG,uBAAuB,CAAC,CAAC;IAC3D,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,iCAAiC;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,qBAAa,0BAA2B,YAAW,oBAAoB;IACrE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,CAAC,EAAE,iCAAiC;IAIjD,OAAO,CACX,OAAO,EAAE,OAAO,EAChB,SAAS,CAAC,EAAE,gBAAgB,GAC3B,OAAO,CAAC,oBAAoB,GAAG,uBAAuB,CAAC;CA6B3D"}
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/distribution/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAEjC,qBAAa,oBAAoB;IAE7B,QAAQ,CAAC,YAAY,EAAE,YAAY;IACnC,QAAQ,CAAC,YAAY,EAAE,eAAe,EAAE;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY;IACpC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM;IAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM;gBAJpB,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,eAAe,EAAE,EAC/B,YAAY,CAAC,EAAE,YAAY,YAAA,EAC3B,cAAc,CAAC,EAAE,MAAM,YAAA,EACvB,WAAW,CAAC,EAAE,MAAM,YAAA;CAEhC;AAED,qBAAa,uBAAuB;IAEhC,QAAQ,CAAC,OAAO,EAAE,OAAO;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,QAAQ,CAAC,YAAY,EAAE,eAAe,EAAE;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY;gBAH3B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,eAAe,EAAE,EAC/B,YAAY,CAAC,EAAE,YAAY,YAAA;CAEvC;AAED,sDAAsD;AACtD,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IACxE,6CAA6C;IAC7C,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,kDAAkD;IAClD,cAAc,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACtE;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CACL,OAAO,EAAE,OAAO,EAChB,SAAS,CAAC,EAAE,gBAAgB,GAC3B,OAAO,CAAC,oBAAoB,GAAG,uBAAuB,CAAC,CAAC;IAC3D,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,iCAAiC;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,qBAAa,0BAA2B,YAAW,oBAAoB;IACrE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,CAAC,EAAE,iCAAiC;IAIjD,OAAO,CACX,OAAO,EAAE,OAAO,EAChB,SAAS,CAAC,EAAE,gBAAgB,GAC3B,OAAO,CAAC,oBAAoB,GAAG,uBAAuB,CAAC;CA6B3D"}
@@ -1,4 +1,4 @@
1
- import { probe, SparqlProbeResult } from './probe.js';
1
+ import { probe, SparqlProbeResult, } from '@lde/distribution-probe';
2
2
  export class ResolvedDistribution {
3
3
  distribution;
4
4
  probeResults;
@@ -41,7 +41,7 @@ export class SparqlDistributionResolver {
41
41
  }
42
42
  async resolve(dataset, callbacks) {
43
43
  const results = await Promise.all(dataset.distributions.map(async (distribution) => {
44
- const result = await probe(distribution, this.timeout);
44
+ const result = await probe(distribution, { timeoutMs: this.timeout });
45
45
  callbacks?.onProbe?.(distribution, result);
46
46
  return result;
47
47
  }));
package/dist/pipeline.js CHANGED
@@ -3,7 +3,7 @@ import { StreamParser } from 'n3';
3
3
  import { FileWriter } from './writer/fileWriter.js';
4
4
  import { NoDistributionAvailable, } from './distribution/resolver.js';
5
5
  import { SparqlDistributionResolver } from './distribution/index.js';
6
- import { NetworkError, SparqlProbeResult, } from './distribution/probe.js';
6
+ import { NetworkError, SparqlProbeResult, } from '@lde/distribution-probe';
7
7
  import { NotSupported } from './sparql/executor.js';
8
8
  /**
9
9
  * Split an async iterable into `count` branches that can be consumed
@@ -23,7 +23,7 @@ function tee(source, count) {
23
23
  }
24
24
  // This branch already consumed the current item – wait for the next round.
25
25
  if (consumed[branch]) {
26
- return new Promise(resolve => waiting.push(resolve)).then(() => advance(branch));
26
+ return new Promise((resolve) => waiting.push(resolve)).then(() => advance(branch));
27
27
  }
28
28
  consumed[branch] = true;
29
29
  // All branches consumed – wake up any that are waiting for the next round.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lde/pipeline",
3
- "version": "0.28.9",
3
+ "version": "0.28.12",
4
4
  "repository": {
5
5
  "url": "git+https://github.com/ldelements/lde.git",
6
6
  "directory": "packages/pipeline"
@@ -24,10 +24,11 @@
24
24
  "!**/*.tsbuildinfo"
25
25
  ],
26
26
  "dependencies": {
27
- "@lde/dataset": "0.7.2",
28
- "@lde/dataset-registry-client": "0.7.5",
29
- "@lde/sparql-importer": "0.6.0",
30
- "@lde/sparql-server": "0.4.10",
27
+ "@lde/dataset": "0.7.3",
28
+ "@lde/dataset-registry-client": "0.7.6",
29
+ "@lde/distribution-probe": "0.1.2",
30
+ "@lde/sparql-importer": "0.6.1",
31
+ "@lde/sparql-server": "0.4.11",
31
32
  "@rdfjs/types": "^2.0.1",
32
33
  "@traqula/generator-sparql-1-1": "^1.0.7",
33
34
  "@traqula/parser-sparql-1-1": "^1.0.4",
@@ -1,49 +0,0 @@
1
- import { Distribution } from '@lde/dataset';
2
- /**
3
- * Result of a network error during probing.
4
- */
5
- export declare class NetworkError {
6
- readonly url: string;
7
- readonly message: string;
8
- constructor(url: string, message: string);
9
- }
10
- /**
11
- * Base class for successful probe results.
12
- */
13
- declare abstract class ProbeResult {
14
- readonly url: string;
15
- readonly statusCode: number;
16
- readonly statusText: string;
17
- readonly lastModified: Date | null;
18
- readonly contentType: string | null;
19
- readonly failureReason: string | null;
20
- readonly warnings: string[];
21
- constructor(url: string, response: Response, failureReason?: string | null);
22
- isSuccess(): boolean;
23
- }
24
- /**
25
- * Result of probing a SPARQL endpoint.
26
- */
27
- export declare class SparqlProbeResult extends ProbeResult {
28
- readonly acceptedContentType = "application/sparql-results+json";
29
- isSuccess(): boolean;
30
- }
31
- /**
32
- * Result of probing a data dump distribution.
33
- */
34
- export declare class DataDumpProbeResult extends ProbeResult {
35
- readonly contentSize: number | null;
36
- constructor(url: string, response: Response, failureReason?: string | null);
37
- }
38
- export type ProbeResultType = SparqlProbeResult | DataDumpProbeResult | NetworkError;
39
- /**
40
- * Probe a distribution to check availability and gather metadata.
41
- *
42
- * For SPARQL endpoints, sends a simple SELECT query.
43
- * For data dumps, sends HEAD (or GET if HEAD returns no Content-Length).
44
- *
45
- * Returns pure probe results without mutating the distribution.
46
- */
47
- export declare function probe(distribution: Distribution, timeout?: number): Promise<ProbeResultType>;
48
- export {};
49
- //# sourceMappingURL=probe.d.ts.map
@@ -1 +0,0 @@
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;aASN,GAAG,EAAE,MAAM;IAR7B,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;IAC3C,SAAgB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,SAAgB,QAAQ,EAAE,MAAM,EAAE,CAAM;gBAGtB,GAAG,EAAE,MAAM,EAC3B,QAAQ,EAAE,QAAQ,EAClB,aAAa,GAAE,MAAM,GAAG,IAAW;IAY9B,SAAS,IAAI,OAAO;CAO5B;AAID;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,WAAW;IAChD,SAAgB,mBAAmB,qCAAuB;IAEjD,SAAS,IAAI,OAAO;CAM9B;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,WAAW;IAClD,SAAgB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;gBAGhD,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,QAAQ,EAClB,aAAa,GAAE,MAAM,GAAG,IAAW;CAQtC;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,201 +0,0 @@
1
- import { Parser } from 'n3';
2
- /**
3
- * Result of a network error during probing.
4
- */
5
- export class NetworkError {
6
- url;
7
- message;
8
- constructor(url, message) {
9
- this.url = url;
10
- this.message = message;
11
- }
12
- }
13
- /**
14
- * Base class for successful probe results.
15
- */
16
- class ProbeResult {
17
- url;
18
- statusCode;
19
- statusText;
20
- lastModified = null;
21
- contentType;
22
- failureReason;
23
- warnings = [];
24
- constructor(url, response, failureReason = null) {
25
- this.url = url;
26
- this.statusCode = response.status;
27
- this.statusText = response.statusText;
28
- this.contentType = response.headers.get('Content-Type');
29
- this.failureReason = failureReason;
30
- const lastModifiedHeader = response.headers.get('Last-Modified');
31
- if (lastModifiedHeader) {
32
- this.lastModified = new Date(lastModifiedHeader);
33
- }
34
- }
35
- isSuccess() {
36
- return (this.statusCode >= 200 &&
37
- this.statusCode < 400 &&
38
- this.failureReason === null);
39
- }
40
- }
41
- const SPARQL_RESULTS_JSON = 'application/sparql-results+json';
42
- /**
43
- * Result of probing a SPARQL endpoint.
44
- */
45
- export class SparqlProbeResult extends ProbeResult {
46
- acceptedContentType = SPARQL_RESULTS_JSON;
47
- isSuccess() {
48
- return (super.isSuccess() &&
49
- (this.contentType?.startsWith(this.acceptedContentType) ?? false));
50
- }
51
- }
52
- /**
53
- * Result of probing a data dump distribution.
54
- */
55
- export class DataDumpProbeResult extends ProbeResult {
56
- contentSize = null;
57
- constructor(url, response, failureReason = null) {
58
- super(url, response, failureReason);
59
- const contentLengthHeader = response.headers.get('Content-Length');
60
- if (contentLengthHeader) {
61
- this.contentSize = parseInt(contentLengthHeader);
62
- }
63
- }
64
- }
65
- /**
66
- * Probe a distribution to check availability and gather metadata.
67
- *
68
- * For SPARQL endpoints, sends a simple SELECT query.
69
- * For data dumps, sends HEAD (or GET if HEAD returns no Content-Length).
70
- *
71
- * Returns pure probe results without mutating the distribution.
72
- */
73
- export async function probe(distribution, timeout = 5000) {
74
- try {
75
- if (distribution.isSparql()) {
76
- return await probeSparqlEndpoint(distribution, timeout);
77
- }
78
- return await probeDataDump(distribution, timeout);
79
- }
80
- catch (e) {
81
- return new NetworkError(distribution.accessUrl?.toString() ?? 'unknown', e instanceof Error ? e.message : String(e));
82
- }
83
- }
84
- async function probeSparqlEndpoint(distribution, timeout) {
85
- const url = distribution.accessUrl.toString();
86
- const response = await fetch(url, {
87
- signal: AbortSignal.timeout(timeout),
88
- method: 'POST',
89
- headers: {
90
- 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
91
- Accept: SPARQL_RESULTS_JSON,
92
- },
93
- body: `query=${encodeURIComponent('SELECT * { ?s ?p ?o } LIMIT 1')}`,
94
- });
95
- const isJsonResponse = response.headers
96
- .get('Content-Type')
97
- ?.startsWith(SPARQL_RESULTS_JSON);
98
- let failureReason = null;
99
- if (response.ok && isJsonResponse) {
100
- failureReason = await validateSparqlResponse(response);
101
- }
102
- else {
103
- // Drain unconsumed body to release the underlying connection.
104
- await response.body?.cancel();
105
- }
106
- return new SparqlProbeResult(url, response, failureReason);
107
- }
108
- async function validateSparqlResponse(response) {
109
- const body = await response.text();
110
- if (body.length === 0) {
111
- return 'SPARQL endpoint returned an empty response';
112
- }
113
- try {
114
- const json = JSON.parse(body);
115
- if (!json.results || typeof json.results !== 'object') {
116
- return 'SPARQL endpoint did not return a valid results object';
117
- }
118
- }
119
- catch {
120
- return 'SPARQL endpoint returned invalid JSON';
121
- }
122
- return null;
123
- }
124
- async function probeDataDump(distribution, timeout) {
125
- const url = distribution.accessUrl.toString();
126
- const requestOptions = {
127
- signal: AbortSignal.timeout(timeout),
128
- headers: {
129
- Accept: distribution.mimeType ?? '*/*',
130
- 'Accept-Encoding': 'identity', // Return uncompressed responses.
131
- },
132
- };
133
- const headResponse = await fetch(url, {
134
- method: 'HEAD',
135
- ...requestOptions,
136
- });
137
- const contentLength = headResponse.headers.get('Content-Length');
138
- const contentLengthBytes = contentLength ? parseInt(contentLength) : 0;
139
- // For small or unknown-size files, do a GET to validate body content.
140
- // This also handles servers that incorrectly return 0 Content-Length for HEAD.
141
- if (contentLengthBytes <= 10_240) {
142
- const getResponse = await fetch(url, {
143
- method: 'GET',
144
- ...requestOptions,
145
- });
146
- const body = await getResponse.text();
147
- const isHttpSuccess = getResponse.status >= 200 && getResponse.status < 400;
148
- const failureReason = isHttpSuccess
149
- ? validateBody(body, getResponse.headers.get('Content-Type'))
150
- : null;
151
- const result = new DataDumpProbeResult(url, getResponse, failureReason);
152
- checkContentTypeMismatch(result, distribution.mimeType);
153
- return result;
154
- }
155
- const result = new DataDumpProbeResult(url, headResponse);
156
- checkContentTypeMismatch(result, distribution.mimeType);
157
- return result;
158
- }
159
- const rdfContentTypes = [
160
- 'text/turtle',
161
- 'application/n-triples',
162
- 'application/n-quads',
163
- ];
164
- function validateBody(body, contentType) {
165
- if (body.length === 0) {
166
- return 'Distribution is empty';
167
- }
168
- if (contentType && rdfContentTypes.some((t) => contentType.startsWith(t))) {
169
- try {
170
- const parser = new Parser();
171
- const quads = parser.parse(body);
172
- if (quads.length === 0) {
173
- return 'Distribution contains no RDF triples';
174
- }
175
- }
176
- catch (e) {
177
- return e instanceof Error ? e.message : String(e);
178
- }
179
- }
180
- return null;
181
- }
182
- /** Content types that indicate compression, not the RDF serialization format. */
183
- const compressionTypes = new Set([
184
- 'application/gzip',
185
- 'application/x-gzip',
186
- 'application/octet-stream',
187
- ]);
188
- /**
189
- * Compare the declared MIME type from the dataset registry against the
190
- * server's Content-Type header. Adds a warning when they disagree.
191
- */
192
- function checkContentTypeMismatch(result, declaredMimeType) {
193
- if (!result.isSuccess() || !declaredMimeType || !result.contentType)
194
- return;
195
- const actual = result.contentType.split(';')[0].trim();
196
- if (compressionTypes.has(actual))
197
- return;
198
- if (actual !== declaredMimeType) {
199
- result.warnings.push(`Server Content-Type ${actual} does not match declared media type ${declaredMimeType}`);
200
- }
201
- }