From 3914f783fc799bbcb456b5c5539cd6f94a815835 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Feb 2026 05:02:27 +0000 Subject: [PATCH 1/5] Initial plan From 52b5f323a785e44156f914e67f43b2aaaf6840f7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Feb 2026 05:04:43 +0000 Subject: [PATCH 2/5] Fix IIIF v2 prefix handling in type normalization Co-authored-by: cubap <1119165+cubap@users.noreply.github.com> --- js/vault.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/js/vault.js b/js/vault.js index 89809aa6..3d9a9083 100644 --- a/js/vault.js +++ b/js/vault.js @@ -8,7 +8,15 @@ class Vault { } _normalizeType(type) { - return (type ?? '').toString().toLowerCase() || 'none' + if (!type) return 'none' + let normalized = type.toString() + + // Strip known IIIF prefixes (sc:, oa:, as:, etc.) before lowercasing + // This ensures both 'sc:Canvas' and 'Canvas' normalize to 'canvas' + const prefixPattern = /^(sc|oa|as|dcterms|exif|iiif|cnt|dctypes|foaf|rdf|rdfs|svcs|xsd):/i + normalized = normalized.replace(prefixPattern, '') + + return normalized.toLowerCase() || 'none' } _isMongoHexString(str) { @@ -100,8 +108,8 @@ class Vault { const iiifResourceTypes = new Set([ 'manifest', 'collection', 'canvas', 'annotation', 'annotationpage', 'annotationcollection', 'range', - 'agent', 'annotationlist', 'sc:manifest', 'oa:annotationlist', - 'oa:annotation' + 'agent', 'annotationlist', 'layer', 'sequence', + 'content', 'choice', 'specificresource' ]) const dataType = this._normalizeType(data?.['@type'] ?? data?.type ?? type) From 141cb16e24963afd15fc9ece945d290e16a691fb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Feb 2026 05:05:37 +0000 Subject: [PATCH 3/5] Move prefix pattern to class constant and document resource types Co-authored-by: cubap <1119165+cubap@users.noreply.github.com> --- js/vault.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/js/vault.js b/js/vault.js index 3d9a9083..faa41110 100644 --- a/js/vault.js +++ b/js/vault.js @@ -2,6 +2,10 @@ import TPEN from "../api/TPEN.js" import { urlFromIdAndType } from "../js/utils.js" class Vault { + // Regex pattern to match and strip known IIIF and RDF prefixes + // Compiled once to avoid overhead on repeated calls + static PREFIX_PATTERN = /^(sc|oa|as|dcterms|exif|iiif|cnt|dctypes|foaf|rdf|rdfs|svcs|xsd):/i + constructor() { this.store = new Map() this.inFlightPromises = new Map() @@ -13,8 +17,7 @@ class Vault { // Strip known IIIF prefixes (sc:, oa:, as:, etc.) before lowercasing // This ensures both 'sc:Canvas' and 'Canvas' normalize to 'canvas' - const prefixPattern = /^(sc|oa|as|dcterms|exif|iiif|cnt|dctypes|foaf|rdf|rdfs|svcs|xsd):/i - normalized = normalized.replace(prefixPattern, '') + normalized = normalized.replace(Vault.PREFIX_PATTERN, '') return normalized.toLowerCase() || 'none' } @@ -105,6 +108,13 @@ class Vault { 'motivation', 'purpose', 'profile' ]) + // IIIF resource types that should be fetched and hydrated + // Includes types from both IIIF Presentation API v2 and v3: + // - Core types: manifest, collection, canvas, range + // - Annotation types: annotation, annotationpage, annotationcollection, annotationlist + // - v2 specific: sequence, layer (structural constructs) + // - Content types: content, choice, specificresource (for media content and targeting) + // - Other: agent (metadata about people/organizations) const iiifResourceTypes = new Set([ 'manifest', 'collection', 'canvas', 'annotation', 'annotationpage', 'annotationcollection', 'range', From c3736b3fff047aa5d29fe12c2bea8288cc80b6e2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Feb 2026 05:22:21 +0000 Subject: [PATCH 4/5] Revert prefix stripping; explicitly add IIIF v2 prefixed types Co-authored-by: cubap <1119165+cubap@users.noreply.github.com> --- js/vault.js | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/js/vault.js b/js/vault.js index faa41110..9045d771 100644 --- a/js/vault.js +++ b/js/vault.js @@ -2,24 +2,13 @@ import TPEN from "../api/TPEN.js" import { urlFromIdAndType } from "../js/utils.js" class Vault { - // Regex pattern to match and strip known IIIF and RDF prefixes - // Compiled once to avoid overhead on repeated calls - static PREFIX_PATTERN = /^(sc|oa|as|dcterms|exif|iiif|cnt|dctypes|foaf|rdf|rdfs|svcs|xsd):/i - constructor() { this.store = new Map() this.inFlightPromises = new Map() } _normalizeType(type) { - if (!type) return 'none' - let normalized = type.toString() - - // Strip known IIIF prefixes (sc:, oa:, as:, etc.) before lowercasing - // This ensures both 'sc:Canvas' and 'Canvas' normalize to 'canvas' - normalized = normalized.replace(Vault.PREFIX_PATTERN, '') - - return normalized.toLowerCase() || 'none' + return (type ?? '').toString().toLowerCase() || 'none' } _isMongoHexString(str) { @@ -108,18 +97,19 @@ class Vault { 'motivation', 'purpose', 'profile' ]) - // IIIF resource types that should be fetched and hydrated - // Includes types from both IIIF Presentation API v2 and v3: - // - Core types: manifest, collection, canvas, range - // - Annotation types: annotation, annotationpage, annotationcollection, annotationlist - // - v2 specific: sequence, layer (structural constructs) - // - Content types: content, choice, specificresource (for media content and targeting) - // - Other: agent (metadata about people/organizations) + // IIIF resource types for both Presentation API v2 (prefixed) and v3 (unprefixed) + // v3 types: manifest, collection, canvas, annotation, annotationpage, etc. + // v2 types use prefixes: sc: (Shared Canvas), oa: (Open Annotation) const iiifResourceTypes = new Set([ + // IIIF Presentation API v3 (unprefixed) 'manifest', 'collection', 'canvas', 'annotation', 'annotationpage', 'annotationcollection', 'range', - 'agent', 'annotationlist', 'layer', 'sequence', - 'content', 'choice', 'specificresource' + 'agent', 'annotationlist', + // IIIF Presentation API v2 (sc: prefix for Shared Canvas types) + 'sc:manifest', 'sc:collection', 'sc:canvas', 'sc:sequence', + 'sc:range', 'sc:layer', + // Open Annotation (oa: prefix) + 'oa:annotation', 'oa:annotationlist' ]) const dataType = this._normalizeType(data?.['@type'] ?? data?.type ?? type) From 261e85a9084153e0a486dba11c3556897f24f3b8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Feb 2026 05:24:00 +0000 Subject: [PATCH 5/5] Clarify documentation for agent and annotationlist types Co-authored-by: cubap <1119165+cubap@users.noreply.github.com> --- js/vault.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/js/vault.js b/js/vault.js index 9045d771..7c97d54a 100644 --- a/js/vault.js +++ b/js/vault.js @@ -98,18 +98,18 @@ class Vault { ]) // IIIF resource types for both Presentation API v2 (prefixed) and v3 (unprefixed) - // v3 types: manifest, collection, canvas, annotation, annotationpage, etc. // v2 types use prefixes: sc: (Shared Canvas), oa: (Open Annotation) + // v3 types are unprefixed const iiifResourceTypes = new Set([ // IIIF Presentation API v3 (unprefixed) 'manifest', 'collection', 'canvas', 'annotation', 'annotationpage', 'annotationcollection', 'range', - 'agent', 'annotationlist', + 'agent', // v3 metadata type for providers/creators // IIIF Presentation API v2 (sc: prefix for Shared Canvas types) 'sc:manifest', 'sc:collection', 'sc:canvas', 'sc:sequence', 'sc:range', 'sc:layer', - // Open Annotation (oa: prefix) - 'oa:annotation', 'oa:annotationlist' + // Open Annotation (oa: prefix) - v2 annotation types + 'oa:annotation', 'oa:annotationlist' // annotationlist is v2; becomes annotationpage in v3 ]) const dataType = this._normalizeType(data?.['@type'] ?? data?.type ?? type)