Skip to content

Session Context

This document describes the public API available to plugins and functions through the session context object returned by the getAPI() function.

When a plugin action or a function is executed, it receives a session context object that provides access to session properties and methods for interacting with the adaptor:ex framework. This context is created by the Session.getAPI() method and contains both read-only properties and function references.

The API object returned by getAPI(state, action, date) contains the following properties and methods.

Properties

_id

  • Type: string
  • Description: Unique identifier of the session instance (database document ID)
  • Read-only: Yes

name

  • Type: string
  • Description: Unique name of the session. Either user-provided or auto-generated from the session ID
  • Read-only: Yes

date

  • Type: Date
  • Description: Current date/time or the original dispatch date if the state is being redispatched (e.g., after server restart)
  • Default: Current time from adaptor.now()
  • Read-only: Yes

reference_collections

  • Type: Array<string>
  • Description: List of collection names whose documents can be referenced by this session. Includes game collections, plugin collections, and system collections (sessions, levels)
  • Read-only: Yes

references

  • Type: Array<Object>
  • Description: Local store of active references for this session
  • Structure: Each reference object contains:
  • collection - Collection name
  • query - Query used to find documents
  • name - Reference name
  • Read-only: Yes

event

  • Type: events.EventEmitter
  • Description: Event emitter instance for plugin-to-session interaction. Plugins can emit custom events or listen to session events
  • Read-only: Reference is read-only, but you can use .emit() and .on() methods

status

  • Type: events.EventEmitter
  • Description: Event emitter for session status changes and incidents
  • Read-only: Reference is read-only, but you can use .emit() and .on() methods

log

  • Type: ContextLog
  • Description: Contextualized logger for this specific state and action
  • Context: Includes game name, session name, state name, and action name
  • Usage: log.debug(), log.info(), log.warn(), log.error(), log.trace()
  • Read-only: Yes

state

  • Type: State
  • Description: Current state object
  • Properties:
  • id - Unique identifier (auto-generated)
  • name - State name as defined in editor
  • path - Array of path names from previous states
  • Read-only: Yes

action

  • Type: Action
  • Description: Current action object being executed
  • Properties:
  • id - Auto-generated unique identifier
  • name - Auto-generated action name (e.g., "set_1")
  • action - Original action type name
  • plugin - Plugin name
  • mode - Either 'run' or 'listen'
  • schema - Action form schema
  • payload - Action data (deep cloned)
  • Read-only: Yes

level

  • Type: Object
  • Description: Level information for the current session
  • Properties:
  • name - Level name
  • _id - Level database document ID
  • Read-only: Yes

variables

  • Type: Variables
  • Description: Variable resolution and data management system for working with session data, references, and database items
  • Read-only: Yes (but provides methods to manipulate data)

The variables system provides ways to store, retrieve, and manipulate data using dot-notation paths and [[variable]] placeholders. It handles data across multiple scopes including session-local storage, state data, database items, level configuration, and more.

See:

Variables System Documentation for a complete reference.

Example:

// Resolve variable in string
const message = await session.variables.review('Hello [[Player.name]]!');

// Get referenced item
const player = await session.variables.get('Player');

// Update data
await session.variables.set('Player.score', 100);


Methods

createReference(collection, query, reference, options)

Creates or updates a reference to document(s) in a specified collection.

Parameters:

  • collection (string) - Name of the collection where the reference will be created
  • query (Object<string, *>) - MongoDB-style query object to find documents
  • reference (string) - Name for this reference
  • options (Object, optional) - Query options
  • multiple (boolean, default: true) - Whether to reference multiple documents
  • sort (Object) - Sort order for query results
  • limit (number) - Maximum number of documents to reference
  • skip (number) - Number of documents to skip

Returns: Promise<void>

Throws: adaptor.InvalidError if the collection doesn't exist

Description: Creates a bidirectional reference between the session and document(s) in the collection. Replaces any existing reference with the same name. References are stored both locally in the session and in the database documents themselves.

Example:

// Reference a single item document
await session.createReference('characters', { name: 'Ada' }, 'protagonist', { multiple: false });

// Reference multiple items
await session.createReference('inventory', { eatable: true }, 'food', { multiple: true, limit: 5 });

getCallback(listener_callback)

Wraps a listener callback function to enable persistent listener functionality and proper error handling.

Parameters:

  • listener_callback (Function) - The plugin's listener callback function

Returns: Function - Wrapped callback function

Description:

This function wraps a plugin's listener callback to provide:

  • Persistent listeners: Supports "keep listening" functionality where listeners can queue incoming events when muted
  • Error handling: Automatically catches and forwards errors through the session's error handling system
  • Queue management: Manages event queuing when listener is muted or stalled, with configurable max queue length

The wrapped callback:

  • Only executes when listener status is "active"
  • Queues events when listener is "muted" or "stalled"
  • Removes oldest events if max queue length is exceeded
  • Emits "queueing" status event when adding to queue
  • Returns undefined if listener has been canceled

Listener Status:

  • active - Listener actively processes incoming events
  • muted - Listener queues incoming events (for persistent listeners)
  • stalled - Listener just dispatched a next state (prevents race conditions)

Example:

async function waitForEvent(data, session) {
  const callback = session.getCallback(async (eventData) => {
    // Process event
    session.log(`Event received: ${eventData.message}`)

    // Call next to transition to next state
    session.next(payload.next)
  })

  // Register callback with your event source
  someEventSource.on('event', callback)

  return {
    cancel: () => someEventSource.off('event', callback)
  }
}

getListener(action_id)

Retrieves a listener from the current active listeners by action ID.

Parameters:

  • action_id (string) - The action ID corresponding to the listener

Returns: Listener | undefined - Listener object if found, undefined otherwise

Listener Properties:

  • id - Unique identifier matching the action ID
  • _id - Database document ID
  • name - Action name
  • action - Action type
  • plugin - Plugin name
  • state - Origin state data
  • date - Timestamp when listener was started
  • session - Session database document ID
  • path - State path array
  • payload - Listener action payload data
  • status - 'active', 'stalled', or 'muted'
  • persistent - Whether listener persists across state changes
  • max_queue_length - Maximum queue size (if persistent)
  • queue - Queued events (if muted/stalled)
  • callback - Wrapped callback function
  • cancel - Cancel function
  • mute - Mute function (if provided)
  • unmute - Unmute function (if provided)

Example:

const listener = session.getListener(session.action.id);
if (listener) {
  console.log(`Listener status: ${listener.status}`);
  console.log(`Queue length: ${listener.queue.length}`);
}

next(next_state)

Dispatches the next state in the session flow.

Parameters:

  • next_state (string | Object) - State identifier
  • As string: State name to dispatch
  • As Object: Query object with name or id property

Returns: void

Description:

Triggers a state transition.

  • Adds the state to the state stack for processing
  • Automatically dispatches the state if no other states are pending

Example:

// Dispatch by name
session.next('GAME_OVER');

// Dispatch by query
session.next({ id: 'state_abc123' });

// Common pattern in plugin action function
function waitForSomething(data, session) {
    my_api.on(data.channel, () => {
            session.next(data.next)
    })
}

splitPath(init_state, path_name)

Creates a new parallel execution path and dispatches its initial state.

Parameters:

  • init_state (string) - Name of the state to dispatch in the new path
  • path_name (string, optional) - Identifier name for the path (for flow visualization)

Returns: void

Description:

Creates a parallel execution path that runs alongside existing paths. This is useful for: - Concurrent storylines - Background processes - Multi-user interactions - Parallel game mechanics

The new path: - Runs independently of other paths - Has its own state transitions - Can have its own listeners - Is tracked separately in the flow

Example:

// Start a background timer path
session.splitPath('TIMER_START', 'background_timer');

// Start a parallel storyline
session.splitPath('SIDE_QUEST_INTRO', 'side_quest_path');

joinPath(path)

Cancels all listeners associated with a specific path, effectively merging or closing that path.

Parameters:

  • path (Array<string>) - Array of path names representing the path to join/close

Returns: Promise<void>

Description:

Cancels all listeners where: - The listener's path contains all elements in the provided path array, OR - The provided path contains all elements in the listener's path

This effectively closes a parallel path created by splitPath(). All listeners in that path are canceled, and any queued events are discarded.

Database Support:

  • MongoDB: Uses $all and $setIsSubset operators
  • NeDB: Uses a custom workaround due to missing operators

Example:

// Close a background timer path
await session.joinPath(['background_timer']);

// Close a side quest path
await session.joinPath(['side_quest_path']);

// Common pattern: close path after completion
async function run(payload, session) {
  // Do final work
  await finalizeQuest();

  // Close this path
  await session.joinPath(session.state.path);

  // Return to main flow
  session.next('MAIN_STORY_RESUME');
}