Core Concepts

Before diving into code, let's understand the key concepts that make dcupl work. This 5-minute overview will give you the mental model you need to be productive.

What is the dcupl core sdk?

dcupl is an in-memory query engine that runs in your browser or Node.js environment. Think of it as a mini-database for your applications.

flowchart LR
  subgraph dcupl["With dcupl"]
    direction LR
    BR[Browser] --> SDK["dcupl SDK + Data"]
    SDK --> Q[Query]
    Q --> R[Results]
  end
flowchart LR
  subgraph traditional["Traditional Approach"]
    direction LR
    B1[Browser] --> API[API Request]
    API --> DB[(Database)]
    DB --> RES[API Response]
    RES --> B2[Browser]
  end

Benefits:

  • No backend required for querying and filtering
  • Instant results (no network latency)
  • Works offline
  • Reduces server costs (computation happens locally)

The Three Core Concepts

Concept What it is
Model A schema defining your data structure (properties + references)
List A queryable view of items from a model
Query The interface for filtering, sorting, and analyzing data
flowchart LR
  M[Model] --> L[List]
  L --> Q[Query]
  Q --> R[Results]

1. Models

Models define the structure of your data - like database tables or TypeScript interfaces. They include properties (fields) and references (relationships).

const productModel: ModelDefinition = {
  key: 'Product',
  properties: [
    { key: 'name', type: 'string' },
    { key: 'price', type: 'int' },
    { key: 'category', type: 'string' },
  ],
  references: [
    { key: 'brand', type: 'singleValued', model: 'Brand' },
  ],
};

Think of it as: The blueprint for your data

Learn more: Models

2. Lists

Lists are filtered views of your data. You create a list to query a specific model.

const productList = dcupl.lists.create({ modelKey: 'Product' });

Think of it as: A live view of your data that updates when filters change

Learn more: Lists

3. Query

Query is the interface attached to each list for filtering, sorting, and retrieving data.

productList.catalog.query.addCondition({ ... });  // Filter
productList.catalog.query.items();                 // Get results
productList.catalog.fn.facets({ ... });            // Get facets

Think of it as: The SQL-like query language for your data

Learn more: Query

Architecture Overview

The dcupl SDK consists of modular packages that work together:

flowchart TB
  subgraph Packages["SDK Packages"]
    direction TB
    CORE["@dcupl/core
Query engine, models, lists"] LOADER["@dcupl/loader
Config & data loading"] COMMON["@dcupl/common
Shared types & utilities"] end subgraph DataSources["Data Sources"] direction TB CONSOLE["dcupl Console
Managed backend"] LOCAL["Local Files
JSON, CSV"] API["Custom APIs
REST, GraphQL"] end subgraph Runtime["Runtime"] direction TB MODELS["Models & Data"] LISTS["Lists"] QUERY["Query API"] RESULTS["Query Results"] end DataSources --> LOADER LOADER --> CORE COMMON -.-> CORE COMMON -.-> LOADER CORE --> MODELS MODELS --> LISTS LISTS --> QUERY QUERY --> RESULTS

Package Responsibilities

Package Purpose
@dcupl/core The query engine - models, lists, query API
@dcupl/loader Configuration fetching, resource loading, transformers
@dcupl/common Shared TypeScript types and utilities

The Data Flow

Here's how data moves through the system:

flowchart LR
  subgraph Setup["1. Setup"]
    direction TB
    DEF["Define Models"]
    LOAD["Load Data"]
  end

  subgraph Init["2. Initialize"]
    INIT["dcupl.init()"]
  end

  subgraph Query["3. Query"]
    direction TB
    LIST["Create List"]
    FILTER["Add Filters"]
    EXEC["Execute Query"]
  end

  subgraph Output["4. Results"]
    direction TB
    ITEMS["Items"]
    FACETS["Facets"]
    AGGS["Aggregations"]
  end

  Setup --> Init --> Query --> Output

Step by step:

  1. Define Models - Create schemas for your data
  2. Load Data - Add data inline or via DcuplAppLoader
  3. Initialize - Call dcupl.init() to process models and data
  4. Create Lists - Create filtered views of your models
  5. Query - Use query API to filter, sort, analyze
  6. Get Results - Items, facets, aggregations, pivot tables

Simple Example

Let's see all three concepts in action:

import { Dcupl } from '@dcupl/core';

// Create instance
const dcupl = new Dcupl();

// 1. Define MODEL with properties
dcupl.models.set({
  key: 'Product',
  properties: [
    { key: 'name', type: 'string' },
    { key: 'price', type: 'int' },
  ],
  data: [
    { key: 'p1', name: 'Laptop', price: 999 },
    { key: 'p2', name: 'Mouse', price: 29 },
  ],
});

// Initialize
await dcupl.init();

// 2. Create LIST
const list = dcupl.lists.create({ modelKey: 'Product' });

// 3. QUERY via catalog
list.catalog.query.addCondition({
  attribute: 'price',
  operator: 'gte',
  value: 100,
});

const results = list.catalog.query.items();
// Results: [{ key: 'p1', name: 'Laptop', price: 999 }]

Key Takeaways

  1. Models define structure (properties + references)
  2. Lists are filtered views of data
  3. Query is how you filter and analyze data
  4. You can have multiple lists for the same model
  5. Everything starts with dcupl.init() and ends with list.catalog.query

What's Next?

Now that you understand the core concepts, dive deeper:

  • Models - Learn about model configuration, properties, and references
  • Lists - Master list management and events
  • Query - Discover query capabilities, facets, and aggregations

Or explore patterns: