# power-compass

React hooks and UI components for the [Compass](../docs/README.md) navigation platform.

The npm package is always installed by the **client application**. It can be used alongside the `power-compass` Ruby gem, but neither depends on the other being present.

## Installation

```bash
yarn add power-compass
```

## Hooks

### `useSearch(props)`

Drives the global search UI. Discovers providers from all configured backends on mount, then runs fuzzy search on every query change.

```typescript
import { useSearch } from "power-compass"

const [results, loading, finished] = useSearch({
  authBackend: "/compass",
  backends: ["/compass", "/admin/compass"],
  contextId: currentUserId,
  query: searchQuery,
  filters: { tagged: "sidebar" }, // optional — scopes the menu source
})
```

**Props**

| Prop          | Type                 | Description                                                |
| ------------- | -------------------- | ---------------------------------------------------------- |
| `authBackend` | `string`             | Backend URL used to fetch shared auth headers              |
| `backends`    | `string[]`           | Backend base URLs to query for providers                   |
| `contextId`   | `string`             | User or context identifier                                 |
| `query`       | `string`             | Search string — must be ≥ 3 characters to trigger a search |
| `filters`     | `CompassMenuFilters` | Optional tag filters for the menu source                   |

**Returns** `[SearchResult[], loading: boolean, finished: boolean]`

---

### `useTasks(props)`

Fetches notifications from all configured backends and merges them into a single list.

```typescript
import { useTasks } from "power-compass"

const { tasks, loading, error } = useTasks({
  authBackend: "/compass",
  backends: ["/compass"],
  contextId: currentUserId,
})
```

**Props**

| Prop          | Type       | Description                                   |
| ------------- | ---------- | --------------------------------------------- |
| `authBackend` | `string`   | Backend URL used to fetch shared auth headers |
| `backends`    | `string[]` | Backend base URLs to query for notifications  |
| `contextId`   | `string`   | User or context identifier                    |

**Returns** `{ tasks: Task[], loading: boolean, error: Error | null }`

Backends that fail to respond are silently skipped. Only an auth failure sets `error`.

---

### `useMenu(props)`

Fetches and aggregates navigation items from all configured backends.

```typescript
import { useMenu } from "power-compass"

const { items, loading } = useMenu({
  authBackend: "/compass",
  backends: ["/compass"],
  contextId: currentUserId,
})
```

---

## HTTP utilities

### `fetchBackend<T>(backend, contextId, service, query, headers?, handleError?)`

Fetches a single JSON endpoint. Retries once with `cache: "force-cache"` if the default request fails, then calls `handleError` (defaults to `console.debug`) and returns `undefined`.

### `fetchBackends<T>(authBackend, backends, contextId, service, query, handleError?)`

Fetches the same service from multiple backends in parallel, sharing a single auth-header round-trip. Returns a filtered array — failed backends are omitted.

```typescript
import { fetchBackends } from "power-compass"

const results = await fetchBackends<NotificationProvider[]>(
  "/compass", // authBackend
  ["/compass"], // backends
  currentUserId, // contextId
  "notifications", // service path
  {}, // query params
)
```

---

## Development

```bash
cd package
yarn install
yarn test          # vitest suite
yarn test:watch    # watch mode
yarn build         # production build
yarn lint          # eslint + prettier check
```
