Skip to content

Commit

Permalink
[@xstate/store] Fix store inspection issues (#5037)
Browse files Browse the repository at this point in the history
* Fix XState Store inspection

* make `ActorRefLike['send']` not callable

* Update packages/xstate-store/src/store.ts

Co-authored-by: Mateusz Burzyński <[email protected]>

* Add comment link

---------

Co-authored-by: Mateusz Burzyński <[email protected]>
  • Loading branch information
davidkpiano and Andarist committed Aug 18, 2024
1 parent 3e5424d commit a36eb37
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 5 deletions.
11 changes: 8 additions & 3 deletions packages/xstate-store/src/store.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { InspectionEvent } from 'xstate';
import {
Recipe,
EventPayloadMap,
Expand All @@ -11,7 +10,8 @@ import {
StorePropertyAssigner,
Observer,
StoreContext,
InteropSubscribable
InteropSubscribable,
InspectionEvent
} from './types';

const symbolObservable: typeof Symbol.observable = (() =>
Expand Down Expand Up @@ -96,7 +96,7 @@ function createStoreCore<
}

const store: Store<TContext, StoreEvent> = {
sessionId: 'test',
sessionId: uniqueId(),
send(event) {
inspectionObservers.get(store)?.forEach((observer) => {
observer.next?.({
Expand Down Expand Up @@ -341,3 +341,8 @@ export function createStoreTransition<
return { ...snapshot, context: currentContext };
};
}

// create a unique 6-char id
export function uniqueId() {
return Math.random().toString(36).slice(6);
}
72 changes: 70 additions & 2 deletions packages/xstate-store/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { InspectionEvent } from 'xstate';

export type EventPayloadMap = Record<string, {} | null | undefined>;

export type ExtractEventsFromPayloadMap<T extends EventPayloadMap> = Values<{
Expand Down Expand Up @@ -197,3 +195,73 @@ export type EventObject = {
type: string;
};
type Values<T> = T[keyof T];

export type InspectionEvent =
| InspectedSnapshotEvent
| InspectedEventEvent
| InspectedActorEvent
| InspectedMicrostepEvent
| InspectedActionEvent;

interface BaseInspectionEventProperties {
rootId: string; // the session ID of the root
/**
* The relevant actorRef for the inspection event.
*
* - For snapshot events, this is the `actorRef` of the snapshot.
* - For event events, this is the target `actorRef` (recipient of event).
* - For actor events, this is the `actorRef` of the registered actor.
*/
actorRef: ActorRefLike;
}

export interface InspectedSnapshotEvent extends BaseInspectionEventProperties {
type: '@xstate.snapshot';
event: AnyEventObject; // { type: string, ... }
snapshot: Snapshot<unknown>;
}

interface InspectedMicrostepEvent extends BaseInspectionEventProperties {
type: '@xstate.microstep';
event: AnyEventObject; // { type: string, ... }
snapshot: Snapshot<unknown>;
_transitions: unknown[];
}

export interface InspectedActionEvent extends BaseInspectionEventProperties {
type: '@xstate.action';
action: {
type: string;
params: Record<string, unknown>;
};
}

export interface InspectedEventEvent extends BaseInspectionEventProperties {
type: '@xstate.event';
// The source might not exist, e.g. when:
// - root init events
// - events sent from external (non-actor) sources
sourceRef: ActorRefLike | undefined;
event: AnyEventObject; // { type: string, ... }
}

interface AnyEventObject {
type: string;
[key: string]: any;
}

export interface InspectedActorEvent extends BaseInspectionEventProperties {
type: '@xstate.actor';
}

// export type ActorRefLike = Pick<
// AnyActorRef,
// 'sessionId' | 'send' | 'getSnapshot'
// >;

export type ActorRefLike = {
sessionId: string;
// https://github.com/statelyai/xstate/pull/5037/files#r1717036732
send: (...args: never) => void;
getSnapshot: () => any;
};

0 comments on commit a36eb37

Please sign in to comment.