@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 +12 -9
- package/dist/lib/iiif-images.d.ts +13 -6
- package/dist/lib/iiif-images.d.ts.map +1 -1
- package/dist/lib/iiif-images.js +8 -4
- package/package.json +3 -3
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
|
-
| `
|
|
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
|
-
- **
|
|
120
|
-
|
|
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
|
|
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
|
-
*
|
|
12
|
-
* all datasets, so construct one per run.
|
|
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
|
|
15
|
-
* image
|
|
16
|
-
*
|
|
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
|
|
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,
|
|
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"}
|
package/dist/lib/iiif-images.js
CHANGED
|
@@ -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.
|
|
18
|
+
const limits = options.fetchWindowMs === undefined
|
|
19
19
|
? {}
|
|
20
|
-
: {
|
|
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.
|
|
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.
|
|
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.
|
|
42
|
+
"@lde/pipeline": "^0.42.0",
|
|
43
43
|
"@lde/search": "^0.36.3"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|