Skip to content

Commit

Permalink
API Docs: ActorOptions (#4419)
Browse files Browse the repository at this point in the history
* 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 #4414

* inspection event argument

* inspect accepts an observer object
  • Loading branch information
audionerd authored Nov 9, 2023
1 parent e1c34b5 commit 3eeb502
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 2 deletions.
12 changes: 12 additions & 0 deletions packages/core/src/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,18 @@ export class Actor<TLogic extends AnyActorLogic>
};
}

/**
* 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<unknown>;
public getPersistedState(options?: unknown): Snapshot<unknown> {
return this.logic.getPersistedState(this._state, options);
Expand Down
111 changes: 109 additions & 2 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1669,8 +1669,30 @@ export interface StateConfig<
}

export interface ActorOptions<TLogic extends AnyActorLogic> {
/**
* 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<any, any>;
/**
* The custom `id` for referencing this service.
Expand All @@ -1683,8 +1705,6 @@ export interface ActorOptions<TLogic extends AnyActorLogic> {
*/
devTools?: boolean | DevToolsAdapter; // TODO: add enhancer options

sync?: boolean;

/**
* The system ID to register this actor under
*/
Expand All @@ -1694,6 +1714,19 @@ export interface ActorOptions<TLogic extends AnyActorLogic> {
*/
input?: InputFrom<TLogic>;

/**
* 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<TActorLogic>
// | InternalStateFrom<TActorLogic>;
Expand All @@ -1704,6 +1737,80 @@ export interface ActorOptions<TLogic extends AnyActorLogic> {
*/
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: InspectionEvent) => void);
Expand Down

0 comments on commit 3eeb502

Please sign in to comment.