# Quick reference

The SDK calls you use most, on one page. Every option, return value and type is in the [API reference](/sdk/api).

## Install

```bash group="install" tab="npm"
npm install @dcupl/core @dcupl/loader
```

```bash group="install" tab="yarn"
yarn add @dcupl/core @dcupl/loader
```

```bash group="install" tab="pnpm"
pnpm add @dcupl/core @dcupl/loader
```

`@dcupl/loader` is only needed to load a `dcupl.lc.json` configuration (see [Setup options](/sdk/setup-options)).

## Lifecycle

```typescript filename="lifecycle.ts"
import { Dcupl } from '@dcupl/core';

const dcupl = new Dcupl(); // options: /sdk/api/dcupl#dcuplinitoptions

dcupl.models.set({
  key: 'Product',
  properties: [
    { key: 'name', type: 'string' },
    { key: 'brand', type: 'string' },
    { key: 'price', type: 'int' },
  ],
});

dcupl.data.set(
  [
    { key: 'p1', name: 'Laptop', brand: 'Acme', price: 999 },
    { key: 'p2', name: 'Mouse', brand: 'Acme', price: 29 },
    { key: 'p3', name: 'Desk', brand: 'Oak & Co', price: 299 },
  ],
  { model: 'Product' },
);

// Builds the indexes. Resolves false, and logs the error, if processing fails.
await dcupl.init();
```

## Load with the loader

Instead of `models.set()` and `data.set()`, load a `dcupl.lc.json` and the files it lists:

```typescript filename="setup.ts"
import { Dcupl } from '@dcupl/core';
import { DcuplAppLoader } from '@dcupl/loader';

const dcupl = new Dcupl();
const loader = new DcuplAppLoader();
dcupl.loaders.add(loader);

// The request url is `${baseUrl}/${loaderFileName}`.
// baseUrl must be non-empty; an empty string falls back to the dcupl CDN default.
await loader.config.fetch({
  baseUrl: window.location.origin, // browser: your app's origin; in Node, pass a full URL
  loaderFileName: 'dcupl.lc.json',
});

await loader.process(); // loads every resource the configuration lists
await dcupl.init();
```

## Lists and queries

```typescript filename="query.ts"
const list = dcupl.lists.create({ modelKey: 'Product' });

// Conditions on different attributes combine with AND, on the same attribute with OR
list.catalog.query.addCondition({ attribute: 'brand', operator: 'eq', value: 'Acme' });
list.catalog.query.addCondition({ attribute: 'price', operator: 'gte', value: 50 });
list.catalog.query.items(); // → Laptop

// A group with an explicit groupType ('or' or 'and')
list.catalog.query.clear();
list.catalog.query.addGroup({
  groupKey: 'cheap-or-oak',
  groupType: 'or',
  queries: [
    { attribute: 'brand', operator: 'eq', value: 'Oak & Co' },
    { attribute: 'price', operator: 'lt', value: 50 },
  ],
});
list.catalog.query.items(); // → Desk, Mouse
list.catalog.query.removeGroup('cheap-or-oak');

// Sort and paginate (order is 'ASC' or 'DESC')
list.catalog.query.applyOptions({ sort: { attributes: ['price'], order: ['DESC'] }, start: 0, count: 2 });
list.catalog.query.items(); // → Laptop, Desk
list.catalog.query.first(); // → Laptop
list.catalog.query.count(); // items on the current page → 2

// Remove all conditions, sort and pagination
list.catalog.query.clear();
```

Operators: [Query Operators](/sdk/api/query-operators). Every query method: [Catalog API](/sdk/api/catalog).

## Analysis functions

```typescript filename="fn.ts"
// Counts per value, for filter UIs
list.catalog.fn.facets({ attribute: 'brand' });
// → [{ value: 'Acme', size: 2, ... }, { value: 'Oak & Co', size: 1, ... }]

// sum, avg, count, min, max, distinct
list.catalog.fn.aggregate({ attribute: 'price', types: ['min', 'max', 'avg'] });
// → { attribute: 'price', min: 29, max: 999, avg: 442.3333333333333, ... }

// Items grouped by a value
list.catalog.fn.groupBy({ attribute: 'brand' });
// → { items: [{ value: 'Acme', _meta: { size: 2 }, ... }, { value: 'Oak & Co', _meta: { size: 1 }, ... }], ... }

// Autocomplete ('/…/' is a regex)
list.catalog.fn.suggest({ attribute: 'name', value: '/^la/', regexFlags: 'i' });
// → [{ value: 'Laptop', keys: ['p1'] }]

// All items matching the current query (count() is capped by the page size)
list.catalog.fn.metadata().currentSize; // → 3
```

Options and return types: [Functions API](/sdk/api/functions).

## Global queries

Read a model without creating a list:

```typescript filename="global-query.ts"
dcupl.query.one({ modelKey: 'Product', itemKey: 'p1' });
// → { key: 'p1', name: 'Laptop', brand: 'Acme', price: 999 }

dcupl.query.execute({
  modelKey: 'Product',
  queries: [
    { attribute: 'brand', operator: 'eq', value: 'Acme' },
    { attribute: 'price', operator: 'gte', value: 50 },
  ],
  sort: { attributes: ['price'], order: ['ASC'] },
  count: 20,
});
// → [{ key: 'p1', name: 'Laptop', ... }]
```

## Update data

Data changes are staged until you call `dcupl.update()`; lists then return the new results.

```typescript filename="update.ts"
// Change existing items; properties you leave out keep their values
dcupl.data.update([{ key: 'p1', price: 899 }], { model: 'Product' });

// Add new items, or update them if they exist
dcupl.data.upsert([{ key: 'p4', name: 'Lamp', brand: 'Oak & Co', price: 40 }], { model: 'Product' });

// Remove items by key
dcupl.data.remove([{ key: 'p2' }], { model: 'Product' });

// Apply the staged changes. Resolves false, and logs the error, if the update fails.
await dcupl.update();

list.catalog.query.items(); // → Laptop (899), Desk, Lamp
```

## Events

```typescript filename="events.ts"
// Every event of the instance: dcupl_initialized, dcupl_updated_manually, list_created, ...
const off = dcupl.on((message) => console.log(message.type));

// Re-render when a list's result changes, e.g. after dcupl.update()
const offList = list.onResultChange(() => render(list.catalog.query.items()));

// Unsubscribe
off();
offList();
```

## Clean up

```typescript filename="cleanup.ts"
list.destroy(); // a list you no longer need
dcupl.destroy(); // the whole instance, e.g. when your app unmounts
```

## See also

- [Quick start](/sdk/quick-start) - Get started in 5 minutes
- [Core concepts](/sdk/core-concepts) - Understand the fundamentals
- [Setup options](/sdk/setup-options) - Console + Loader, your own files, or SDK-only
- [API reference](/sdk/api) - Every class, method and type
