# @insurup/table-adapter-core

> Framework-agnostic TanStack Table adapter for InsurUp SDK with @tanstack/query-core

Latest version **0.1.42** (published 2026-06-30) · MIT license · 0 weekly downloads

## Install

```sh
npm install @insurup/table-adapter-core
pnpm add @insurup/table-adapter-core
yarn add @insurup/table-adapter-core
bun add @insurup/table-adapter-core
```

## Health

**Score 60/100 (C)** — status: active.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.1.42 |
| Published | 2026-06-30 |
| First published | 2026-01-26 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 3 |
| Unpacked size | 719.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | InsurUp Engineering |
| Maintainers | kerem-acer |
| Keywords | tanstack-table, tanstack-query, graphql, insurup, sdk, adapter, pagination, typescript |

## Links

- npm: https://www.npmjs.com/package/@insurup/table-adapter-core
- Repository: https://github.com/InsurUp/ts-toolkit
- Homepage: https://github.com/InsurUp/ts-toolkit#readme
- Issues: https://github.com/InsurUp/ts-toolkit/issues
- npm.io page: https://npm.io/package/@insurup/table-adapter-core

## Dependencies (3)

- [@insurup/sdk](https://npm.io/package/@insurup/sdk.md) 0.1.42
- [@tanstack/query-core](https://npm.io/package/@tanstack/query-core.md) ^5.100.10
- [@tanstack/table-core](https://npm.io/package/@tanstack/table-core.md) ^8.21.3

## Alternatives

- [gamedig](https://npm.io/package/gamedig.md) — 29.3K weekly downloads
- [join-monster](https://npm.io/package/join-monster.md) — 12.8K weekly downloads
- [masked](https://npm.io/package/masked.md) — 5.5K weekly downloads
- [@comunica/actor-query-process-explain-logical](https://npm.io/package/@comunica/actor-query-process-explain-logical.md) — 4.7K weekly downloads
- [@veracity/vui](https://npm.io/package/@veracity/vui.md) — 4.6K weekly downloads

## Recent versions

- 0.1.42 (latest) — 2026-06-30
- 0.1.40 — 2026-06-16
- 0.1.39 — 2026-06-10
- 0.1.38 — 2026-06-10
- 0.1.37 — 2026-06-10
- 0.1.36 — 2026-06-09
- 0.1.35 — 2026-06-08
- 0.1.34 — 2026-06-06
- 0.1.33 — 2026-06-05
- 0.1.32 — 2026-06-04
- 0.1.31 — 2026-05-31
- 0.1.30 — 2026-05-31
- 0.1.29 — 2026-05-30
- 0.1.28 — 2026-05-30
- 0.1.27 — 2026-05-29
- … 24 more at https://npm.io/package/@insurup/table-adapter-core/versions

## README

# @insurup/table-adapter-core

Framework-agnostic TanStack Table adapter for [@insurup/sdk](https://www.npmjs.com/package/@insurup/sdk).

This is the core package that provides the table adapter logic. For framework-specific bindings, see:

- [`@insurup/table-adapter-react`](https://www.npmjs.com/package/@insurup/table-adapter-react) - React bindings
- [`@insurup/table-adapter-vue`](https://www.npmjs.com/package/@insurup/table-adapter-vue) - Vue bindings
- [`@insurup/table-adapter-svelte`](https://www.npmjs.com/package/@insurup/table-adapter-svelte) - Svelte bindings

## Features

- 🚀 Framework agnostic - works with React, Vue, Svelte, Solid, or vanilla JS
- 🔄 Built-in caching via `@tanstack/query-core`
- 📝 Type-safe columns with SDK field autocompletion
- 📄 Cursor pagination handled internally

## Installation

```bash
npm install @insurup/table-adapter-core @insurup/sdk
```

```bash
bun add @insurup/table-adapter-core @insurup/sdk
```

## Quick Start

```typescript
import { createCustomerTable } from '@insurup/table-adapter-core';
import { DefaultInsurUpClient } from '@insurup/sdk';

const client = new DefaultInsurUpClient({
  baseUrl: 'https://api.insurup.com',
  tokenProvider: () => token,
});

// Create table adapter with builder API
const customerTable = createCustomerTable({
  columns: (col) => [
    col.id({ header: 'ID' }),
    col.name({ header: 'Name', sortable: true }),
    col.primaryEmail('Email'),
    col.createdAt({ header: 'Created', sortable: true }),
  ],
  fetch: (options) => client.customers.getCustomers(options),
  pageSize: 10,
  autoFetch: true,
  // Sorting is managed by the consumer via tableOptions.state.sorting
  tableOptions: {
    state: {
      sorting: [{ id: 'createdAt', desc: true }],
    },
    onSortingChange: (updater) => {
      // Update your sorting state here
    },
  },
});

// Subscribe to state changes
const unsubscribe = customerTable.subscribe(() => {
  const state = customerTable.getSnapshot();
  console.log('Data:', state.rows);
});

// Get TanStack Table options
const tableOptions = customerTable.getTableOptions();

// Cleanup when done
customerTable.destroy();
```

## API

### createCustomerTable

Creates a customer table adapter with built-in caching and state management.

```typescript
const customerTable = createCustomerTable({
  // Required
  columns: (col) => [...],            // Builder function for columns
  fetch: (options) => Promise,        // SDK fetch function

  // Optional
  pageSize?: number,                  // Items per page (default: 20)
  defaultFilter?: UnifiedFilterInput, // Initial filter (see "Filter and search" below)
  staleTime?: number,                 // Cache stale time in ms (default: 30000)
  gcTime?: number,                    // Garbage collection time in ms (default: 300000)
  autoFetch?: boolean,                // Fetch on creation (default: false)

  // Callbacks
  onError?: (error) => void,          // Called on fetch error
  onSuccess?: (data) => void,         // Called on fetch success
  onSettled?: (data, error) => void   // Called after fetch completes
});
```

### Filter and search

The adapter exposes a **single unified filter API**. There is no separate `setSearch` — every field in `setFilter` is either a regular filter or, when carrying the `$search: true` marker, a server-side search clause.

```typescript
table.setFilter({
  // Regular filter — routed to the server's `filter:` slot
  type: { eq: CustomerType.Individual },
  birthDate: { gte: '1990-01-01' },

  // Search — `$search: true` promotes the field to the server's `search:` slot
  // and unlocks the search-only operators (`textSearch`, `wildcard`, `autocomplete`)
  name: { $search: true, textSearch: 'ali' },

  // Long form with relevance score
  identityNumber: {
    $search: true,
    textSearch: { value: '123', score: { boost: 2 } },
  },
});
```

String shorthand is normalized by the SDK: `textSearch: 'ali'` is equivalent to `textSearch: { value: 'ali' }`. Likewise `in: ['a','b']` becomes `{ values: ['a','b'] }`.

`and` / `or` combinators are supported recursively. Each combinator item is split per-bucket — `and` semantics are preserved; an `or` whose items mix filter and search keys becomes an implicit AND at the wire (server combines its `filter:` and `search:` slots with AND). Keep each `or` item homogeneous if intent matters.

To introspect what's filterable / searchable on an entity at runtime, read the generated meta:

```typescript
import { QueryCustomerModelMeta } from '@insurup/sdk';

QueryCustomerModelMeta.name.filterable; // true
QueryCustomerModelMeta.name.searchable; // true
QueryCustomerModelMeta.name.filterOperators; // ['eq','neq','contains','notContains', ...]
QueryCustomerModelMeta.name.searchOperators; // ['eq','neq','textSearch','wildcard', ...]
```

### Column Builder

The `columns` option receives a builder with methods for each field:

```typescript
columns: (col) => [
  // Simple - uses field name as header
  col.id(),

  // With custom header
  col.name('Customer Name'),

  // With full config
  col.type({
    header: 'Type',
    sortable: true,
    render: (value) => (value === 'Individual' ? '👤' : '🏢'),
  }),

  // Computed column using multiple fields
  col.computed({
    uses: ['cityText', 'districtText'] as const,
    header: 'Location',
    render: (row) => `${row.cityText}, ${row.districtText}`,
  }),
];
```

### Adapter Methods

| Method                | Description                                                               |
| --------------------- | ------------------------------------------------------------------------- |
| `columns`             | TanStack ColumnDef[] (readonly)                                           |
| `getState()`          | Current state: `{ rows, rowCount, pageCount, isLoading, error, ... }`     |
| `getTableOptions()`   | Complete TanStack Table options (includes data, columns, getCoreRowModel) |
| `subscribe(listener)` | Subscribe to state changes (for useSyncExternalStore)                     |
| `getSnapshot()`       | Get current state snapshot (for useSyncExternalStore)                     |
| `getServerSnapshot()` | Get server snapshot for SSR (for useSyncExternalStore)                    |
| `fetch()`             | Trigger a manual fetch                                                    |
| `invalidate()`        | Invalidate cache and refetch                                              |
| `refetch({ force })`  | Refetch with optional cache bypass                                        |
| `destroy()`           | Clean up resources (call on unmount)                                      |
| `setFilter(filter)`   | Set unified filter (filter + `$search`-marked entries) and refetch        |
| `getFilter()`         | Return the current unified filter                                         |
| `clearFilter()`       | Clear filter and refetch                                                  |
| `setPageSize(size)`   | Change page size                                                          |

### AdapterState

State returned by `getState()` and `getSnapshot()`.

```typescript
interface AdapterState<TEntity> {
  rows: TEntity[]; // Current page data
  rowCount: number; // Total records
  pageCount: number; // Total pages
  isLoading: boolean; // Initial loading
  isFetching: boolean; // Any fetch in progress
  error: Error | null; // Error if any
  isError: boolean;
  isSuccess: boolean;
}
```

## Pagination Limitations

This adapter uses **cursor-based pagination**, which only supports sequential navigation (previous/next). Jumping to arbitrary pages (e.g., page 1 → page 5) is **not supported**.

The `getTableOptions()` method returns `paginationMode: 'cursor'` to signal this limitation.

## License

MIT

---
_Source: https://npm.io/package/@insurup/table-adapter-core · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
