@idpass/data-collect-core / EntityStoreImpl
Class: EntityStoreImpl
Defined in: components/EntityStore.ts:92
Entity store implementation for managing current entity state with change tracking.
The EntityStoreImpl provides the current state view in the event sourcing architecture. It maintains both the initial state (from last sync/load) and the current modified state for each entity, enabling conflict resolution and change tracking.
Key responsibilities:
- State Management: Maintains current entity state derived from events.
- Change Tracking: Tracks changes between initial and current state.
- Duplicate Detection: Manages potential duplicate entity pairs.
- Search Operations: Provides flexible entity querying capabilities.
- Sync Coordination: Marks entities as synced and manages sync states.
- External ID Mapping: Maps between internal and external system IDs.
Architecture:
- Uses pluggable storage adapters for different persistence backends.
- Implements CQRS query side - provides read operations for entities.
- Maintains entity pairs (initial + modified) for conflict resolution.
- Supports flexible search criteria with MongoDB-style queries.
Examples
Basic usage:
const entityStore = new EntityStoreImpl(storageAdapter);
await entityStore.initialize();
// Save entity state
await entityStore.saveEntity(initialEntity, modifiedEntity);
// Retrieve entity
const entityPair = await entityStore.getEntity('entity-123');
if (entityPair) {
console.log('Initial state:', entityPair.initial);
console.log('Current state:', entityPair.modified);
console.log('Has changes:', entityPair.initial.version !== entityPair.modified.version);
}
Search operations:
// Find all adults
const adults = await entityStore.searchEntities([
{ "data.age": { $gte: 18 } },
{ "type": "individual" }
]);
// Find groups by name pattern
const families = await entityStore.searchEntities([
{ "data.name": { $regex: /family/i } },
{ "type": "group" }
]);
Duplicate management:
// Save potential duplicates found during entity creation
await entityStore.savePotentialDuplicates([
{ entityGuid: 'person-123', duplicateGuid: 'person-456' }
]);
// Get all potential duplicates for review
const duplicates = await entityStore.getPotentialDuplicates();
// Resolve duplicates after manual review
await entityStore.resolvePotentialDuplicates(resolvedDuplicates);
Implements
Constructors
Constructor
new EntityStoreImpl(
entityStorageAdapter):EntityStoreImpl
Defined in: components/EntityStore.ts:111
Creates a new EntityStoreImpl instance.
Parameters
entityStorageAdapter
Storage adapter for persistence (IndexedDB, PostgreSQL, etc.).
Returns
EntityStoreImpl
Example
// With IndexedDB for browser
const indexedDbAdapter = new IndexedDbEntityStorageAdapter('tenant-123');
const browserEntityStore = new EntityStoreImpl(indexedDbAdapter);
// With PostgreSQL for server
const postgresAdapter = new PostgresEntityStorageAdapter(connectionString, 'tenant-123');
const serverEntityStore = new EntityStoreImpl(postgresAdapter);
Methods
closeConnection()
closeConnection():
Promise<void>
Defined in: components/EntityStore.ts:122
Closes database connections and cleans up resources.
Should be called when the EntityStore is no longer needed to prevent memory leaks.
Returns
Promise<void>
A Promise that resolves when the connection is closed.
Implementation of
initialize()
initialize():
Promise<void>
Defined in: components/EntityStore.ts:134
Initializes the entity store and prepares it for operations.
This method must be called before any other operations.
Returns
Promise<void>
A Promise that resolves when the store is initialized.
Throws
When storage initialization fails.
Implementation of
deleteEntity()
deleteEntity(
id):Promise<void>
Defined in: components/EntityStore.ts:147
Deletes an entity from the store.
⚠️ WARNING: This permanently removes the entity and cannot be undone!
Parameters
id
string
Internal database ID of the entity to delete.
Returns
Promise<void>
A Promise that resolves when the entity is deleted.
Throws
When deletion fails.
Implementation of
searchEntities()
searchEntities(
criteria):Promise<EntityPair[]>
Defined in: components/EntityStore.ts:174
Searches entities using flexible criteria.
Supports MongoDB-style query syntax for complex searches.
Parameters
criteria
Search criteria array with query conditions.
Returns
Promise<EntityPair[]>
Array of entity pairs matching the criteria.
Example
// Search for adults
const adults = await entityStore.searchEntities([
{ "data.age": { $gte: 18 } },
{ "type": "individual" }
]);
// Search for groups containing "family"
const families = await entityStore.searchEntities([
{ "data.name": { $regex: /family/i } },
{ "type": "group" }
]);
Implementation of
getEntity()
getEntity(
id):Promise<EntityPair|null>
Defined in: components/EntityStore.ts:200
Retrieves a specific entity by its internal database ID.
Parameters
id
string
Internal database ID of the entity.
Returns
Promise<EntityPair | null>
Entity pair with initial and current state, or null if not found.
Example
const entityPair = await entityStore.getEntity('entity-123');
if (entityPair) {
console.log('Found entity:', entityPair.modified.data.name);
// Check if entity has local changes
const hasChanges = entityPair.initial.version !== entityPair.modified.version;
if (hasChanges) {
console.log('Entity has unsaved changes');
}
} else {
console.log('Entity not found');
}
Implementation of
saveEntity()
saveEntity(
initial,modified):Promise<void>
Defined in: components/EntityStore.ts:231
Saves an entity with both initial and current state for change tracking.
Parameters
initial
Initial state of the entity (from last sync).
modified
Current modified state of the entity.
Returns
Promise<void>
Example
// Save a new entity
const newEntity = {
id: 'person-123',
guid: 'person-123',
type: 'individual',
data: { name: 'John Doe', age: 30 },
version: 1,
lastUpdated: new Date().toISOString(),
syncLevel: SyncLevel.LOCAL
};
// Initially, both states are the same
await entityStore.saveEntity(newEntity, newEntity);
// Later, after modifications
const modifiedEntity = { ...newEntity, data: { ...newEntity.data, age: 31 }, version: 2 };
await entityStore.saveEntity(newEntity, modifiedEntity); // Keep original initial state
Implementation of
getAllEntities()
getAllEntities():
Promise<EntityPair[]>
Defined in: components/EntityStore.ts:252
Retrieves all entities from the store.
Returns
Promise<EntityPair[]>
Array of all entity pairs with initial and current state.
Example
const allEntities = await entityStore.getAllEntities();
// Find entities with local changes
const modifiedEntities = allEntities.filter(pair =>
pair.initial.version !== pair.modified.version
);
console.log(`${modifiedEntities.length} entities have local changes`);
Implementation of
getModifiedEntitiesSince()
getModifiedEntitiesSince(
timestamp):Promise<EntityPair[]>
Defined in: components/EntityStore.ts:275
Retrieves entities modified since a specific timestamp.
Useful for incremental sync operations to identify entities that need synchronization.
Parameters
timestamp
string
ISO timestamp to filter entities from.
Returns
Promise<EntityPair[]>
Array of entity pairs modified after the specified timestamp.
Example
const lastSync = '2024-01-01T00:00:00Z';
const modifiedEntities = await entityStore.getModifiedEntitiesSince(lastSync);
console.log(`${modifiedEntities.length} entities modified since last sync`);
modifiedEntities.forEach(pair => {
console.log(`${pair.modified.data.name} was updated at ${pair.modified.lastUpdated}`);
});
Implementation of
EntityStore.getModifiedEntitiesSince
markEntityAsSynced()
markEntityAsSynced(
id):Promise<void>
Defined in: components/EntityStore.ts:300
Marks an entity as synced by updating its initial state to match current state.
This method is typically called after successfully syncing an entity with the server, to indicate that the current state is now the baseline for future change detection.
Parameters
id
string
Internal database ID of the entity to mark as synced.
Returns
Promise<void>
A Promise that resolves when the entity is marked as synced.
Example
// After successfully syncing entity to server
await syncEntityToServer(entityId);
await entityStore.markEntityAsSynced(entityId);
// Now the entity is considered "clean" with no local changes
const entityPair = await entityStore.getEntity(entityId);
console.log('Has changes:', entityPair.initial.version !== entityPair.modified.version); // false
Implementation of
EntityStore.markEntityAsSynced
getEntityByExternalId()
getEntityByExternalId(
externalId):Promise<EntityPair|null>
Defined in: components/EntityStore.ts:327
Retrieves an entity by its external system ID.
Used for mapping between internal entities and external system records during synchronization operations.
Parameters
externalId
string
External system identifier for the entity.
Returns
Promise<EntityPair | null>
Entity pair if found, null otherwise.
Example
// Find entity by OpenSPP ID
const entityPair = await entityStore.getEntityByExternalId('openspp-123');
if (entityPair) {
console.log('Found entity for external ID:', entityPair.modified.data.name);
// Update with new external data...
}
Implementation of
EntityStore.getEntityByExternalId
savePotentialDuplicates()
savePotentialDuplicates(
duplicates):Promise<void>
Defined in: components/EntityStore.ts:349
Saves potential duplicate entity pairs for manual review.
Parameters
duplicates
object[]
Array of entity GUID pairs that are potential duplicates.
Returns
Promise<void>
A Promise that resolves when duplicates are saved.
Example
// System detected potential duplicates during entity creation
const duplicates = [
{ entityGuid: 'person-123', duplicateGuid: 'person-456' },
{ entityGuid: 'person-789', duplicateGuid: 'person-101' }
];
await entityStore.savePotentialDuplicates(duplicates);
console.log('Potential duplicates saved for review');
Implementation of
EntityStore.savePotentialDuplicates
getPotentialDuplicates()
getPotentialDuplicates():
Promise<object[]>
Defined in: components/EntityStore.ts:374
Retrieves all potential duplicate entity pairs awaiting review.
Returns
Promise<object[]>
Array of entity GUID pairs that are potential duplicates.
Example
const duplicates = await entityStore.getPotentialDuplicates();
for (const pair of duplicates) {
const entity1 = await entityStore.getEntity(pair.entityGuid);
const entity2 = await entityStore.getEntity(pair.duplicateGuid);
console.log('Potential duplicate pair:');
console.log('Entity 1:', entity1?.modified.data);
console.log('Entity 2:', entity2?.modified.data);
// Present to user for manual review...
}
Implementation of
EntityStore.getPotentialDuplicates
resolvePotentialDuplicates()
resolvePotentialDuplicates(
duplicates):Promise<void>
Defined in: components/EntityStore.ts:395
Resolves potential duplicate pairs after manual review.
Parameters
duplicates
object[]
Array of duplicate pairs that have been resolved.
Returns
Promise<void>
A Promise that resolves when duplicates are resolved.
Example
// After user manually reviews and resolves duplicates
const resolvedDuplicates = [
{ entityGuid: 'person-123', duplicateGuid: 'person-456' } // User confirmed these are different people
];
await entityStore.resolvePotentialDuplicates(resolvedDuplicates);
console.log('Duplicate pairs resolved and removed from pending list');
Implementation of
EntityStore.resolvePotentialDuplicates
clearStore()
clearStore():
Promise<void>
Defined in: components/EntityStore.ts:414
Clears all entities from the store.
⚠️ WARNING: This permanently deletes all entity data and cannot be undone! Only use for testing or when intentionally resetting the system.
Returns
Promise<void>
Example
// For testing only
if (process.env.NODE_ENV === 'test') {
await entityStore.clearStore();
console.log('Test entity data cleared');
}