From 3eeb5024516cd480afc4f599dfd0b4afd3f72480 Mon Sep 17 00:00:00 2001 From: Eric Skogen Date: Thu, 9 Nov 2023 10:22:22 -0600 Subject: [PATCH] API Docs: ActorOptions (#4419) * inspect * clock * logger * ActorOptions.state and Actor#getPersistedState * cross-reference state and getPersistedState * getSnapshot link * sync was removed * mark parent as `@internal` * ActorOptions.inspect: update `@example` Based on https://github.com/statelyai/xstate/pull/4414 * inspection event argument * inspect accepts an observer object --- packages/core/src/interpreter.ts | 12 ++++ packages/core/src/types.ts | 111 ++++++++++++++++++++++++++++++- 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/packages/core/src/interpreter.ts b/packages/core/src/interpreter.ts index b6d7db3bff..3e658a4cda 100644 --- a/packages/core/src/interpreter.ts +++ b/packages/core/src/interpreter.ts @@ -598,6 +598,18 @@ export class Actor }; } + /** + * Obtain the internal state of the actor, which can be persisted. + * + * @remarks + * The internal state can be persisted from any actor, not only machines. + * + * Note that the persisted state is not the same as the snapshot from {@link Actor.getSnapshot}. Persisted state represents the internal state of the actor, while snapshots represent the actor's last emitted value. + * + * Can be restored with {@link ActorOptions.state} + * + * @see https://stately.ai/docs/persistence + */ public getPersistedState(): Snapshot; public getPersistedState(options?: unknown): Snapshot { return this.logic.getPersistedState(this._state, options); diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 8b87e5fb9a..71dd71c524 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -1669,8 +1669,30 @@ export interface StateConfig< } export interface ActorOptions { + /** + * The clock that is responsible for setting and clearing timeouts, such as delayed events and transitions. + * + * @remarks + * You can create your own “clock”. The clock interface is an object with two functions/methods: + * + * - `setTimeout` - same arguments as `window.setTimeout(fn, timeout)` + * - `clearTimeout` - same arguments as `window.clearTimeout(id)` + * + * By default, the native `setTimeout` and `clearTimeout` functions are used. + * + * For testing, XState provides `SimulatedClock`. + * + * @see {@link Clock} + * @see {@link SimulatedClock} + */ clock?: Clock; + /** + * Specifies the logger to be used for log(...) actions. Defaults to the native console.log method. + */ logger?: (...args: any[]) => void; + /** + * @internal + */ parent?: ActorRef; /** * The custom `id` for referencing this service. @@ -1683,8 +1705,6 @@ export interface ActorOptions { */ devTools?: boolean | DevToolsAdapter; // TODO: add enhancer options - sync?: boolean; - /** * The system ID to register this actor under */ @@ -1694,6 +1714,19 @@ export interface ActorOptions { */ input?: InputFrom; + /** + * Initializes actor logic from a specific persisted internal state. + * + * @remarks + * + * If the state is compatible with the actor logic, when the actor is started it will be at that persisted state. + * Actions from machine actors will not be re-executed, because they are assumed to have been already executed. + * However, invocations will be restarted, and spawned actors will be restored recursively. + * + * Can be generated with {@link Actor.getPersistedState}. + * + * @see https://stately.ai/docs/persistence + */ // state?: // | PersistedStateFrom // | InternalStateFrom; @@ -1704,6 +1737,80 @@ export interface ActorOptions { */ src?: string | AnyActorLogic; + /** + * A callback function or observer object which can be used to inspect actor system updates. + * + * @remarks + * If a callback function is provided, it can accept an inspection event argument. The types of inspection events that can be observed include: + * + * - `@xstate.actor` - An actor ref has been created in the system + * - `@xstate.event` - An event was sent from a source actor ref to a target actor ref in the system + * - `@xstate.snapshot` - An actor ref emitted a snapshot due to a received event + * + * @example + * ```ts + * import { createMachine } from 'xstate'; + * + * const machine = createMachine({ + * // ... + * }); + * + * const actor = createActor(machine, { + * inspect: (inspectionEvent) => { + * if (inspectionEvent.actorRef === actor) { + * // This event is for the root actor + * } + * + * if (inspectionEvent.type === '@xstate.actor') { + * console.log(inspectionEvent.actorRef); + * } + * + * if (inspectionEvent.type === '@xstate.event') { + * console.log(inspectionEvent.sourceRef); + * console.log(inspectionEvent.actorRef); + * console.log(inspectionEvent.event); + * } + * + * if (inspectionEvent.type === '@xstate.snapshot') { + * console.log(inspectionEvent.actorRef); + * console.log(inspectionEvent.event); + * console.log(inspectionEvent.snapshot); + * } + * } + * }); + * ``` + * + * Alternately, an observer object (`{ next?, error?, complete? }`) can be provided: + * + * @example + * ```ts + * const actor = createActor(machine, { + * inspect: { + * next: (inspectionEvent) => { + * if (inspectionEvent.actorRef === actor) { + * // This event is for the root actor + * } + * + * if (inspectionEvent.type === '@xstate.actor') { + * console.log(inspectionEvent.actorRef); + * } + * + * if (inspectionEvent.type === '@xstate.event') { + * console.log(inspectionEvent.sourceRef); + * console.log(inspectionEvent.actorRef); + * console.log(inspectionEvent.event); + * } + * + * if (inspectionEvent.type === '@xstate.snapshot') { + * console.log(inspectionEvent.actorRef); + * console.log(inspectionEvent.event); + * console.log(inspectionEvent.snapshot); + * } + * } + * } + * }); + * ``` + */ inspect?: | Observer | ((inspectionEvent: InspectionEvent) => void);