Skip to content

search: a derive can no longer read a Reference Type entry’s node IRI – LOL loses iiifManifest on 0.26.0 #842

Closed

Description

@ddeboer

#832 says nothing read a Reference Type entry’s id. One thing did: a derive.

Linked Open Limburg derives iiifManifest from the projected associatedMedia entries: the one whose encodingFormat names the IIIF Presentation context, returning that entry’s id. SCHEMA-AP-NDE § 4.2.6 puts the manifest URI in the node’s @id and nowhere else – no contentUrl, no url. Under @lde/search 0.26.0 the entry arrives as { encodingFormat: [...] } and the derive returns undefined, so every work in every collection would go out with iiifManifest: null – seen in the projection test below, not yet in a deployed index, because LOL is still on 0.25.0. Both routes are hit: the conformant associatedMedia entry (Drapo) and the pre-v0.6.0 isBasedOn target the derive falls back to (Limburgs Museum, Discovery Museum).

Nothing in @lde/search caught it because the id was dropped from the projection tests. In LOL it went unnoticed because the derive’s unit test hand-builds the document with an id on the entry. A test through projectRoots fails on 0.26.0 and passes on 0.25.0: limburg/lol#173.

What LOL needs

A declared way for a Reference Type entry to carry the IRI of the node it was projected from, so a derive can read it. The two escape hatches named in the reference do not cover this:

  • an idOnly reference over the same path gives a flat list of media IRIs beside the entries – parallel arrays a derive would have to pair by index, which is the shape fix(search)!: fan out a qualified edge into one entry per tuple #801 took out of CreatorRole
  • the identity companion of an inline reference is likewise flat on the referrer, and only where the field is filterable

Two directions I can see; which fits the model is for you to decide:

  1. A field kind or path that projects the node’s own IRI under a declared name – say { name: 'url', kind: 'iri', path: '@id' } on MediaObject. The collection then declares the field, which was the complaint in fix(search)!: give a Reference Type's entries no id #832, and an entry’s shape stays the same for a blank node (field absent) as for any other optional field.
  2. Keep fix(search)!: give a Reference Type's entries no id #832 as it is and have a derive reach the framed node rather than the projected entry. That is a bigger change to what a derive sees.

Until one lands, LOL cannot take 0.26.0 without losing the manifest on every work.

Activity

  1. added theissue type on Sep 9, 2026
  2. ddeboer commented on Sep 9, 2026

    @ddeboer
    MemberAuthor

    Decision, after working it through against the data: the id stays off by default, and a Reference Type opts back in with identified: true.

    Why not the @id path from direction 1: it makes the caller choose a name, a kind and roles that all come out the same for every type in this class, and it needs the reader to skip a field that binds no triple. One bit on the type hides all of that. Why not default on: LOL’s own numbers say 132 of Limburgs Museum’s 291 creator roles are named nodes and all 17 of Discovery Museum’s are blank, so a default that keeps the id would put #832’s two-shapes problem straight back into the collection it was found in.

    Named identified rather than identity, because ref.identity already means the flat companion.

    PR follows.

  3. ddeboer commented on Sep 9, 2026

    @ddeboer
    MemberAuthor

    Revised after more thought: no flag after all. The node IRI becomes a reading device, the same rule an internal field already follows. Every entry carries it as id while the referrer’s derives run, and the internal-field prune removes it before the document leaves the projection, so the index and the API never see it and two edge nodes stating one fact still collapse into one entry. Nothing to declare, and the surface #832 defined is unchanged.

    The flag would have taught schema authors a new member, and every name for it collided with ref.identity. What it could do that this cannot is expose a nested node’s IRI in the API per entry, which nobody has asked for.

    #843 is rewritten accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions