@ndes/iiif-images 0.1.1 → 0.2.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.
package/README.md CHANGED
@@ -48,11 +48,11 @@ const pipeline = await createSearchIndexer(config, {
48
48
  `representativeImage` and `associatedMedia`, so a deployment on an older schema loses
49
49
  the enrichment rather than the run.
50
50
 
51
- | Option | Default | Purpose |
52
- | --------------- | --------------- | -------------------------------------------------------- |
53
- | `storePath` | required | SQLite file holding resolved facts between runs |
54
- | `fetchesPerRun` | 500 | Manifests, and separately `info.json` documents, per run |
55
- | `report` | console warning | Called for each reference whose fetch failed |
51
+ | Option | Default | Purpose |
52
+ | --------------- | --------------- | ---------------------------------------------------------- |
53
+ | `storePath` | required | SQLite file holding resolved facts between runs |
54
+ | `fetchWindowMs` | no limit | How long after construction a fetch may still start, in ms |
55
+ | `report` | console warning | Called for each reference whose fetch failed |
56
56
 
57
57
  `storePath` has to be on a durable volume. The store is the only place these facts
58
58
  live between runs, and with an empty one every image is fetched from the publisher
@@ -116,12 +116,15 @@ again.
116
116
  manifest too broken to read. A 200 that is no IIIF document at all, such as an error
117
117
  page served as JSON, counts as a failure, so it is retried every run and five in a
118
118
  row stop that dataset’s manifests for the run.
119
- - **Budget:** `fetchesPerRun` covers all datasets together. What it defers is not
120
- reported, and those works are indexed without an image until a later run.
119
+ - **Window:** without `fetchWindowMs`, a cold store is fetched in one run, as fast
120
+ as each publisher keeps up. With it, a fetch that has not started once the window
121
+ has passed waits for a later run; one already under way finishes. The window covers
122
+ all datasets together, and what it defers is not reported: those works are indexed
123
+ without an image until a later run.
121
124
  - **Later runs:** retries, deferred works and refreshes all need the dataset to be
122
125
  reprocessed. With `PROVENANCE_FILE`, an unchanged dataset waits until it changes
123
- or `PIPELINE_VERSION` is bumped, so set `fetchesPerRun` high enough to cover it in
124
- one run.
126
+ or `PIPELINE_VERSION` is bumped, so leave `fetchWindowMs` long enough to cover it
127
+ in one run.
125
128
  - **Limits:** manifest requests are grouped per dataset, because manifest URLs often
126
129
  sit on a redirector such as `n2t.net`, and `info.json` requests per host. Datasets
127
130
  on one server are limited separately, with only the overall limit across them.
@@ -8,14 +8,15 @@ export interface IiifImagesOptions {
8
8
  */
9
9
  readonly storePath: string;
10
10
  /**
11
- * Manifests, and separately `info.json` documents, this object may fetch across
12
- * all datasets, so construct one per run. Defaults to the resolver’s 500.
11
+ * How long after this object’s construction it may still start fetching, in
12
+ * milliseconds, across all datasets, so construct one per run. Unset, there is
13
+ * no limit: everything is fetched as fast as the publishers allow.
13
14
  *
14
- * What the budget defers is not reported, and those works are indexed without an
15
- * image. A cold store then warms only as datasets are reprocessed, so where
16
- * unchanged datasets are skipped, set this high enough to cover them in one run.
15
+ * What the window defers is counted, as `manifests deferred` or
16
+ * `image services deferred`, but not reported, and those works are indexed
17
+ * without an image until a later run fetches it.
17
18
  */
18
- readonly fetchesPerRun?: number;
19
+ readonly fetchWindowMs?: number;
19
20
  /** Told about each reference that failed. Defaults to a console warning. */
20
21
  readonly report?: (failure: ResolutionFailure) => void;
21
22
  }
@@ -24,6 +25,12 @@ export interface IiifImagesContext {
24
25
  readonly dataset: {
25
26
  readonly iri: URL;
26
27
  };
28
+ /**
29
+ * Told what became of each manifest and image service, such as
30
+ * `manifests fetched` or `image services from store`, so the stage can add
31
+ * up the run. An `@lde/pipeline` reader passes its own.
32
+ */
33
+ readonly count?: (name: string) => void;
27
34
  }
28
35
  /** A transform attachable to a reader as an `@lde/pipeline` `QuadTransform`. */
29
36
  export type IiifImagesTransform = (quads: AsyncIterable<Quad>, context: IiifImagesContext) => AsyncIterable<Quad>;
@@ -1 +1 @@
1
- {"version":3,"file":"iiif-images.d.ts","sourceRoot":"","sources":["../../src/lib/iiif-images.ts"],"names":[],"mappings":"AAWA,OAAO,EAKL,KAAK,iBAAiB,EAEvB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACV,QAAQ,EAER,YAAY,EAEb,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,IAAI,EAA6B,MAAM,cAAc,CAAC;AASpE,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACxD;AAED,kEAAkE;AAClE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA;KAAE,CAAC;CACzC;AAED,gFAAgF;AAChF,MAAM,MAAM,mBAAmB,GAAG,CAChC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,EAC1B,OAAO,EAAE,iBAAiB,KACvB,aAAa,CAAC,IAAI,CAAC,CAAC;AAEzB,MAAM,WAAW,UAAU;IACzB;;;;;OAKG;IACH,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,mBAAmB,GAAG,SAAS,CAAC;IAClE,4EAA4E;IAC5E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,iBAAiB,GACzB,UAAU,CAoHZ"}
1
+ {"version":3,"file":"iiif-images.d.ts","sourceRoot":"","sources":["../../src/lib/iiif-images.ts"],"names":[],"mappings":"AAWA,OAAO,EAKL,KAAK,iBAAiB,EAGvB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACV,QAAQ,EAER,YAAY,EAEb,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,IAAI,EAA6B,MAAM,cAAc,CAAC;AASpE,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;;;;;OAQG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACxD;AAED,kEAAkE;AAClE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA;KAAE,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,gFAAgF;AAChF,MAAM,MAAM,mBAAmB,GAAG,CAChC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,EAC1B,OAAO,EAAE,iBAAiB,KACvB,aAAa,CAAC,IAAI,CAAC,CAAC;AAEzB,MAAM,WAAW,UAAU;IACzB;;;;;OAKG;IACH,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,mBAAmB,GAAG,SAAS,CAAC;IAClE,4EAA4E;IAC5E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,iBAAiB,GACzB,UAAU,CAsHZ"}
@@ -15,9 +15,9 @@ import { iiifImage, iiifImageService, iiifImageSize, representativeImageField, }
15
15
  * in `associatedMedia`, and a failed resolution is retried on a later run.
16
16
  */
17
17
  export function iiifImages(schema, options) {
18
- const limits = options.fetchesPerRun === undefined
18
+ const limits = options.fetchWindowMs === undefined
19
19
  ? {}
20
- : { fetchesPerResolver: options.fetchesPerRun };
20
+ : { fetchWindowMs: options.fetchWindowMs };
21
21
  const report = options.report ??
22
22
  ((failure) => console.warn(`${failure.key}: ${failure.reason}`));
23
23
  const manifests = createResolver({
@@ -85,7 +85,7 @@ export function iiifImages(schema, options) {
85
85
  }
86
86
  const manifestOfWork = manifestsIn(batch, aliases);
87
87
  const dataset = context.dataset.iri.toString();
88
- const selected = await manifests.resolveAll([...manifestOfWork.values()].map((url) => ({ url, dataset })));
88
+ const selected = await manifests.resolveAll([...manifestOfWork.values()].map((url) => ({ url, dataset })), countedAs('manifests', context));
89
89
  const imageOfWork = new Map();
90
90
  for (const [work, manifest] of manifestOfWork) {
91
91
  const resolution = selected.get(manifest);
@@ -93,7 +93,7 @@ export function iiifImages(schema, options) {
93
93
  imageOfWork.set(work, resolution.fact);
94
94
  }
95
95
  }
96
- const resolved = await services.resolveAll([...imageOfWork.values()].flatMap(({ service }) => service === undefined ? [] : [service]));
96
+ const resolved = await services.resolveAll([...imageOfWork.values()].flatMap(({ service }) => service === undefined ? [] : [service]), countedAs('image services', context));
97
97
  for (const [work, image] of imageOfWork) {
98
98
  const representative = representativeOf(image, resolved);
99
99
  if (representative !== undefined) {
@@ -109,6 +109,10 @@ export function iiifImages(schema, options) {
109
109
  };
110
110
  }
111
111
  const factory = new DataFactory();
112
+ /** Pass the resolver’s counts on to the context, prefixed with what is resolved. */
113
+ function countedAs(prefix, { count }) {
114
+ return { count: (name) => count?.(`${prefix} ${name}`) };
115
+ }
112
116
  const INTEGER = factory.namedNode('http://www.w3.org/2001/XMLSchema#integer');
113
117
  /** What the profile’s `encodingFormat` for a manifest entry contains. */
114
118
  const IIIF_PRESENTATION_CONTEXT = 'iiif.io/api/presentation';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ndes/iiif-images",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Enriches SCHEMA-AP-NDE works with the dimensions and sizes of their representative IIIF image, as a quad transform for the search indexer.",
5
5
  "repository": {
6
6
  "url": "git+https://github.com/netwerk-digitaal-erfgoed/stack.git",
@@ -33,13 +33,13 @@
33
33
  "dependencies": {
34
34
  "@lde/iiif-image": "^0.2.0",
35
35
  "@lde/public-fetch": "^0.1.0",
36
- "@lde/resolver": "^0.2.1",
36
+ "@lde/resolver": "^0.7.0",
37
37
  "@rdfjs/types": "^2.0.1",
38
38
  "rdf-data-factory": "^2.1.0",
39
39
  "tslib": "^2.3.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@lde/pipeline": "^0.36.7",
42
+ "@lde/pipeline": "^0.42.0",
43
43
  "@lde/search": "^0.36.3"
44
44
  },
45
45
  "peerDependencies": {