cozy-iiif 0.2.6 → 0.3.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
@@ -134,6 +134,10 @@ console.log(image.getRegionURL(bounds));
134
134
 
135
135
  // With custom minimum shorted dimension
136
136
  console.log(image.getRegionURL(bounds, 800));
137
+
138
+ // Resolves the actual image pixel size from the info.json
139
+ // or the image file (which may **differ**) from the canvas size!
140
+ console.log(image.getPixelSize());
137
141
  ```
138
142
 
139
143
  ## Cozy Helpers
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
+ import { imageSize as ce } from "image-size";
1
2
  import { g as m, a as j, b as S } from "./resource-DS2brz47.js";
2
- import { c as Wt } from "./resource-DS2brz47.js";
3
- var ce = "http://library.stanford.edu/iiif/image-api/compliance.html#level0", le = "http://library.stanford.edu/iiif/image-api/compliance.html#level1", F = "http://library.stanford.edu/iiif/image-api/compliance.html#level2", pe = "http://library.stanford.edu/iiif/image-api/conformance.html#level0", ve = "http://library.stanford.edu/iiif/image-api/conformance.html#level1", W = "http://library.stanford.edu/iiif/image-api/conformance.html#level2", he = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level0", ue = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level1", B = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2", fe = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level0", me = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level1", H = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level2", ge = "http://iiif.io/api/image/1/level0.json", de = "http://iiif.io/api/image/1/profiles/level0.json", ye = "http://iiif.io/api/image/1/level1.json", Ae = "http://iiif.io/api/image/1/profiles/level1.json", J = "http://iiif.io/api/image/1/level2.json", G = "http://iiif.io/api/image/1/profiles/level2.json", Ce = "http://iiif.io/api/image/2/level0.json", be = "http://iiif.io/api/image/2/profiles/level0.json", Re = "http://iiif.io/api/image/2/level1.json", Le = "http://iiif.io/api/image/2/profiles/level1.json", K = "http://iiif.io/api/image/2/level2.json", Q = "http://iiif.io/api/image/2/profiles/level2.json", we = "level0", Ie = "level1", X = "level2", Se = "http://iiif.io/api/image/2/level0", Te = "http://iiif.io/api/image/2/level1", Y = "http://iiif.io/api/image/2/level2", xe = [Y, F, W, B, H, J, G, K, Q, X], $e = [Se, Te, Y, ce, le, F, pe, ve, W, he, ue, B, fe, me, H, ge, de, ye, Ae, J, G, Ce, be, Re, Le, K, Q, we, Ie, X], Me = $e;
3
+ import { c as zt } from "./resource-DS2brz47.js";
4
+ var le = "http://library.stanford.edu/iiif/image-api/compliance.html#level0", pe = "http://library.stanford.edu/iiif/image-api/compliance.html#level1", V = "http://library.stanford.edu/iiif/image-api/compliance.html#level2", ve = "http://library.stanford.edu/iiif/image-api/conformance.html#level0", he = "http://library.stanford.edu/iiif/image-api/conformance.html#level1", F = "http://library.stanford.edu/iiif/image-api/conformance.html#level2", ue = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level0", fe = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level1", W = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2", me = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level0", ge = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level1", H = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level2", de = "http://iiif.io/api/image/1/level0.json", ye = "http://iiif.io/api/image/1/profiles/level0.json", Ae = "http://iiif.io/api/image/1/level1.json", Ce = "http://iiif.io/api/image/1/profiles/level1.json", J = "http://iiif.io/api/image/1/level2.json", z = "http://iiif.io/api/image/1/profiles/level2.json", be = "http://iiif.io/api/image/2/level0.json", Re = "http://iiif.io/api/image/2/profiles/level0.json", Le = "http://iiif.io/api/image/2/level1.json", we = "http://iiif.io/api/image/2/profiles/level1.json", G = "http://iiif.io/api/image/2/level2.json", K = "http://iiif.io/api/image/2/profiles/level2.json", Ie = "level0", Se = "level1", Q = "level2", xe = "http://iiif.io/api/image/2/level0", Te = "http://iiif.io/api/image/2/level1", X = "http://iiif.io/api/image/2/level2", $e = [X, V, F, W, H, J, z, G, K, Q], Me = [xe, Te, X, le, pe, V, ve, he, F, ue, fe, W, me, ge, H, de, ye, Ae, Ce, J, z, be, Re, Le, we, G, K, Ie, Se, Q], je = Me;
4
5
  function g(t) {
5
6
  for (let e in t) (typeof t[e] > "u" || t[e] === null) && delete t[e];
6
7
  return t;
@@ -8,8 +9,8 @@ function g(t) {
8
9
  function w(t) {
9
10
  return Array.isArray(t) ? t : t ? [t] : [];
10
11
  }
11
- var je = Object.defineProperty, ke = (t, e, r) => e in t ? je(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r, b = (t, e, r) => (ke(t, typeof e != "symbol" ? e + "" : e, r), r), N = ["sc:Collection", "sc:Manifest", "sc:Canvas", "sc:AnnotationList", "oa:Annotation", "sc:Range", "sc:Layer", "sc:Sequence", "oa:Choice", "Service", "ContentResource"];
12
- function Pe(t) {
12
+ var ke = Object.defineProperty, Pe = (t, e, r) => e in t ? ke(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r, b = (t, e, r) => (Pe(t, typeof e != "symbol" ? e + "" : e, r), r), N = ["sc:Collection", "sc:Manifest", "sc:Canvas", "sc:AnnotationList", "oa:Annotation", "sc:Range", "sc:Layer", "sc:Sequence", "oa:Choice", "Service", "ContentResource"];
13
+ function Oe(t) {
13
14
  if (typeof t > "u" || t === null) throw new Error("Null or undefined is not a valid entity.");
14
15
  if (Array.isArray(t)) throw new Error("Array is not a valid entity");
15
16
  if (typeof t != "object") throw new Error(`${typeof t} is not a valid entity`);
@@ -21,12 +22,12 @@ function Pe(t) {
21
22
  if (t.format || t["@type"]) return "ContentResource";
22
23
  throw new Error("Resource type is not known");
23
24
  }
24
- var Oe = class Z {
25
+ var Ue = class Y {
25
26
  constructor(e, r = {}) {
26
27
  b(this, "traversals"), b(this, "options"), this.traversals = { collection: [], manifest: [], canvas: [], annotationList: [], sequence: [], annotation: [], contentResource: [], choice: [], range: [], service: [], layer: [], ...e }, this.options = { convertPropsToArray: !0, mergeMemberProperties: !0, allowUndefinedReturn: !1, ...r };
27
28
  }
28
29
  static all(e) {
29
- return new Z({ collection: [e], manifest: [e], canvas: [e], annotationList: [e], sequence: [e], annotation: [e], contentResource: [e], choice: [e], range: [e], service: [e], layer: [e] });
30
+ return new Y({ collection: [e], manifest: [e], canvas: [e], annotationList: [e], sequence: [e], annotation: [e], contentResource: [e], choice: [e], range: [e], service: [e], layer: [e] });
30
31
  }
31
32
  traverseCollection(e) {
32
33
  return this.traverseType(this.traverseDescriptive(this.traverseLinking(this.traverseCollectionItems(e))), this.traversals.collection);
@@ -99,7 +100,7 @@ var Oe = class Z {
99
100
  }
100
101
  traverseUnknown(e) {
101
102
  if (!e["@type"] || typeof e == "string") return e;
102
- switch (Pe(e)) {
103
+ switch (Oe(e)) {
103
104
  case "sc:Collection":
104
105
  return this.traverseCollection(e);
105
106
  case "sc:Manifest":
@@ -152,8 +153,8 @@ var Oe = class Z {
152
153
  return typeof n > "u" && !this.options.allowUndefinedReturn ? i : n;
153
154
  }, e);
154
155
  }
155
- }, Ue = "http://library.stanford.edu/iiif/image-api/compliance.html#level1", De = "http://library.stanford.edu/iiif/image-api/compliance.html#level2", Ne = "http://library.stanford.edu/iiif/image-api/conformance.html#level1", Ee = "http://library.stanford.edu/iiif/image-api/conformance.html#level2", qe = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level1", _e = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2", Ve = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level1", Fe = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level2", We = "http://iiif.io/api/image/1/level1.json", Be = "http://iiif.io/api/image/1/profiles/level1.json", He = "http://iiif.io/api/image/1/level2.json", Je = "http://iiif.io/api/image/1/profiles/level2.json", Ge = "http://iiif.io/api/image/2/level1.json", Ke = "http://iiif.io/api/image/2/profiles/level1.json", Qe = "http://iiif.io/api/image/2/level2.json", Xe = "http://iiif.io/api/image/2/profiles/level2.json", Ye = "level1", Ze = "level2", ze = "http://iiif.io/api/image/2/level1", et = "http://iiif.io/api/image/2/level2", tt = [ze, et, Ue, De, Ne, Ee, qe, _e, Ve, Fe, We, Be, He, Je, Ge, Ke, Qe, Xe, Ye, Ze], k = { attributionLabel: "Attribution", providerId: "http://example.org/provider", providerName: "Unknown" };
156
- function rt(t) {
156
+ }, De = "http://library.stanford.edu/iiif/image-api/compliance.html#level1", Ne = "http://library.stanford.edu/iiif/image-api/compliance.html#level2", Ee = "http://library.stanford.edu/iiif/image-api/conformance.html#level1", qe = "http://library.stanford.edu/iiif/image-api/conformance.html#level2", _e = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level1", Be = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2", Ve = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level1", Fe = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level2", We = "http://iiif.io/api/image/1/level1.json", He = "http://iiif.io/api/image/1/profiles/level1.json", Je = "http://iiif.io/api/image/1/level2.json", ze = "http://iiif.io/api/image/1/profiles/level2.json", Ge = "http://iiif.io/api/image/2/level1.json", Ke = "http://iiif.io/api/image/2/profiles/level1.json", Qe = "http://iiif.io/api/image/2/level2.json", Xe = "http://iiif.io/api/image/2/profiles/level2.json", Ye = "level1", Ze = "level2", et = "http://iiif.io/api/image/2/level1", tt = "http://iiif.io/api/image/2/level2", rt = [et, tt, De, Ne, Ee, qe, _e, Be, Ve, Fe, We, He, Je, ze, Ge, Ke, Qe, Xe, Ye, Ze], k = { attributionLabel: "Attribution", providerId: "http://example.org/provider", providerName: "Unknown" };
157
+ function it(t) {
157
158
  if (typeof t == "string") return [t];
158
159
  if (!t) return [];
159
160
  let e = Array.isArray(t) ? t : [t], r = [];
@@ -168,7 +169,7 @@ function rt(t) {
168
169
  }
169
170
  function I(t, e = "none") {
170
171
  if (!t) return { none: [""] };
171
- let r = rt(t), i = {};
172
+ let r = it(t), i = {};
172
173
  for (let s of r) {
173
174
  if (typeof s == "string") {
174
175
  i[e] = i[e] ? i[e] : [], i[e].push(s || "");
@@ -183,14 +184,14 @@ function I(t, e = "none") {
183
184
  }
184
185
  return Object.keys(i).length === 0 ? { none: [""] } : i;
185
186
  }
186
- function z(t) {
187
- if (Array.isArray(t)) return z(t.find((e) => typeof e == "string"));
188
- if (xe.indexOf(t) !== -1) return "level2";
189
- if (tt.indexOf(t) !== -1) return "level1";
190
- if (Me.indexOf(t) !== -1) return "level0";
187
+ function Z(t) {
188
+ if (Array.isArray(t)) return Z(t.find((e) => typeof e == "string"));
189
+ if ($e.indexOf(t) !== -1) return "level2";
190
+ if (rt.indexOf(t) !== -1) return "level1";
191
+ if (je.indexOf(t) !== -1) return "level0";
191
192
  if (typeof t == "string") return t;
192
193
  }
193
- function it(t) {
194
+ function st(t) {
194
195
  let e = Array.isArray(t) ? t : [t];
195
196
  for (let r of e) switch (r) {
196
197
  case "http://iiif.io/api/image/2/context.json":
@@ -203,7 +204,7 @@ function it(t) {
203
204
  return "ImageApiSelector";
204
205
  }
205
206
  }
206
- function st(t) {
207
+ function nt(t) {
207
208
  switch (t) {
208
209
  case "http://iiif.io/api/image/2/level0.json":
209
210
  case "http://iiif.io/api/image/2/level1.json":
@@ -236,15 +237,15 @@ function E(t) {
236
237
  for (let e of ["sc", "oa", "dcterms", "dctypes", "iiif"]) if (t.startsWith(`${e}:`)) return t.slice(e.length + 1);
237
238
  return t;
238
239
  }
239
- var nt = ["Collection", "Manifest", "Annotation", "AnnotationPage", "Range", "Service"];
240
+ var at = ["Collection", "Manifest", "Annotation", "AnnotationPage", "Range", "Service"];
240
241
  function U(t) {
241
242
  let e = t["@id"] || t.id, r = t["@type"] || t.type, i = t.profile || void 0, s = t["@context"] || void 0;
242
243
  if (i) {
243
- let n = st(i);
244
+ let n = nt(i);
244
245
  if (n) return n;
245
246
  }
246
247
  if (s) {
247
- let n = it(s);
248
+ let n = st(s);
248
249
  if (n) return n;
249
250
  }
250
251
  if (r) {
@@ -266,7 +267,7 @@ function U(t) {
266
267
  return "TextualBody";
267
268
  }
268
269
  }
269
- if (r && nt.indexOf(r) !== -1) return r;
270
+ if (r && at.indexOf(r) !== -1) return r;
270
271
  if (t.format) {
271
272
  if (t.format.startsWith("image/")) return "Image";
272
273
  if (t.format.startsWith("text/") || t.format === "application/pdf") return "Text";
@@ -274,15 +275,15 @@ function U(t) {
274
275
  }
275
276
  return e && (e.endsWith(".jpg") || e.endsWith(".png") || e.endsWith(".jpeg")) ? "Image" : r || "unknown";
276
277
  }
277
- var at = /http(s)?:\/\/(creativecommons.org|rightsstatements.org)[^"'\\<\n]+/gm;
278
- function ot(t) {
279
- let e = t.match(at);
278
+ var ot = /http(s)?:\/\/(creativecommons.org|rightsstatements.org)[^"'\\<\n]+/gm;
279
+ function ct(t) {
280
+ let e = t.match(ot);
280
281
  return e ? e[0] : t;
281
282
  }
282
- function ct(t, e = "Rights/License", r = "none") {
283
+ function lt(t, e = "Rights/License", r = "none") {
283
284
  let i = null, s = [], n = Array.isArray(t) ? t : [t];
284
285
  for (let o of n) {
285
- let c = o ? ot(o) : void 0;
286
+ let c = o ? ct(o) : void 0;
286
287
  if (c && (c.indexOf("creativecommons.org") !== -1 || c.indexOf("rightsstatements.org") !== -1)) {
287
288
  c.startsWith("https://") ? i = `http://${c.slice(8)}` : i = c;
288
289
  continue;
@@ -291,15 +292,15 @@ function ct(t, e = "Rights/License", r = "none") {
291
292
  }
292
293
  return [i, s];
293
294
  }
294
- var lt = ["http://iiif.io/api/presentation/2/context.json", "http://iiif.io/api/image/2/context.json", "http://iiif.io/api/image/1/context.json", "http://library.stanford.edu/iiif/image-api/1.1/context.json", "http://iiif.io/api/search/1/context.json", "http://iiif.io/api/search/0/context.json", "http://iiif.io/api/auth/1/context.json", "http://iiif.io/api/auth/0/context.json", "http://iiif.io/api/annex/openannotation/context.json"];
295
- function pt(t) {
295
+ var pt = ["http://iiif.io/api/presentation/2/context.json", "http://iiif.io/api/image/2/context.json", "http://iiif.io/api/image/1/context.json", "http://library.stanford.edu/iiif/image-api/1.1/context.json", "http://iiif.io/api/search/1/context.json", "http://iiif.io/api/search/0/context.json", "http://iiif.io/api/auth/1/context.json", "http://iiif.io/api/auth/0/context.json", "http://iiif.io/api/annex/openannotation/context.json"];
296
+ function vt(t) {
296
297
  if (t) {
297
298
  let e = Array.isArray(t) ? t : [t], r = [];
298
- for (let i of e) i === "http://iiif.io/api/presentation/2/context.json" && r.push("http://iiif.io/api/presentation/3/context.json"), lt.indexOf(i) === -1 && r.push(i);
299
+ for (let i of e) i === "http://iiif.io/api/presentation/2/context.json" && r.push("http://iiif.io/api/presentation/3/context.json"), pt.indexOf(i) === -1 && r.push(i);
299
300
  if (e.length) return r.length === 1 ? r[0] : r;
300
301
  }
301
302
  }
302
- function vt(t) {
303
+ function ht(t) {
303
304
  return t ? t.map((e) => ({ label: I(e.label), value: I(e.value) })) : [];
304
305
  }
305
306
  var q = 0;
@@ -311,16 +312,16 @@ function A(t) {
311
312
  let e = [...t.behavior || []];
312
313
  t.viewingHint && e.push(t.viewingHint);
313
314
  let r;
314
- return Array.isArray(t.motivation) ? r = t.motivation.map(E) : t.motivation && (r = E(t.motivation)), { "@context": t["@context"] ? pt(t["@context"]) : void 0, id: (t["@id"] || ee(t)).trim(), type: U(t), behavior: e.length ? e : void 0, height: t.height ? t.height : void 0, width: t.width ? t.width : void 0, motivation: r, viewingDirection: t.viewingDirection, profile: t.profile, format: t.format ? t.format : void 0, duration: void 0, timeMode: void 0 };
315
+ return Array.isArray(t.motivation) ? r = t.motivation.map(E) : t.motivation && (r = E(t.motivation)), { "@context": t["@context"] ? vt(t["@context"]) : void 0, id: (t["@id"] || ee(t)).trim(), type: U(t), behavior: e.length ? e : void 0, height: t.height ? t.height : void 0, width: t.width ? t.width : void 0, motivation: r, viewingDirection: t.viewingDirection, profile: t.profile, format: t.format ? t.format : void 0, duration: void 0, timeMode: void 0 };
315
316
  }
316
317
  function C(t) {
317
- let [e, r] = ct(t.license), i = [...t.metadata ? vt(t.metadata) : [], ...r];
318
- return { rights: e, metadata: i.length ? i : void 0, label: t.label ? I(t.label) : void 0, requiredStatement: t.attribution ? { label: I(k.attributionLabel), value: I(t.attribution) } : void 0, navDate: t.navDate, summary: t.description ? I(t.description) : void 0, thumbnail: ht(t.thumbnail) };
318
+ let [e, r] = lt(t.license), i = [...t.metadata ? ht(t.metadata) : [], ...r];
319
+ return { rights: e, metadata: i.length ? i : void 0, label: t.label ? I(t.label) : void 0, requiredStatement: t.attribution ? { label: I(k.attributionLabel), value: I(t.attribution) } : void 0, navDate: t.navDate, summary: t.description ? I(t.description) : void 0, thumbnail: ut(t.thumbnail) };
319
320
  }
320
- function ht(t) {
321
+ function ut(t) {
321
322
  return t && (Array.isArray(t) ? t : [t]).map((e) => typeof e == "string" ? { id: e, type: "Image" } : (e.type === "unknown" && (e.type = "Image"), e));
322
323
  }
323
- function ut(t) {
324
+ function ft(t) {
324
325
  if (!t.within) return;
325
326
  let e = Array.isArray(t.within) ? t.within : [t.within], r = [];
326
327
  for (let i of e) if (typeof i == "string") {
@@ -334,21 +335,21 @@ function ut(t) {
334
335
  }
335
336
  function R(t) {
336
337
  let e = t.related ? Array.isArray(t.related) ? t.related : [t.related] : [], r = t.contentLayer;
337
- return { provider: t.logo || e.length ? [{ id: k.providerId, type: "Agent", homepage: e.length ? [e[0]] : void 0, logo: t.logo ? Array.isArray(t.logo) ? t.logo : [t.logo] : void 0, label: I(k.providerName) }] : void 0, partOf: ut(t), rendering: t.rendering, seeAlso: t.seeAlso, start: t.startCanvas, service: t.service ? w(t.service) : void 0, supplementary: r ? [r] : void 0 };
338
+ return { provider: t.logo || e.length ? [{ id: k.providerId, type: "Agent", homepage: e.length ? [e[0]] : void 0, logo: t.logo ? Array.isArray(t.logo) ? t.logo : [t.logo] : void 0, label: I(k.providerName) }] : void 0, partOf: ft(t), rendering: t.rendering, seeAlso: t.seeAlso, start: t.startCanvas, service: t.service ? w(t.service) : void 0, supplementary: r ? [r] : void 0 };
338
339
  }
339
- function ft(t) {
340
+ function mt(t) {
340
341
  return { chars: t.chars, format: t.format ? t.format : void 0, language: t.language };
341
342
  }
342
- function mt(t) {
343
+ function gt(t) {
343
344
  return g({ ...A(t), ...C(t), ...R(t), items: t.members });
344
345
  }
345
- function gt(t) {
346
+ function dt(t) {
346
347
  let e = [], r = [], i;
347
348
  for (let n of t.sequences || []) n.canvases.length && e.push(...n.canvases), n.behavior && r.push(...n.behavior), n.startCanvas && (i = n.startCanvas);
348
349
  let s = A(t);
349
- return r.length && (s.behavior ? s.behavior.push(...r) : s.behavior = r), g({ ...s, ...C(t), ...R(t), start: i, items: e, structures: dt(t.structures) });
350
+ return r.length && (s.behavior ? s.behavior.push(...r) : s.behavior = r), g({ ...s, ...C(t), ...R(t), start: i, items: e, structures: yt(t.structures) });
350
351
  }
351
- function dt(t) {
352
+ function yt(t) {
352
353
  if (!t) return t;
353
354
  let e = /* @__PURE__ */ new Map();
354
355
  for (let i of t) e.set(i.id, i);
@@ -359,16 +360,16 @@ function dt(t) {
359
360
  }
360
361
  return t.filter((i) => r.indexOf(i.id) === -1);
361
362
  }
362
- function yt(t) {
363
+ function At(t) {
363
364
  return g({ ...A(t), ...C(t), ...R(t), annotations: t.otherContent && t.otherContent.length ? t.otherContent : void 0, items: t.images && t.images.length ? [{ id: ee(t, "annotation-page"), type: "AnnotationPage", items: t.images }] : void 0 });
364
365
  }
365
- function At(t) {
366
+ function Ct(t) {
366
367
  return g({ ...A(t), ...C(t), ...R(t), items: t.resources && t.resources.length ? t.resources : void 0 });
367
368
  }
368
- function Ct(t) {
369
+ function bt(t) {
369
370
  return !t.canvases || t.canvases.length === 0 ? { canvases: [], behavior: [] } : { canvases: t.canvases, behavior: t.viewingHint ? [t.viewingHint] : [], startCanvas: t.startCanvas };
370
371
  }
371
- function bt(t) {
372
+ function Rt(t) {
372
373
  function e(r) {
373
374
  if (Array.isArray(r)) {
374
375
  if (r.length > 1) return { type: "List", items: r.map(e) };
@@ -391,25 +392,25 @@ function _(t) {
391
392
  }
392
393
  function te(t) {
393
394
  let e = t;
394
- return g({ ...A(e), ...C(e), ...R(e), ...ft(e) });
395
+ return g({ ...A(e), ...C(e), ...R(e), ...mt(e) });
395
396
  }
396
- function Rt(t) {
397
+ function Lt(t) {
397
398
  let e = [];
398
399
  return t.default && t.default !== "rdf:nil" && e.push(t.default), t.item && t.item !== "rdf:nil" && e.push(...t.item), g({ ...A(t), ...C(t), items: e });
399
400
  }
400
- function Lt(t) {
401
+ function wt(t) {
401
402
  return g({ ...A(t), ...C(t), ...R(t), items: t.members });
402
403
  }
403
- function wt(t) {
404
+ function It(t) {
404
405
  let { "@id": e, "@type": r, "@context": i, profile: s, ...n } = t, o = {};
405
- return e && (o["@id"] = e), o["@type"] = U(t), o["@type"] === "unknown" && (i && i.length && (o["@context"] = i), o["@type"] = "Service"), s && (o.profile = z(s)), g({ ...o, ...n });
406
+ return e && (o["@id"] = e), o["@type"] = U(t), o["@type"] === "unknown" && (i && i.length && (o["@context"] = i), o["@type"] = "Service"), s && (o.profile = Z(s)), g({ ...o, ...n });
406
407
  }
407
- function It(t) {
408
+ function St(t) {
408
409
  return g({ ...A(t), ...C(t), ...R(t) });
409
410
  }
410
- var St = new Oe({ collection: [mt], manifest: [gt], canvas: [yt], annotationList: [At], sequence: [Ct], annotation: [bt], contentResource: [te], choice: [Rt], range: [Lt], service: [wt], layer: [It] });
411
+ var xt = new Ue({ collection: [gt], manifest: [dt], canvas: [At], annotationList: [Ct], sequence: [bt], annotation: [Rt], contentResource: [te], choice: [Lt], range: [wt], service: [It], layer: [St] });
411
412
  function re(t) {
412
- return t && t["@context"] && (t["@context"] === "http://iiif.io/api/presentation/2/context.json" || t["@context"].indexOf("http://iiif.io/api/presentation/2/context.json") !== -1 || t["@context"] === "http://www.shared-canvas.org/ns/context.json") || t["@context"] === "http://iiif.io/api/image/2/context.json" ? St.traverseUnknown(t) : t;
413
+ return t && t["@context"] && (t["@context"] === "http://iiif.io/api/presentation/2/context.json" || t["@context"].indexOf("http://iiif.io/api/presentation/2/context.json") !== -1 || t["@context"] === "http://www.shared-canvas.org/ns/context.json") || t["@context"] === "http://iiif.io/api/image/2/context.json" ? xt.traverseUnknown(t) : t;
413
414
  }
414
415
  function P(t) {
415
416
  if ((Array.isArray(t["@type"]) && t["@type"].includes("oa:SvgSelector") || t["@type"] == "oa:SvgSelector") && ("chars" in t || "value" in t)) return { type: "SvgSelector", value: "chars" in t ? t.chars : t.value };
@@ -421,10 +422,10 @@ function P(t) {
421
422
  function M(t) {
422
423
  return typeof t == "string" ? !1 : t && !t.type && "source" in t ? (t.type = "SpecificResource", !0) : !!t && t.type === "SpecificResource";
423
424
  }
424
- function T(...t) {
425
+ function x(...t) {
425
426
  return (e) => t.reduce((r, i) => i(r), e);
426
427
  }
427
- var V = ["Collection", "Manifest", "Canvas", "AnnotationPage", "AnnotationCollection", "Annotation", "ContentResource", "Range", "Service", "Selector", "Agent"];
428
+ var B = ["Collection", "Manifest", "Canvas", "AnnotationPage", "AnnotationCollection", "Annotation", "ContentResource", "Range", "Service", "Selector", "Agent"];
428
429
  function Tt(t, e) {
429
430
  if (typeof t > "u" || t === null) throw new Error("Null or undefined is not a valid entity.");
430
431
  if (Array.isArray(t)) throw new Error("Array is not a valid entity");
@@ -433,15 +434,15 @@ function Tt(t, e) {
433
434
  throw new Error(`${typeof t} is not a valid entity`);
434
435
  }
435
436
  if (typeof t.type == "string") {
436
- let r = V.indexOf(t.type);
437
- if (r !== -1) return V[r];
437
+ let r = B.indexOf(t.type);
438
+ if (r !== -1) return B[r];
438
439
  }
439
440
  if (t.profile) return "Service";
440
441
  throw new Error("Resource type is not known");
441
442
  }
442
443
  var D = class ie {
443
444
  constructor(e, r = {}) {
444
- b(this, "traversals"), b(this, "options"), b(this, "_traverseManifest", T(this.traverseManifestItems.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this), this.traverseLinkedCanvases.bind(this), this.traverseManifestStructures.bind(this), this.traverseInlineAnnotationPages.bind(this))), b(this, "_traverseCanvas", T(this.traverseCanvasItems.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this), this.traverseLinkedCanvases.bind(this), this.traverseInlineAnnotationPages.bind(this))), b(this, "_traverseAnnotationPage", T(this.traverseAnnotationPageItems.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this))), b(this, "_traverseRange", T(this.traverseRangeRanges.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this), this.traverseLinkedCanvases.bind(this))), this.traversals = { collection: [], manifest: [], canvas: [], annotationCollection: [], annotationPage: [], annotation: [], contentResource: [], choice: [], range: [], service: [], agent: [], specificResource: [], geoJson: [], ...e }, this.options = { allowUndefinedReturn: !1, ...r };
445
+ b(this, "traversals"), b(this, "options"), b(this, "_traverseManifest", x(this.traverseManifestItems.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this), this.traverseLinkedCanvases.bind(this), this.traverseManifestStructures.bind(this), this.traverseInlineAnnotationPages.bind(this))), b(this, "_traverseCanvas", x(this.traverseCanvasItems.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this), this.traverseLinkedCanvases.bind(this), this.traverseInlineAnnotationPages.bind(this))), b(this, "_traverseAnnotationPage", x(this.traverseAnnotationPageItems.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this))), b(this, "_traverseRange", x(this.traverseRangeRanges.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this), this.traverseLinkedCanvases.bind(this))), this.traversals = { collection: [], manifest: [], canvas: [], annotationCollection: [], annotationPage: [], annotation: [], contentResource: [], choice: [], range: [], service: [], agent: [], specificResource: [], geoJson: [], ...e }, this.options = { allowUndefinedReturn: !1, ...r };
445
446
  }
446
447
  static all(e) {
447
448
  return new ie({ collection: [e], manifest: [e], canvas: [e], annotationCollection: [e], annotationPage: [e], annotation: [e], contentResource: [e], choice: [e], range: [e], service: [e], geoJson: [e], specificResource: [e], agent: [e] });
@@ -570,16 +571,16 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
570
571
  return `${i}/full/full/0/default.jpg`;
571
572
  }
572
573
  return `${i}/full/!${e},${r}/0/default.jpg`;
573
- }, xt = (t, e, r) => {
574
+ }, $t = (t, e, r) => {
574
575
  const i = m(t, "id"), s = t.profile || "";
575
576
  if (typeof s == "string" && (s.includes("level0") || s.includes("level:0"))) return;
576
577
  const { x: o, y: c, w: a, h: l } = e, u = a / l, v = u < 1, d = Math.ceil(v ? r / u : r), p = Math.ceil(v ? r : r / u), f = `${Math.round(o)},${Math.round(c)},${Math.round(a)},${Math.round(l)}`;
577
578
  return `${i}/${f}/!${p},${d}/0/default.jpg`;
578
- }, $t = (t) => (e, r = 400) => {
579
+ }, Mt = (t) => (e, r = 400) => {
579
580
  if (t.type === "dynamic")
580
- return xt(t.service, e, r);
581
+ return $t(t.service, e, r);
581
582
  console.error("Level 0 or static image canvas: unsupported");
582
- }, Mt = (t, e = []) => (r = 400) => {
583
+ }, jt = (t, e = []) => (r = 400) => {
583
584
  const { width: i, height: s } = t;
584
585
  if (!i || !s) return;
585
586
  const n = i / s, o = n < 1, c = Math.ceil(o ? r / n : r), a = Math.ceil(o ? r : r / n);
@@ -598,7 +599,7 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
598
599
  if (l.type === "static")
599
600
  return l.url;
600
601
  }
601
- }, jt = (t, e = []) => (r = 800) => {
602
+ }, kt = (t, e = []) => (r = 800) => {
602
603
  const { width: i, height: s } = t;
603
604
  if (!i || !s) return;
604
605
  const n = i / s, o = n < 1, c = Math.ceil(o ? r / n : r), a = Math.ceil(o ? r : r / n);
@@ -608,21 +609,31 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
608
609
  if (l.type === "static")
609
610
  return l.url;
610
611
  }
611
- }, ae = (t) => t.endsWith("/info.json") ? t : `${t.endsWith("/") ? t : `${t}/`}info.json`, kt = (t) => {
612
+ }, ae = (t) => t.endsWith("/info.json") ? t : `${t.endsWith("/") ? t : `${t}/`}info.json`, Pt = (t) => () => fetch(t).then((e) => e.json()).then((e) => {
613
+ const r = e.width, i = e.height;
614
+ return r !== void 0 && i !== void 0 ? { width: r, height: i } : void 0;
615
+ }), Ot = (t) => () => {
616
+ const e = typeof window < "u";
617
+ return fetch(t).then((r) => r.blob()).then((r) => e ? createImageBitmap(r).then((i) => {
618
+ const { width: s, height: n } = i;
619
+ return i.close(), { width: s, height: n };
620
+ }) : r.arrayBuffer().then((i) => ce(new Uint8Array(i))));
621
+ }, Ut = (t) => {
612
622
  const { format: e, height: r, width: i } = t, s = m(t, "id"), n = (t.service || []).find(se), o = n ? ne(n) : void 0;
613
623
  if (o) {
614
- const c = {
624
+ const c = ae(m(n, "id")), a = {
615
625
  source: t,
616
626
  type: o.profileLevel === 0 ? "level0" : "dynamic",
617
627
  service: n,
618
628
  width: i,
619
629
  height: r,
620
630
  majorVersion: o.majorVersion,
621
- serviceUrl: ae(m(n, "id"))
631
+ serviceUrl: c,
632
+ getPixelSize: Pt(c)
622
633
  };
623
- return o.profileLevel === 0 ? c : {
624
- ...c,
625
- getRegionURL: $t(c)
634
+ return o.profileLevel === 0 ? a : {
635
+ ...a,
636
+ getRegionURL: Mt(a)
626
637
  };
627
638
  } else
628
639
  return {
@@ -631,19 +642,20 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
631
642
  width: i,
632
643
  height: r,
633
644
  url: s,
634
- format: e
645
+ format: e,
646
+ getPixelSize: Ot(s)
635
647
  };
636
- }, Pt = (t) => {
648
+ }, Dt = (t) => {
637
649
  const e = [];
638
650
  return new D({
639
651
  annotation: [(i) => {
640
652
  if (i.motivation === "painting" || !i.motivation) {
641
653
  const n = (i.body ? Array.isArray(i.body) ? i.body : [i.body] : []).filter((o) => o.type === "Image");
642
- e.push(...n.map((o) => kt(o)));
654
+ e.push(...n.map((o) => Ut(o)));
643
655
  }
644
656
  }]
645
657
  }).traverseCanvas(t), e;
646
- }, Ot = (t) => () => {
658
+ }, Nt = (t) => () => {
647
659
  const e = /* @__PURE__ */ new Map(), r = (a, l, u = 0) => {
648
660
  const v = {
649
661
  id: a.id,
@@ -658,8 +670,8 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
658
670
  };
659
671
  a.items && a.items.length > 0 && a.items.forEach((h) => {
660
672
  if (h.source.type === "Range") {
661
- const x = r(h, v, u + 1);
662
- v.children.push(x);
673
+ const T = r(h, v, u + 1);
674
+ v.children.push(T);
663
675
  } else {
664
676
  const L = {
665
677
  id: h.id,
@@ -690,7 +702,7 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
690
702
  const u = (v, d = []) => v.parent ? u(v.parent, [v, ...d]) : [v, ...d];
691
703
  return u(l);
692
704
  }, getNode: (a) => e.get(a) };
693
- }, Ut = async (t) => {
705
+ }, Et = async (t) => {
694
706
  try {
695
707
  new URL(t);
696
708
  } catch {
@@ -756,15 +768,15 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
756
768
  return m(t, "type").includes("Collection") ? {
757
769
  type: "collection",
758
770
  url: e || i,
759
- resource: Dt(t, s)
771
+ resource: qt(t, s)
760
772
  } : {
761
773
  type: "manifest",
762
774
  url: e || i,
763
- resource: Nt(t, s)
775
+ resource: _t(t, s)
764
776
  };
765
777
  }
766
778
  if (r.includes("image/2") || r.includes("image/3")) {
767
- const s = Et(t);
779
+ const s = Bt(t);
768
780
  return s ? {
769
781
  type: "iiif-image",
770
782
  url: e || i,
@@ -780,7 +792,7 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
780
792
  code: "INVALID_MANIFEST",
781
793
  message: "JSON resource is not a recognized IIIF format"
782
794
  };
783
- }, Dt = (t, e) => {
795
+ }, qt = (t, e) => {
784
796
  const r = (n) => {
785
797
  const o = [];
786
798
  return new D({
@@ -800,7 +812,7 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
800
812
  getLabel: S(i),
801
813
  getMetadata: j(i)
802
814
  };
803
- }, Nt = (t, e) => {
815
+ }, _t = (t, e) => {
804
816
  const r = (o) => {
805
817
  const c = [], a = [];
806
818
  new D({
@@ -812,7 +824,7 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
812
824
  }]
813
825
  }).traverseManifest(o);
814
826
  const u = c.map((p) => {
815
- const f = Pt(p);
827
+ const f = Dt(p);
816
828
  return {
817
829
  source: p,
818
830
  id: p.id,
@@ -820,18 +832,18 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
820
832
  height: p.height,
821
833
  images: f,
822
834
  annotations: p.annotations || [],
823
- getImageURL: jt(p, f),
835
+ getImageURL: kt(p, f),
824
836
  getLabel: S(p),
825
837
  getMetadata: j(p),
826
- getThumbnailURL: Mt(p, f)
838
+ getThumbnailURL: jt(p, f)
827
839
  };
828
840
  }), v = (p) => {
829
- const f = p.items || [], h = f.filter((y) => y.type === "Canvas").map((y) => u.find(($) => $.id === y.id)).filter(Boolean), L = f.filter((y) => y.type === "Range").map((y) => v(y)), x = [...h, ...L];
841
+ const f = p.items || [], h = f.filter((y) => y.type === "Canvas").map((y) => u.find(($) => $.id === y.id)).filter(Boolean), L = f.filter((y) => y.type === "Range").map((y) => v(y)), T = [...h, ...L];
830
842
  return {
831
843
  source: p,
832
844
  id: p.id,
833
845
  // Maintain original order
834
- items: f.map((y) => x.find(($) => $.id === y.id)),
846
+ items: f.map((y) => T.find(($) => $.id === y.id)),
835
847
  canvases: h,
836
848
  ranges: L,
837
849
  getLabel: S(p)
@@ -847,9 +859,9 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
847
859
  structure: n,
848
860
  getLabel: S(i),
849
861
  getMetadata: j(i),
850
- getTableOfContents: Ot(n)
862
+ getTableOfContents: Nt(n)
851
863
  };
852
- }, Et = (t) => {
864
+ }, Bt = (t) => {
853
865
  const { width: e, height: r } = t, i = ne(t);
854
866
  if (i)
855
867
  return {
@@ -860,20 +872,20 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
860
872
  majorVersion: i.majorVersion,
861
873
  serviceUrl: ae(m(t, "id"))
862
874
  };
863
- }, _t = { parse: oe, parseURL: Ut };
875
+ }, Wt = { parse: oe, parseURL: Et };
864
876
  export {
865
- _t as Cozy,
866
- jt as getImageURL,
877
+ Wt as Cozy,
878
+ kt as getImageURL,
867
879
  O as getImageURLFromService,
868
- Pt as getImages,
880
+ Dt as getImages,
869
881
  S as getLabel,
870
882
  j as getMetadata,
871
883
  m as getPropertyValue,
872
- $t as getRegionURL,
873
- xt as getRegionURLFromService,
874
- Wt as getStringValue,
875
- Ot as getTableOfContents,
876
- Mt as getThumbnailURL,
884
+ Mt as getRegionURL,
885
+ $t as getRegionURLFromService,
886
+ zt as getStringValue,
887
+ Nt as getTableOfContents,
888
+ jt as getThumbnailURL,
877
889
  se as isImageService,
878
890
  ae as normalizeServiceUrl,
879
891
  ne as parseImageService
@@ -1,3 +1,4 @@
1
+ import "image-size";
1
2
  import { g as $ } from "../resource-DS2brz47.js";
2
3
  const F = (t) => ({ id: $(t, "id"), ...t }), T = (t) => fetch(t.serviceUrl).then((e) => e.json()).then(F), P = new FinalizationRegistry(({ signal: t, aborted: e }) => {
3
4
  t == null || t.removeEventListener("abort", e);
@@ -92,7 +93,7 @@ const H = () => {
92
93
  });
93
94
  }
94
95
  return d;
95
- }, L = async (t, e) => {
96
+ }, O = async (t, e) => {
96
97
  const c = await T(t), i = R(c, e), r = document.createElement("canvas"), n = r.getContext("2d");
97
98
  if (!n)
98
99
  throw new Error("Error initializing canvas context");
@@ -164,7 +165,7 @@ const H = () => {
164
165
  });
165
166
  }
166
167
  return a;
167
- }, O = async (t, e) => {
168
+ }, X = async (t, e) => {
168
169
  const c = await T(t), i = k(c, e), r = b(c, e), n = document.createElement("canvas");
169
170
  n.width = r.width, n.height = r.height;
170
171
  const o = n.getContext("2d");
@@ -181,6 +182,6 @@ const H = () => {
181
182
  });
182
183
  };
183
184
  export {
184
- L as cropRegion,
185
- O as getThumbnail
185
+ O as cropRegion,
186
+ X as getThumbnail
186
187
  };
package/dist/types.d.ts CHANGED
@@ -61,6 +61,7 @@ export interface CozyCanvas {
61
61
  readonly height: number;
62
62
  readonly images: CozyImageResource[];
63
63
  readonly annotations: AnnotationPage[];
64
+ getImageURL(minSize?: number): string;
64
65
  getLabel(locale?: string): string;
65
66
  getMetadata(locale?: string): CozyMetadata[];
66
67
  getThumbnailURL(minSize?: number): string;
@@ -93,6 +94,10 @@ interface BaseImageResource {
93
94
  readonly type: 'static' | 'dynamic' | 'level0';
94
95
  readonly width: number;
95
96
  readonly height: number;
97
+ getPixelSize(): Promise<{
98
+ width: number;
99
+ height: number;
100
+ }>;
96
101
  }
97
102
  export interface StaticImageResource extends BaseImageResource {
98
103
  readonly type: 'static';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-iiif",
3
- "version": "0.2.6",
3
+ "version": "0.3.0",
4
4
  "description": "A developer-friendly collection of abstractions and utilities built on top of @iiif/presentation-3 and @iiif/parser",
5
5
  "license": "MIT",
6
6
  "author": "Rainer Simon",
@@ -30,11 +30,12 @@
30
30
  "devDependencies": {
31
31
  "vite": "^6.3.5",
32
32
  "vite-plugin-dts": "^4.5.4",
33
- "vitest": "^3.2.2"
33
+ "vitest": "^3.2.3"
34
34
  },
35
35
  "dependencies": {
36
36
  "@iiif/parser": "2.1.7",
37
37
  "@iiif/presentation-3": "^2.2.3",
38
+ "image-size": "^2.0.2",
38
39
  "p-throttle": "^7.0.0",
39
40
  "uuid": "^11.1.0"
40
41
  }
@@ -1,3 +1,4 @@
1
+ import { imageSize } from 'image-size';
1
2
  import type { Canvas, IIIFExternalWebResource } from '@iiif/presentation-3';
2
3
  import { Traverse } from '@iiif/parser';
3
4
  import { getPropertyValue } from './resource';
@@ -65,6 +66,30 @@ export const getImageURL = (canvas: Canvas, images: CozyImageResource[] = []) =>
65
66
  export const normalizeServiceUrl = (url: string) =>
66
67
  url.endsWith('/info.json') ? url : `${url.endsWith('/') ? url : `${url}/`}info.json`;
67
68
 
69
+ const getPixelSizeFromServiceUrl = (serviceUrl: string) => () =>
70
+ fetch(serviceUrl).then(res => res.json()).then(data => {
71
+ const width: number = data.width;
72
+ const height: number = data.height;
73
+ return (width !== undefined && height !== undefined) ? { width, height } : undefined;
74
+ });
75
+
76
+ const getStaticImagePixelSize = (url: string) => () => {
77
+ const isBrowser = typeof window !== 'undefined';
78
+
79
+ return fetch(url).then(res => res.blob()).then(blob => {
80
+ if (isBrowser) {
81
+ return createImageBitmap(blob).then(bitmap => {
82
+ const { width, height } = bitmap;
83
+ bitmap.close();
84
+ return { width, height }
85
+ });
86
+ } else {
87
+ return blob.arrayBuffer().then(buffer =>
88
+ imageSize(new Uint8Array(buffer)));
89
+ }
90
+ });
91
+ }
92
+
68
93
  const toCozyImageResource = (resource: IIIFExternalWebResource) => {
69
94
  const { format, height, width } = resource;
70
95
 
@@ -75,6 +100,8 @@ const toCozyImageResource = (resource: IIIFExternalWebResource) => {
75
100
  const service = imageService ? parseImageService(imageService) : undefined;
76
101
 
77
102
  if (service) {
103
+ const serviceUrl = normalizeServiceUrl(getPropertyValue<string>(imageService, 'id'));
104
+
78
105
  const image = {
79
106
  source: resource,
80
107
  type: service.profileLevel === 0 ? 'level0' : 'dynamic',
@@ -82,7 +109,8 @@ const toCozyImageResource = (resource: IIIFExternalWebResource) => {
82
109
  width,
83
110
  height,
84
111
  majorVersion: service.majorVersion,
85
- serviceUrl: normalizeServiceUrl(getPropertyValue<string>(imageService, 'id'))
112
+ serviceUrl,
113
+ getPixelSize: getPixelSizeFromServiceUrl(serviceUrl)
86
114
  } as ImageServiceResource;
87
115
 
88
116
  if (service.profileLevel === 0) {
@@ -100,7 +128,8 @@ const toCozyImageResource = (resource: IIIFExternalWebResource) => {
100
128
  width,
101
129
  height,
102
130
  url: id,
103
- format
131
+ format,
132
+ getPixelSize: getStaticImagePixelSize(id)
104
133
  } as StaticImageResource;
105
134
  }
106
135
  }
@@ -102,4 +102,4 @@ export const getRegionURL = (
102
102
  } else {
103
103
  console.error('Level 0 or static image canvas: unsupported');
104
104
  }
105
- }
105
+ }
package/src/types.ts CHANGED
@@ -99,6 +99,8 @@ export interface CozyCanvas {
99
99
 
100
100
  readonly annotations: AnnotationPage[];
101
101
 
102
+ getImageURL(minSize?: number): string;
103
+
102
104
  getLabel(locale?: string): string;
103
105
 
104
106
  getMetadata(locale?: string): CozyMetadata[];
@@ -167,6 +169,8 @@ interface BaseImageResource {
167
169
 
168
170
  readonly height: number;
169
171
 
172
+ getPixelSize(): Promise<{ width: number, height: number }>;
173
+
170
174
  }
171
175
 
172
176
  export interface StaticImageResource extends BaseImageResource {
@@ -0,0 +1,42 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { Cozy, CozyManifest } from '../../src';
3
+
4
+ import { STATIC_IMAGE, WITH_DIFFERENT_CANVAS_DIMENSIONS } from './fixtures';
5
+
6
+ describe('canvas', () => {
7
+
8
+ it('should determine correct pixel size for image service', async () => {
9
+ const result = await Cozy.parseURL(WITH_DIFFERENT_CANVAS_DIMENSIONS);
10
+ expect(result.type).toBe('manifest');
11
+ expect('resource' in result).toBeTruthy();
12
+
13
+ const manifest = (result as any).resource as CozyManifest;
14
+ expect(manifest.canvases.length).toBe(66);
15
+
16
+ const page2 = manifest.canvases[1];
17
+ expect(page2.getLabel()).toBe('Page 2');
18
+ expect(page2.images.length).toBe(1);
19
+
20
+ const image = page2.images[0];
21
+ const { width, height } = await image.getPixelSize();
22
+ expect(width).toBe(3796);
23
+ expect(height).toBe(5910);
24
+ });
25
+
26
+ it('should determine correct pixel size for static image', async () => {
27
+ const result = await Cozy.parseURL(STATIC_IMAGE);
28
+ expect(result.type).toBe('manifest');
29
+ expect('resource' in result).toBeTruthy();
30
+
31
+ const manifest = (result as any).resource as CozyManifest;
32
+ expect(manifest.canvases.length).toBe(1);
33
+
34
+ const image = manifest.canvases[0].images[0];
35
+ expect(image.type).toBe('static');
36
+
37
+ const { width, height } = await image.getPixelSize();
38
+ expect(width).toBe(1200);
39
+ expect(height).toBe(1800);
40
+ });
41
+
42
+ });
@@ -1,2 +1,12 @@
1
+ // IIIF cookbook static image
2
+ export const STATIC_IMAGE =
3
+ 'https://iiif.io/api/cookbook/recipe/0001-mvm-image/manifest.json';
4
+
5
+ // Manifest that uses `structures` to define a Table of Contents
1
6
  export const WITH_STRUCTURES =
2
- 'https://lib.is/IE19255085/manifest';
7
+ 'https://lib.is/IE19255085/manifest';
8
+
9
+ // Manifest that specifies a different size for the canvas
10
+ // then the physical image pixel size
11
+ export const WITH_DIFFERENT_CANVAS_DIMENSIONS =
12
+ 'https://www.loc.gov/item/00552972/manifest.json';
package/vite.config.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { defineConfig } from 'vite';
2
- import { resolve } from 'path';
3
2
  import dts from 'vite-plugin-dts';
4
3
 
5
4
  export default defineConfig({
@@ -7,11 +6,14 @@ export default defineConfig({
7
6
  build: {
8
7
  lib: {
9
8
  entry: {
10
- 'index': resolve(__dirname, 'src/index.ts'),
11
- 'helpers/index': resolve(__dirname, 'src/helpers/index.ts'),
12
- 'level-0/index': resolve(__dirname, 'src/level-0/index.ts'),
9
+ 'index': './src/index.ts',
10
+ 'helpers/index': './src/helpers/index.ts',
11
+ 'level-0/index': './src/level-0/index.ts',
13
12
  },
14
13
  formats: ['es']
14
+ },
15
+ rollupOptions: {
16
+ external: ['image-size']
15
17
  }
16
18
  }
17
19
  });