refactor(chat): split machine by business flow
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
import {
|
||||
createChatPromotionState,
|
||||
shouldPromptUnlockHistory,
|
||||
} from "../chat-machine.helpers";
|
||||
import { initialState } from "../chat-state";
|
||||
import {
|
||||
guestInitializingState,
|
||||
userInitializingState,
|
||||
} from "./history-flow";
|
||||
import {
|
||||
guestReadyState,
|
||||
guestSendingState,
|
||||
userSendingViaHttpState,
|
||||
} from "./send-flow";
|
||||
import {
|
||||
unlockingHistoryState,
|
||||
unlockingMessageState,
|
||||
unlockMachineSetup,
|
||||
} from "./unlock-flow";
|
||||
|
||||
const startGuestSessionAction = unlockMachineSetup.assign(
|
||||
({ context }) => ({
|
||||
...initialState,
|
||||
promotion: context.promotion,
|
||||
}),
|
||||
);
|
||||
|
||||
const startUserSessionAction = unlockMachineSetup.assign(
|
||||
({ context }) => ({
|
||||
...initialState,
|
||||
promotion: context.promotion,
|
||||
}),
|
||||
);
|
||||
|
||||
const clearChatSessionAction = unlockMachineSetup.assign(() => ({
|
||||
...initialState,
|
||||
}));
|
||||
|
||||
const injectPromotionAction = unlockMachineSetup.assign(({ event }) => {
|
||||
if (event.type !== "ChatPromotionInjected") return {};
|
||||
return {
|
||||
promotion: createChatPromotionState(
|
||||
event.promotion,
|
||||
event.messageId,
|
||||
),
|
||||
};
|
||||
});
|
||||
|
||||
const clearPromotionAction = unlockMachineSetup.assign({ promotion: null });
|
||||
|
||||
export const chatMachineSetup = unlockMachineSetup.extend({
|
||||
actions: {
|
||||
startGuestSession: startGuestSessionAction,
|
||||
startUserSession: startUserSessionAction,
|
||||
clearChatSession: clearChatSessionAction,
|
||||
injectPromotion: injectPromotionAction,
|
||||
clearPromotion: clearPromotionAction,
|
||||
},
|
||||
});
|
||||
|
||||
const idleState = chatMachineSetup.createStateConfig({
|
||||
on: {
|
||||
ChatGuestLogin: {
|
||||
target: "#chat.guestSession",
|
||||
actions: "startGuestSession",
|
||||
},
|
||||
ChatUserLogin: {
|
||||
target: "#chat.userSession",
|
||||
actions: "startUserSession",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const guestSessionState = chatMachineSetup.createStateConfig({
|
||||
invoke: [
|
||||
{
|
||||
id: "messageQueue",
|
||||
src: "httpMessageQueue",
|
||||
},
|
||||
{
|
||||
id: "loadHistory",
|
||||
src: "loadHistory",
|
||||
},
|
||||
],
|
||||
on: {
|
||||
ChatUserLogin: {
|
||||
target: "#chat.userSession",
|
||||
actions: "startUserSession",
|
||||
},
|
||||
ChatNetworkHistoryLoaded: {
|
||||
actions: "applyNetworkHistoryLoaded",
|
||||
},
|
||||
ChatHistoryLoadFailed: {
|
||||
actions: "markHistoryLoadFailed",
|
||||
},
|
||||
ChatQueuedSendStarted: {
|
||||
actions: "markQueuedSendStarted",
|
||||
},
|
||||
ChatQueuedHttpDone: {
|
||||
actions: "applyQueuedHttpOutput",
|
||||
},
|
||||
ChatQueuedSendError: {
|
||||
actions: "appendQueuedSendErrorMessage",
|
||||
},
|
||||
},
|
||||
initial: "initializing",
|
||||
states: {
|
||||
initializing: guestInitializingState,
|
||||
ready: guestReadyState,
|
||||
sending: guestSendingState,
|
||||
},
|
||||
});
|
||||
|
||||
const userReadyState = chatMachineSetup.createStateConfig({
|
||||
on: {
|
||||
ChatSendMessage: {
|
||||
guard: ({ context, event }) =>
|
||||
context.canSendMessage && event.content.trim().length > 0,
|
||||
actions: ["appendUserMessage", "enqueueMessage"],
|
||||
},
|
||||
ChatSendImage: {
|
||||
actions: "appendUserImage",
|
||||
},
|
||||
ChatUnlockMessageRequested: {
|
||||
guard: ({ event }) => event.messageId.trim().length > 0,
|
||||
target: "unlockingMessage",
|
||||
actions: "markUnlockMessageStarted",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const userSessionState = chatMachineSetup.createStateConfig({
|
||||
invoke: [
|
||||
{
|
||||
id: "messageQueue",
|
||||
src: "httpMessageQueue",
|
||||
},
|
||||
{
|
||||
id: "loadHistory",
|
||||
src: "loadHistory",
|
||||
},
|
||||
],
|
||||
on: {
|
||||
ChatGuestLogin: {
|
||||
target: "#chat.guestSession",
|
||||
actions: "startGuestSession",
|
||||
},
|
||||
ChatLogout: {
|
||||
target: "#chat.idle",
|
||||
actions: "clearChatSession",
|
||||
},
|
||||
ChatNetworkHistoryLoaded: [
|
||||
{
|
||||
guard: ({ context, event }) =>
|
||||
event.type === "ChatNetworkHistoryLoaded" &&
|
||||
context.paymentUnlockPending &&
|
||||
shouldPromptUnlockHistory(event.output.messages),
|
||||
target: ".ready",
|
||||
actions: "showUnlockHistoryPromptFromNetwork",
|
||||
},
|
||||
{
|
||||
guard: ({ context }) => context.paymentUnlockPending,
|
||||
target: ".ready",
|
||||
actions: "applyNetworkHistoryLoadedAndClearPayment",
|
||||
},
|
||||
{
|
||||
guard: ({ context }) =>
|
||||
!context.isUnlockingHistory && !context.isUnlockingMessage,
|
||||
actions: "applyNetworkHistoryLoaded",
|
||||
},
|
||||
],
|
||||
ChatHistoryLoadFailed: {
|
||||
actions: "markHistoryLoadFailed",
|
||||
},
|
||||
ChatQueuedSendStarted: {
|
||||
actions: "markQueuedSendStarted",
|
||||
},
|
||||
ChatQueuedHttpDone: {
|
||||
actions: "applyQueuedHttpOutput",
|
||||
},
|
||||
ChatQueuedSendError: {
|
||||
actions: "appendQueuedSendErrorMessage",
|
||||
},
|
||||
ChatPaymentSucceeded: [
|
||||
{
|
||||
guard: ({ context }) =>
|
||||
context.historyLoaded &&
|
||||
shouldPromptUnlockHistory(context.messages),
|
||||
actions: ["clearUpgradePrompt", "showUnlockHistoryPrompt"],
|
||||
},
|
||||
{
|
||||
guard: ({ context }) => !context.historyLoaded,
|
||||
actions: ["clearUpgradePrompt", "markPaymentUnlockPending"],
|
||||
},
|
||||
{
|
||||
guard: ({ context }) => context.historyLoaded,
|
||||
actions: ["clearUpgradePrompt", "dismissUnlockHistoryPrompt"],
|
||||
},
|
||||
],
|
||||
ChatUnlockHistoryConfirmed: {
|
||||
target: ".unlockingHistory",
|
||||
actions: "markUnlockHistoryStarted",
|
||||
},
|
||||
ChatUnlockHistoryDismissed: {
|
||||
actions: "dismissUnlockHistoryPrompt",
|
||||
},
|
||||
ChatUnlockPaywallNavigationConsumed: {
|
||||
actions: "clearUnlockPaywallRequest",
|
||||
},
|
||||
},
|
||||
initial: "initializing",
|
||||
states: {
|
||||
initializing: userInitializingState,
|
||||
ready: userReadyState,
|
||||
sendingViaHttp: userSendingViaHttpState,
|
||||
unlockingHistory: unlockingHistoryState,
|
||||
unlockingMessage: unlockingMessageState,
|
||||
},
|
||||
});
|
||||
|
||||
export const chatRootStateConfig = chatMachineSetup.createStateConfig({
|
||||
initial: "idle",
|
||||
on: {
|
||||
ChatPromotionInjected: { actions: "injectPromotion" },
|
||||
ChatPromotionCleared: { actions: "clearPromotion" },
|
||||
},
|
||||
states: {
|
||||
idle: idleState,
|
||||
guestSession: guestSessionState,
|
||||
userSession: userSessionState,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user