@annotorious/annotorious 3.0.0 → 3.0.2

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.
@@ -6,3 +6,5 @@ export interface ImageAnnotation extends Annotation {
6
6
  export interface ImageAnnotationTarget extends AnnotationTarget {
7
7
  selector: Shape;
8
8
  }
9
+ export declare const isImageAnnotation: <T extends Annotation>(a: T | ImageAnnotation) => a is ImageAnnotation;
10
+ export declare const isImageAnnotationTarget: <T extends AnnotationTarget>(t: T | ImageAnnotationTarget) => t is ImageAnnotationTarget;
@@ -1,10 +1,10 @@
1
- import { Store, SvelteAnnotatorState, SvelteStore } from '@annotorious/core';
1
+ import { Annotation, Store, SvelteAnnotatorState, SvelteStore } from '@annotorious/core';
2
2
  import { ImageAnnotation } from '../model';
3
- export type ImageAnnotationStore = Store<ImageAnnotation> & {
3
+ export type ImageAnnotationStore<I extends Annotation> = Store<I> & {
4
4
  getAt(x: number, y: number): ImageAnnotation | undefined;
5
5
  getIntersecting(x: number, y: number, width: number, height: number): ImageAnnotation[];
6
6
  };
7
- export type SvelteImageAnnotationStore = SvelteStore<ImageAnnotation> & ImageAnnotationStore;
8
- export type SvelteImageAnnotatorState = SvelteAnnotatorState<ImageAnnotation> & {
9
- store: SvelteImageAnnotationStore;
7
+ export type SvelteImageAnnotationStore<I extends Annotation = Annotation> = SvelteStore<I> & ImageAnnotationStore<I>;
8
+ export type SvelteImageAnnotatorState<I extends Annotation = Annotation> = SvelteAnnotatorState<I> & {
9
+ store: SvelteImageAnnotationStore<I>;
10
10
  };
@@ -1,11 +1,11 @@
1
1
  import { ImageAnnotation } from '../model';
2
2
  import { AnnotoriousOpts } from '../AnnotoriousOpts';
3
- import { AnnotatorState, HoverState, SelectionState } from '@annotorious/core';
3
+ import { Annotation, AnnotatorState, HoverState, SelectionState } from '@annotorious/core';
4
4
  import { ImageAnnotationStore, SvelteImageAnnotatorState } from './ImageAnnotationStore';
5
- export type ImageAnnotatorState<T extends ImageAnnotationStore = ImageAnnotationStore> = AnnotatorState<ImageAnnotation> & {
6
- store: T;
5
+ export type ImageAnnotatorState<I extends Annotation> = AnnotatorState<I> & {
6
+ store: ImageAnnotationStore<I>;
7
7
  selection: SelectionState<ImageAnnotation>;
8
8
  hover: HoverState<ImageAnnotation>;
9
9
  };
10
- export declare const createImageAnnotatorState: <E extends unknown>(opts: AnnotoriousOpts<ImageAnnotation, E>) => ImageAnnotatorState<ImageAnnotationStore>;
11
- export declare const createSvelteImageAnnotatorState: <E extends unknown>(opts: AnnotoriousOpts<ImageAnnotation, E>) => SvelteImageAnnotatorState;
10
+ export declare const createImageAnnotatorState: <I extends Annotation, E extends unknown>(opts: AnnotoriousOpts<I, E>) => ImageAnnotatorState<I>;
11
+ export declare const createSvelteImageAnnotatorState: <I extends Annotation, E extends unknown>(opts: AnnotoriousOpts<I, E>) => SvelteImageAnnotatorState<I>;
@@ -1,4 +1,5 @@
1
1
  import { ImageAnnotationTarget } from '../model';
2
+ import { AnnotationTarget } from '@annotorious/core';
2
3
  interface IndexedTarget {
3
4
  minX: number;
4
5
  minY: number;
@@ -11,10 +12,10 @@ export declare const createSpatialTree: () => {
11
12
  clear: () => void;
12
13
  getAt: (x: number, y: number) => ImageAnnotationTarget | undefined;
13
14
  getIntersecting: (x: number, y: number, width: number, height: number) => ImageAnnotationTarget[];
14
- insert: (target: ImageAnnotationTarget) => void;
15
- remove: (target: ImageAnnotationTarget) => void;
16
- set: (targets: ImageAnnotationTarget[], replace?: boolean) => void;
15
+ insert: (target: AnnotationTarget) => void;
16
+ remove: (target: AnnotationTarget) => void;
17
+ set: (targets: AnnotationTarget[], replace?: boolean) => void;
17
18
  size: () => number;
18
- update: (previous: ImageAnnotationTarget, updated: ImageAnnotationTarget) => void;
19
+ update: (previous: AnnotationTarget, updated: AnnotationTarget) => void;
19
20
  };
20
21
  export {};
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@annotorious/annotorious",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "Add image annotation functionality to any web page with a few lines of JavaScript",
5
5
  "author": "Rainer Simon",
6
6
  "license": "BSD-3-Clause",
7
- "homepage": "https://annotorious.github.io",
7
+ "homepage": "https://annotorious.dev",
8
8
  "type": "module",
9
9
  "repository": {
10
10
  "type": "git",
@@ -48,7 +48,7 @@
48
48
  "vitest": "^2.0.5"
49
49
  },
50
50
  "dependencies": {
51
- "@annotorious/core": "3.0.0",
51
+ "@annotorious/core": "3.0.2",
52
52
  "rbush": "^4.0.1",
53
53
  "uuid": "^10.0.0"
54
54
  }
@@ -1,6 +1,6 @@
1
1
  import type { SvelteComponent } from 'svelte';
2
2
  import { UserSelectAction } from '@annotorious/core';
3
- import type { Annotator, DrawingStyleExpression, Filter, User } from '@annotorious/core';
3
+ import type { Annotation, Annotator, DrawingStyleExpression, Filter, User } from '@annotorious/core';
4
4
  import { createAnonymousGuest, createBaseAnnotator, createLifecycleObserver, createUndoStack } from '@annotorious/core';
5
5
  import { registerEditor } from './annotation/editors';
6
6
  import { getTool, registerTool, listDrawingTools, type DrawingTool } from './annotation/tools';
@@ -17,7 +17,7 @@ import './Annotorious.css';
17
17
  import './themes/dark/index.css';
18
18
  import './themes/light/index.css';
19
19
 
20
- export interface ImageAnnotator<E extends unknown = ImageAnnotation> extends Annotator<ImageAnnotation, E> {
20
+ export interface ImageAnnotator<I extends Annotation = ImageAnnotation, E extends unknown = ImageAnnotation> extends Annotator<I, E> {
21
21
 
22
22
  element: HTMLDivElement;
23
23
 
@@ -35,10 +35,10 @@ export interface ImageAnnotator<E extends unknown = ImageAnnotation> extends Ann
35
35
 
36
36
  }
37
37
 
38
- export const createImageAnnotator = <E extends unknown = ImageAnnotation>(
38
+ export const createImageAnnotator = <I extends Annotation = ImageAnnotation, E extends unknown = ImageAnnotation>(
39
39
  image: string | HTMLImageElement | HTMLCanvasElement,
40
- options: AnnotoriousOpts<ImageAnnotation, E> = {}
41
- ): ImageAnnotator<E> => {
40
+ options: AnnotoriousOpts<I, E> = {}
41
+ ): ImageAnnotator<I, E> => {
42
42
 
43
43
  if (!image)
44
44
  throw 'Missing argument: image';
@@ -47,20 +47,20 @@ export const createImageAnnotator = <E extends unknown = ImageAnnotation>(
47
47
  typeof image === 'string' ? document.getElementById(image) : image
48
48
  ) as HTMLImageElement | HTMLCanvasElement;
49
49
 
50
- const opts = fillDefaults<ImageAnnotation, E>(options, {
50
+ const opts = fillDefaults<I, E>(options, {
51
51
  drawingEnabled: true,
52
52
  drawingMode: 'drag',
53
53
  userSelectAction: UserSelectAction.EDIT,
54
54
  theme: 'light'
55
55
  });
56
56
 
57
- const state = createSvelteImageAnnotatorState(opts);
57
+ const state = createSvelteImageAnnotatorState<I, E>(opts);
58
58
 
59
59
  const { selection, store } = state;
60
60
 
61
61
  const undoStack = createUndoStack(store);
62
62
 
63
- const lifecycle = createLifecycleObserver<ImageAnnotation, E>(
63
+ const lifecycle = createLifecycleObserver<I, E>(
64
64
  state, undoStack, opts.adapter, opts.autoSave
65
65
  );
66
66
 
@@ -87,13 +87,13 @@ export const createImageAnnotator = <E extends unknown = ImageAnnotation>(
87
87
  drawingEnabled: Boolean(opts.drawingEnabled),
88
88
  image: img,
89
89
  preferredDrawingMode: opts.drawingMode!,
90
- state,
90
+ state: state,
91
91
  style: opts.style,
92
92
  user: currentUser
93
93
  }
94
94
  });
95
95
 
96
- annotationLayer.$on('click', (evt: CustomEvent<SVGAnnotationLayerPointerEvent>) => {
96
+ annotationLayer.$on('click', (evt: CustomEvent<SVGAnnotationLayerPointerEvent<I>>) => {
97
97
  const { originalEvent, annotation } = evt.detail;
98
98
  if (annotation)
99
99
  selection.userSelect(annotation.id, originalEvent);
@@ -106,7 +106,7 @@ export const createImageAnnotator = <E extends unknown = ImageAnnotation>(
106
106
  /******++++++*************/
107
107
 
108
108
  // Most of the external API functions are covered in the base annotator
109
- const base = createBaseAnnotator<ImageAnnotation, E>(state, undoStack, opts.adapter);
109
+ const base = createBaseAnnotator<I, E>(state, undoStack, opts.adapter);
110
110
 
111
111
  const destroy = () => {
112
112
  // Destroy Svelte annotation layer
@@ -146,8 +146,8 @@ export const createImageAnnotator = <E extends unknown = ImageAnnotation>(
146
146
  console.warn('Filter not implemented yet');
147
147
  }
148
148
 
149
- const setStyle = (style: DrawingStyleExpression<ImageAnnotation> | undefined) =>
150
- annotationLayer.$set({ style });
149
+ const setStyle = (style: DrawingStyleExpression<I> | undefined) =>
150
+ annotationLayer.$set({ style: style as DrawingStyleExpression<ImageAnnotation> });
151
151
 
152
152
  const setTheme = (theme: Theme) => _setTheme(img, container, theme);
153
153
 
@@ -25,7 +25,7 @@ export type DrawingMode = 'click' | 'drag';
25
25
 
26
26
  export type Theme = 'dark' | 'light' | 'auto';
27
27
 
28
- export const fillDefaults = <I extends ImageAnnotation = ImageAnnotation, E extends unknown = ImageAnnotation> (
28
+ export const fillDefaults = <I extends Annotation = ImageAnnotation, E extends unknown = ImageAnnotation> (
29
29
  opts: AnnotoriousOpts<I, E>,
30
30
  defaults: AnnotoriousOpts<I, E>
31
31
  ): AnnotoriousOpts<I, E> => ({
@@ -1,8 +1,8 @@
1
- <script lang="ts">
1
+ <script lang="ts" generics="T extends Annotation">
2
2
  import { SvelteComponent, onMount } from 'svelte';
3
3
  import { v4 as uuidv4 } from 'uuid';
4
- import type { DrawingStyleExpression, StoreChangeEvent, User } from '@annotorious/core';
5
- import { ShapeType } from '../model';
4
+ import type { Annotation, DrawingStyleExpression, StoreChangeEvent, User } from '@annotorious/core';
5
+ import { isImageAnnotation, ShapeType } from '../model';
6
6
  import type { ImageAnnotation, Shape} from '../model';
7
7
  import { getEditor as _getEditor, EditorMount } from './editors';
8
8
  import { Ellipse, Polygon, Rectangle} from './shapes';
@@ -17,7 +17,7 @@
17
17
  export let drawingEnabled: boolean;
18
18
  export let image: HTMLImageElement | HTMLCanvasElement;
19
19
  export let preferredDrawingMode: DrawingMode;
20
- export let state: SvelteImageAnnotatorState;
20
+ export let state: SvelteImageAnnotatorState<T>;
21
21
  export let style: DrawingStyleExpression<ImageAnnotation> | undefined = undefined;
22
22
  export let toolName: string = listDrawingTools()[0];
23
23
  export let user: User;
@@ -44,7 +44,7 @@
44
44
 
45
45
  $: ({ onPointerDown, onPointerUp } = addEventListeners(svgEl, store));
46
46
 
47
- let storeObserver: (event: StoreChangeEvent<ImageAnnotation>) => void | undefined;
47
+ let storeObserver: (event: StoreChangeEvent<T>) => void | undefined;
48
48
 
49
49
  let editableAnnotations: ImageAnnotation[] | undefined;
50
50
 
@@ -62,12 +62,14 @@
62
62
 
63
63
  if (editableIds.length > 0) {
64
64
  // Resolve selected IDs from the store
65
- editableAnnotations = editableIds.map(id => store.getAnnotation(id)!).filter(Boolean);
65
+ editableAnnotations = editableIds
66
+ .map(id => store.getAnnotation(id)!)
67
+ .filter(a => a && isImageAnnotation(a));
66
68
 
67
69
  // Track updates on the editable annotations
68
- storeObserver = (event: StoreChangeEvent<ImageAnnotation>) => {
70
+ storeObserver = (event: StoreChangeEvent<T>) => {
69
71
  const { updated } = event.changes;
70
- editableAnnotations = updated?.map(change => change.newValue);
72
+ editableAnnotations = updated?.map(change => change.newValue) as unknown as ImageAnnotation[];
71
73
  }
72
74
 
73
75
  store.observe(storeObserver, { annotations: editableIds });
@@ -76,7 +78,7 @@
76
78
  }
77
79
  }
78
80
 
79
- const onSelectionCreated = <T extends Shape>(evt: CustomEvent<T>) => {
81
+ const onSelectionCreated = <S extends Shape>(evt: CustomEvent<S>) => {
80
82
  const id = uuidv4();
81
83
 
82
84
  const annotation: ImageAnnotation = {
@@ -90,7 +92,7 @@
90
92
  }
91
93
  };
92
94
 
93
- store.addAnnotation(annotation);
95
+ store.addAnnotation(annotation as unknown as Partial<T>);
94
96
 
95
97
  selection.setSelected(annotation.id);
96
98
  }
@@ -143,8 +145,8 @@
143
145
  on:pointermove={onPointerMove}>
144
146
 
145
147
  <g>
146
- {#each $store as annotation}
147
- {#if !isEditable(annotation)}
148
+ {#each $store.filter(a => isImageAnnotation(a)) as annotation}
149
+ {#if isImageAnnotation(annotation) && !isEditable(annotation)}
148
150
  {@const selector = annotation.target.selector}
149
151
  {#key annotation.id}
150
152
  {#if (selector?.type === ShapeType.ELLIPSE)}
@@ -1,20 +1,20 @@
1
1
  import { createEventDispatcher } from 'svelte';
2
2
  import type { SvelteImageAnnotationStore } from '../state';
3
- import type { ImageAnnotation } from '../model';
3
+ import type { Annotation } from '@annotorious/core';
4
4
 
5
- export interface SVGAnnotationLayerPointerEvent {
5
+ export interface SVGAnnotationLayerPointerEvent<T extends Annotation> {
6
6
 
7
7
  originalEvent: PointerEvent;
8
8
 
9
- annotation?: ImageAnnotation;
9
+ annotation?: T;
10
10
 
11
11
  }
12
12
 
13
13
  // Maximum amount of ms between pointer down and up to make it a click
14
14
  const MAX_CLICK_DURATION = 250;
15
15
 
16
- export const addEventListeners = (svg: SVGSVGElement, store: SvelteImageAnnotationStore) => {
17
- const dispatch = createEventDispatcher<{ click: SVGAnnotationLayerPointerEvent}>();
16
+ export const addEventListeners = <T extends Annotation>(svg: SVGSVGElement, store: SvelteImageAnnotationStore<T>) => {
17
+ const dispatch = createEventDispatcher<{ click: SVGAnnotationLayerPointerEvent<T> }>();
18
18
 
19
19
  let lastPointerDown: number;
20
20
 
@@ -27,7 +27,7 @@ export const addEventListeners = (svg: SVGSVGElement, store: SvelteImageAnnotati
27
27
  if (duration < MAX_CLICK_DURATION) {
28
28
  const { x, y } = getSVGPoint(evt, svg);
29
29
 
30
- const annotation = store.getAt(x, y);
30
+ const annotation = store.getAt(x, y) as T | undefined;
31
31
 
32
32
  if (annotation)
33
33
  dispatch('click', { originalEvent: evt, annotation });
@@ -11,4 +11,15 @@ export interface ImageAnnotationTarget extends AnnotationTarget {
11
11
 
12
12
  selector: Shape
13
13
 
14
- }
14
+ }
15
+
16
+ export const isImageAnnotation = <T extends Annotation>(
17
+ a: T | ImageAnnotation
18
+ ): a is ImageAnnotation =>
19
+ isImageAnnotationTarget(a.target);
20
+
21
+ export const isImageAnnotationTarget = <T extends AnnotationTarget>(
22
+ t: T | ImageAnnotationTarget
23
+ ): t is ImageAnnotationTarget =>
24
+ t?.annotation !== undefined &&
25
+ (t as ImageAnnotationTarget)?.selector?.geometry?.bounds !== undefined;
@@ -1,7 +1,7 @@
1
- import type { Store, SvelteAnnotatorState, SvelteStore } from '@annotorious/core';
1
+ import type { Annotation, Store, SvelteAnnotatorState, SvelteStore } from '@annotorious/core';
2
2
  import type { ImageAnnotation } from '../model';
3
3
 
4
- export type ImageAnnotationStore = Store<ImageAnnotation> & {
4
+ export type ImageAnnotationStore<I extends Annotation> = Store<I> & {
5
5
 
6
6
  getAt(x: number, y: number): ImageAnnotation | undefined;
7
7
 
@@ -9,10 +9,10 @@ export type ImageAnnotationStore = Store<ImageAnnotation> & {
9
9
 
10
10
  }
11
11
 
12
- export type SvelteImageAnnotationStore = SvelteStore<ImageAnnotation> & ImageAnnotationStore;
12
+ export type SvelteImageAnnotationStore<I extends Annotation = Annotation> = SvelteStore<I> & ImageAnnotationStore<I>;
13
13
 
14
- export type SvelteImageAnnotatorState = SvelteAnnotatorState<ImageAnnotation> & {
14
+ export type SvelteImageAnnotatorState<I extends Annotation = Annotation> = SvelteAnnotatorState<I> & {
15
15
 
16
- store: SvelteImageAnnotationStore;
16
+ store: SvelteImageAnnotationStore<I>;
17
17
 
18
18
  }
@@ -4,6 +4,7 @@ import { createSpatialTree } from './spatialTree';
4
4
  import {
5
5
  createViewportState,
6
6
  toSvelteStore,
7
+ type Annotation,
7
8
  type AnnotatorState,
8
9
  type HoverState,
9
10
  type SelectionState
@@ -19,9 +20,9 @@ import type {
19
20
  SvelteImageAnnotatorState
20
21
  } from './ImageAnnotationStore';
21
22
 
22
- export type ImageAnnotatorState<T extends ImageAnnotationStore = ImageAnnotationStore> = AnnotatorState<ImageAnnotation> & {
23
+ export type ImageAnnotatorState<I extends Annotation> = AnnotatorState<I> & {
23
24
 
24
- store: T;
25
+ store: ImageAnnotationStore<I>;
25
26
 
26
27
  selection: SelectionState<ImageAnnotation>;
27
28
 
@@ -29,16 +30,15 @@ export type ImageAnnotatorState<T extends ImageAnnotationStore = ImageAnnotation
29
30
 
30
31
  }
31
32
 
32
- export const createImageAnnotatorState = <E extends unknown>(
33
- opts: AnnotoriousOpts<ImageAnnotation, E>
34
- ): ImageAnnotatorState<ImageAnnotationStore> => {
33
+ export const createImageAnnotatorState = <I extends Annotation, E extends unknown> (
34
+ opts: AnnotoriousOpts<I, E>
35
+ ): ImageAnnotatorState<I> => {
35
36
 
36
- const store = createStore<ImageAnnotation>();
37
+ const store = createStore<I>();
37
38
 
38
39
  const tree = createSpatialTree();
39
40
 
40
- const selection = createSelectionState(store);
41
- selection.setUserSelectAction(opts.userSelectAction);
41
+ const selection = createSelectionState<I>(store, opts.userSelectAction);
42
42
 
43
43
  const hover = createHoverState(store);
44
44
 
@@ -49,40 +49,40 @@ export const createImageAnnotatorState = <E extends unknown>(
49
49
 
50
50
  (changes.deleted || []).forEach(a => tree.remove(a.target as ImageAnnotationTarget));
51
51
 
52
- (changes.updated || []).forEach(({ oldValue, newValue }) =>
52
+ (changes.updated || []).forEach(({ oldValue, newValue }) =>
53
53
  tree.update(oldValue.target, newValue.target));
54
54
  });
55
55
 
56
56
  const getAt = (x: number, y: number): ImageAnnotation | undefined => {
57
57
  const target = tree.getAt(x, y);
58
- return target ? store.getAnnotation(target.annotation) : undefined;
58
+ return target ? store.getAnnotation(target.annotation) as unknown as ImageAnnotation : undefined;
59
59
  }
60
60
 
61
61
  const getIntersecting = (x: number, y: number, width: number, height: number) =>
62
- tree.getIntersecting(x, y, width, height).map(target => store.getAnnotation(target.annotation));
62
+ tree.getIntersecting(x, y, width, height).map(target => store.getAnnotation(target.annotation) as unknown as ImageAnnotation);
63
63
 
64
64
  return {
65
65
  store: {
66
66
  ...store,
67
67
  getAt,
68
68
  getIntersecting
69
- } as ImageAnnotationStore,
69
+ },
70
70
  selection,
71
71
  hover,
72
72
  viewport
73
- }
73
+ } as ImageAnnotatorState<I>;
74
74
 
75
75
  }
76
76
 
77
- export const createSvelteImageAnnotatorState = <E extends unknown>(
78
- opts: AnnotoriousOpts<ImageAnnotation, E>
79
- ): SvelteImageAnnotatorState => {
77
+ export const createSvelteImageAnnotatorState = <I extends Annotation, E extends unknown>(
78
+ opts: AnnotoriousOpts<I, E>
79
+ ): SvelteImageAnnotatorState<I> => {
80
80
 
81
81
  const state = createImageAnnotatorState(opts);
82
82
 
83
83
  return {
84
84
  ...state,
85
- store: toSvelteStore(state.store) as SvelteImageAnnotationStore
85
+ store: toSvelteStore(state.store) as SvelteImageAnnotationStore<I>
86
86
  }
87
87
 
88
88
  }
@@ -1,6 +1,7 @@
1
1
  import RBush from 'rbush';
2
- import { ShapeType,computeArea, intersects } from '../model';
2
+ import { ShapeType,computeArea, intersects, isImageAnnotationTarget } from '../model';
3
3
  import type { ImageAnnotationTarget } from '../model';
4
+ import type { AnnotationTarget } from '@annotorious/core';
4
5
 
5
6
  interface IndexedTarget {
6
7
 
@@ -29,7 +30,9 @@ export const createSpatialTree = () => {
29
30
  index.clear();
30
31
  }
31
32
 
32
- const insert = (target: ImageAnnotationTarget) => {
33
+ const insert = (target: AnnotationTarget) => {
34
+ if (!isImageAnnotationTarget(target)) return;
35
+
33
36
  const { minX, minY, maxX, maxY } = target.selector.geometry.bounds;
34
37
 
35
38
  const t = { minX, minY, maxX, maxY, target };
@@ -38,28 +41,30 @@ export const createSpatialTree = () => {
38
41
  index.set(target.annotation, t);
39
42
  };
40
43
 
41
- const remove = (target: ImageAnnotationTarget) => {
44
+ const remove = (target: AnnotationTarget) => {
45
+ if (!isImageAnnotationTarget(target)) return;
46
+
42
47
  const item = index.get(target.annotation);
43
48
  if (item)
44
49
  tree.remove(item);
45
50
  index.delete(target.annotation);
46
51
  };
47
52
 
48
- const update = (previous: ImageAnnotationTarget, updated: ImageAnnotationTarget) => {
53
+ const update = (previous: AnnotationTarget, updated: AnnotationTarget) => {
49
54
  remove(previous);
50
55
  insert(updated);
51
56
  };
52
57
 
53
- const set = (targets: ImageAnnotationTarget[], replace: boolean = true) => {
58
+ const set = (targets: AnnotationTarget[], replace: boolean = true) => {
54
59
  if (replace)
55
60
  clear();
56
61
 
57
62
  const indexedTargets = targets.reduce<IndexedTarget[]>((all, target) => {
58
- if (target.selector?.geometry?.bounds) {
63
+ if (isImageAnnotationTarget(target)) {
59
64
  // In case the host app injects any custom annotations, the
60
65
  // spatial index should simply ignore them.
61
66
  const { minX, minY, maxX, maxY } = target.selector.geometry.bounds;
62
- return [...all, { minX, minY, maxX, maxY, target }];
67
+ return [...all, { minX, minY, maxX, maxY, target } as IndexedTarget];
63
68
  } else {
64
69
  return all;
65
70
  }