.md

Quick start

Build a filterable product list in 5 minutes.

What you'll build: A query that filters products by category and returns matching items instantly — no backend required.

Prerequisites

  • A supported Node.js version, see Compatibility (node -v to check)
  • A TypeScript/JavaScript project (or use npx tsx to run standalone)

Install

npm install @dcupl/core
yarn add @dcupl/core
pnpm add @dcupl/core

TypeScript types are included; type names such as ModelDefinition come from @dcupl/common, which you install (npm install @dcupl/common) only when you import them in your own code.

Create your first query

Create a new file and paste this complete example:

demo.ts
import { Dcupl } from '@dcupl/core';

async function main() {
  // 1. Create a dcupl instance
  const dcupl = new Dcupl();

  // 2. Define a model with filterable properties
  dcupl.models.set({
    key: 'Product',
    properties: [
      { key: 'name', type: 'string' },
      { key: 'price', type: 'int' },
      { key: 'category', type: 'string' },
    ],
  });

  // 3. Load data (inline or from external API)
  dcupl.data.set(
    [
      { key: 'p1', name: 'Laptop', price: 999, category: 'Electronics' },
      { key: 'p2', name: 'Mouse', price: 29, category: 'Electronics' },
      { key: 'p3', name: 'Desk', price: 299, category: 'Furniture' },
    ],
    { model: 'Product' },
  );

  // 4. Initialize (builds indexes). Resolves false, and logs the error,
  //    if processing fails; it doesn't throw.
  await dcupl.init();

  // 5. Create a list to query the model
  const list = dcupl.lists.create({ modelKey: 'Product' });

  // 6. Add filter conditions
  list.catalog.query.addCondition({
    attribute: 'category',
    operator: 'eq',
    value: 'Electronics',
  });

  // 7. Get results
  const results = list.catalog.query.items();
  console.log('Filtered results:', results);
  // → [
  //     { key: 'p1', name: 'Laptop', price: 999, category: 'Electronics' },
  //     { key: 'p2', name: 'Mouse', price: 29, category: 'Electronics' }
  //   ]
}

main();

Run it with npx tsx demo.ts or your preferred TypeScript runner.

Want to skip setup? → Try it in the Playground — experiment with filters, sorting, and facets live.

Common operations

Common query operations
// Conditions on different attributes combine with AND (with step 6: Electronics and price >= 50)
list.catalog.query.addCondition({ attribute: 'price', operator: 'gte', value: 50 });
list.catalog.query.items(); // → Laptop

// Conditions on the same attribute combine with OR
list.catalog.query.clear(); // removes all conditions and sort/pagination options
list.catalog.query.addCondition([
  { attribute: 'category', operator: 'eq', value: 'Electronics' },
  { attribute: 'category', operator: 'eq', value: 'Furniture' },
]); // → Laptop, Mouse, Desk

// OR across attributes: a group with an explicit groupType
list.catalog.query.clear();
list.catalog.query.addGroup({
  groupKey: 'cheap-or-furniture',
  groupType: 'or',
  queries: [
    { attribute: 'category', operator: 'eq', value: 'Furniture' },
    { attribute: 'price', operator: 'lt', value: 50 },
  ],
}); // → Desk, Mouse

// Sort ('ASC' or 'DESC', uppercase) and paginate
list.catalog.query.clear();
list.catalog.query.applyOptions({ sort: { attributes: ['price'], order: ['ASC'] }, start: 0, count: 2 });
list.catalog.query.items(); // → Mouse, Desk

Every other common call (facets, metadata, aggregations) is on one page: Quick reference.

Update data

Data changes after init() are staged. Apply them with dcupl.update(); lists then return the new results.

Update data after init
dcupl.data.upsert([{ key: 'p4', name: 'Monitor', price: 199, category: 'Electronics' }], { model: 'Product' });
await dcupl.update(); // resolves false, and logs the error, if the update fails

list.catalog.query.items(); // → Mouse, Monitor (still sorted by price, 2 per page)