# Events

ForesightManager emits events for element registration, prediction, and callback execution. The [ForesightJS DevTools](/docs/react/devtools.md) use them for visual debugging, and you can listen to them yourself for telemetry, analytics, or counters.

## Usage[​](#usage "Direct link to Usage")

In React the easiest way to listen to events is the [`useForesightEvent`](/docs/react/useForesightEvent.md) hook, which adds and removes the listener for you:

```
import { useState } from "react"
import { useForesightEvent } from "@foresightjs/react"

function PrefetchCounter() {
  const [hits, setHits] = useState(0)

  useForesightEvent("callbackInvoked", event => {
    setHits(count => count + 1)
  })

  return <p>{hits} prefetches triggered</p>
}
```

The standard `ForesightManager.instance.addEventListener` / `removeEventListener` pattern is also available if you want to listen outside of a component.

## Available Events[​](#available-events "Direct link to Available Events")

### Interaction Events[​](#interaction-events "Direct link to Interaction Events")

Events fired when user interactions trigger callbacks.

***

#### `callbackInvoked`[​](#callbackinvoked "Direct link to callbackinvoked")

Fired **before** an element's callback is executed

```
type CallbackInvokedEvent = {
  type: "callbackInvoked"
  timestamp: number
  element: ForesightElement
  state: ForesightElementState
  hitType: CallbackHitType
}
```

**Related Types:** [`CallbackHitType`](/docs/getting-started/typescript.md#callbackhittype) • [`ForesightElementState`](/docs/getting-started/typescript.md#foresightelementstate)

***

#### `callbackCompleted`[​](#callbackcompleted "Direct link to callbackcompleted")

Fired **after** an element's callback is executed

```
type CallbackCompletedEvent = {
  type: "callbackCompleted"
  timestamp: number
  element: ForesightElement
  state: ForesightElementState
  hitType: CallbackHitType
  elapsed: number // Time between callbackInvoked and callbackCompleted
  status: "success" | "error" | undefined
  errorMessage: string | null
  wasLastActiveElement: boolean
}
```

**Related Types:** [`CallbackHitType`](/docs/getting-started/typescript.md#callbackhittype) • [`ForesightElementState`](/docs/getting-started/typescript.md#foresightelementstate)

### Element Lifecycle Events[​](#element-lifecycle-events "Direct link to Element Lifecycle Events")

Events fired during element registration, updates, and cleanup.

***

#### `elementRegistered`[​](#elementregistered "Direct link to elementregistered")

Fired when an element is successfully registered with `ForesightManager` using `ForesightManager.instance.register(element)`.

```
type ElementRegisteredEvent = {
  type: "elementRegistered"
  timestamp: number
  element: ForesightElement
  state: ForesightElementState
}
```

**Related Types:** [`ForesightElementState`](/docs/getting-started/typescript.md#foresightelementstate)

***

#### `elementUnregistered`[​](#elementunregistered "Direct link to elementunregistered")

Fired when an element is removed from `ForesightManager`'s tracking via `ForesightManager.instance.unregister(element)`. Detaching an element from the DOM no longer unregisters it. It is parked (kept registered but inactive) and resumed on reattach, so no `elementUnregistered` event fires for that. The `"disconnected"` reason is therefore no longer emitted.

```
type ElementUnregisteredEvent = {
  type: "elementUnregistered"
  timestamp: number
  element: ForesightElement
  state: ForesightElementState
  unregisterReason: "disconnected" | "apiCall" | "devtools" | (string & {})
  wasLastRegisteredElement: boolean
}
```

**Related Types:** [`ForesightElementState`](/docs/getting-started/typescript.md#foresightelementstate)

***

### Prediction Events[​](#prediction-events "Direct link to Prediction Events")

Events fired during movement prediction calculations.

***

#### `mouseTrajectoryUpdate`[​](#mousetrajectoryupdate "Direct link to mousetrajectoryupdate")

Fired during mouse movement for trajectory calculations

```
type MouseTrajectoryUpdateEvent = {
  type: "mouseTrajectoryUpdate"
  trajectoryPositions: {
    positions: CircularBuffer<MousePosition> // mouse position history
    currentPoint: { x: number; y: number }
    predictedPoint: { x: number; y: number }
  }
  predictionEnabled: boolean
}
```

***

#### `scrollTrajectoryUpdate`[​](#scrolltrajectoryupdate "Direct link to scrolltrajectoryupdate")

Fired during scroll events when scroll prediction is active

```
type ScrollTrajectoryUpdateEvent = {
  type: "scrollTrajectoryUpdate"
  currentPoint: Point // { x: number; y: number }
  predictedPoint: Point // { x: number; y: number }
  scrollDirection: ScrollDirection // "down" | "up" | "left" | "right"
}
```

***

### Configuration Events[​](#configuration-events "Direct link to Configuration Events")

Events fired when ForesightManager configuration changes.

***

#### `managerSettingsChanged`[​](#managersettingschanged "Direct link to managersettingschanged")

Fired when global `ForesightManager` settings are updated via the devtools or via `ForesightManager.instance.alterGlobalSettings()`.

```
type ManagerSettingsChangedEvent = {
  type: "managerSettingsChanged"
  timestamp: number
  managerData: Readonly<ForesightManagerData>
  updatedSettings: UpdatedManagerSetting[]
}
```

**Related Types:** [`ForesightManagerData`](/docs/getting-started/typescript.md#foresightmanagerdata)

***

#### `deviceStrategyChanged`[​](#devicestrategychanged "Direct link to devicestrategychanged")

Fired when user switches between input methods (mouse, touch, or pen).

```
type DeviceStrategyChangedEvent = {
  type: "deviceStrategyChanged"
  timestamp: number
  newStrategy: CurrentDeviceStrategy // "mouse" | "touch" | "pen"
  oldStrategy: CurrentDeviceStrategy // "mouse" | "touch" | "pen"
}
```

***
