Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@ticatec/app-data-manager

ticatec262MIT1.2.4TypeScript support: included

A comprehensive TypeScript library providing hierarchical data manager classes for CRUD operations, pagination, and data management in frontend applications. Features include full list, paged, and stackable data managers with built-in caching and transfor

data-manager, typescript, crud, pagination, frontend, data-service, api, http, caching, infinite-scroll, stack-data, paged-data, data-transformation, web-development

readme

App Data Manager

npm version TypeScript License: MIT

中文文档

A comprehensive TypeScript library that provides a hierarchical set of data manager classes for handling CRUD operations and paginated data retrieval via HTTP requests. This library simplifies data management in frontend applications by abstracting the complexity of data operations and providing a structured approach to managing different types of datasets.

Features

  • Type-safe: Full TypeScript support with comprehensive type definitions
  • Hierarchical Architecture: Well-structured inheritance hierarchy for different data management needs
  • Pagination Support: Built-in pagination handling with both standard and stackable pagination
  • CRUD Operations: Complete Create, Read, Update, Delete functionality
  • Data Transformation: Built-in data conversion and validation support
  • Extensible: Easy to extend and customize for specific use cases
  • Dependency Injection: Service-based architecture for better testability

Installation

npm install @ticatec/app-data-manager

Architecture Overview

The library is built on a hierarchical structure with the following core classes:

BaseDataManager (Abstract)
├── FullListDataManager
└── CommonPagedDataManager (Abstract)
    ├── PagedDataManager
    └── StackDataManager

Core Classes

1. BaseDataManager

Abstract base class for managing data collections with common CRUD operations.

Key Features:

  • Data collection management with local caching
  • CRUD operations with automatic local synchronization
  • Data transformation support via convert function
  • Equality checking via checkEqual function
  • Service-based architecture for data operations

Properties:

  • service: CommonDataService - Data service instance
  • checkEqual: CheckEqual - Function to compare data items
  • convert?: DataConvert - Optional data transformation function
  • list: Array<any> - Current dataset (read-only copy)

Methods:

  • save(data: any, isNew: boolean): Promise<void> - Save/update data
  • remove(item: any): Promise<void> - Delete data
  • append(item: any): void - Add item to beginning of list
  • replace(item: any): void - Replace existing item with matching key
  • removeItem(item: any): void - Remove item from local collection only

2. FullListDataManager

Concrete class inheriting from BaseDataManager for managing complete datasets.

Use Cases:

  • Dropdown lists
  • Static reference data
  • Small to medium-sized complete datasets
  • Configuration lists

Constructor:

protected constructor(
  service: T, 
  keyField: string | CheckEqual, 
  options: ManagerOptions = null
)

Additional Methods:

  • loadData(): Promise<void> - Load complete dataset from service using tagData as filter conditions

Example:

import { FullListDataManager } from '@ticatec/app-data-manager';
import { MyFullListDataService } from './services';

class CategoryManager extends FullListDataManager<MyFullListDataService> {
  constructor() {
    super(
      new MyFullListDataService(), 
      'id', 
      {
        tagData: { status: 'active', type: 'public' } // filter conditions for getList
      }
    );
  }
}

const manager = new CategoryManager();
await manager.loadData(); // Uses tagData as filter conditions
console.log(manager.list); // Filtered category list

3. CommonPagedDataManager

Abstract base class for paginated data management with comprehensive pagination support.

Constructor:

protected constructor(
  service: T, 
  keyField: string | CheckEqual, 
  options: any = null
)

Key Features:

  • Pagination state management (pageNo, pageCount, totalCount)
  • Query criteria handling with tagData-based initialization
  • Configurable pagination parameters
  • Abstract processDataResult method for custom data processing

Static Configuration:

  • CommonPagedDataManager.setRowsPerPage(25) - Set default rows per page
  • CommonPagedDataManager.setRowsKey('rows') - Set rows parameter name
  • CommonPagedDataManager.setPageNoKey('page') - Set page parameter name

Properties:

  • criteria: any - Current query criteria (initialized from options.tagData or empty object)
  • count: number - Total record count

Methods:

  • search(criteria: any): Promise<void> - Search with criteria
  • setPageNo(pageNo: number): Promise<void> - Navigate to specific page
  • setRowsPage(rows: number): Promise<void> - Change page size
  • refresh(): Promise<void> - Refresh current data
  • resetSearch(): Promise<void> - Reset to default criteria

4. PagedDataManager

Concrete implementation of CommonPagedDataManager for standard pagination.

Use Cases:

  • Data tables with pagination
  • Search results with page navigation
  • Standard paginated lists

Additional Properties:

  • pageCount: number - Total number of pages
  • pageNo: number - Current page number

Data Processing:

  • Replaces entire dataset with new page data
  • Simple and straightforward pagination

Constructor:

constructor(
  service: T, 
  keyField: string | CheckEqual, 
  options: any = null
)

Example:

import { PagedDataManager } from '@ticatec/app-data-manager';
import { MyPagingDataService } from './services';

class UserManager extends PagedDataManager<MyPagingDataService> {
  constructor() {
    super(
      new MyPagingDataService(), 
      'userId',
      {
        tagData: { status: 'active' } // default criteria via tagData
      }
    );
  }
}

const manager = new UserManager();
// Will search with default criteria from tagData { status: 'active' }
await manager.resetSearch(); 
console.log(`Page ${manager.pageNo} of ${manager.pageCount}`);
console.log(`Total users: ${manager.count}`);
console.log(manager.list); // Current page users

// Navigate to next page
await manager.setPageNo(2);

// Search with additional criteria
await manager.search({ status: 'active', role: 'admin' });

5. StackDataManager

Concrete implementation of CommonPagedDataManager for stackable pagination ("infinite scroll").

Use Cases:

  • Social media feeds
  • Infinite scroll implementations
  • "Load More" functionality
  • Progressive data loading

Key Features:

  • Accumulates data across pages
  • Automatic duplicate prevention using union method
  • loadMore() and hasMore() methods for progressive loading

Additional Methods:

  • loadMore(): Promise<void> - Load next page and append to existing data
  • hasMore(): boolean - Check if more pages are available

Data Processing:

  • Merges new data with existing dataset
  • Prevents duplicates using checkEqual function

Constructor:

constructor(
  service: T, 
  keyField: string | CheckEqual, 
  options: any = null
)

Example:

import { StackDataManager } from '@ticatec/app-data-manager';
import { MyPagingDataService } from './services';

class FeedManager extends StackDataManager<MyPagingDataService> {
  constructor() {
    super(
      new MyPagingDataService(), 
      'postId',
      {
        tagData: { category: 'technology' } // default criteria via tagData
      }
    );
  }
}

const manager = new FeedManager();
// Will search with default criteria from tagData { category: 'technology' }
await manager.resetSearch();

// Load more content
while (manager.hasMore()) {
  await manager.loadMore();
  console.log(`Loaded ${manager.list.length} posts`);
}

// Search with different criteria
await manager.search({ category: 'science', featured: true });

Interface Definitions

IPagedDataManager

Interface defining the contract for paginated data management operations.

Properties:

  • list: Array<any> - Current dataset (read-only)
  • count: number - Total record count
  • pageNo: number - Current page number
  • pageCount: number - Total number of pages
  • criteria: any - Current query criteria

Methods:

  • refresh(): Promise<void> - Refresh current data
  • resetCriteria(): any - Reset search criteria to default
  • resetSearch(): Promise<void> - Reset to default criteria and reload
  • search(params: any): Promise<void> - Search with new criteria
  • setRowsPage(rows: number): Promise<void> - Change page size
  • setPageNo(value: number): Promise<void> - Navigate to specific page

Implementation:

  • PagedDataManager implements this interface for standard pagination

Example:

import { IPagedDataManager, PagedDataManager } from '@ticatec/app-data-manager';

class UserService extends PagingDataService {
  constructor() {
    super('/api/users');
  }
}

// PagedDataManager implements IPagedDataManager
const userManager: IPagedDataManager = new PagedDataManager(
  new UserService(), 
  'id'
);

await userManager.search({ status: 'active' });
console.log(`Page ${userManager.pageNo} of ${userManager.pageCount}`);
console.log(`Total: ${userManager.count} records`);

Type Definitions

CheckEqual

type CheckEqual = (e1: any, e2: any) => boolean;

Function to determine if two data items are equal (typically by comparing primary keys).

DataConvert

type DataConvert = (item: any, isNew: boolean) => any;

Optional function to transform data items during save/load operations.

ManagerOptions

interface ManagerOptions {
  convert?: DataConvert;    // Data transformation function
  fromTop?: boolean;        // Add new items to top of list (default: true)
  tagData?: any;           // Default query criteria/filter conditions
}

tagData Usage:

  • For paginated managers: Used as default query criteria for searches
  • For FullListDataManager: Used as filter conditions for the getList method

Advanced Usage

Custom Data Manager

import { BaseDataManager } from '@ticatec/app-data-manager';

class CustomDataManager extends BaseDataManager<MyDataService> {
  constructor(service: MyDataService) {
    super(service, 'id', {
      convert: (item, isNew) => ({
        ...item,
        timestamp: isNew ? Date.now() : item.timestamp
      }),
      fromTop: true
    });
  }

  // Custom business logic
  async archiveItem(item: any): Promise<void> {
    const archived = { ...item, archived: true };
    await this.save(archived, false);
  }
}

Service Implementation Example

import { PagingDataService } from '@ticatec/app-data-service';

class MyPagingService extends PagingDataService {
    constructor() {
        super('/api/users');
    }
}

Best Practices

  1. Choose the Right Manager:

    • Use FullListDataManager for small, static datasets
    • Use PagedDataManager for traditional paginated tables
    • Use StackDataManager for infinite scroll or feed-like interfaces
  2. Implement Proper Equality Checking:

    // Good: Use unique identifiers
    const manager = new PagedDataManager(service, 'id');
    
    // Better: Custom comparison for complex keys
    const manager = new PagedDataManager(service, (a, b) => 
      a.companyId === b.companyId && a.userId === b.userId
    );
  3. Handle Errors Gracefully:

    try {
      await manager.search({ query: 'user input' });
    } catch (error) {
      console.error('Search failed:', error);
      // Handle error appropriately
    }
  4. Use Data Conversion for Consistency:

    const options = {
      convert: (item, isNew) => ({
        ...item,
        createdAt: isNew ? new Date().toISOString() : item.createdAt,
        updatedAt: new Date().toISOString()
      })
    };

Dependencies

Browser Support

  • Chrome/Edge 88+
  • Firefox 85+
  • Safari 14+
  • Node.js 14+

Contributing

Issues and pull requests are welcome. Please ensure:

  1. All tests pass
  2. Code follows TypeScript best practices
  3. Documentation is updated for new features
  4. Examples are provided for new functionality

License

Copyright © 2023 Ticatec. All rights reserved.

This library is released under the MIT License. See LICENSE file for details.

Contact