{"version":3,"file":"cyclone.esm.mjs","sources":["../../src/main/ts/error.ts","../../src/main/ts/generator.ts","../../src/main/ts/log.ts","../../src/main/ts/machine.ts","../../src/main/ts/registry.ts","../../src/main/ts/factory.ts"],"sourcesContent":["export const TRANSITION_VIOLATION = 'Transition violation'\nexport const INVALID_UNLOCK_KEY = 'Invalid unlock key'\nexport const LOCK_VIOLATION = 'Lock violation'\nexport const UNREACHABLE_STATE = 'Unreachable state'\n\nexport class MachineError extends Error {}\n","export const generateDate = (): Date => new Date()\nexport const generateId = (): string => Math.random().toString()\n","export const LOG_PREFIX = '[cyclone]'\n\nexport const debug = console.debug.bind(console, LOG_PREFIX)\nexport const info = console.info.bind(console, LOG_PREFIX)\nexport const error = console.error.bind(console, LOG_PREFIX)\nexport const warn = console.warn.bind(console, LOG_PREFIX)\n\nexport const log = {\n  debug,\n  info,\n  error,\n  warn\n}\n","import {\n  INVALID_UNLOCK_KEY,\n  LOCK_VIOLATION,\n  MachineError,\n  TRANSITION_VIOLATION,\n  UNREACHABLE_STATE\n} from './error'\nimport {\n  generateDate,\n  generateId\n} from './generator'\nimport { log } from './log'\n\ntype IState = string\n\ntype IAny = any\n\ntype IHandler = (data: IAny, ...payload: Array<IAny>) => IAny\n\ntype ITransitions = {\n  [key: string]: IHandler | null | boolean\n}\n\ntype IMachineOpts = {\n  transitions: ITransitions,\n  initialState?: IState,\n  initialData?: IAny,\n  immutable?: boolean,\n  historySize?: number\n}\n\nexport const DELIMITER = '>'\nexport const DEFAULT_HANDLER: IHandler = (...last) => last.pop()\nexport const DEFAULT_HISTORY_SIZE = 10\nexport const DEFAULT_OPTS: IMachineOpts = {\n  transitions: {},\n  historySize: DEFAULT_HISTORY_SIZE,\n  immutable: false\n}\n\ntype IKey = string | null\n\ntype IDigest = {\n  state?: IState,\n  data?: IAny\n}\n\ntype IHistoryItem = {\n  state: IState,\n  data: IAny,\n  id: string,\n  date: Date\n}\ntype IHistory = IHistoryItem[]\n\ninterface IMachine {\n  next(state: IState, ...payload: Array<IAny>): IMachine,\n  prev(state?: IState): IMachine,\n  current(): IDigest,\n  lock(key?: IKey): IMachine,\n  unlock(key: IKey): IMachine,\n\n  transitions: ITransitions,\n  history: IHistory,\n  opts: IMachineOpts,\n  key: IKey,\n  id: string,\n}\n\ntype IPredicate = (item: IHistoryItem) => boolean\n\nexport class Machine implements IMachine {\n\n  /**\n   * Machine options.\n   * @property\n   */\n  public opts: IMachineOpts\n\n  /**\n   * State history.\n   * @property\n   */\n  public history: IHistory\n\n  /**\n   * Lock key.\n   * @property\n   */\n  public key: IKey\n\n  /**\n   * Unique machine id\n   * @property\n   */\n  public id: string\n\n  /**\n   * Transition handler map\n   * @property\n   */\n  public transitions: ITransitions\n\n  constructor(opts: IMachineOpts) {\n    this.opts = { ...DEFAULT_OPTS, ...opts }\n    this.history = []\n    this.key = null\n    this.id = generateId()\n    this.transitions = opts.transitions\n\n    if (typeof opts.initialState === 'string') {\n      this.history.push({\n        state: opts.initialState,\n        data: opts.initialData,\n        id: generateId(),\n        date: generateDate()\n      })\n    }\n\n    return this\n  }\n\n  /**\n   * Provides next state transition.\n   * @param state Next state name.\n   * @param payload Any data for handler.\n   */\n  public next(state: IState, ...payload: Array<IAny>): IMachine {\n    if (this.key) {\n      throw new MachineError(LOCK_VIOLATION)\n    }\n\n    const handler = Machine.getHandler(state, this.history, this.transitions)\n    const current = this.current()\n    const data = handler(current.data, ...payload)\n    const id = generateId()\n    const date = generateDate()\n\n    this.history.push({\n      state,\n      data,\n      id,\n      date\n    })\n\n    if (this.history.length > Machine.getHistoryLimit(this.opts.historySize)) {\n      log.debug('history limit reached')\n      this.history.shift()\n    }\n\n    return this\n  }\n\n  /**\n   * Returns the machine's digest: state name and stored data.\n   */\n  public current(): IHistoryItem {\n    return { ...this.history[this.history.length - 1] }\n  }\n\n  /**\n   * Returns the last state, that satisfies the condition\n   */\n  public last(condition?: string | IPredicate): IHistoryItem | void {\n    if (condition === undefined) {\n      return this.current()\n    }\n\n    const filter = typeof condition === 'string'\n      ? ({ state }: IHistoryItem) => state === condition\n      : condition\n\n    return [...this.history].reverse().find(filter)\n  }\n\n  /**\n   * Reverts current state to the previous.\n   * @param state\n   */\n  public prev(state?: string | IPredicate): IMachine {\n    if (this.key) {\n      throw new MachineError(LOCK_VIOLATION)\n    }\n\n    if (this.history.length < 2) {\n      throw new MachineError(UNREACHABLE_STATE)\n    }\n\n    if (state === undefined) {\n      this.history.pop()\n      return this\n    }\n\n    const last = this.last(state)\n    if (!last) {\n      throw new MachineError(UNREACHABLE_STATE)\n    }\n\n    this.history.length = this.history.indexOf(last) + 1\n\n    return this\n  }\n\n  /**\n   * Locks the machine. Any transitions are prohibited before unlocking.\n   * @param key\n   */\n  public lock(key?: IKey): IMachine {\n    this.key = key || `lock${generateId()}`\n\n    return this\n  }\n\n  /**\n   * Unlocks the machine.\n   * @param key\n   */\n  public unlock(key: IKey): IMachine {\n    if (this.key !== key) {\n      throw new MachineError(INVALID_UNLOCK_KEY)\n    }\n\n    this.key = null\n\n    return this\n  }\n\n  public static getHistoryLimit(historySize?: number): number {\n    if (historySize === undefined) {\n      return DEFAULT_HISTORY_SIZE\n    }\n\n    if (historySize === -1) {\n      return Number.POSITIVE_INFINITY\n    }\n\n    return historySize\n  }\n\n  public static getHandler(next: IState, history: IHistory, transitions: ITransitions): IHandler {\n    const targetTransition = this.getTargetTransition(next, history)\n    const nextTransition = this.getTransition(targetTransition, transitions)\n\n    if (!nextTransition) {\n      throw new MachineError(TRANSITION_VIOLATION)\n    }\n\n    const handler = transitions[nextTransition]\n\n    return typeof handler === 'function'\n      ? handler\n      : DEFAULT_HANDLER\n  }\n\n  public static getTransition(targetTransition: string, transitions: ITransitions): string | void {\n    // TODO Support wildcards\n    // TODO Support OR operator\n    // TODO Generate patterns in constructor\n    return Object.keys(transitions)\n      .filter(transition => targetTransition.length > transition.length\n        ? new RegExp(`.*${transition}$`).test(targetTransition)\n        : targetTransition === transition\n      )\n      .sort((a, b) => b.length - a.length)[0]\n  }\n\n  public static getTargetTransition(next: IState, history: IHistory): string {\n    return [...history.map(({ state }: IHistoryItem) => state), next]\n      .join(DELIMITER)\n  }\n\n  /**\n   * Returns the last passes argument as a result\n   * @param {any} state\n   * @param {any} [payload]\n   * @return {any}\n   */\n  public DEFAULT_HANDLER = DEFAULT_HANDLER\n\n}\n\nexport {\n  IMachine, IHistory, ITransitions, IHistoryItem, IHandler, IMachineOpts\n}\n","export class Registry {\n\n  store: { [key: string]: any }\n\n  constructor () {\n    this.store = {}\n  }\n\n  get (key: string): void {\n    return this.store[key]\n  }\n\n  add (key: string, value: any): void {\n    this.store[key] = value\n  }\n\n  remove (key: string): void {\n    delete this.store[key]\n  }\n\n}\n","import {\n  DEFAULT_OPTS as DEFAULT_MACHINE_OPTS,\n  IMachine,\n  IMachineOpts,\n  Machine} from './machine'\nimport {\n  Registry\n} from './registry'\n\nexport const DEFAULT_TEMPLATE = {}\nexport const DEFAULT_TEMPLATE_REGISTRY = new Registry()\nexport const DEFAULT_MACHINE_REGISTRY = new Registry()\n\ntype IFactoryOpts = {\n  machine?: IMachineOpts\n  template?: string | Object\n  templateRegistry?: Registry\n  machineRegistry?: Registry\n}\n\nexport const factory = (opts: IFactoryOpts): IMachine => {\n  // NOTE flowgen throws error on typed args destruction\n  const {\n    machine,\n    template,\n    templateRegistry = DEFAULT_TEMPLATE_REGISTRY,\n    machineRegistry = DEFAULT_MACHINE_REGISTRY\n  } = opts\n  const _template = getTemplate(template, templateRegistry)\n  const machineOpts: IMachineOpts = { ...DEFAULT_MACHINE_OPTS, ..._template, ...machine }\n  const instance = new Machine(machineOpts)\n\n  machineRegistry.add(instance.id, instance)\n\n  return instance\n}\n\nexport const getTemplate = (template: string | Object | void, templateRegistry: Registry): any => {\n  return typeof template === 'string'\n    ? templateRegistry.get(template)\n    : template\n}\n\nexport {\n  IFactoryOpts\n}\n"],"names":["TRANSITION_VIOLATION","INVALID_UNLOCK_KEY","UNREACHABLE_STATE","MachineError","_Error","apply","this","arguments","_wrapNativeSuper","Error","Date","Math","random","toString","log","debug","console","bind","info","error","warn","DELIMITER","DEFAULT_HANDLER","pop","DEFAULT_HISTORY_SIZE","DEFAULT_OPTS","transitions","historySize","immutable","Machine","opts","history","key","id","_extends","generateId","initialState","push","state","data","initialData","date","generateDate","next","getHandler","current","handler","length","getHistoryLimit","shift","last","condition","undefined","filter","_ref","concat","reverse","find","prev","indexOf","_proto","lock","unlock","Number","POSITIVE_INFINITY","targetTransition","getTargetTransition","nextTransition","getTransition","Object","keys","transition","test","sort","a","b","map","_ref2","join","Registry","store","prototype","get","add","value","remove","DEFAULT_TEMPLATE","DEFAULT_TEMPLATE_REGISTRY","DEFAULT_MACHINE_REGISTRY","factory","machine","templateRegistry","machineRegistry","_opts$machineRegistry","_template","getTemplate","template","_opts$templateRegistr","machineOpts","DEFAULT_MACHINE_OPTS","instance"],"mappings":"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"}