- 
                Notifications
    
You must be signed in to change notification settings  - Fork 1
 
Docs: Keyval
- Introduction
 - Installation
 - Overview
 - 
Key Concepts
- IndexedDB Integration
 - CRUD Operations with Keyval
 - JSON Rules Engine for Filtering and Querying
 
 - 
Core Components
KeyvalModule
 - 
Key Factories
idbEntityCrudAdaptorPluginFactoryinitializeIdbDataFactory
 - 
Usage
- Registering the Plugin
 - Performing CRUD Operations
 - Querying Data with Rules
 
 - API Reference
 - Examples
 - Testing
 
The Keyval library provides an Angular module and factory for integrating CRUD operations with IndexedDB in the browser. It serves as an adaptor plugin for @rollthecloudinc/crud and enables persistent data storage, offline capabilities, and complex filtering using rules-based engines (json-rules-engine).
The library is designed to handle scenarios where lightweight, client-side data storage is essential while supporting extensive querying and CRUD workflows.
Install the library along with required dependencies:
npm install keyval idb-keyval @rollthecloudinc/crud @rollthecloudinc/dparamEnsure @angular/common is already installed as it assists in platform detection.
Keyval serves as an Angular module and IndexedDB integration tool for local data storage. It supports dynamic CRUD operations and advanced filtering.
- 
CRUD Operations: 
create,read,update,delete, andqueryoperations powered byidb-keyval. - 
Advanced Querying: Allows queries using rules defined by 
json-rules-engine. - 
Offline Mode: Utilizes 
IndexedDBfor local persistence on the browser platform. - 
Param Evaluation: Dynamically evaluates parameters and configurations via 
@rollthecloudinc/dparam. 
The library uses the lightweight idb-keyval library to interact with the browser's IndexedDB storage mechanism. This provides fast and scalable storage for client-side applications.
The library defines four basic actions: create, read, update, and delete, each implemented with idb-keyval methods (set, getMany, etc.).
json-rules-engine allows complex condition-based filtering of stored data. Custom operators, facts, and rules define how entities are queried based on dynamic conditions.
The KeyvalModule is the primary module of the library, responsible for:
- Registering the IndexedDB plugin (
idb_keyval) with theCrudAdaptorPluginManager. - Injecting services such as 
ParamEvaluatorServicefor dynamic parameter evaluation. - Handling CRUD actions and queries using factories.
 
This factory creates a new CrudAdaptorPlugin for interacting with IndexedDB. It defines CRUD operations and custom query handling.
- 
create(): Persists an object intoIndexedDBusing a unique key and optional prefix. - 
update(): Updates an existing object inIndexedDB. - 
delete(): Deletes an object fromIndexedDB(currently stubbed for development). - 
query(): Retrieves entities that match query parameters and optional filtering rules. 
This factory initializes IndexedDB with predefined data during application load. It loads key-value pairs into the browser's IndexedDB storage, ensuring data is available offline.
To enable the idbEntityCrudAdaptorPlugin, simply import and initialize the KeyvalModule in your Angular application.
Example:
import { KeyvalModule } from 'keyval';
@NgModule({
  declarations: [],
  imports: [
    KeyvalModule // Enables Keyval Module and registers the plugin
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }The create method writes data into IndexedDB using a key and optional prefix.
Example:
const crudInput = {
  object: { id: '123', name: 'TestItem' },
  params: { prefix: 'myApp_' },
  identity: () => of({ identity: 'testKey' })
};
idbEntityCrudAdaptorPluginFactory(paramEvaluatorService).create(crudInput).subscribe(response => {
  console.log('Create successful:', response.success);
});The read method retrieves individual objects based on their keys.
Example (read stubbed for development):
idbEntityCrudAdaptorPluginFactory(paramEvaluatorService).read({}).subscribe(response => {
  console.log('Read successful:', response.success);
});The update method overwrites an object in IndexedDB with a new value.
Example:
const crudInput = {
  object: { id: '123', name: 'UpdatedItem' },
  params: { prefix: 'myApp_' },
  identity: () => of({ identity: 'testKey' })
};
idbEntityCrudAdaptorPluginFactory(paramEvaluatorService).update(crudInput).subscribe(response => {
  console.log('Update successful:', response.success);
});The delete method removes an object from IndexedDB.
Example (delete stubbed for development):
idbEntityCrudAdaptorPluginFactory(paramEvaluatorService).delete({}).subscribe(response => {
  console.log('Delete successful:', response.success);
});The query method retrieves all entities matching a given prefix and filters the results using rules from json-rules-engine.
Example:
const queryInput = {
  params: { prefix: 'myApp_' },
  rule: {
    conditions: {
      all: [
        { fact: 'identity', operator: 'startsWith', value: 'test' }
      ]
    },
    event: { type: 'visible' }
  },
  identity: () => of({ identity: 'identityValue' })
};
idbEntityCrudAdaptorPluginFactory(paramEvaluatorService).query(queryInput).subscribe(response => {
  console.log('Query successful, entities:', response.entities);
});- 
idbEntityCrudAdaptorPluginFactorycreate(input: CrudOperationInput): Observable<CrudOperationResponse>read(input: CrudOperationInput): Observable<CrudOperationResponse>update(input: CrudOperationInput): Observable<CrudOperationResponse>delete(input: CrudOperationInput): Observable<CrudOperationResponse>query(input: CrudCollectionOperationInput): Observable<CrudCollectionOperationResponse>
 - 
initializeIdbDataFactory(config)- Initializes 
IndexedDBwith given data and keys. - 
platformId: Object: Identifies the environment. - 
data: Array<any>: Contains the key-value data. - 
key: (data: any) => IDBValidKey: Defines how keys are generated for the data. 
 - Initializes 
 
Register the plugin in the root module using KeyvalModule.
import { KeyvalModule } from 'keyval';
@NgModule({
  imports: [KeyvalModule],
  bootstrap: [AppComponent]
})
export class AppModule { }Use the query method to fetch data matching the given parameters and rule conditions.
const input = {
  params: { prefix: 'appPrefix_' },
  rule: {
    conditions: { all: [{ fact: 'identity', operator: 'startsWith', value: 'user' }] },
    event: { type: 'visible' }
  }
};
idbEntityCrudAdaptorPluginFactory(paramEvaluatorService).query(input).subscribe(response => {
  console.log('Queried entities:', response.entities);
});Example test for verifying create functionality:
describe('idbEntityCrudAdaptorPluginFactory', () => {
  it('should create an item in IndexedDB', () => {
    const input = {
      object: { id: 'item1', name: 'Test Name' },
      params: { prefix: 'testPrefix_' },
      identity: () => of({ identity: 'itemKey1' })
    };
    idbEntityCrudAdaptorPluginFactory(paramEvaluatorService).create(input).subscribe(response => {
      expect(response.success).toBeTruthy();
    });
  });
});Example test for verifying data factory initialization:
describe('initializeIdbDataFactory', () => {
  it('should initialize IndexedDB with predefined data', () => {
    const data = [{ id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' }];
    const factory = initializeIdbDataFactory({
      data,
      key: ({ data }) => `item_${data.id}`
    });
    factory(platformBrowserId)().subscribe(() => {
      expect(console.log).toHaveBeenCalledWith('data loaded into idb');
    });
  });
});The Keyval library bridges the gap between Angular applications and IndexedDB to create a powerful offline-first solution for client-side data management. By combining CRUD operations, advanced querying, and runtime parameter evaluation, developers can build scalable and modular applications with ease.
For issues, contributions, or questions, feel free to contact us!