diff --git a/packages/data-store/src/entities/machineState/MachineStateInfoEntity.ts b/packages/data-store/src/entities/machineState/MachineStateInfoEntity.ts index c368f4c1f..6ed5ad644 100644 --- a/packages/data-store/src/entities/machineState/MachineStateInfoEntity.ts +++ b/packages/data-store/src/entities/machineState/MachineStateInfoEntity.ts @@ -1,5 +1,22 @@ import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryColumn, UpdateDateColumn } from 'typeorm' +/** + * @class MachineStateInfoEntity + * Represents a machine state. It allows to continue a machine at a later point in time at the point it was left of + * + * @param {string} instanceId - The instance ID of the machine state. + * @param {string} [sessionId] - The session ID of the machine state. (optional) + * @param {string} machineName - The name of the machine. + * @param {string} [latestStateName] - The name of the latest state. (optional) + * @param {string} latestEventType - The type of the latest event. + * @param {string} state - The current state of the machine. + * @param {Date} createdAt - The date and time when the machine state was created. + * @param {Date} updatedAt - The date and time when the machine state was last updated. + * @param {number} updatedCount - The number of times the machine state has been updated. + * @param {Date} [expiresAt] - The date and time when the machine state expires. (optional) + * @param {Date} [completedAt] - The date and time when the machine state was completed. (optional) + * @param {string} [tenantId] - The ID of the tenant associated with the machine state. (optional) + */ @Entity('MachineStateInfoEntity') export class MachineStateInfoEntity extends BaseEntity { @PrimaryColumn({ name: 'instance_id', type: 'varchar', nullable: false }) diff --git a/packages/data-store/src/machineState/IAbstractMachineStateStore.ts b/packages/data-store/src/machineState/IAbstractMachineStateStore.ts index 988390052..9d0768638 100644 --- a/packages/data-store/src/machineState/IAbstractMachineStateStore.ts +++ b/packages/data-store/src/machineState/IAbstractMachineStateStore.ts @@ -8,11 +8,58 @@ import { StoreMachineStateGetArgs, } from '../types' +/** + * Represents an abstract class for storing machine states. + * This class provides methods for persisting, retrieving, and deleting machine states. + * + * @interface + */ export abstract class IAbstractMachineStateStore { + /** + * Persists the machine state. + * + * @param {StoreMachineStatePersistArgs} state - The object containing the machine state to persist. + * @return {Promise} - A Promise that resolves to the information about the persisted machine state. + */ abstract persistMachineState(state: StoreMachineStatePersistArgs): Promise + + /** + * Finds active machine states based on the given arguments. + * + * @param {StoreMachineStatesFindActiveArgs} args - The arguments for finding active machine states. + * @return {Promise>} - A promise that resolves with an array of active machine states. + */ abstract findActiveMachineStates(args: StoreMachineStatesFindActiveArgs): Promise> + + /** + * Retrieves the state of a particular machine. + * + * @param {StoreMachineStateGetArgs} args - The arguments for retrieving the machine state. + * @returns {Promise} - A promise that resolves to the machine state information. + */ abstract getMachineState(args: StoreMachineStateGetArgs): Promise + + /** + * Finds the machine states based on the given arguments. + * + * @param {StoreFindMachineStatesArgs} [args] - The arguments to filter the machine states. + * @returns {Promise>} - A promise that resolves to an array of machine state information. + */ abstract findMachineStates(args?: StoreFindMachineStatesArgs): Promise> + + /** + * Deletes a machine state. + * + * @param {StoreMachineStateDeleteArgs} args - The arguments for deleting the machine state. + * @return {Promise} - A promise that resolves to a boolean indicating if the machine state was successfully deleted or not. + */ abstract deleteMachineState(args: StoreMachineStateDeleteArgs): Promise + + /** + * Deletes expired machine states from the database. + * + * @param {StoreMachineStateDeleteExpiredArgs} args - The arguments for deleting expired machine states. + * @return {Promise} - A promise that resolves to the number of deleted machine states. + */ abstract deleteExpiredMachineStates(args: StoreMachineStateDeleteExpiredArgs): Promise } diff --git a/packages/data-store/src/machineState/MachineStateStore.ts b/packages/data-store/src/machineState/MachineStateStore.ts index 317038f46..f1dc70c13 100644 --- a/packages/data-store/src/machineState/MachineStateStore.ts +++ b/packages/data-store/src/machineState/MachineStateStore.ts @@ -16,6 +16,9 @@ import { IAbstractMachineStateStore } from './IAbstractMachineStateStore' const debug = Debug('sphereon:ssi-sdk:machine-state:store') +/** + * Represents a data store for managing machine states. + */ export class MachineStateStore extends IAbstractMachineStateStore { private readonly _dbConnection: OrPromise diff --git a/packages/xstate-persistence/README.md b/packages/xstate-persistence/README.md index 0609684ed..74c424b43 100644 --- a/packages/xstate-persistence/README.md +++ b/packages/xstate-persistence/README.md @@ -2,94 +2,180 @@


Sphereon -
XState Persistence (Typescript) +
XState Machine Persistence +
Allows to continue xstate machine at a later point in time +

---- - -**Warning: This package still is in very early development. Breaking changes without notice will happen at this point!** - ---- - -A Veramo contact manager plugin. This plugin manages xstate and identity configurations to third parties and persists them. These configurations can then be used to establish a connection. +The XState Persistence Plugin is designed to manage and persist XState machine states, allowing for durable, long-term +storage of state machines. +This enables applications to save, load, and delete state machine instances, facilitating seamless state management and +recovery across sessions. -The XState Persistence Plugin for Veramo is designed to manage and persist XState machine states, allowing for durable, long-term storage of state machine snapshots. This enables applications to save, load, and delete state machine instances, facilitating seamless state management and recovery across sessions. Features: - Load State: Retrieve the current state of an XState machine from persistent storage. -- Delete Expired States: Automatically remove state instances that have exceeded their lifespan, ensuring efficient use of storage. -- Persist Machine Snapshot: Save snapshots of XState machine states, allowing for recovery and resumption of stateful processes. +- Delete Expired States: Automatically remove state instances that have exceeded their lifespan, or are finished + ensuring efficient use of storage. +- Persist Machine Snapshot: Save snapshots of XState machine states, allowing for recovery and resumption of stateful + processes. This can be done manually or it can be automatically registered with any xstate interpreter instance Installation To add the XState Persistence Plugin to your project, run: ```shell -yarn add @sphereon/xstate-persistence-plugin +yarn add @sphereon/ssi-sdk.xstate-machine-persistence ``` Or if you prefer using npm: ```shell -npm install @sphereon/xstate-persistence-plugin +npm install @sphereon/ssi-sdk.xstate-machine-persistence ``` -Usage +# Usage + Configuring the Plugin with Veramo First, ensure you have Veramo set up in your project. Then, integrate the XState Persistence Plugin as follows: ```typescript import { createAgent } from '@veramo/core' -import { XStatePersistencePlugin } from '@sphereon/xstate-persistence-plugin' +import { MachineStatePersistence, DataStoreMachineStateMigrations, DataStoreMachineStateEntities } from '@sphereon/ssi-sdk.xstate-machine-persistence' + +const dbConnection = await new DataSource({ + type: 'sqlite', + database: ':memory:', + logging: 'all', + migrationsRun: false, + migrations: DataStoreMachineStateMigrations, // Database migrations for the data store, specific for state machines + synchronize: false, + entities: DataStoreMachineStateEntities, // All the entities needed for the data store, related to state machines +}).initialize() const agent = createAgent({ plugins: [ - new XStatePersistencePlugin({ - // Plugin options here + new MachineStatePersistence({ + eventTypes: ['EVERY'], // Enables listening to 'EVERY' events to persist the state on every state change + store: new MachineStateStore(dbConnection), }), ], }) ``` -Persisting a Machine Snapshot +## Automatic registration of state change persistence -To save the current state of an XState machine: +You can use a simple method on an Xstate machine interpreter to automatically persist the latest state on every state +change of the machine, allowing for later continuation of the machine. ```typescript -await agent.persistMachineSnapshot({ - stateId: 'your-state-instanceId', - type: 'YourmachineId', - eventName: 'YOUR_EVENT_NAME', - state: 'serialized-state-here', // Your XState machine state serialized as a string - expiresAt: new Date('2023-01-01'), // Optional expiration date +import { createMachine, interpret } from 'xstate' +import { machineStatePersistRegistration } from '@sphereon/ssi-sdk.xstate-machine-persistence' + +const context = { ...agent.context, agent } +export const exampleMachine = createMachine({ + predictableActionArguments: true, + id: 'example', + context: {}, + initial: 'init', + states: { + init: { + id: 'init', + on: { + finalize: { + target: 'final', + }, + }, + }, + final: { + id: 'final', + type: 'final', + }, + }, }) + +const instance = interpret(exampleMachine).start() + +/** + * - instance is the Xstate Machine interpreter instance + * - context is the agent context + * - machineName is optional. It will be deduced from the machine if not provided. If you use a different name, be sure to use that for any future methods as well + * - instanceId is optional. Allows you to provide your own unique Id. If not provided a random uuid will be generated + */ +const registration = await machineStatePersistRegistration({ instance, context, machineName: exampleMachine.id }) +console.log(JSON.stringify(registration)) +/** + * { + * "machineName": "example", + * "instanceId": "585b72e3-0655-4aee-a575-1234873ea7b0", + * "createdAt": "2024-03-07T22:47:45.445Z" + * } + */ + +// That is all. From this point on the machine will persist the state on every state change. You can use the instanceId value if you want to do anything with the persisted object at a later point in time ``` -Loading a State +## Retrieving machine state info. + +You can retrieve machine state info in 2 ways. If you know the instanceId, you can directly get it. Otherwise you can query for the active, read not finalized or cleaned up, instances of machine states. -To load the latest snapshot of a specific machine type: +Getting a single machine state info object by instance id: ```typescript -const state = await agent.loadState({ - type: 'YourmachineId', -}) +const machineStateInfo = await agent.machineStateGet({ instanceId }) +console.log(JSON.stringify(machineStateInfo, null, 2)) +/** + * { + * "instanceId": "585b72e3-0655-4aee-a575-1234873ea7b0", + * "sessionId": "x:1", <=== The xtsate session id. Please note that this is only unique for a single xstate instance in memory and will be lost accross restarts + * "machineName": "example", + * "latestStateName": "init", <=== The latest state of the xstate machine for easy access + * "latestEventType": "increment", <=== The latest event of the xstate machine for easy access + * "state": { <=== This is the actual Xstate state + * "actions": [], + * "activities": {}, + * "meta": {}, + * .... + * }, + * "createdAt": "2024-03-07T23:00:11.438Z", + * "updatedAt": "2024-03-07T23:00:11.543Z", + * "updatedCount": 1, <=== The amount of updates applied to the persisted state (the amount of events/statechanges) + * "expiresAt": null, <=== If this date-time is set, the machine state will not be used anymore + * "completedAt": null <=== The date-time the instance reached a final state + * } + */ ``` -Deleting Expired States +Getting active machine state info objects by machine name: -To clean up expired states from the storage: +```typescript +const machineStateInfos = await agent.machineStatesFindActive({ machineName: 'example' }) +console.log(JSON.stringify(machineStateInfos[0], null, 2)) +// See console.log example in previous code block +``` -````typescript -await agent.deleteExpiredMachineStates({ -type: 'YourmachineId', // Optional: Specify the machine type to narrow down the deletion -});``` +## Manual persistence and cleanup methods -Contributing +Persisting a Machine Snapshot -Contributions are welcome! Please open an issue or submit a pull request for any bugs, features, or improvements. -License +To save the current state of an XState machine: -This project is licensed under the MIT License. -```` +```typescript +await agent.machineStatePersist({ + instanceId: 'your-state-instanceId', + state: 'You Xstate here', +}) +``` + +Deleting Expired States + +To clean up expired states from the storage: + +```typescript +await agent.machineStatesDeleteExpired({ + deleteDoneStates: false, // Optional: If true, will delete any states that are completed. If false, will delete any expired states, no matter whether they are done or not + machineName: 'example', // Optional: Only delete istances for machines named 'example' +}) +``` diff --git a/packages/xstate-persistence/agent.yml b/packages/xstate-persistence/agent.yml index 4971bc3be..0e750e2ee 100644 --- a/packages/xstate-persistence/agent.yml +++ b/packages/xstate-persistence/agent.yml @@ -18,9 +18,9 @@ dbConnection: synchronize: false migrationsRun: true migrations: - $require: './packages/data-store?t=object#DataStoreMigrations' + $require: './packages/data-store?t=object#DataStoreMachineStateMigrations' entities: - $require: './packages/data-store?t=object#DataStoreMachineStateInfoEntities' + $require: './packages/data-store?t=object#DataStoreMachineStateEntities' server: baseUrl: diff --git a/packages/xstate-persistence/src/__tests__/shared/MachineStatePersistenceAgentLogic.ts b/packages/xstate-persistence/src/__tests__/shared/MachineStatePersistenceAgentLogic.ts index 1b4b04e1a..e15b671b7 100644 --- a/packages/xstate-persistence/src/__tests__/shared/MachineStatePersistenceAgentLogic.ts +++ b/packages/xstate-persistence/src/__tests__/shared/MachineStatePersistenceAgentLogic.ts @@ -28,10 +28,7 @@ export const counterMachine = createMachine({ on: { increment: { actions: assign({ - count: (context) => { - console.log(context.count + 1) - return context.count + 1 - }, + count: (context) => context.count + 1, }), }, finalize: { @@ -137,6 +134,7 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro it('should automatically store xstate state changes', async (): Promise => { const init = await machineStatePersistRegistration({ context, instance, machineName: instance.machine.id }) + console.log(JSON.stringify(init, null, 2)) if (!init) { return Promise.reject(new Error('No init')) } @@ -156,6 +154,7 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro expect(activeStates[0].createdAt).toBeDefined() expect(activeStates[0].state).toBeDefined() expect(activeStates[0].state.context.count).toEqual(1) + console.log(JSON.stringify(activeStates[0], null, 2)) instance.send('increment') // Wait some time since events are async diff --git a/packages/xstate-persistence/src/agent/MachineStatePersistence.ts b/packages/xstate-persistence/src/agent/MachineStatePersistence.ts index 5d37c22e2..e64be249c 100644 --- a/packages/xstate-persistence/src/agent/MachineStatePersistence.ts +++ b/packages/xstate-persistence/src/agent/MachineStatePersistence.ts @@ -80,9 +80,12 @@ export class MachineStatePersistence implements IAgentPlugin { } private async machineStateInit(args: InitMachineStateArgs): Promise { - debug(`machineStateInit for machine name ${args.machineName} and tenant ${args.tenantId}`) - const machineInit = { - ...args, + const { tenantId, machineName, expiresAt } = args + debug(`machineStateInit for machine name ${machineName} and tenant ${tenantId}`) + const machineInit: MachineStateInit = { + machineName, + tenantId, + expiresAt, instanceId: args.instanceId ?? uuidv4(), createdAt: args.createdAt ?? new Date(), } diff --git a/packages/xstate-persistence/src/functions/machineRegistration.ts b/packages/xstate-persistence/src/functions/machineRegistration.ts index dfff1fcc8..ef12002e0 100644 --- a/packages/xstate-persistence/src/functions/machineRegistration.ts +++ b/packages/xstate-persistence/src/functions/machineRegistration.ts @@ -1,8 +1,16 @@ import { IAgentContext } from '@veramo/core' import { DefaultContext, EventObject, Interpreter, StateSchema, TypegenDisabled, Typestate } from 'xstate' -import { InitMachineStateArgs, MachineStateInit, MachineStatePersistEventType } from '../types' +import { IMachineStatePersistence, InitMachineStateArgs, MachineStateInit, MachineStatePersistEventType } from '../types' import { emitMachineStatePersistEvent } from './stateEventEmitter' +/** + * Initialize the machine state persistence. Returns a unique instanceId and the machine name amongst others + * + * @param {Object} opts - The options for initializing the machine state persistence. + * @param {InitMachineStateArgs} opts - The arguments for initializing the machine state. + * @param {IAgentContext} opts.context - The agent context. + * @returns {Promise} - A promise that resolves to the initialized machine state, or undefined if the agent isn't using the Xstate plugin. + */ export const machineStatePersistInit = async ( opts: InitMachineStateArgs & { context: IAgentContext // We use any as this method could be called from an agent with access to, but not exposing this plugin @@ -13,9 +21,19 @@ export const machineStatePersistInit = async ( console.log(`IMachineStatePersistence was not exposed in the current agent. Not initializing new persistence object`) return } - return await context.agent.machineStateInit(args) + return await (context as IAgentContext).agent.machineStateInit(args) } +/** + * This function allows for the persistence of machine state on every xstate transition. It emits an event with the new state + * and other relevant data to be handled by the persistence plugin when enabled. + * + * @param {Object} opts - The options object. + * @param {Interpreter} opts.instance - The XState machine interpreter instance. + * @param {IAgentContext} opts.context - The agent context. + * @param {MachineStateInit} opts.init - The initial persistence options, containing the unique instanceId. + * @returns {Promise} - A promise that resolves when the persistence event is emitted. + */ export const machineStatePersistOnTransition = async < TContext = DefaultContext, TStateSchema extends StateSchema = any, @@ -55,6 +73,13 @@ export const machineStatePersistOnTransition = async < }) } +/** + * Persist the initial state of a machine and register it with the given machine instance. + * + * @param {InitMachineStateArgs & {instance: Interpreter, context: IAgentContext}} args - The options for initializing + * machine state and registering it. + * @returns {Promise} - A promise that resolves to the initial state of the machine, or undefined if the agent isn't using the Xstate plugin. + */ export const machineStatePersistRegistration = async < TContext = DefaultContext, TStateSchema extends StateSchema = any, @@ -65,14 +90,16 @@ export const machineStatePersistRegistration = async < }, TResolvedTypesMeta = TypegenDisabled >( - opts: InitMachineStateArgs & { - instance: Interpreter - context: IAgentContext // We use any as this method could be called from an agent with access to, but not exposing this plugin - } + args: InitMachineStateArgs & + Partial> & { + instance: Interpreter + context: IAgentContext // We use any as this method could be called from an agent with access to, but not exposing this plugin + } ): Promise => { - const init = await machineStatePersistInit(opts) + const machineName = args.machineName ?? args.instance.machine.id ?? args.instance.id + const init = await machineStatePersistInit({ ...args, machineName }) if (init) { - await machineStatePersistOnTransition({ ...opts, init }) + await machineStatePersistOnTransition({ ...args, init }) } return init } diff --git a/packages/xstate-persistence/src/functions/stateEventEmitter.ts b/packages/xstate-persistence/src/functions/stateEventEmitter.ts index 7aa964ead..8958045ca 100644 --- a/packages/xstate-persistence/src/functions/stateEventEmitter.ts +++ b/packages/xstate-persistence/src/functions/stateEventEmitter.ts @@ -2,6 +2,14 @@ import Debug from 'debug' import { MachineStatePersistEvent, RequiredContext } from '../types' const debug = Debug('sphereon:ssi-sdk:machine-state:xstate-persistence') + +/** + * Emits a machine state persistence event. + * + * @param {MachineStatePersistEvent} event - The event to be emitted. + * @param {RequiredContext} context - The required agent context for the event emission. + * @returns {void} + */ export const emitMachineStatePersistEvent = (event: MachineStatePersistEvent, context: RequiredContext) => { debug(`Emitting machine state persistence event '${event.type}' with counter: ${event.data._eventCounter}`) void context.agent.emit(event.type, event.data) diff --git a/packages/xstate-persistence/src/functions/stateMapper.ts b/packages/xstate-persistence/src/functions/stateMapper.ts index e353f7dc1..8fe65c0c8 100644 --- a/packages/xstate-persistence/src/functions/stateMapper.ts +++ b/packages/xstate-persistence/src/functions/stateMapper.ts @@ -3,6 +3,13 @@ import { State } from 'xstate' import { EventObject } from 'xstate/lib/types' import { MachineStatePersistArgs, SerializableState } from '../types' +/** + * Create a machine state info object useful for the store, based on the provided machine info and existing state. + * + * @param {MachineStatePersistArgs} machineInfo - The machine info object. + * @param {Partial} [existingState] - The optional existing state object. + * @returns {StoreMachineStateInfo} - The store machine state info object. + */ export const machineStateToStoreInfo = ( machineInfo: MachineStatePersistArgs, existingState?: Partial @@ -34,6 +41,12 @@ export const machineStateToStoreInfo = ( } } +/** + * Serializes a machine state to a string representation. + * + * @param {State | SerializableState | string} state - The machine state to serialize. + * @returns {string} - The serialized machine state. + */ export const serializeMachineState = (state: State | SerializableState | string): string => { if (typeof state === 'string') { return state @@ -41,6 +54,14 @@ export const serializeMachineState = (state: Stat const jsonState = 'toJSON' in state ? state.toJSON() : state return JSON.stringify(jsonState) } +/** + * Deserializes a serialized machine state. + * + * @template T - The type of the machine's context. + * @template TEvent - The type of the events that the machine handles. + * @param {string} state - The serialized machine state. + * @returns {State} - The deserialized machine state. + */ export const deserializeMachineState = (state: string): State => { return State.create(JSON.parse(state)) } diff --git a/packages/xstate-persistence/src/types/types.ts b/packages/xstate-persistence/src/types/types.ts index 20e6fa291..7ede2945e 100644 --- a/packages/xstate-persistence/src/types/types.ts +++ b/packages/xstate-persistence/src/types/types.ts @@ -9,44 +9,132 @@ import { AnyEventObject, EventObject, HistoryValue, SCXML, StateValue } from 'xs import { IMachineStatePersistence } from './IMachineStatePersistence' +/** + * Represents the options for persisting machine state. + * + * @typedef {Object} MachineStatePersistOpts + * @property {IAbstractMachineStateStore} store - The store used to persist the machine state. + * @property {Array} eventTypes - The types of events to be persisted. + */ export type MachineStatePersistOpts = { store: IAbstractMachineStateStore; eventTypes: Array } +/** + * Enum representing the types of machine state persist events. + * @enum {string} + */ export enum MachineStatePersistEventType { INIT = 'INIT', EVERY = 'EVERY', } +/** + * Represents the arguments for deleting expired states from a machine. + */ export type DeleteExpiredStatesArgs = Pick +/** + * Represents the arguments for finding active states of a store machine. + */ export type FindActiveStatesArgs = StoreMachineStatesFindActiveArgs +/** + * Represents the result of a state deletion operation. + * + * @typedef {number} DeleteStateResult + */ export type DeleteStateResult = number +/** + * Represents a machine state persist event. + * + * @typedef {Object} MachineStatePersistEvent + * @property {MachineStatePersistEventType} type - The type of the persist event. + * @property {MachineStatePersistArgs} data - The data associated with the persist event, along with additional properties `_eventCounter` and `_eventDate`. + * @property {number} data._eventCounter - The counter for the persist event. + * @property {Date} data._eventDate - The date and time the persist event occurred. + */ export type MachineStatePersistEvent = { type: MachineStatePersistEventType data: MachineStatePersistArgs & { _eventCounter: number; _eventDate: Date } } +/** + * Represents a RequiredContext class, which is a type definition for the context required by an agent. + * It is used to enforce that the agent context implements the necessary interfaces. + * + * @typeparam T - The type of the machine state persistence. + */ export type RequiredContext = IAgentContext +/** + * Represents the information about the current state of a machine. + * @typedef {Object} MachineStateInfo + * @property {string} id - The ID of the machine. + * @property {SerializableState} state - The serializable state of the machine. + * @property {string} description - The description of the machine state. + */ export type MachineStateInfo = Omit & { state: SerializableState } +/** + * Represents the initial state for a machine. + * + * @typedef {Object} MachineStateInit + * @property {string} instanceId - The unique identifier for the machine instance. + * @property {string} machineName - The name of the machine. + * @property {string} tenantId - The identifier for the tenant associated with the machine. + * @property {Date} createdAt - The date and time when the machine was created. + * @property {Date} expiresAt - The date and time when the machine's state expires. + */ export type MachineStateInit = Pick +/** + * Represents the arguments required to initialize the machine state. + * @typedef {Object} InitMachineStateArgs + * @property {string} machineName - The name of the machine. + * @property {Partial} [additionalArgs] - Additional initialization arguments for the machine state. + */ export type InitMachineStateArgs = Partial & Pick +/** + * Represents the arguments required to persist the machine state. + */ export type MachineStatePersistArgs = Omit & Pick & Partial> +/** + * Represents the arguments required to get machine state. + * @typedef {Object} MachineStateGetArgs + * @property {string} instanceId - The ID of the machine instance. + * @property {string} tenantId - The ID of the tenant the machine belongs to. + */ export type MachineStateGetArgs = Pick + +/** + * Represents the arguments required for deleting a machine state. + * + * @typedef {object} MachineStateDeleteArgs + * @property {string} instanceId - The ID of the machine instance to delete the state for. + * @property {string} tenantId - The ID of the tenant owning the machine instance. + */ export type MachineStateDeleteArgs = Pick +/** + * Represents the serializable state of a machine. + * + * @typedef {Object} SerializableState + * @property {XStateConfig} config - The machine configuration. + */ export type SerializableState = XStateConfig -// Simplified StateConfig object from XState so we have a minimal typed structure +/** + * The configuration for the XState machine state. Simplified StateConfig object from XState so we have a minimal typed structure + * + * @template TContext - The context type for the state. + * @template TEvent - The event type for the state. + */ export interface XStateConfig { value: StateValue context: TContext