Sharpee - Refactoring Standard Library Event Wiring
Sometimes you're testing code and go through the pipeline of connected code and realize something just "smells wrong".
emitSuccess() - for success events with messages
emitError() - for error events with messages
emit() - for generic events
emitMany() - for multiple events at once
createEvent() - to create events without emitting
resolveMessageId() - to resolve short message IDs to full ones
Where all we needed was:
event() - append an event to the event source
We also added the turn number to the base event. We documented this in ADRs 039-042.
We're also explicitly defining all event data for each action like this:
/**
* Event data types for the taking action
*
* These interfaces define the structure of data emitted by the taking action
*/
import { EntityId } from '@sharpee/core';
/**
* Data for the 'if.event.taken' event
*
* Emitted when an item is successfully taken
*/
export interface TakenEventData {
/** The name of the item that was taken */
item: string;
/** Where the item was taken from (entity ID) */
fromLocation?: EntityId;
/** Name of container/supporter it was taken from */
container?: string;
/** True if taken from a container */
fromContainer?: boolean;
/** True if taken from a supporter */
fromSupporter?: boolean;
}
/**
* Data for 'action.error' events from taking action
*
* Different error reasons have different data requirements
*/
export interface TakingErrorData {
/** The specific error reason */
reason:
| 'no_target' // No object specified
| 'cant_take_self' // Trying to take yourself
| 'already_have' // Already carrying the item
| 'cant_take_room' // Trying to take a room
| 'fixed_in_place' // Item is scenery/fixed
| 'container_full' // Inventory is full
| 'too_heavy' // Item is too heavy
| 'cant_reach'; // Item is not reachable
/** Name of the item (when applicable) */
item?: string;
/** Additional context for the error */
details?: Record<string, any>;
}
/**
* Data for the 'if.event.removed' event
*
* Emitted when a worn item is implicitly removed before being taken
*/
export interface RemovedEventData {
/** Whether this removal was implicit (part of another action) */
implicit: boolean;
/** The item that was removed */
item?: string;
}
I didn't need to implement this change, but I think it helps with making a self-documenting architecture.
I suspect this won't be the last iteration through all 40-something standard actions.