Last active
March 21, 2025 08:10
-
-
Save JamieMason/c78e27f4281049a6d9b72f6cf9782fb8 to your computer and use it in GitHub Desktop.
Revisions
-
JamieMason revised this gist
Jan 24, 2025 . 1 changed file with 6 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -132,6 +132,12 @@ export function logInspectionEvent(event: InspectionEvent): void { ['actor', event.action.params?.to?.id], ]); break; default: logWithColor(event, [ ['internal', event.type], ['action', event.action?.type], ['actor', event.actorRef?.id], ]); } break; } -
JamieMason revised this gist
Jan 23, 2025 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -35,6 +35,7 @@ const isVisibleByEventName = { 'xstate.stopChild': true, } as const; // taken from https://tailscan.com/colors const stylesByName = { action: 'color:#a78bfa', // violet 400 spawn: 'color:#a3e635', // green 400 -
JamieMason revised this gist
Jan 23, 2025 . 1 changed file with 14 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -23,6 +23,18 @@ You'll notice type errors such as `ts: Property 'id' does not exist on type 'Act ```ts import type { InspectionEvent, StateValue } from 'xstate'; const isVisibleByEventName = { '@xstate.action': true, '@xstate.actor': false, '@xstate.event': true, '@xstate.microstep': true, '@xstate.snapshot': false, 'xstate.emit': true, 'xstate.sendTo': true, 'xstate.spawnChild': true, 'xstate.stopChild': true, } as const; const stylesByName = { action: 'color:#a78bfa', // violet 400 spawn: 'color:#a3e635', // green 400 @@ -35,6 +47,7 @@ const stylesByName = { } as const; export function logInspectionEvent(event: InspectionEvent): void { if (isVisibleByEventName[event.type] === false) return; switch (event.type) { case '@xstate.snapshot': { logWithColor(event, [ @@ -80,6 +93,7 @@ export function logInspectionEvent(event: InspectionEvent): void { break; } case '@xstate.action': { if (isVisibleByEventName[event.action?.type] === false) return; switch (event.action?.type) { case 'xstate.emit': logWithColor(event, [ -
JamieMason revised this gist
Jan 23, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -75,7 +75,7 @@ export function logInspectionEvent(event: InspectionEvent): void { ['internal', event.type], ['event', event.event?.type], ['actor', event.actorRef?.id], ['internal', `\n ${stateNotation}`], ]); break; } -
JamieMason revised this gist
Jan 23, 2025 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -70,11 +70,12 @@ export function logInspectionEvent(event: InspectionEvent): void { break; } case '@xstate.microstep': { const stateNotation = getStateNotation(event.snapshot?.value).sort().join('\n '); logWithColor(event, [ ['internal', event.type], ['event', event.event?.type], ['actor', event.actorRef?.id], ['internal', `\n${stateNotation}`], ]); break; } -
JamieMason revised this gist
Jan 23, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,7 +4,7 @@ A small `inspect` function to log events to the browser console, when you expand ## Screenshot  ## Usage -
JamieMason revised this gist
Jan 23, 2025 . 1 changed file with 44 additions and 28 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -24,19 +24,22 @@ You'll notice type errors such as `ts: Property 'id' does not exist on type 'Act import type { InspectionEvent, StateValue } from 'xstate'; const stylesByName = { action: 'color:#a78bfa', // violet 400 spawn: 'color:#a3e635', // green 400 stop: 'color:#f87171', // red 400 actor: 'color:inherit', arrow: 'color:inherit', event: 'color:#38bdf8', // sky 400 internal: 'color:#94a3b8', // slate 400 snapshot: 'color:inherit', } as const; export function logInspectionEvent(event: InspectionEvent): void { switch (event.type) { case '@xstate.snapshot': { logWithColor(event, [ ['internal', event.type], ['snapshot', event.actorRef?.id], ]); break; } @@ -76,30 +79,43 @@ export function logInspectionEvent(event: InspectionEvent): void { break; } case '@xstate.action': { switch (event.action?.type) { case 'xstate.emit': logWithColor(event, [ ['internal', event.type], ['action', event.action?.type], ['event', event.action.params?.event?.type], ['actor', event.actorRef?.id], ]); break; case 'xstate.stopChild': logWithColor(event, [ ['internal', event.type], ['stop', event.action?.type], ['actor', event.actorRef?.id], ['arrow', '➤'], ['actor', event.action.params?.src], ]); break; case 'xstate.spawnChild': logWithColor(event, [ ['internal', event.type], ['spawn', event.action?.type], ['actor', event.actorRef?.id], ['arrow', '➤'], ['actor', event.action.params?.src], ]); break; case 'xstate.sendTo': logWithColor(event, [ ['internal', event.type], ['action', event.action?.type], ['event', event.action.params?.event?.type], ['actor', event.actorRef?.id], ['arrow', '➤'], ['actor', event.action.params?.to?.id], ]); break; } break; } -
JamieMason revised this gist
Jan 23, 2025 . 1 changed file with 67 additions and 39 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,79 +16,107 @@ const [state, send, actor] = useActor(myMachine, { ## Implementation Adds colours to the browser console output, see [MDN: Styling console output](https://developer.mozilla.org/en-US/docs/Web/API/console#styling_console_output). You'll notice type errors such as `ts: Property 'id' does not exist on type 'ActorRefLike'` – but they can have an ID. ```ts import type { InspectionEvent, StateValue } from 'xstate'; const stylesByName = { action: 'color:#F48FB1', actor: 'color:inherit', arrow: 'color:inherit', event: 'color:#81D4FA', internal: 'color:#999', } as const; export function logInspectionEvent(event: InspectionEvent): void { switch (event.type) { case '@xstate.snapshot': { logWithColor(event, [ ['internal', event.type], ['actor', event.actorRef?.id], ]); break; } case '@xstate.event': { if (event.sourceRef?.id && event.actorRef?.id) { logWithColor(event, [ ['internal', event.type], ['event', event.event?.type], ['actor', event.sourceRef?.id], ['internal', '➤'], ['actor', event.actorRef?.id], ]); } else { logWithColor(event, [ ['internal', event.type], ['event', event.event?.type], ['actor', event.actorRef?.id], ]); } break; } case '@xstate.actor': { const actorId = event.actorRef?.id; logWithColor(event, [ ['internal', event.type], ['actor', actorId], ]); break; } case '@xstate.microstep': { logWithColor(event, [ ['internal', event.type], ['event', event.event?.type], ['actor', event.actorRef?.id], ['internal', getStateNotation(event.snapshot?.value).sort().join('\n ')], ]); break; } case '@xstate.action': { if (event.action?.type === 'xstate.emit') { logWithColor(event, [ ['internal', event.type], ['action', event.action?.type], ['event', event.action.params?.event?.type], ['actor', event.actorRef?.id], ]); } else if (event.action?.type === 'xstate.stopChild' || event.action?.type === 'xstate.spawnChild') { logWithColor(event, [ ['internal', event.type], ['action', event.action?.type], ['actor', event.actorRef?.id], ['arrow', '➤'], ['actor', event.action.params?.src], ]); } else if (event.action?.type === 'xstate.sendTo') { logWithColor(event, [ ['internal', event.type], ['action', event.action?.type], ['event', event.action.params?.event?.type], ['actor', event.actorRef?.id], ['arrow', '➤'], ['actor', event.action.params?.to?.id], ]); } break; } } } function logWithColor(event: InspectionEvent, values: [styleName: Exclude<keyof typeof stylesByName, number | symbol>, value: string][]): void { console.groupCollapsed(values.map(([_, value]) => `%c${value}`).join(' '), ...values.map(([styleName]) => stylesByName[styleName])); console.log(event); console.groupEnd(); } function getStateNotation(stateValue: StateValue): string[] { if (typeof stateValue === 'string') { return [stateValue]; } const valueKeys = Object.keys(stateValue); return valueKeys.concat(...valueKeys.map(key => getStateNotation(stateValue[key]!).map(s => `${key}.${s}`))); } ``` -
JamieMason revised this gist
Jan 23, 2025 . 1 changed file with 18 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -50,21 +50,33 @@ export function logInspectionEvent(event: InspectionEvent): void { break; } case '@xstate.actor': { const actorId = event.actorRef?.id; console.groupCollapsed(`%c${internalEvent} %c${actorId}`, style.internalEvent, style.actor); break; } case '@xstate.microstep': { const actorId = event.actorRef?.id; const eventType = event.event?.type; const stateValue = getStateValueStrings(event.snapshot.value).sort().join('\n '); console.groupCollapsed(`%c${internalEvent} %c${eventType} %c${actorId}\n %c${stateValue}`, style.internalEvent, style.eventType, style.actor, style.internalEvent); break; } case '@xstate.action': { const actorId = event.actorRef?.id; const actionType = event.action?.type; if (actionType === 'xstate.emit') { const eventType = event.action.params?.event?.type; console.groupCollapsed(`%c${internalEvent} %c${actionType} %c${actorId} %c${eventType}`, style.internalEvent, style.action, style.actor, style.eventType); } else if (actionType === 'xstate.stopChild' || actionType === 'xstate.spawnChild') { const childSrc = event.action.params?.src; console.groupCollapsed(`%c${internalEvent} %c${actionType} %c${actorId} ➤ %c${childSrc}`, style.internalEvent, style.action, style.actor, style.actor); } else if (actionType === 'xstate.sendTo') { const targetId = event.action.params?.to?.id; const eventType = event.action.params?.event?.type; console.groupCollapsed(`%c${internalEvent} %c${actionType} %c${eventType} %c${actorId} ➤ %c${targetId}`, style.internalEvent, style.action, style.eventType, style.actor, style.actor); } // console.groupCollapsed(`%c${internalEvent} %c${actionType} %c${actorId}`, style.internalEvent, style.action, style.actor); break; } } -
JamieMason revised this gist
Jan 22, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,7 +4,7 @@ A small `inspect` function to log events to the browser console, when you expand ## Screenshot  ## Usage -
JamieMason revised this gist
Jan 22, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -43,7 +43,7 @@ export function logInspectionEvent(event: InspectionEvent): void { const sourceId = event.sourceRef?.id; const actorId = event.actorRef?.id; if (sourceId && actorId) { console.groupCollapsed(`%c${internalEvent} %c${eventType} %c${sourceId} ➤ ${actorId}`, style.internalEvent, style.eventType, style.actor); } else { console.groupCollapsed(`%c${internalEvent} %c${eventType} %c${actorId}`, style.internalEvent, style.eventType, style.actor); } -
JamieMason revised this gist
Jan 22, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,7 +4,7 @@ A small `inspect` function to log events to the browser console, when you expand ## Screenshot  ## Usage -
JamieMason revised this gist
Jan 22, 2025 . 1 changed file with 12 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -21,9 +21,9 @@ I know right 🤮, mainly this is down to [the API for applying colours to brows If you do any clean up on this, please comment and let me know. You'll notice there is a `ts: Property 'id' does not exist on type 'ActorRefLike'` – but they can have an ID. ```ts import type { InspectionEvent, StateValue } from 'xstate'; export function logInspectionEvent(event: InspectionEvent): void { const internalEvent = event.type; const style = { action: 'color:#F48FB1', @@ -57,7 +57,8 @@ function logInspectionEvent(event: InspectionEvent): void { case '@xstate.microstep': { const subjectId = event.actorRef?.id; const eventType = event.event?.type; const stateValue = getStateValueStrings(event.snapshot.value).sort().join('\n '); console.groupCollapsed(`%c${internalEvent} %c${eventType} %c${subjectId}\n %c${stateValue}`, style.internalEvent, style.eventType, style.actor, style.internalEvent); break; } case '@xstate.action': { @@ -70,4 +71,12 @@ function logInspectionEvent(event: InspectionEvent): void { console.log(event); console.groupEnd(); } function getStateValueStrings(stateValue: StateValue): string[] { if (typeof stateValue === 'string') { return [stateValue]; } const valueKeys = Object.keys(stateValue); return valueKeys.concat(...valueKeys.map(key => getStateValueStrings(stateValue[key]!).map(s => key + '.' + s))); } ``` -
JamieMason revised this gist
Jan 22, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -18,7 +18,7 @@ const [state, send, actor] = useActor(myMachine, { I know right 🤮, mainly this is down to [the API for applying colours to browser console logs](https://developer.mozilla.org/en-US/docs/Web/API/console#styling_console_output) and this is about 30 minutes' work. If you do any clean up on this, please comment and let me know. You'll notice there is a `ts: Property 'id' does not exist on type 'ActorRefLike'` – but they can have an ID. ```ts import { type InspectionEvent } from 'xstate'; -
JamieMason revised this gist
Jan 22, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -18,7 +18,7 @@ const [state, send, actor] = useActor(myMachine, { I know right 🤮, mainly this is down to [the API for applying colours to browser console logs](https://developer.mozilla.org/en-US/docs/Web/API/console#styling_console_output) and this is about 30 minutes' work. If you do any clean up on this, please comment and let me know. You'll notice there is a `ts: Property 'id' does not exist on type 'ActorRefLike'` – but they do have an ID. ```ts import { type InspectionEvent } from 'xstate'; -
JamieMason revised this gist
Jan 22, 2025 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,7 @@ # Log XState inspector events to the Browser Console A small `inspect` function to log events to the browser console, when you expand a group you see a log of the full event object. ## Screenshot  -
JamieMason revised this gist
Jan 22, 2025 . 1 changed file with 4 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,9 @@ # Log XState inspector events to the Browser Console ## Screenshot  ## Usage ```ts -
JamieMason created this gist
Jan 22, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,67 @@ # Log XState inspector events to the Browser Console ## Usage ```ts const [state, send, actor] = useActor(myMachine, { inspect: logInspectionEvent, }); ``` ## Implementation I know right 🤮, mainly this is down to [the API for applying colours to browser console logs](https://developer.mozilla.org/en-US/docs/Web/API/console#styling_console_output) and this is about 30 minutes' work. If you do any clean up on this, please comment and let me know. ```ts import { type InspectionEvent } from 'xstate'; function logInspectionEvent(event: InspectionEvent): void { const internalEvent = event.type; const style = { action: 'color:#F48FB1', actor: 'color:inherit', eventType: 'color:#81D4FA', internalEvent: 'color:#999', } as const; switch (event.type) { case '@xstate.snapshot': { const actor = event.actorRef?.id; console.groupCollapsed(`%c${internalEvent} %c${actor}`, style.internalEvent, style.actor); break; } case '@xstate.event': { const eventType = event.event?.type; const sourceId = event.sourceRef?.id; const actorId = event.actorRef?.id; if (sourceId && actorId) { console.groupCollapsed(`%c${internalEvent} %c${sourceId} %c${eventType} ➤ %c${actorId}`, style.internalEvent, style.actor, style.eventType, style.actor); } else { console.groupCollapsed(`%c${internalEvent} %c${eventType} %c${actorId}`, style.internalEvent, style.eventType, style.actor); } break; } case '@xstate.actor': { const subjectId = event.actorRef?.id; console.groupCollapsed(`%c${internalEvent} %c${subjectId}`, style.internalEvent, style.actor); break; } case '@xstate.microstep': { const subjectId = event.actorRef?.id; const eventType = event.event?.type; console.groupCollapsed(`%c${internalEvent} %c${eventType} %c${subjectId}`, style.internalEvent, style.eventType, style.actor); break; } case '@xstate.action': { const subjectId = event.actorRef?.id; const actionType = event.action?.type; console.groupCollapsed(`%c${internalEvent} %c${actionType} %c${subjectId}`, style.internalEvent, style.action, style.actor); break; } } console.log(event); console.groupEnd(); } ```