Skip to content

Commit

Permalink
chore: created deleteExpiredStates() method, updated the docs and fix…
Browse files Browse the repository at this point in the history
…ed broken tests
  • Loading branch information
zoemaas committed Feb 21, 2024
1 parent 4d5432c commit 3c9bd88
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ describe('Database entities tests', (): void => {
state: 'test_state',
type: 'b40b8474-58a2-4b23-9fde-bd6ee1902cdb',
completedAt: new Date(),
tenantId: 'test_tenant_id',
ttl: 30000
tenantId: 'test_tenant_id'
}

const xstateEventEntity: StateEntity = stateEntityFrom(xstateEvent)
Expand All @@ -41,7 +40,6 @@ describe('Database entities tests', (): void => {
expect(fromDb?.type).toEqual(xstateEvent.type)
expect(fromDb?.state).toEqual(xstateEvent.state)
expect(fromDb?.tenantId).toEqual(xstateEvent.tenantId)
expect(fromDb?.ttl).toEqual(xstateEvent.ttl)
expect(fromDb?.completedAt).toEqual(xstateEvent.completedAt)
})
})
20 changes: 7 additions & 13 deletions packages/data-store/src/__tests__/xstatePersistence.store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ describe('Database entities tests', (): void => {
createdAt: new Date(),
updatedAt: new Date(),
completedAt: new Date(),
tenantId: 'test_tenant_id',
ttl: 30000
tenantId: 'test_tenant_id'
}

const savedXStoreEvent: State = await xstateStore.saveState(xstateEvent)
Expand All @@ -45,8 +44,7 @@ describe('Database entities tests', (): void => {
state: 'test_state',
type: 'b40b8474-58a2-4b23-9fde-bd6ee1902cdb',
completedAt: new Date(),
tenantId: 'test_tenant_id',
ttl: 30000
tenantId: 'test_tenant_id'
}

const stateEvent1: NonPersistedXStateStoreEvent = await xstateStore.saveState({...xstateEvent})
Expand All @@ -64,8 +62,7 @@ describe('Database entities tests', (): void => {
state: 'test_state',
type: 'b40b8474-58a2-4b23-9fde-bd6ee1902cdb',
completedAt: new Date(),
tenantId: 'test_tenant_id',
ttl: 30000
tenantId: 'test_tenant_id'
}

const savedXStoreEvent1: State = await xstateStore.saveState(xstateEvent)
Expand All @@ -90,33 +87,30 @@ describe('Database entities tests', (): void => {
type: 'test_type_1',
createdAt: now,
completedAt: new Date(),
tenantId: 'test_tenant_id',
ttl: 30000
tenantId: 'test_tenant_id'
}
const middleXstateEvent: NonPersistedXStateStoreEvent = {
state: 'test_state',
type: 'test_type_2',
createdAt: new Date(+now - 30000),
completedAt: new Date(),
tenantId: 'test_tenant_id',
ttl: 30000
tenantId: 'test_tenant_id'
}

const oldestXstateEvent: NonPersistedXStateStoreEvent = {
state: 'test_state',
type: 'test_type_3',
createdAt: new Date(+now - 60000),
completedAt: new Date(),
tenantId: 'test_tenant_id',
ttl: 30000
tenantId: 'test_tenant_id'
}

await xstateStore.saveState(oldestXstateEvent)
await xstateStore.saveState(middleXstateEvent)
await xstateStore.saveState(newestXstateEvent)

await xstateStore.deleteState({
where: `created_at < datetime('now', '-30 seconds')`
where: `created_at < datetime('now', :ttl)`, parameters: { ttl: '-30 seconds' }
})

await expect(xstateStore.getState({ type: 'test_type_1'})).resolves.toBeDefined()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ export class StateEntity extends BaseEntity {

@Column({ name: 'tenant_id', type: 'varchar', nullable: true })
tenantId?: string

@Column({ name: 'ttl', default: 0 })
ttl!: number
}

export const stateEntityFrom = (args: NonPersistedXStateStoreEvent): StateEntity => {
Expand All @@ -34,6 +31,5 @@ export const stateEntityFrom = (args: NonPersistedXStateStoreEvent): StateEntity
stateEntity.type = args.type
stateEntity.completedAt = args.completedAt
stateEntity.tenantId = args.tenantId
stateEntity.ttl = args.ttl
return stateEntity
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export type SaveStateArgs = {
updatedAt?: Date
completedAt?: Date
tenantId?: string
ttl: number
}

export type GetStateArgs = Pick<SaveStateArgs, 'type'>
Expand All @@ -31,5 +30,4 @@ export type State = {
updatedAt: Date
completedAt?: Date
tenantId?: string
ttl: number
}
3 changes: 1 addition & 2 deletions packages/data-store/src/xstatePersistence/XStateStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ export class XStateStore extends IAbstractXStateStore {
createdAt: state.createdAt,
updatedAt: state.updatedAt,
completedAt: state.completedAt,
tenantId: state.tenantId,
ttl: state.ttl
tenantId: state.tenantId
}
}
}
36 changes: 16 additions & 20 deletions packages/xstate-persistence/plugin.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,27 @@
"IXStatePersistence": {
"components": {
"schemas": {
"DeleteStateArgs": {
"DeleteExpiredStatesArgs": {
"type": "object",
"properties": {
"where": {
"type": "string"
"duration": {
"type": "number"
},
"parameters": {
"$ref": "#/components/schemas/ObjectLiteral"
"dialect": {
"$ref": "#/components/schemas/SQLDialect"
}
},
"required": [
"where"
"duration",
"dialect"
]
},
"ObjectLiteral": {
"type": "object",
"description": "Interface of the simple literal object with any string keys."
"SQLDialect": {
"type": "string",
"enum": [
"SQLite3",
"PostgreSQL"
]
},
"DeleteStateResult": {
"$ref": "#/components/schemas/VoidResult"
Expand Down Expand Up @@ -67,17 +71,13 @@
},
"tenantId": {
"type": "string"
},
"ttl": {
"type": "number"
}
},
"required": [
"state",
"type",
"createdAt",
"updatedAt",
"ttl"
"updatedAt"
]
},
"XStatePersistenceEvent": {
Expand Down Expand Up @@ -125,15 +125,11 @@
},
"tenantId": {
"type": "string"
},
"ttl": {
"type": "number"
}
},
"required": [
"state",
"type",
"ttl"
"type"
]
},
"OnEventResult": {
Expand All @@ -144,7 +140,7 @@
"deleteExpiredStates": {
"description": "Deletes the state of an xstate machine in the database.",
"arguments": {
"$ref": "#/components/schemas/DeleteStateArgs"
"$ref": "#/components/schemas/DeleteExpiredStatesArgs"
},
"returnType": {
"$ref": "#/components/schemas/DeleteStateResult"
Expand Down
26 changes: 23 additions & 3 deletions packages/xstate-persistence/src/agent/XStatePersistence.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {DeleteStateArgs, IAbstractXStateStore} from "@sphereon/ssi-sdk.data-store";
import {IAbstractXStateStore} from "@sphereon/ssi-sdk.data-store";
import {IAgentPlugin,} from '@veramo/core'

import {
DeleteExpiredStatesArgs,
DeleteStateResult,
OnEventResult,
RequiredContext,
Expand Down Expand Up @@ -56,10 +57,29 @@ export class XStatePersistence implements IAgentPlugin {
return this.store.getState(args)
}

private async deleteExpiredStates(args: DeleteStateArgs): Promise<DeleteStateResult> {
private async deleteExpiredStates(args: DeleteExpiredStatesArgs): Promise<DeleteStateResult> {
if (!this.store) {
return Promise.reject(Error('No store available in options'))
}
return this.store.deleteState(args)
switch (args.dialect) {
case 'SQLite3':
const sqLiteParams = {
where: `created_at < datetime('now', :duration)`,
params: {
duration: `-${args.duration / 1000} seconds`
}
}
return this.store.deleteState(sqLiteParams)
case 'PostgreSQL':
const postgreSQLParams = {
where: 'created_at < :duration',
params: {
duration: `NOW() - '${args.duration / 1000} seconds'::interval`
}
}
return this.store.deleteState(postgreSQLParams)
default:
return Promise.reject(Error('Invalid database dialect'))
}
}
}
16 changes: 11 additions & 5 deletions packages/xstate-persistence/src/types/IXStatePersistence.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {DeleteStateArgs} from "@sphereon/ssi-sdk.data-store";
import {IPluginMethodMap} from '@veramo/core'

import {
DeleteExpiredStatesArgs,
DeleteStateResult,
LoadStateArgs,
LoadStateResult,
Expand All @@ -22,7 +22,8 @@ export interface IXStatePersistence extends IPluginMethodMap {
/**
* Loads the state of an xstate machine from the database.
*
* @param args
* @param args LoadStateArgs
* type of the event
*
* @returns state or null
*
Expand All @@ -34,15 +35,20 @@ export interface IXStatePersistence extends IPluginMethodMap {
/**
* Deletes the state of an xstate machine in the database.
*
* @param args
* @param args DeleteExpiredStatesArgs
* duration in milliseconds
* dialect 'SQLite3' or 'PostgreSQL'
*
* @beta This API is likely to change without a BREAKING CHANGE notice
*/
deleteExpiredStates(args: DeleteStateArgs): Promise<DeleteStateResult>
deleteExpiredStates(args: DeleteExpiredStatesArgs): Promise<DeleteStateResult>

/**
* Persists the state whenever an event is emitted
* @param event
* @param event XStatePersistenceEvent
* type of the event ('every' is the only one available at the moment)
* data of the event
*
* @param context
* @beta This API is likely to change without a BREAKING CHANGE notice
*/
Expand Down
12 changes: 9 additions & 3 deletions packages/xstate-persistence/src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,20 @@ export enum XStatePersistenceEventType {
EVERY = 'every'
}

export type PersistStateArgs = SaveStateArgs
export enum SQLDialect {
SQLite3 = 'SQLite3',
PostgreSQL = 'PostgreSQL',
}

export type DeleteExpiredStatesArgs = {
duration: number,
dialect: SQLDialect,
}

export type NonPersistedXStatePersistenceEvent = SaveStateArgs

export type LoadStateArgs = GetStateArgs

export type PersistStateResult = VoidResult

export type LoadStateResult = State

export type DeleteStateResult = VoidResult
Expand Down

0 comments on commit 3c9bd88

Please sign in to comment.