{"version":3,"file":"fsm.mjs","sourceRoot":"","sources":["../src/fsm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,wBAAwB;AAEzC,OAAO,EAAE,iBAAiB,EAAE,oBAAoB;AAEhD;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAI7B,OAAuD;IACvD,MAAM,CAAC,UAAU,IAAI,OAAO,EAAE,2CAA2C,CAAC,CAAC;IAC3E,MAAM,KAAK,GAAG,OAEb,CAAC;IAEF,KAAK;IACL,MAAM,OAAO,GAAG,CAAO,GAAkB,EAAU,EAAE;QACnD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,GAAG,CAAC;QACb,CAAC;aAAM,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAC7C,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,CAAC;IACf,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,MAAM,UAAU,GAAG,CAAC,OAAY,EAAE,EAAE,CAClC,OAAO,CAAC,OAAO,CAAC;SACb,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QAClB,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,CAAC,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC;QACrC,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;SACD,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAE9C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAC/B,KAAK,CAAC,MAAM,CAAC,MAAM,CACpB,EAAE,CAAC;QACF,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACxB,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACvB,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,MAAM,CAAM,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YAC5D,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAC5B,MAAM,CACJ,KAAK,CAAC,QAAQ,CAAC,OAAO,KAAK,SAAS,IAAI,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,EACxE,WAAW,MAAM,kCAAkC,CACpD,CACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,WAAW,CAAC,WAAgD;IAC1E,wEAAwE;IACxE,4DAA4D;IAC5D,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,WAAW,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;QAC9B,MAAM,CAAC,CAAC,eAAe,IAAI,KAAK,CAAC,OAAO,EAAE,0BAA0B,CAAC,CAAC;QACtE,eAAe,GAAG,IAAI,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAClD,WAAW,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE;QAC7B,MAAM,CACJ,WAAW,CAAC,MAAM,KAAK,iBAAiB,CAAC,OAAO,EAChD,wBAAwB,CACzB,CAAC;QACF,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;IACzB,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { assert } from '@metamask/utils';\nimport type { EventObject, StateMachine, Typestate } from '@xstate/fsm';\nimport { InterpreterStatus } from '@xstate/fsm';\n\n/**\n * Validates the set-up of a @xstate/fsm machine.\n *\n * 1. Ensures that all named actions in the config have a provided implementation.\n *\n * @param machine - The machine to validate.\n * @throws {@link AssertionError}. If the validation fails.\n */\nexport function validateMachine<\n  TContext extends object,\n  TEvent extends EventObject,\n  TState extends Typestate<TContext>,\n>(machine: StateMachine.Machine<TContext, TEvent, TState>) {\n  assert('_options' in machine, 'The machine is not an @xstate/fsm machine');\n  const typed = machine as StateMachine.Machine<TContext, TEvent, TState> & {\n    _options: { actions?: StateMachine.ActionMap<TContext, TEvent> };\n  };\n\n  // 1.\n  const toArray = <Type>(obj: Type | Type[]): Type[] => {\n    if (Array.isArray(obj)) {\n      return obj;\n    } else if (obj === undefined || obj === null) {\n      return [];\n    }\n    return [obj];\n  };\n\n  const allActions = new Set<string>();\n  const addActions = (actions: any) =>\n    toArray(actions)\n      .flatMap((action) => {\n        if (typeof action === 'string') {\n          return [action];\n        }\n        assert(typeof action === 'function');\n        return [];\n      })\n      .forEach(allActions.add.bind(allActions));\n\n  for (const state of Object.values<(typeof typed.config.states)[string]>(\n    typed.config.states,\n  )) {\n    addActions(state.entry);\n    addActions(state.exit);\n    for (const transition of Object.values<any>(state.on ?? {})) {\n      addActions(transition.actions);\n    }\n  }\n\n  allActions.forEach((action) =>\n    assert(\n      typed._options.actions !== undefined && action in typed._options.actions,\n      `Action \"${action}\" doesn't have an implementation`,\n    ),\n  );\n}\n\n/**\n * Ensure that the interpreter is strict.\n * Strict means that the transition must occur.\n * The event must exist in .on {} state config and it's guard must succeed.\n *\n * The error will be thrown when an invalid `interpreter.send()` is called\n * and will be bubbled there.\n *\n * TODO(ritave): Doesn't support self transitions.\n *\n * @param interpreter - The interpreter that will be force into strict mode.\n * @throws {@link Error} Thrown when the transition is invalid.\n */\nexport function forceStrict(interpreter: StateMachine.Service<any, any, any>) {\n  // As soon as a listener subscribes, it is called. It might be called in\n  // an initial state which doesn't have the .changed property\n  let onInitialCalled = false;\n  interpreter.subscribe((state) => {\n    assert(!onInitialCalled || state.changed, 'Invalid state transition');\n    onInitialCalled = true;\n  });\n\n  const ogSend = interpreter.send.bind(interpreter);\n  interpreter.send = (...args) => {\n    assert(\n      interpreter.status === InterpreterStatus.Running,\n      'Interpreter is stopped',\n    );\n    return ogSend(...args);\n  };\n}\n"]}