Skip to content

Commit

Permalink
feat(core): Generic Repository events
Browse files Browse the repository at this point in the history
Signed-off-by: Łukasz Przytuła <[email protected]>
  • Loading branch information
Przytua committed Jun 9, 2022
1 parent c297dfd commit c48ec8d
Show file tree
Hide file tree
Showing 21 changed files with 227 additions and 39 deletions.
8 changes: 6 additions & 2 deletions packages/core/src/cache/CacheRepository.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { inject, scoped, Lifecycle } from 'tsyringe'

import { EventEmitter } from '../agent/EventEmitter'
import { InjectionSymbols } from '../constants'
import { Repository } from '../storage/Repository'
import { StorageService } from '../storage/StorageService'
Expand All @@ -8,7 +9,10 @@ import { CacheRecord } from './CacheRecord'

@scoped(Lifecycle.ContainerScoped)
export class CacheRepository extends Repository<CacheRecord> {
public constructor(@inject(InjectionSymbols.StorageService) storageService: StorageService<CacheRecord>) {
super(CacheRecord, storageService)
public constructor(
@inject(InjectionSymbols.StorageService) storageService: StorageService<CacheRecord>,
eventEmitter: EventEmitter
) {
super(CacheRecord, storageService, eventEmitter)
}
}
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export type { FileSystem } from './storage/FileSystem'
export { BaseRecord } from './storage/BaseRecord'
export { InMemoryMessageRepository } from './storage/InMemoryMessageRepository'
export { Repository } from './storage/Repository'
export * from './storage/RepositoryEvents'
export { StorageService } from './storage/StorageService'
export { getDirFromFilePath } from './utils/path'
export { InjectionSymbols } from './constants'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ describe('BasicMessageService', () => {
let eventEmitter: EventEmitter

beforeEach(() => {
basicMessageRepository = new Repository<BasicMessageRecord>(BasicMessageRecord, storageService)
eventEmitter = new EventEmitter(agentConfig)
basicMessageRepository = new Repository<BasicMessageRecord>(BasicMessageRecord, storageService, eventEmitter)
basicMessageService = new BasicMessageService(basicMessageRepository, eventEmitter)
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { inject, scoped, Lifecycle } from 'tsyringe'

import { EventEmitter } from '../../../agent/EventEmitter'
import { InjectionSymbols } from '../../../constants'
import { Repository } from '../../../storage/Repository'
import { StorageService } from '../../../storage/StorageService'
Expand All @@ -8,7 +9,10 @@ import { BasicMessageRecord } from './BasicMessageRecord'

@scoped(Lifecycle.ContainerScoped)
export class BasicMessageRepository extends Repository<BasicMessageRecord> {
public constructor(@inject(InjectionSymbols.StorageService) storageService: StorageService<BasicMessageRecord>) {
super(BasicMessageRecord, storageService)
public constructor(
@inject(InjectionSymbols.StorageService) storageService: StorageService<BasicMessageRecord>,
eventEmitter: EventEmitter
) {
super(BasicMessageRecord, storageService, eventEmitter)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { inject, scoped, Lifecycle } from 'tsyringe'

import { EventEmitter } from '../../../agent/EventEmitter'
import { InjectionSymbols } from '../../../constants'
import { Repository } from '../../../storage/Repository'
import { StorageService } from '../../../storage/StorageService'
Expand All @@ -8,8 +9,11 @@ import { ConnectionRecord } from './ConnectionRecord'

@scoped(Lifecycle.ContainerScoped)
export class ConnectionRepository extends Repository<ConnectionRecord> {
public constructor(@inject(InjectionSymbols.StorageService) storageService: StorageService<ConnectionRecord>) {
super(ConnectionRecord, storageService)
public constructor(
@inject(InjectionSymbols.StorageService) storageService: StorageService<ConnectionRecord>,
eventEmitter: EventEmitter
) {
super(ConnectionRecord, storageService, eventEmitter)
}

public async findByDids({ ourDid, theirDid }: { ourDid: string; theirDid: string }) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { inject, scoped, Lifecycle } from 'tsyringe'

import { EventEmitter } from '../../../agent/EventEmitter'
import { InjectionSymbols } from '../../../constants'
import { Repository } from '../../../storage/Repository'
import { StorageService } from '../../../storage/StorageService'
Expand All @@ -9,8 +10,9 @@ import { CredentialExchangeRecord } from './CredentialExchangeRecord'
@scoped(Lifecycle.ContainerScoped)
export class CredentialRepository extends Repository<CredentialExchangeRecord> {
public constructor(
@inject(InjectionSymbols.StorageService) storageService: StorageService<CredentialExchangeRecord>
@inject(InjectionSymbols.StorageService) storageService: StorageService<CredentialExchangeRecord>,
eventEmitter: EventEmitter
) {
super(CredentialExchangeRecord, storageService)
super(CredentialExchangeRecord, storageService, eventEmitter)
}
}
5 changes: 4 additions & 1 deletion packages/core/src/modules/dids/__tests__/peer-did.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { IndyLedgerService } from '../../ledger'

import { getAgentConfig } from '../../../../tests/helpers'
import { EventEmitter } from '../../../agent/EventEmitter'
import { KeyType } from '../../../crypto'
import { IndyStorageService } from '../../../storage/IndyStorageService'
import { JsonTransformer } from '../../../utils'
Expand All @@ -23,14 +24,16 @@ describe('peer dids', () => {
let didRepository: DidRepository
let didResolverService: DidResolverService
let wallet: IndyWallet
let eventEmitter: EventEmitter

beforeEach(async () => {
wallet = new IndyWallet(config)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
await wallet.createAndOpen(config.walletConfig!)

const storageService = new IndyStorageService<DidRecord>(wallet, config)
didRepository = new DidRepository(storageService)
eventEmitter = new EventEmitter(config)
didRepository = new DidRepository(storageService, eventEmitter)

// Mocking IndyLedgerService as we're only interested in the did:peer resolver
didResolverService = new DidResolverService(config, {} as unknown as IndyLedgerService, didRepository)
Expand Down
8 changes: 6 additions & 2 deletions packages/core/src/modules/dids/repository/DidRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Key } from '../domain/Key'

import { inject, scoped, Lifecycle } from 'tsyringe'

import { EventEmitter } from '../../../agent/EventEmitter'
import { InjectionSymbols } from '../../../constants'
import { Repository } from '../../../storage/Repository'
import { StorageService } from '../../../storage/StorageService'
Expand All @@ -10,8 +11,11 @@ import { DidRecord } from './DidRecord'

@scoped(Lifecycle.ContainerScoped)
export class DidRepository extends Repository<DidRecord> {
public constructor(@inject(InjectionSymbols.StorageService) storageService: StorageService<DidRecord>) {
super(DidRecord, storageService)
public constructor(
@inject(InjectionSymbols.StorageService) storageService: StorageService<DidRecord>,
eventEmitter: EventEmitter
) {
super(DidRecord, storageService, eventEmitter)
}

public findByRecipientKey(recipientKey: Key) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { inject, scoped, Lifecycle } from 'tsyringe'

import { EventEmitter } from '../../../agent/EventEmitter'
import { InjectionSymbols } from '../../../constants'
import { Repository } from '../../../storage/Repository'
import { StorageService } from '../../../storage/StorageService'
Expand All @@ -8,7 +9,10 @@ import { GenericRecord } from './GenericRecord'

@scoped(Lifecycle.ContainerScoped)
export class GenericRecordsRepository extends Repository<GenericRecord> {
public constructor(@inject(InjectionSymbols.StorageService) storageService: StorageService<GenericRecord>) {
super(GenericRecord, storageService)
public constructor(
@inject(InjectionSymbols.StorageService) storageService: StorageService<GenericRecord>,
eventEmitter: EventEmitter
) {
super(GenericRecord, storageService, eventEmitter)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { inject, scoped, Lifecycle } from 'tsyringe'

import { EventEmitter } from '../../../agent/EventEmitter'
import { InjectionSymbols } from '../../../constants'
import { Repository } from '../../../storage/Repository'
import { StorageService } from '../../../storage/StorageService'
Expand All @@ -8,7 +9,10 @@ import { OutOfBandRecord } from './OutOfBandRecord'

@scoped(Lifecycle.ContainerScoped)
export class OutOfBandRepository extends Repository<OutOfBandRecord> {
public constructor(@inject(InjectionSymbols.StorageService) storageService: StorageService<OutOfBandRecord>) {
super(OutOfBandRecord, storageService)
public constructor(
@inject(InjectionSymbols.StorageService) storageService: StorageService<OutOfBandRecord>,
eventEmitter: EventEmitter
) {
super(OutOfBandRecord, storageService, eventEmitter)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { inject, scoped, Lifecycle } from 'tsyringe'

import { EventEmitter } from '../../../agent/EventEmitter'
import { InjectionSymbols } from '../../../constants'
import { Repository } from '../../../storage/Repository'
import { StorageService } from '../../../storage/StorageService'
Expand All @@ -8,7 +9,10 @@ import { ProofRecord } from './ProofRecord'

@scoped(Lifecycle.ContainerScoped)
export class ProofRepository extends Repository<ProofRecord> {
public constructor(@inject(InjectionSymbols.StorageService) storageService: StorageService<ProofRecord>) {
super(ProofRecord, storageService)
public constructor(
@inject(InjectionSymbols.StorageService) storageService: StorageService<ProofRecord>,
eventEmitter: EventEmitter
) {
super(ProofRecord, storageService, eventEmitter)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { inject, scoped, Lifecycle } from 'tsyringe'

import { EventEmitter } from '../../../agent/EventEmitter'
import { InjectionSymbols } from '../../../constants'
import { Repository } from '../../../storage/Repository'
import { StorageService } from '../../../storage/StorageService'
Expand All @@ -8,7 +9,10 @@ import { QuestionAnswerRecord } from './QuestionAnswerRecord'

@scoped(Lifecycle.ContainerScoped)
export class QuestionAnswerRepository extends Repository<QuestionAnswerRecord> {
public constructor(@inject(InjectionSymbols.StorageService) storageService: StorageService<QuestionAnswerRecord>) {
super(QuestionAnswerRecord, storageService)
public constructor(
@inject(InjectionSymbols.StorageService) storageService: StorageService<QuestionAnswerRecord>,
eventEmitter: EventEmitter
) {
super(QuestionAnswerRecord, storageService, eventEmitter)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { inject, scoped, Lifecycle } from 'tsyringe'

import { EventEmitter } from '../../../agent/EventEmitter'
import { InjectionSymbols } from '../../../constants'
import { Repository } from '../../../storage/Repository'
import { StorageService } from '../../../storage/StorageService'
Expand All @@ -8,8 +9,11 @@ import { MediationRecord } from './MediationRecord'

@scoped(Lifecycle.ContainerScoped)
export class MediationRepository extends Repository<MediationRecord> {
public constructor(@inject(InjectionSymbols.StorageService) storageService: StorageService<MediationRecord>) {
super(MediationRecord, storageService)
public constructor(
@inject(InjectionSymbols.StorageService) storageService: StorageService<MediationRecord>,
eventEmitter: EventEmitter
) {
super(MediationRecord, storageService, eventEmitter)
}

public getSingleByRecipientKey(recipientKey: string) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { inject, scoped, Lifecycle } from 'tsyringe'

import { EventEmitter } from '../../../agent/EventEmitter'
import { InjectionSymbols } from '../../../constants'
import { Repository } from '../../../storage/Repository'
import { StorageService } from '../../../storage/StorageService'
Expand All @@ -10,7 +11,10 @@ import { MediatorRoutingRecord } from './MediatorRoutingRecord'
export class MediatorRoutingRepository extends Repository<MediatorRoutingRecord> {
public readonly MEDIATOR_ROUTING_RECORD_ID = 'MEDIATOR_ROUTING_RECORD'

public constructor(@inject(InjectionSymbols.StorageService) storageService: StorageService<MediatorRoutingRecord>) {
super(MediatorRoutingRecord, storageService)
public constructor(
@inject(InjectionSymbols.StorageService) storageService: StorageService<MediatorRoutingRecord>,
eventEmitter: EventEmitter
) {
super(MediatorRoutingRecord, storageService, eventEmitter)
}
}
36 changes: 32 additions & 4 deletions packages/core/src/storage/Repository.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,59 @@
import type { EventEmitter } from '../agent/EventEmitter'
import type { BaseRecord } from './BaseRecord'
import type { RecordSavedEvent, RecordUpdatedEvent, RecordDeletedEvent } from './RepositoryEvents'
import type { BaseRecordConstructor, Query, StorageService } from './StorageService'

import { RecordDuplicateError, RecordNotFoundError } from '../error'

import { RepositoryEventTypes } from './RepositoryEvents'

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export class Repository<T extends BaseRecord<any, any, any>> {
private storageService: StorageService<T>
private recordClass: BaseRecordConstructor<T>
private eventEmitter: EventEmitter

public constructor(recordClass: BaseRecordConstructor<T>, storageService: StorageService<T>) {
public constructor(
recordClass: BaseRecordConstructor<T>,
storageService: StorageService<T>,
eventEmitter: EventEmitter
) {
this.storageService = storageService
this.recordClass = recordClass
this.eventEmitter = eventEmitter
}

/** @inheritDoc {StorageService#save} */
public async save(record: T): Promise<void> {
return this.storageService.save(record)
await this.storageService.save(record)
this.eventEmitter.emit<RecordSavedEvent<T>>({
type: RepositoryEventTypes.RecordSaved,
payload: {
record,
},
})
}

/** @inheritDoc {StorageService#update} */
public async update(record: T): Promise<void> {
return this.storageService.update(record)
await this.storageService.update(record)
this.eventEmitter.emit<RecordUpdatedEvent<T>>({
type: RepositoryEventTypes.RecordUpdated,
payload: {
record,
},
})
}

/** @inheritDoc {StorageService#delete} */
public async delete(record: T): Promise<void> {
return this.storageService.delete(record)
await this.storageService.delete(record)
this.eventEmitter.emit<RecordDeletedEvent<T>>({
type: RepositoryEventTypes.RecordDeleted,
payload: {
record,
},
})
}

/** @inheritDoc {StorageService#getById} */
Expand Down
32 changes: 32 additions & 0 deletions packages/core/src/storage/RepositoryEvents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { BaseEvent } from '../agent/Events'
import type { BaseRecord } from './BaseRecord'

export enum RepositoryEventTypes {
RecordSaved = 'RecordSaved',
RecordUpdated = 'RecordUpdated',
RecordDeleted = 'RecordDeleted',
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export interface RecordSavedEvent<T extends BaseRecord<any, any, any>> extends BaseEvent {
type: typeof RepositoryEventTypes.RecordSaved
payload: {
record: T
}
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export interface RecordUpdatedEvent<T extends BaseRecord<any, any, any>> extends BaseEvent {
type: typeof RepositoryEventTypes.RecordUpdated
payload: {
record: T
}
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export interface RecordDeletedEvent<T extends BaseRecord<any, any, any>> extends BaseEvent {
type: typeof RepositoryEventTypes.RecordDeleted
payload: {
record: T
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { mockFunction } from '../../../tests/helpers'
import { getAgentConfig, mockFunction } from '../../../tests/helpers'
import { EventEmitter } from '../../agent/EventEmitter'
import { ConnectionInvitationMessage } from '../../modules/connections'
import { JsonTransformer } from '../../utils/JsonTransformer'
import { IndyStorageService } from '../IndyStorageService'
Expand All @@ -19,10 +20,12 @@ const invitationJson = {
describe('Repository', () => {
let repository: DidCommMessageRepository
let storageMock: IndyStorageService<DidCommMessageRecord>
let eventEmitter: EventEmitter

beforeEach(async () => {
storageMock = new StorageMock()
repository = new DidCommMessageRepository(storageMock)
eventEmitter = new EventEmitter(getAgentConfig('DidCommMessageRepositoryTest'))
repository = new DidCommMessageRepository(storageMock, eventEmitter)
})

const getRecord = ({ id }: { id?: string } = {}) => {
Expand Down
Loading

0 comments on commit c48ec8d

Please sign in to comment.