UNPKG

repond-events

Version:
106 lines (90 loc) 4.13 kB
import { breakableForEach, forEach } from "chootils/dist/loops"; import { ItemState, getItemWillExist, getState, makeEffects, removeItem, setState, whenSettingStates } from "repond"; import { getActiveEventIds } from "../internal"; import { repondEventsMeta } from "../meta"; export const chainEffects = makeEffects((then) => ({ whenLiveEventIdsChange: then( (chainId) => { const nowChainState = getState("chains", chainId); if (!nowChainState) return; const { liveEventIds: firstLiveEventIds, canAutoActivate } = nowChainState; const isSubChain = getItemWillExist("liveEvents", chainId); // Remove the chain if there's no liveEventIds left in the chain if (firstLiveEventIds.length === 0) { removeItem("chains", chainId); // if there's a getEventValue that was waiting for a returnValue in the chain, but the chain ended, // return null for the chain repondEventsMeta.resolveValueMap[chainId]?.(undefined); } // Check which events should be active whenSettingStates(() => { const chainState = getState("chains", chainId); if (!chainState) return; // NOTE maybe warn here const { liveEventIds } = chainState; let idsToActivate: string[] = getActiveEventIds(liveEventIds ?? []); // NOTE these are only for reference! we don't use this to set state directly let newLiveEventsState: Record<string, Partial<ItemState<"liveEvents">>> = {}; let newChainsState: Record<string, Partial<ItemState<"chains">>> = {}; if (isSubChain) { let foundNonAddEvent = false; breakableForEach(idsToActivate, (id) => { const loopedRunMode = getState("events", id)?.nowRunMode; if (!loopedRunMode) { console.log("no loopedRunMode: id", id); } if (loopedRunMode && loopedRunMode !== "add") { foundNonAddEvent = true; return true; // break } }); if (foundNonAddEvent) { newChainsState[chainId] = { canAutoActivate: true }; setState("chains.canAutoActivate", true, chainId); } } // Return if the chain can't or wont be able to auto activate if (!canAutoActivate && !newChainsState[chainId]?.canAutoActivate) { return; } if (!liveEventIds?.length) { if (isSubChain) { // If it's a sub chain, finish the parent liveEvent // return { liveEvents: { [chainId]: { goalEndTime: 0 } } }; setState("liveEvents.goalEndTime", 0, chainId); // Set state then exit return; } // Only exit return; } breakableForEach(idsToActivate, (id) => { const liveEventState = getState("liveEvents", id); if (!liveEventState) return; const { runModeOptionsWhenReady } = liveEventState; if (runModeOptionsWhenReady) { const { runMode, runBy } = runModeOptionsWhenReady; newLiveEventsState[id] = { nowRunMode: runMode, runBy: runBy ?? null, runModeOptionsWhenReady: null }; setState("liveEvents.nowRunMode", runMode, id); setState("liveEvents.runBy", runBy ?? null, id); setState("liveEvents.runModeOptionsWhenReady", null, id); } else { newLiveEventsState[id] = { nowRunMode: "start" }; setState("liveEvents.nowRunMode", "start", id); } }); // Loop through all the new partial events, if any of them have a subChain, set the chain to canAutoActivate forEach(Object.keys(newLiveEventsState), (liveId) => { const loopedEventHasSubChain = getItemWillExist("chains", liveId); if (loopedEventHasSubChain) { newChainsState[liveId] = { canAutoActivate: true }; setState("chains.canAutoActivate", true, liveId); } }); }); }, { changes: ["chains.liveEventIds", "chains.canAutoActivate"], step: "eventUpdates", } ), }));