Skip to content

Commit

Permalink
fix: remove xstate
Browse files Browse the repository at this point in the history
  • Loading branch information
malcolm-kee committed Nov 26, 2022
1 parent a61563c commit 274941c
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 38 deletions.
8 changes: 4 additions & 4 deletions client-src/index.js
Expand Up @@ -142,7 +142,7 @@ const onSocketMessage = {

// Fixes #1042. overlay doesn't clear if errors are fixed but warnings remain.
if (options.overlay) {
overlay.send("DISMISS");
overlay.send({ type: "DISMISS" });
}

sendMessage("Invalid");
Expand Down Expand Up @@ -199,7 +199,7 @@ const onSocketMessage = {
log.info("Nothing changed.");

if (options.overlay) {
overlay.send("DISMISS");
overlay.send({ type: "DISMISS" });
}

sendMessage("StillOk");
Expand All @@ -208,7 +208,7 @@ const onSocketMessage = {
sendMessage("Ok");

if (options.overlay) {
overlay.send("DISMISS");
overlay.send({ type: "DISMISS" });
}

reloadApp(options, status);
Expand Down Expand Up @@ -317,7 +317,7 @@ const onSocketMessage = {
log.info("Disconnected!");

if (options.overlay) {
overlay.send("DISMISS");
overlay.send({ type: "DISMISS" });
}

sendMessage("Close");
Expand Down
7 changes: 2 additions & 5 deletions client-src/overlay.js
Expand Up @@ -3,7 +3,6 @@

import ansiHTML from "ansi-html-community";
import { encode } from "html-entities";
import { interpret } from "@xstate/fsm";
import {
containerStyle,
dismissButtonStyle,
Expand Down Expand Up @@ -143,7 +142,7 @@ const createOverlay = (options) => {
closeButtonElement.ariaLabel = "Dismiss";
closeButtonElement.addEventListener("click", () => {
// eslint-disable-next-line no-use-before-define
overlayService.send("DISMISS");
overlayService.send({ type: "DISMISS" });
});

contentElement.appendChild(headerElement);
Expand Down Expand Up @@ -254,14 +253,12 @@ const createOverlay = (options) => {
}, trustedTypesPolicyName);
}

const overlayMachine = createOverlayMachine({
const overlayService = createOverlayMachine({
showOverlay: ({ level = "error", messages }) =>
show(level, messages, options.trustedTypesPolicyName),
hideOverlay: hide,
});

const overlayService = interpret(overlayMachine).start();

listenToRuntimeError((err) => {
console.log(err);
overlayService.send({
Expand Down
57 changes: 57 additions & 0 deletions client-src/overlay/fsm.js
@@ -0,0 +1,57 @@
/**
* @typedef {Object} StateDefinitions
* @property {{[event: string]: { target: string; actions?: Array<string> }}} [on]
*/

/**
* @typedef {Object} Options
* @property {{[state: string]: StateDefinitions}} states
* @property {object} context;
* @property {string} initial
*/

/**
* @typedef {Object} Implementation
* @property {{[actionName: string]: (ctx: object, event: any) => object}} actions
*/

/**
* A simplified `createMachine` from `@xstate/fsm` with the following differences:
*
* - the returned machine is technically a "service". No `interpret(machine).start()` is needed.
* - the state definition only support `on` and target must be declared with { target: 'nextState', actions: [] } explicitly.
* - event passed to `send` must be an object with `type` property.
* - actions implementation will be [assign action](https://xstate.js.org/docs/guides/context.html#assign-action) if you return any value.
* Do not return anything if you just want to invoke side effect.
*
* The goal of this custom function is to avoid installing the entire `'xstate/fsm'` package, while enabling modeling using
* state machine. You can copy the first parameter into the editor at https://stately.ai/viz to visualize the state machine.
*
* @param {Options} options
* @param {Implementation} implementation
*/
function createMachine({ states, context, initial }, { actions }) {
let currentState = initial;
let currentContext = context;

return {
send: (event) => {
const transitionConfig = states[currentState].on?.[event.type];

if (transitionConfig) {
currentState = transitionConfig.target;
transitionConfig.actions?.forEach((actName) => {
const nextContextValue = actions[actName]?.(currentContext, event);
if (nextContextValue) {
currentContext = {
...currentContext,
...nextContextValue,
};
}
});
}
},
};
}

export default createMachine;
44 changes: 27 additions & 17 deletions client-src/overlay/state-machine.js
@@ -1,4 +1,4 @@
import { createMachine, assign } from "@xstate/fsm";
import createMachine from "./fsm.js";

/**
* @typedef {Object} ShowOverlayData
Expand All @@ -19,15 +19,13 @@ const createOverlayMachine = (options) => {
const { hideOverlay, showOverlay } = options;
const overlayMachine = createMachine(
{
id: "overlay",
initial: "hidden",
context: {
level: "error",
messages: [],
},
states: {
hidden: {
entry: "hideOverlay",
on: {
BUILD_ERROR: {
target: "displayBuildError",
Expand All @@ -41,7 +39,10 @@ const createOverlayMachine = (options) => {
},
displayBuildError: {
on: {
DISMISS: { target: "hidden", actions: "dismissMessages" },
DISMISS: {
target: "hidden",
actions: ["dismissMessages", "hideOverlay"],
},
BUILD_ERROR: {
target: "displayBuildError",
actions: ["appendMessages", "showOverlay"],
Expand All @@ -50,7 +51,10 @@ const createOverlayMachine = (options) => {
},
displayRuntimeError: {
on: {
DISMISS: { target: "hidden", actions: "dismissMessages" },
DISMISS: {
target: "hidden",
actions: ["dismissMessages", "hideOverlay"],
},
RUNTIME_ERROR: {
target: "displayRuntimeError",
actions: ["appendMessages", "showOverlay"],
Expand All @@ -65,18 +69,24 @@ const createOverlayMachine = (options) => {
},
{
actions: {
dismissMessages: assign({
messages: [],
level: "error",
}),
appendMessages: assign({
messages: (context, event) => context.messages.concat(event.messages),
level: (context, event) => event.level || context.level,
}),
setMessages: assign({
messages: (_, event) => event.messages,
level: (context, event) => event.level || context.level,
}),
dismissMessages: () => {
return {
messages: [],
level: "error",
};
},
appendMessages: (context, event) => {
return {
messages: context.messages.concat(event.messages),
level: event.level || context.level,
};
},
setMessages: (context, event) => {
return {
messages: event.messages,
level: event.level || context.level,
};
},
hideOverlay,
showOverlay,
},
Expand Down
11 changes: 0 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Expand Up @@ -51,7 +51,6 @@
"@types/serve-static": "^1.13.10",
"@types/sockjs": "^0.3.33",
"@types/ws": "^8.5.1",
"@xstate/fsm": "^2.0.0",
"ansi-html-community": "^0.0.8",
"bonjour-service": "^1.0.11",
"chokidar": "^3.5.3",
Expand Down

0 comments on commit 274941c

Please sign in to comment.