Lists API

The Lists API (dcupl.lists) provides methods for creating and managing isolated data collections with their own filters, queries, and state management.

Overview

Lists are isolated views of your data that maintain their own query state and provide access to the catalog API for querying, filtering, and analytics. Each list operates independently and can have different filters applied to the same underlying data model.

Methods

create()

Creates a new list instance.

Signature:

create<T>(config: DcuplListOptions): DcuplList<T>

Parameters:

Parameter Type Required Description
config DcuplListOptions Yes List configuration options

Returns: DcuplList - The created list instance

Examples:

Create list for all products
const productList = dcupl.lists.create({
  modelKey: 'Product',
});
Create list with custom key
const activeProducts = dcupl.lists.create({
  modelKey: 'Product',
  listKey: 'activeProducts',
});
Create list with specific items
const selectedProducts = dcupl.lists.create({
  modelKey: 'Product',
  listItemKeys: ['p1', 'p2', 'p3'],
});
Create list with initial query
const expensiveProducts = dcupl.lists.create({
  modelKey: 'Product',
  query: {
    modelKey: 'Product',
    queries: [{ operator: 'gte', attribute: 'price', value: 100 }],
  },
});
Create list with auto-update enabled
const list = dcupl.lists.create({
  modelKey: 'Product',
  autoUpdate: true,
});

get()

Retrieves a list by its key.

Signature:

get(listKey: string): DcuplList | undefined

Parameters:

Parameter Type Required Description
listKey string Yes The key of the list to retrieve

Returns: DcuplList | undefined - The list instance or undefined if not found

Examples:

Get an existing list
const list = dcupl.lists.get('activeProducts');
if (list) {
  const items = list.catalog.query.items();
}
Check if list exists
const exists = dcupl.lists.get('myList') !== undefined;
Safe access
const list = dcupl.lists.get('myList');
if (list) {
  // Use list
} else {
  // Create list
  const newList = dcupl.lists.create({
    modelKey: 'Product',
    listKey: 'myList',
  });
}

getAll()

Retrieves all lists or filters by model.

Signature:

getAll(filter?: { modelKey: string }): DcuplList[]

Parameters:

Parameter Type Required Description
filter { modelKey: string } No Optional filter by model key

Returns: DcuplList[] - Array of list instances

Examples:

Get all lists
const allLists = dcupl.lists.getAll();
console.log(allLists.length);
Get lists for specific model
const productLists = dcupl.lists.getAll({ modelKey: 'Product' });
Update all lists
dcupl.lists.getAll().forEach((list) => {
  list.update();
});
Count lists per model
const listsByModel = {};
dcupl.lists.getAll().forEach((list) => {
  listsByModel[list.modelKey] = (listsByModel[list.modelKey] || 0) + 1;
});

destroy()

Destroys lists and cleans up resources.

Signature:

destroy(options?: { listKey?: string; modelKey?: string }): void

Parameters:

Parameter Type Required Description
options object No Destroy options (all lists if omitted)
options.listKey string No Specific list key to destroy
options.modelKey string No Destroy all lists for a model

Examples:

Destroy specific list
dcupl.lists.destroy({ listKey: 'activeProducts' });
Destroy all lists for a model
dcupl.lists.destroy({ modelKey: 'Product' });
Destroy all lists
dcupl.lists.destroy();
Safe destroy with check
const list = dcupl.lists.get('myList');
if (list) {
  dcupl.lists.destroy({ listKey: 'myList' });
}

DcuplList Class

The DcuplList class represents an individual list instance with its own state and catalog API.

Properties

key

The unique identifier for this list.

Type: string

Example:

const list = dcupl.lists.create({
  modelKey: 'Product',
  listKey: 'myList',
});
console.log(list.key); // 'myList'

modelKey

The model this list is based on.

Type: string

Example:

console.log(list.modelKey); // 'Product'

catalog

Access to the catalog API for querying and analytics.

Type: Catalog

See: Catalog API Reference

Example:

const items = list.catalog.query.items();
const facets = list.catalog.fn.facets({ attribute: 'category' });

Methods

update()

Updates the list with the latest data and reprocesses queries.

Signature:

update(options?: { reprocessData?: boolean }): void

Parameters:

Parameter Type Required Description
options object No Update options
options.reprocessData boolean No Force full data reprocessing

Examples:

Basic update
list.update();
Force full reprocessing
list.update({ reprocessData: true });
Update after data change
dcupl.data.update([{ key: 'p1', price: 150 }], { model: 'Product' });
await dcupl.update();
list.update(); // Update list to reflect changes
Auto-update workflow
const list = dcupl.lists.create({
  modelKey: 'Product',
  autoUpdate: true
});
// List automatically updates when data changes
dcupl.data.update([...], { model: 'Product' });
await dcupl.update(); // List updates automatically

destroy()

Destroys the list and cleans up resources.

Signature:

destroy(): void

Examples:

Destroy a list
const list = dcupl.lists.create({ modelKey: 'Product' });
list.destroy();
Cleanup in component
class MyComponent {
  private list: DcuplList;

  constructor() {
    this.list = dcupl.lists.create({ modelKey: 'Product' });
  }

  destroy() {
    this.list.destroy();
  }
}

on()

Subscribes to change events from the list.

Signature:

on(callback: CallbackFunction): () => void

Parameters:

Parameter Type Required Description
callback CallbackFunction Yes Function to call on changes

Returns: () => void - Unsubscribe function

Examples:

Subscribe to list changes
const unsubscribe = list.on((message) => {
  console.log('List changed:', message);
});
Unsubscribe
unsubscribe();
React to specific events
list.on((message) => {
  if (message.type === 'list_updated') {
    console.log('List was updated');
  }
  if (message.type === 'query_apply') {
    console.log('Query was applied');
  }
});
Multiple subscribers
const unsub1 = list.on(callback1);
const unsub2 = list.on(callback2);

// Cleanup
unsub1();
unsub2();

Configuration Types

DcuplListOptions

Configuration options for creating a list.

Type Definition:

type DcuplListOptions = {
  modelKey: string;
  listKey?: string;
  listItemKeys?: string[];
  query?: DcuplGlobalQueryOptions;
  autoUpdate?: boolean;
};

Properties:

Property Type Required Description
modelKey string Yes Model this list is based on
listKey string No Unique list identifier (auto-generated if omitted)
listItemKeys string[] No Specific item keys to include
query DcuplGlobalQueryOptions No Initial query to apply
autoUpdate boolean No Auto-update when data changes

Examples:

Minimal configuration
{
  modelKey: 'Product';
}
With custom key
{
  modelKey: 'Product',
  listKey: 'featuredProducts'
}
With specific items
{
  modelKey: 'Product',
  listItemKeys: ['p1', 'p2', 'p3']
}
With initial query
{
  modelKey: 'Product',
  query: {
    modelKey: 'Product',
    queries: [
      { operator: 'eq', attribute: 'status', value: 'active' }
    ]
  }
}
With auto-update
{
  modelKey: 'Product',
  listKey: 'activeProducts',
  autoUpdate: true
}

Common Patterns

Filtered List Pattern

Create lists with pre-applied filters for common queries.

Active products list
const activeProducts = dcupl.lists.create({
  modelKey: 'Product',
  listKey: 'activeProducts',
  query: {
    modelKey: 'Product',
    queries: [{ operator: 'eq', attribute: 'status', value: 'active' }],
  },
});
Featured products list
const featuredProducts = dcupl.lists.create({
  modelKey: 'Product',
  listKey: 'featuredProducts',
  query: {
    modelKey: 'Product',
    queries: [
      { operator: 'eq', attribute: 'featured', value: true },
      { operator: 'eq', attribute: 'status', value: 'active' },
    ],
  },
});

Master-Detail Pattern

Create lists that work together for master-detail views.

Master list: All categories
const categoriesList = dcupl.lists.create({
  modelKey: 'Category',
  listKey: 'categories',
});
Detail list: Products for selected category
const categoryProducts = dcupl.lists.create({
  modelKey: 'Product',
  listKey: 'categoryProducts',
});
Update detail when master selection changes
function selectCategory(categoryKey: string) {
  categoryProducts.catalog.query.setCondition({
    operator: 'eq',
    attribute: 'category',
    value: { key: categoryKey },
  });
}

Search Results Pattern

Create a list for search results that can be updated dynamically.

Create search results list
const searchResults = dcupl.lists.create({
  modelKey: 'Product',
  listKey: 'searchResults',
});
Search function
function search(query: string) {
  if (query.length === 0) {
    searchResults.catalog.query.clear();
  } else {
    searchResults.catalog.query.setCondition({
      operator: 'find',
      attribute: 'name',
      value: query,
      options: { transform: ['lowercase'] },
    });
  }

  return searchResults.catalog.query.items();
}

Faceted Search Pattern

Create lists with dynamic facet-based filtering.

Create main search list
const productSearch = dcupl.lists.create({
  modelKey: 'Product',
  listKey: 'productSearch',
});
Get available facets
const categories = productSearch.catalog.fn.facets({
  attribute: 'category',
});
Apply category filter
function filterByCategory(categoryKey: string) {
  productSearch.catalog.query.addCondition({
    operator: 'eq',
    attribute: 'category',
    value: { key: categoryKey },
    queryKey: 'category',
  });
}
Remove category filter
function clearCategoryFilter() {
  productSearch.catalog.query.removeCondition({
    queryKey: 'category',
  });
}

Pagination Pattern

Create lists with pagination support.

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

const pageSize = 20;
let currentPage = 0;

function getPage(page: number) {
  currentPage = page;
  return productList.catalog.query.items({
    start: page * pageSize,
    count: pageSize,
  });
}

function getTotalPages() {
  const total = productList.catalog.query.count();
  return Math.ceil(total / pageSize);
}

function nextPage() {
  return getPage(currentPage + 1);
}

function prevPage() {
  return getPage(Math.max(0, currentPage - 1));
}

Multiple Filter Groups Pattern

Create complex filters with multiple grouped conditions.

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

// Price range filter
productList.catalog.query.addGroup({
  groupKey: 'priceRange',
  groupType: 'and',
  queries: [
    { operator: 'gte', attribute: 'price', value: 50 },
    { operator: 'lte', attribute: 'price', value: 200 },
  ],
});

// Category filter
productList.catalog.query.addGroup({
  groupKey: 'categories',
  groupType: 'or',
  queries: [
    { operator: 'eq', attribute: 'category', value: { key: 'cat1' } },
    { operator: 'eq', attribute: 'category', value: { key: 'cat2' } },
  ],
});

// Remove specific group
productList.catalog.query.removeGroup('priceRange');

Subset List Pattern

Create a list from specific items.

Get items from main list
const mainList = dcupl.lists.create({ modelKey: 'Product' });
const allProducts = mainList.catalog.query.items();
Create subset based on selection
const selectedKeys = ['p1', 'p5', 'p10'];
const selectionList = dcupl.lists.create({
  modelKey: 'Product',
  listKey: 'selection',
  listItemKeys: selectedKeys,
});
Work with subset
const selectedItems = selectionList.catalog.query.items();

Auto-Update Pattern

Lists that automatically update when data changes.

Global auto-update configuration
const dcupl = new Dcupl({
  performance: {
    autoUpdateLists: {
      enabled: true,
    },
  },
});
This list inherits global setting
const autoList = dcupl.lists.create({
  modelKey: 'Product',
});
This list always auto-updates
const alwaysAutoList = dcupl.lists.create({
  modelKey: 'Product',
  autoUpdate: true,
});
This list never auto-updates
const manualList = dcupl.lists.create({
  modelKey: 'Product',
  autoUpdate: false,
});
Update data - autoList and alwaysAutoList update automatically
dcupl.data.update([{ key: 'p1', price: 150 }], { model: 'Product' });
await dcupl.update();
manualList requires explicit update
manualList.update();

Complete Examples

Product Listing with Filters

// Create product list
const productList = dcupl.lists.create({
  modelKey: 'Product',
  listKey: 'products',
});

// Add filters
productList.catalog.query.addCondition([
  { operator: 'eq', attribute: 'status', value: 'active' },
  { operator: 'gte', attribute: 'price', value: 50 },
]);

// Get results with pagination
const products = productList.catalog.query.items({
  start: 0,
  count: 20,
  sort: { price: 'asc' },
});

// Get facets for filtering UI
const categories = productList.catalog.fn.facets({
  attribute: 'category',
});

// Update filter based on user selection
productList.catalog.query.addCondition({
  operator: 'eq',
  attribute: 'category',
  value: { key: 'electronics' },
});

Shopping Cart Implementation

// Create cart list
const cart = dcupl.lists.create({
  modelKey: 'Product',
  listKey: 'shoppingCart',
  listItemKeys: [],
});

// Add item to cart
function addToCart(productKey: string) {
  const currentKeys = cart.catalog.query.items().map((item) => item.key);
  if (!currentKeys.includes(productKey)) {
    currentKeys.push(productKey);
    const newCart = dcupl.lists.create({
      modelKey: 'Product',
      listKey: 'shoppingCart',
      listItemKeys: currentKeys,
    });
  }
}

// Remove from cart
function removeFromCart(productKey: string) {
  const currentKeys = cart.catalog.query
    .items()
    .map((item) => item.key)
    .filter((key) => key !== productKey);

  dcupl.lists.destroy({ listKey: 'shoppingCart' });
  const newCart = dcupl.lists.create({
    modelKey: 'Product',
    listKey: 'shoppingCart',
    listItemKeys: currentKeys,
  });
}

// Get cart total
function getCartTotal(): number {
  const aggregation = cart.catalog.fn.aggregate({
    attribute: 'price',
    types: ['sum'],
  });
  return aggregation.sum || 0;
}

Multi-List Dashboard

// Create multiple lists for dashboard
const allProducts = dcupl.lists.create({
  modelKey: 'Product',
  listKey: 'allProducts',
});

const newProducts = dcupl.lists.create({
  modelKey: 'Product',
  listKey: 'newProducts',
  query: {
    modelKey: 'Product',
    queries: [{ operator: 'gte', attribute: 'createdAt', value: last30Days }],
  },
});

const featuredProducts = dcupl.lists.create({
  modelKey: 'Product',
  listKey: 'featured',
  query: {
    modelKey: 'Product',
    queries: [{ operator: 'eq', attribute: 'featured', value: true }],
  },
});

// Get dashboard metrics
const metrics = {
  total: allProducts.catalog.query.count(),
  new: newProducts.catalog.query.count(),
  featured: featuredProducts.catalog.query.count(),
  averagePrice: allProducts.catalog.fn.aggregate({
    attribute: 'price',
    types: ['avg'],
  }).avg,
};

See Also