@credo-ts/core
Version:
<p align="center"> <br /> <img alt="Credo Logo" src="https://github.com/openwallet-foundation/credo-ts/blob/c7886cb8377ceb8ee4efe8d264211e561a75072d/images/credo-logo.png" height="250px" /> </p> <h1 align="center"><b>Credo - Core</b></h1
153 lines (149 loc) • 6.11 kB
JavaScript
import { RecordDuplicateError } from "../error/RecordDuplicateError.mjs";
import { RecordNotFoundError } from "../error/RecordNotFoundError.mjs";
import "../error/index.mjs";
import { JsonTransformer } from "../utils/JsonTransformer.mjs";
import "../utils/index.mjs";
import { CacheModuleConfig } from "../modules/cache/CacheModuleConfig.mjs";
import { CachedStorageService } from "../modules/cache/CachedStorageService.mjs";
import { RepositoryEventTypes } from "./RepositoryEvents.mjs";
//#region src/storage/Repository.ts
var Repository = class {
constructor(recordClass, storageService, eventEmitter) {
this.recordClass = recordClass;
this.storageService = storageService;
this.eventEmitter = eventEmitter;
}
getStorageService(agentContext) {
try {
if (agentContext.dependencyManager.isRegistered(CachedStorageService, true)) return agentContext.resolve(CachedStorageService);
return this.storageService;
} catch {
return this.storageService;
}
}
supportsLocking(agentContext) {
return this.getStorageService(agentContext).supportsLocking?.(agentContext) ?? false;
}
/** @inheritDoc {StorageService#save} */
async save(agentContext, record) {
await this.getStorageService(agentContext).save(agentContext, record);
this.eventEmitter.emit(agentContext, {
type: RepositoryEventTypes.RecordSaved,
payload: { record: record.clone() }
});
}
/** @inheritDoc {StorageService#update} */
async update(agentContext, record) {
await this.getStorageService(agentContext).update(agentContext, record);
this.eventEmitter.emit(agentContext, {
type: RepositoryEventTypes.RecordUpdated,
payload: { record: record.clone() }
});
}
/** @inheritDoc {StorageService#updateByIdWithLock} */
async updateByIdWithLock(agentContext, id, updateCallback) {
const storageService = this.getStorageService(agentContext);
if (!storageService.updateByIdWithLock) {
const record = await this.getById(agentContext, id);
const updatedRecord = await updateCallback(record);
await this.update(agentContext, record);
return updatedRecord;
}
const updatedRecord = await storageService.updateByIdWithLock(agentContext, this.recordClass, id, updateCallback);
this.eventEmitter.emit(agentContext, {
type: RepositoryEventTypes.RecordUpdated,
payload: { record: updatedRecord.clone() }
});
return updatedRecord;
}
/** @inheritDoc {StorageService#delete} */
async delete(agentContext, record) {
await this.getStorageService(agentContext).delete(agentContext, record);
this.eventEmitter.emit(agentContext, {
type: RepositoryEventTypes.RecordDeleted,
payload: { record: record.clone() }
});
}
/**
* Delete record by id. Throws {RecordNotFoundError} if no record is found
* @param id the id of the record to delete
* @returns
*/
async deleteById(agentContext, id) {
await this.getStorageService(agentContext).deleteById(agentContext, this.recordClass, id);
this.eventEmitter.emit(agentContext, {
type: RepositoryEventTypes.RecordDeleted,
payload: { record: {
id,
type: this.recordClass.type
} }
});
}
/** @inheritDoc {StorageService#getById} */
async getById(agentContext, id) {
return this.getStorageService(agentContext).getById(agentContext, this.recordClass, id);
}
/**
* Find record by id. Returns null if no record is found
* @param id the id of the record to retrieve
* @returns
*/
async findById(agentContext, id) {
try {
return await this.getStorageService(agentContext).getById(agentContext, this.recordClass, id);
} catch (error) {
if (error instanceof RecordNotFoundError) return null;
throw error;
}
}
/** @inheritDoc {StorageService#getAll} */
async getAll(agentContext) {
return this.getStorageService(agentContext).getAll(agentContext, this.recordClass);
}
/** @inheritDoc {StorageService#findByQuery} */
async findByQuery(agentContext, query, queryOptions) {
return this.getStorageService(agentContext).findByQuery(agentContext, this.recordClass, query, queryOptions);
}
/**
* Find a single record by query. Returns null if not found.
* @param query the query
* @param cacheKey optional cache key to use for caching. By default query results are not cached, but if a cache key is provided
* as well as the record allows caching and the agent has a cached storage service enabled it will use the cache.
* @returns the record, or null if not found
* @throws {RecordDuplicateError} if multiple records are found for the given query
*/
async findSingleByQuery(agentContext, query, { cacheKey } = {}) {
const cache = agentContext.resolve(CacheModuleConfig);
const useCacheStorage = cache.useCachedStorageService ?? false;
if (useCacheStorage && cacheKey) {
const recordId = await cache?.cache.get(agentContext, cacheKey) ?? null;
if (recordId !== null) {
const recordJson = await cache?.cache.get(agentContext, recordId);
if (recordJson) return JsonTransformer.fromJSON(recordJson, this.recordClass);
}
}
const records = await this.findByQuery(agentContext, query);
if (records.length > 1) throw new RecordDuplicateError(`Multiple records found for given query '${JSON.stringify(query)}'`, { recordType: this.recordClass.type });
if (records.length < 1) return null;
if (useCacheStorage && cacheKey) {
await cache?.cache.set(agentContext, cacheKey, records[0].id);
await cache?.cache.set(agentContext, records[0].id, records[0].toJSON());
}
return records[0];
}
/**
* Find a single record by query. Throws if not found
* @param query the query
* @returns the record
* @throws {RecordDuplicateError} if multiple records are found for the given query
* @throws {RecordNotFoundError} if no record is found for the given query
*/
async getSingleByQuery(agentContext, query) {
const record = await this.findSingleByQuery(agentContext, query);
if (!record) throw new RecordNotFoundError(`No record found for given query '${JSON.stringify(query)}'`, { recordType: this.recordClass.type });
return record;
}
};
//#endregion
export { Repository };
//# sourceMappingURL=Repository.mjs.map