Skip to content

IIIF-Commons/iiif-helpers

Repository files navigation

@iiif/helpers

@iiif/helpers is a TypeScript utility library for building IIIF applications.

It combines:

  • pure helpers for annotation targets, content state, language maps, and image services
  • higher-level helpers for thumbnails, painting annotations, ranges, search, navDate, and transcriptions
  • a normalized IIIF vault/store layer for loading, editing, serializing, and subscribing to IIIF resources

This repository publishes one npm package, @iiif/helpers, with a set of focused subpath entry points such as @iiif/helpers/thumbnail and @iiif/helpers/vault/store.

What The Library Covers

  • IIIF Presentation 2 and 3 loading, upgrading, and normalization
  • normalized storage and mutation of IIIF entities through the Vault
  • selector parsing for xywh, temporal fragments, Image API selectors, and SVG selectors
  • IIIF Content State parsing, encoding, decoding, validation, and normalization
  • language map selection and localization helpers
  • thumbnail and image-service candidate selection
  • painting annotation extraction, choice handling, and media discovery
  • range traversal, table-of-contents generation, and sequence calculation
  • Search API 1 search/autocomplete stores
  • transcript discovery and extraction from plain text, VTT, and supplemental annotations
  • vault-backed UI glue for events and styles

Installation

@iiif/parser is a peer dependency and should be installed alongside the helpers package.

npm install @iiif/helpers @iiif/parser
pnpm add @iiif/helpers @iiif/parser
yarn add @iiif/helpers @iiif/parser

Notes:

  • The package ships ESM, CJS, and TypeScript declarations for each public entry point.
  • If you parse SVG selectors in Node, provide a DOMParser implementation such as jsdom or happy-dom.
  • If you use remote loading in Node, a modern runtime with built-in fetch is the simplest setup.

Import Strategy

Use the root package when you want the common surface area:

import { Vault, createThumbnailHelper, getValue, expandTarget } from '@iiif/helpers';

Use subpath imports when you want a smaller, more explicit import surface or when you need packages that are not re-exported from the root:

import { getCanvasTranscription } from '@iiif/helpers/transcriptions';
import { createStore } from '@iiif/helpers/vault/store';
import { entityActions } from '@iiif/helpers/vault/actions';
import { Vault as NodeVault } from '@iiif/helpers/vault-node';

The root entry point re-exports the main helper packages, but it does not re-export:

  • @iiif/helpers/transcriptions
  • @iiif/helpers/vault-node
  • @iiif/helpers/vault/actions
  • @iiif/helpers/vault/store
  • @iiif/helpers/vault/utility
  • @iiif/helpers/vault/global-vault

Quick Start

import { Vault, getValue, createThumbnailHelper } from '@iiif/helpers';

const vault = new Vault();
const manifest = await vault.loadManifest('https://iiif.io/api/cookbook/recipe/0005-image-service/manifest.json');

if (!manifest) {
  throw new Error('Manifest failed to load');
}

const firstCanvas = vault.get(manifest.items[0]);
const label = getValue(manifest.label, { language: 'en-GB' });

const thumbnails = await createThumbnailHelper(vault).getBestThumbnailAtSize(firstCanvas, {
  width: 300,
  height: 300,
});

console.log(label);
console.log(thumbnails.best);

Entry Points

The package is organized as subpath exports. The table below is the complete public entry-point map from package.json.

Entry point Re-exported from @iiif/helpers Purpose
@iiif/helpers n/a Convenience entry point for the main helpers.
@iiif/helpers/events Yes Vault-backed event registration for IIIF resources.
@iiif/helpers/i18n Yes Language map and localization helpers.
@iiif/helpers/styles Yes Vault-backed style metadata helpers.
@iiif/helpers/thumbnail Yes Best-thumbnail resolution for collections, manifests, canvases, annotations, and resources.
@iiif/helpers/annotation-targets Yes Selector and target parsing for IIIF and W3C annotations.
@iiif/helpers/content-state Yes Content State parsing, encoding, decoding, and normalization.
@iiif/helpers/fetch Yes Fetch and upgrade Presentation manifests and collections.
@iiif/helpers/painting-annotations Yes Painting annotation flattening and choice/media extraction.
@iiif/helpers/ranges Yes Range traversal, TOC generation, and range selection helpers.
@iiif/helpers/sequences Yes Visible-canvas and page-order helpers for paged/continuous/individuals behavior.
@iiif/helpers/search1 Yes Search API 1 search and autocomplete stores.
@iiif/helpers/image-service Yes Image-service loading, prediction, candidate extraction, and selection.
@iiif/helpers/nav-date Yes Date-navigation trees from navDate values.
@iiif/helpers/vault Yes Core Vault class, types, and singleton helper.
@iiif/helpers/vault-node No Node-oriented Vault with fetch support.
@iiif/helpers/vault/global-vault No Global singleton bridge for browser-global environments.
@iiif/helpers/vault/actions No Action constants and creators for vault state updates.
@iiif/helpers/vault/store No Zustand-based store factory and reducers used by the vault.
@iiif/helpers/vault/utility No Lower-level helpers for fetch pipelines and store access.
@iiif/helpers/transcriptions No Transcript detection and extraction helpers.

Package Reference

@iiif/helpers

The root entry point is a convenience export for the most commonly used helpers. It re-exports:

  • events
  • styles
  • thumbnail
  • i18n
  • content-state
  • annotation-targets
  • painting-annotations
  • ranges
  • sequences
  • vault
  • fetch
  • search1
  • nav-date
  • image-service

Use it when you want a single import surface for most browser-side work.

@iiif/helpers/annotation-targets

This package normalizes IIIF and W3C annotation targets into a predictable SpecificResource-shaped structure.

Key exports:

  • expandTarget
  • parseSelector
  • parseRotation
  • splitCanvasFragment
  • isImageApiSelector
  • isValidCanvasFragment
  • selector and target result types such as SupportedTarget, BoxSelector, PointSelector, SvgSelector, TemporalSelector, and TemporalBoxSelector

What it handles:

  • plain canvas ids
  • #xywh= fragments
  • temporal fragments such as #t=...
  • SpecificResource targets
  • Image API selectors
  • SVG selectors with normalized geometry and extracted style data
  • targets with embedded selector fragments in source.id

Important notes:

  • SVG selector parsing is best in the browser or with a provided DOMParser.
  • The returned structure is designed to be easier to render than raw W3C selectors.
  • expandTarget() always returns a type: 'SpecificResource' shape with source, selector, and selectors.

Example:

import { expandTarget } from '@iiif/helpers/annotation-targets';

const target = expandTarget('https://example.org/canvas-1#xywh=100,200,300,400');

console.log(target.selector?.type);
// BoxSelector

Selector-only example:

import { parseSelector } from '@iiif/helpers/annotation-targets';

const parsed = parseSelector({
  type: 'FragmentSelector',
  value: 'xywh=10,20,300,400&t=5,12.5',
});

console.log(parsed.selector);
// {
//   type: 'TemporalBoxSelector',
//   spatial: { x: 10, y: 20, width: 300, height: 400, unit: 'pixel' },
//   temporal: { startTime: 5, endTime: 12.5 }
// }

@iiif/helpers/content-state

This package works with IIIF Content State values.

Key exports:

  • parseContentState
  • serialiseContentState
  • encodeContentState
  • decodeContentState
  • validateContentState
  • normaliseContentState
  • related types such as ContentState, StateSource, and NormalisedContentState

What it does:

  • parses already-decoded JSON strings
  • parses base64url-encoded content state strings
  • optionally fetches remote content state resources when called asynchronously
  • encodes and decodes content state payloads
  • normalizes different content state shapes into a consistent annotation form

Important notes:

  • Validation is intentionally light-weight at the moment. It should be treated as a sanity check rather than full spec enforcement.
  • Normalization uses the annotation-target helpers internally, so spatial selectors become structured selector objects instead of raw fragments.

Example:

import {
  parseContentState,
  serialiseContentState,
  validateContentState,
  normaliseContentState,
} from '@iiif/helpers/content-state';

const encoded = serialiseContentState({
  id: 'https://example.org/canvas-1#xywh=100,200,300,400',
  type: 'Canvas',
  partOf: [{ id: 'https://example.org/manifest-1', type: 'Manifest' }],
});

const parsed = parseContentState(encoded);
const [valid, error] = validateContentState(parsed, true);

if (!valid) {
  throw new Error(error?.reason ?? 'Invalid content state');
}

const normalized = normaliseContentState(parsed);
console.log(normalized.target[0].selector);

@iiif/helpers/events

This is a small vault-backed event registry for IIIF resources.

Key exports:

  • createEventsHelper

The helper gives you:

  • addEventListener(resource, event, listener, scope?)
  • removeEventListener(resource, event, listener)
  • getListenersAsProps(resourceOrId, scope?)

It stores event handlers in vault meta so you can attach UI behavior to resources before they are rendered. This is especially useful in component-based UIs where passing callbacks down through many layers would otherwise be awkward.

Example:

import { Vault } from '@iiif/helpers';
import { createEventsHelper } from '@iiif/helpers/events';

const vault = new Vault();
const events = createEventsHelper(vault);
const annotation = { id: 'https://example.org/annotation/1', type: 'Annotation' };

events.addEventListener(annotation, 'onClick', (_event, resource) => {
  console.log('Clicked', resource.id);
});

const props = events.getListenersAsProps(annotation);

// React:
// <div {...props} />

// DOM:
// element.addEventListener('click', props.onClick);

@iiif/helpers/fetch

This package exports a single helper:

  • fetch

It fetches a Manifest or Collection and upgrades the response through @iiif/parser/upgrader, which makes it convenient when you want to support both Presentation 2 and Presentation 3 sources before loading them into a vault.

Example:

import { fetch as fetchIiif } from '@iiif/helpers/fetch';

const resource = await fetchIiif('https://example.org/manifest.json');

@iiif/helpers/i18n

This package contains language-map helpers and a simple template-tag helper for localized strings.

Key exports:

  • getClosestLanguage
  • buildLocaleString
  • getValue
  • getAvailableLanguagesFromResource
  • createStringHelper
  • iiifString

Typical uses:

  • select the best value from an IIIF language map
  • apply explicit fallback languages
  • detect languages used anywhere inside a collection, manifest, canvas, or range
  • build localized labels inline with template literals

Example:

import { getValue, iiifString } from '@iiif/helpers/i18n';

const label = getValue({ fr: ['Titre'], en: ['Title'] }, { language: 'fr' });
const summary = iiifString`Label: ${{ en: ['An English label'] }}`;

Fallback example:

import { buildLocaleString } from '@iiif/helpers/i18n';

const label = buildLocaleString(
  { en: ['English title'], fr: ['Titre francais'], none: ['Untitled'] },
  'cy-GB',
  {
    fallbackLanguages: ['en-GB', 'en'],
    defaultText: 'Untitled manifest',
  }
);

@iiif/helpers/image-service

This is the low-level image-service package used by the thumbnail helpers and useful on its own when you need to inspect or select image delivery options.

Key exports:

  • ImageServiceLoader
  • createImageServiceStore
  • imageServices
  • getImageCandidates
  • getImageCandidatesFromService
  • getFixedSizeFromImage
  • getFixedSizesFromService
  • getCustomSizeFromService
  • getImageFromTileSource
  • getImageServerFromId
  • getSmallestScaleFactorAsSingleImage
  • pickBestFromCandidates
  • imageSizesMatch
  • inferImageSizeFromUrl
  • sampledTilesToTiles
  • isImage3
  • isBestMatch
  • image candidate/result types

What it is good for:

  • turning content resources and image services into a ranked set of image candidates
  • picking the best candidate for a desired width/height or min/max constraints
  • preloading or sampling image service responses
  • predicting compatible services on known image servers to reduce repeated network work
  • exposing service-loading state through a vanilla Zustand store

Important notes:

  • ImageServiceLoader has both synchronous and asynchronous loading paths.
  • The store returned by createImageServiceStore() includes both a Zustand store and an event emitter.
  • The candidate model distinguishes fixed images, fixed-size services, variable services, and unknown-size images.

Example:

import {
  ImageServiceLoader,
  getImageCandidates,
  pickBestFromCandidates,
} from '@iiif/helpers/image-service';

const loader = new ImageServiceLoader();

const resource = {
  id: 'https://example.org/image/full/max/0/default.jpg',
  type: 'Image',
  width: 1200,
  height: 800,
  service: [
    {
      id: 'https://example.org/image',
      type: 'ImageService3',
      profile: 'level1',
    },
  ],
} as any;

const candidates = getImageCandidates(resource, false, loader);
const choice = pickBestFromCandidates({ width: 300, height: 200 }, [() => candidates]);

console.log(choice.best);
console.log(choice.fallback);

@iiif/helpers/nav-date

This package builds navigation trees from navDate.

Key exports:

  • createDateNavigation
  • date-navigation types such as DateNavigationCentury, DateNavigationDecade, DateNavigationYear, DateNavigationMonth, and DateNavigationDay

How it behaves:

  • it reads navDate values from items in a Collection or Manifest
  • it groups them into century, decade, year, month, and day buckets
  • if you do not pass an explicit level, it automatically collapses through single-item levels and returns the most useful level

Use it when you want archive-style time browsing or date facets built directly from IIIF metadata.

Example:

import { Vault } from '@iiif/helpers';
import { createDateNavigation } from '@iiif/helpers/nav-date';

const vault = new Vault();
const collection = vault.loadSync('https://example.org/collection', {
  id: 'https://example.org/collection',
  type: 'Collection',
  label: { en: ['Archive'] },
  items: [
    {
      id: 'https://example.org/manifest/1986',
      type: 'Manifest',
      label: { en: ['Issue 1986'] },
      navDate: '1986-01-01T00:00:00+00:00',
    },
    {
      id: 'https://example.org/manifest/1987',
      type: 'Manifest',
      label: { en: ['Issue 1987'] },
      navDate: '1987-01-01T00:00:00+00:00',
    },
  ],
});

const years = createDateNavigation(vault, collection!, 'year');

for (const year of years) {
  console.log(year.label.en?.[0], year.count);
}

@iiif/helpers/painting-annotations

This package is for flattening painting annotations into a simpler renderable structure.

Key exports:

  • createPaintingAnnotationsHelper
  • parseSpecificResource
  • Paintables
  • choice-related types such as SingleChoice, ComplexChoice, and ChoiceDescription

The helper gives you:

  • getAllPaintingAnnotations(canvasOrId)
  • getPaintables(canvasOrAnnotations, enabledChoices?)
  • extractChoices(canvasOrAnnotations)

What it does:

  • resolves all painting annotations on a canvas
  • unwraps SpecificResource bodies
  • handles Choice bodies and records the available/selected choices
  • returns a list of paintable resources with their original annotation, target, selector, and normalized type

This is useful when you are rendering mixed media, alternative image choices, or need a flat list of paintable bodies from a canvas.

Example:

import { Vault } from '@iiif/helpers';
import { createPaintingAnnotationsHelper } from '@iiif/helpers/painting-annotations';

const vault = new Vault();
const manifest = await vault.loadManifest('https://example.org/manifest.json');

if (!manifest) {
  throw new Error('Manifest failed to load');
}

const canvas = vault.get(manifest.items[0]);
const painting = createPaintingAnnotationsHelper(vault);
const paintables = painting.getPaintables(canvas);

console.log(paintables.types);
console.log(paintables.choice);

for (const item of paintables.items) {
  console.log(item.type, item.resource.id, item.selector);
}

@iiif/helpers/ranges

This package covers traversal and interpretation of IIIF ranges.

Key exports:

  • createRangeHelper
  • findFirstCanvasFromRange
  • findFirstCanvasFromRangeWithSelector
  • findAllCanvasesInRange
  • findManifestSelectedRange
  • findSelectedRange
  • rangeToTableOfContentsTree
  • rangesToTableOfContentsTree
  • isRangeContiguous
  • RangeTableOfContentsNode

What it is good for:

  • finding the first canvas represented by a range
  • flattening all canvases found inside nested ranges
  • determining which range contains a given canvas
  • building a nested table-of-contents tree with canvas leaves and parent links
  • checking whether a range is contiguous within a known canvas order, including gap and subset reporting

Important notes:

  • rangeToTableOfContentsTree() creates a structured tree that is ready to render.
  • rangesToTableOfContentsTree() creates a virtual root when you pass multiple top-level ranges.
  • isRangeContiguous() can optionally return detailed diagnostics about invalid ranges, missing canvases, and gaps.

Example:

import { Vault } from '@iiif/helpers';
import {
  rangeToTableOfContentsTree,
  isRangeContiguous,
} from '@iiif/helpers/ranges';

const vault = new Vault();
const manifest = await vault.loadManifest('https://example.org/manifest.json');

if (!manifest || !manifest.structures?.length) {
  throw new Error('Manifest has no ranges');
}

const range = vault.get(manifest.structures[0]);
const toc = rangeToTableOfContentsTree(vault, range);
const [isContiguous, detail] = isRangeContiguous(vault, range, manifest.items, { detail: true });

console.log(toc?.items?.map((item) => item.label));
console.log(isContiguous, detail?.gaps);

@iiif/helpers/search1

This package contains helpers for IIIF Search API 1.

Key exports:

  • findSearch1Service
  • findAutocompleteService
  • createSearch1Store
  • createSearch1AutocompleteStore
  • store types such as Search1Store, Search1AutocompleteStore, Search1Service, and SingleSearchHit

What it provides:

  • a search store that queries a Search API 1 service, keeps resources and hits, and supports hit highlighting
  • an autocomplete store that queries autocomplete endpoints and keeps a result list
  • automatic aborting of in-flight requests when a new search replaces an old one

Example:

import {
  createSearch1Store,
  createSearch1AutocompleteStore,
} from '@iiif/helpers/search1';

const service = {
  '@id': 'https://example.org/search',
  profile: 'http://iiif.io/api/search/1/search',
  service: {
    '@id': 'https://example.org/search/autocomplete',
    profile: 'http://iiif.io/api/search/1/autocomplete',
  },
} as any;

const store = createSearch1Store(service);
await store.getState().search({ q: '1615' });
store.getState().highlightHit(0);

const autocomplete = createSearch1AutocompleteStore(service);
await autocomplete.getState().search('wunder');

@iiif/helpers/sequences

This package calculates visible canvases and page order from IIIF behavior.

Key exports:

  • createSequenceHelper
  • getVisibleCanvasesFromCanvasId
  • getManifestSequence

It understands manifest and range behaviors such as:

  • paged
  • continuous
  • individuals
  • canvas-level facing-pages
  • canvas-level non-paged

Use it when you need to answer questions like:

  • which canvases should be visible when canvas X is selected?
  • what are the page groups for a paged interface?
  • should this manifest render as single pages, spreads, or one continuous strip?

Example:

import { Vault } from '@iiif/helpers';
import {
  getManifestSequence,
  getVisibleCanvasesFromCanvasId,
} from '@iiif/helpers/sequences';

const vault = new Vault();
const manifest = await vault.loadManifest('https://example.org/manifest.json');

if (!manifest) {
  throw new Error('Manifest failed to load');
}

const [items, pageGroups] = getManifestSequence(vault, manifest);
const visible = getVisibleCanvasesFromCanvasId(vault, manifest, items[0].id);

console.log(pageGroups);
console.log(visible);

@iiif/helpers/styles

This is a small vault-backed style metadata helper.

Key exports:

  • createStylesHelper
  • StyleDefinition
  • StyledHelper

The helper gives you:

  • applyStyles(resource, scope, styles)
  • getAppliedStyles(resource)

It is useful when style information lives outside the IIIF resource but still needs to follow the same resource ids, for example annotation colors, highlight state, or editor-only presentation metadata.

Example:

import { Vault } from '@iiif/helpers';
import { createStylesHelper } from '@iiif/helpers/styles';

const vault = new Vault();
const styles = createStylesHelper(vault);
const annotation = { id: 'https://example.org/annotation/1', type: 'Annotation' };

vault.batch(() => {
  styles.applyStyles(annotation, 'selected', { background: 'red' });
  styles.applyStyles(annotation, 'hovered', { background: 'pink' });
});

console.log(styles.getAppliedStyles(annotation));

@iiif/helpers/thumbnail

This package is the high-level thumbnail helper built on top of the image-service utilities.

Key exports:

  • getThumbnail
  • createThumbnailHelper
  • imageServiceLoader
  • thumbnail input/output types

What it accepts:

  • string ids or URLs
  • collection, manifest, canvas, annotation, annotation page, and content-resource references
  • normalized IIIF resources

What it returns:

  • best: the chosen thumbnail candidate
  • fallback: other viable candidates
  • log: explanation messages from the candidate-selection process

What it does:

  • follows explicit thumbnail properties where present
  • falls back to painted resources when needed
  • dereferences and inspects image services when appropriate
  • chooses the best available result for a requested size or constraint set

Example:

import { Vault } from '@iiif/helpers';
import { createThumbnailHelper, getThumbnail } from '@iiif/helpers/thumbnail';

const vault = new Vault();
const manifest = await vault.loadManifest('https://example.org/manifest.json');

if (!manifest) {
  throw new Error('Manifest failed to load');
}

const canvas = vault.get(manifest.items[0]);
const helper = createThumbnailHelper(vault);
const result = await helper.getBestThumbnailAtSize(canvas, { width: 256, height: 256 });

const quickResult = await getThumbnail(canvas, {
  vault,
  width: 512,
  height: 512,
  returnAllOptions: true,
});

console.log(result.best);
console.log(quickResult.fallback);

@iiif/helpers/transcriptions

This package is focused on transcript detection and extraction.

Key exports:

  • canvasHasTranscriptionSync
  • canvasLoadExternalAnnotationPages
  • getCanvasTranscription
  • manifestHasTranscriptions
  • annotationPageToTranscription
  • vttToTranscription
  • timeStampToSeconds

What it supports:

  • plain text renderings on canvases
  • text/vtt supplemental bodies on AV canvases
  • TextualBody and text/plain supplemental annotations
  • external annotation pages that need to be loaded before transcript detection

Returned transcription objects include:

  • plaintext
  • segments
  • selector/timing information for segments when available

Important notes:

  • VTT files are parsed into segment records with temporal selectors.
  • External annotation pages can be loaded on demand with canvasLoadExternalAnnotationPages().
  • ALTO renderings are detected, but ALTO parsing is not implemented yet, so those paths currently return null.

Example:

import { Vault } from '@iiif/helpers';
import {
  manifestHasTranscriptions,
  getCanvasTranscription,
} from '@iiif/helpers/transcriptions';

const vault = new Vault();
const manifest = await vault.loadManifest('https://example.org/manifest.json');

if (!manifest) {
  throw new Error('Manifest failed to load');
}

const hasTranscriptions = await manifestHasTranscriptions(vault, manifest);

if (hasTranscriptions) {
  const canvas = vault.get(manifest.items[0]);
  const transcription = await getCanvasTranscription(vault, canvas);

  console.log(transcription?.plaintext);
  console.log(transcription?.segments[0]?.selector);
}

@iiif/helpers/vault

This is the core stateful package in the library.

Key exports:

  • Vault
  • globalVault
  • vault types such as VaultOptions, Entities, IIIFStore, RequestState, MetaState, and related action/type helpers

The Vault is a normalized IIIF resource store with loading, mutation, serialization, subscription, and helper methods.

Major capabilities:

  • load manifests, collections, and other IIIF resources with load(), loadManifest(), and loadCollection()
  • load synchronously from already-available JSON with loadSync()
  • access normalized resources with get() and hydrate()
  • navigate safely with deep()
  • subscribe to store changes with subscribe()
  • listen to dispatched actions with on()
  • batch state changes with batch() and asyncBatch()
  • serialize resources back to Presentation 2 or Presentation 3 with toPresentation2() and toPresentation3()
  • manage per-resource meta state with setMetaValue() and getResourceMeta()
  • paginate paged collections with getPaginationState() and loadNextPage()

The Vault also includes higher-level object wrappers:

  • getObject()
  • loadObject()
  • loadManifestObject()
  • loadCollectionObject()
  • wrapObject() and isWrapped() methods on the class

Those wrapped objects resolve nested references through getters and expose helper methods like refresh(), reactive(), unwrap(), toJSON(), toPresentation2(), and toPresentation3().

Example:

import { Vault } from '@iiif/helpers/vault';

const vault = new Vault();
const manifest = await vault.loadManifest('https://example.org/manifest.json');

if (!manifest) {
  throw new Error('Manifest failed to load');
}

const firstCanvas = vault.get(manifest.items[0]);
vault.setMetaValue([firstCanvas.id, 'ui', 'selected'], true);

console.log(vault.getResourceMeta(firstCanvas.id, 'ui'));

const wrapped = vault.getObject(manifest);
console.log(wrapped.items[0].id);
console.log(wrapped.items[0].unwrap());

@iiif/helpers/vault-node

This is the Node-oriented vault package.

Key exports:

  • Vault
  • globalVault
  • the same core types re-exported by @iiif/helpers/vault

The Vault class in this package extends the core vault and configures a Node-friendly fetch path. Use it when you want vault behavior in server-side code and you do not want to wire a custom fetcher yourself.

Example:

import { Vault } from '@iiif/helpers/vault-node';

const vault = new Vault();
const manifest = await vault.loadManifest('https://example.org/manifest.json');

console.log(manifest?.id);

@iiif/helpers/vault/actions

This package exposes the vault's Redux-style action constants and action creators.

Examples include:

  • entityActions
  • mappingActions
  • metaActions
  • requestActions
  • addReference
  • modifyEntityField
  • moveEntity
  • moveEntities
  • updateReference
  • changeReferenceIdentifier
  • request lifecycle constants such as REQUEST_RESOURCE, RESOURCE_READY, and RESOURCE_ERROR

Use it when you are integrating the vault store directly or building custom tooling on top of the same reducer model.

Example:

import { Vault } from '@iiif/helpers/vault';
import { entityActions } from '@iiif/helpers/vault/actions';

const vault = new Vault();
const manifest = await vault.loadManifest('https://example.org/manifest.json');

if (!manifest) {
  throw new Error('Manifest failed to load');
}

vault.dispatch(
  entityActions.modifyEntityField({
    id: manifest.id,
    type: 'Manifest',
    key: 'label',
    value: { en: ['Updated title'] },
  })
);

@iiif/helpers/vault/store

This package exposes the underlying store factory and reducers used by the vault.

Key exports:

  • createStore
  • reducers
  • VaultStoreState
  • VaultZustandStore

The store is built with vanilla Zustand plus Redux-style reducers. Use it when you want to embed the vault state model into an existing application architecture rather than always going through the Vault class.

Example:

import { emptyManifest } from '@iiif/parser';
import { createStore } from '@iiif/helpers/vault/store';
import { entityActions } from '@iiif/helpers/vault/actions';

const store = createStore();
const manifestId = 'https://example.org/manifest-1';

store.dispatch(
  entityActions.importEntities({
    entities: {
      Manifest: {
        [manifestId]: {
          ...emptyManifest,
          id: manifestId,
          type: 'Manifest',
          items: [],
        },
      },
    },
  })
);

store.dispatch(
  entityActions.modifyEntityField({
    id: manifestId,
    type: 'Manifest',
    key: 'label',
    value: { en: ['An example label'] },
  })
);

console.log(store.getState().iiif.entities.Manifest[manifestId]);

@iiif/helpers/vault/utility

This package contains lower-level utility helpers used by the vault internals and occasionally useful for advanced integrations.

Key exports:

  • actionListFromResource
  • areInputsEqual
  • createFetchHelper
  • getDefaultEntities
  • resolveIfExists
  • resolveList

These are useful when you want to:

  • build your own fetch-to-actions pipeline
  • inspect or recreate the vault's normalization defaults
  • resolve reference lists against a store directly
  • reuse the vault's selector-equality logic

Example:

import { Vault } from '@iiif/helpers/vault';
import { createFetchHelper } from '@iiif/helpers/vault/utility';

const vault = new Vault();

const fetchManifest = createFetchHelper(vault, async (url: string) => {
  return {
    id: url,
    type: 'Manifest',
    label: { en: ['Generated manifest'] },
    items: [],
  };
});

const manifest = await fetchManifest('https://example.org/manifest.json');
console.log(manifest?.id);

@iiif/helpers/vault/global-vault

This is a small compatibility bridge for global/browser-based setups.

Key export:

  • getGlobalVault

It returns globalThis.IIIF_VAULT if one already exists, and if not, it will try to initialize one from a global IIIFVault object. In modern module-based applications, globalVault() from @iiif/helpers/vault is usually the clearer API. This subpath is mostly useful when working with browser globals or legacy integration points.

Example:

import { getGlobalVault } from '@iiif/helpers/vault/global-vault';

const vault = getGlobalVault();
console.log(vault);

Choosing The Right Package

If you are not sure where to start:

  • start with @iiif/helpers for general browser-side helper work
  • use @iiif/helpers/vault when you want normalized loading and resource access
  • use @iiif/helpers/thumbnail and @iiif/helpers/image-service for image selection and delivery logic
  • use @iiif/helpers/annotation-targets and @iiif/helpers/content-state for viewer/deeplink interoperability
  • use @iiif/helpers/ranges, @iiif/helpers/sequences, and @iiif/helpers/nav-date for navigation structures
  • use @iiif/helpers/search1 and @iiif/helpers/transcriptions for discovery and text experiences

Repo Docs And Demos

There are also focused notes and examples in this repository:

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors