{"version":3,"sources":["../src/index.ts","../src/temporal.ts"],"sourcesContent":["import { createStore } from 'zustand';\nimport { temporalStateCreator } from './temporal';\nimport type {\n  StateCreator,\n  StoreMutatorIdentifier,\n  Mutate,\n  StoreApi,\n} from 'zustand';\nimport type {\n  TemporalState,\n  _TemporalState,\n  Write,\n  ZundoOptions,\n} from './types';\n\ntype Zundo = <\n  TState,\n  Mps extends [StoreMutatorIdentifier, unknown][] = [],\n  Mcs extends [StoreMutatorIdentifier, unknown][] = [],\n  UState = TState,\n>(\n  config: StateCreator<TState, [...Mps, ['temporal', unknown]], Mcs>,\n  options?: ZundoOptions<TState, UState>,\n) => StateCreator<\n  TState,\n  Mps,\n  [['temporal', StoreApi<TemporalState<UState>>], ...Mcs]\n>;\n\ndeclare module 'zustand/vanilla' {\n  interface StoreMutators<S, A> {\n    temporal: Write<S, { temporal: A }>;\n  }\n}\n\nexport const temporal = (<TState>(\n  config: StateCreator<TState, [], []>,\n  options?: ZundoOptions<TState>,\n): StateCreator<TState, [], []> => {\n  const configWithTemporal = (\n    set: StoreApi<TState>['setState'],\n    get: StoreApi<TState>['getState'],\n    store: Mutate<\n      StoreApi<TState>,\n      [['temporal', StoreApi<TemporalState<TState>>]]\n    >,\n  ) => {\n    store.temporal = createStore(\n      options?.wrapTemporal?.(temporalStateCreator(set, get, options)) ||\n        temporalStateCreator(set, get, options),\n    );\n\n    const curriedHandleSet =\n      options?.handleSet?.(\n        (store.temporal.getState() as _TemporalState<TState>)\n          ._handleSet as StoreApi<TState>['setState'],\n      ) || (store.temporal.getState() as _TemporalState<TState>)._handleSet;\n\n    const temporalHandleSet = (pastState: TState) => {\n      if (!store.temporal.getState().isTracking) return;\n\n      const currentState = options?.partialize?.(get()) || get();\n      const deltaState = options?.diff?.(pastState, currentState);\n      if (\n        // Don't call handleSet if state hasn't changed, as determined by diff fn or equality fn\n        !(\n          // If the user has provided a diff function but nothing has been changed, deltaState will be null\n          (\n            deltaState === null ||\n            // If the user has provided an equality function, use it\n            options?.equality?.(pastState, currentState)\n          )\n        )\n      ) {\n        curriedHandleSet(\n          pastState,\n          undefined as unknown as Parameters<typeof set>[1],\n          currentState,\n          deltaState,\n        );\n      }\n    };\n\n    const setState = store.setState;\n    // Modify the setState function to call the userlandSet function\n    store.setState = (...args) => {\n      // Get most up to date state. The state from the callback might be a partial state.\n      // The order of the get() and set() calls is important here.\n      const pastState = options?.partialize?.(get()) || get();\n      setState(...(args as Parameters<typeof setState>));\n      temporalHandleSet(pastState);\n    };\n\n    return config(\n      // Modify the set function to call the userlandSet function\n      (...args) => {\n        // Get most up-to-date state. The state from the callback might be a partial state.\n        // The order of the get() and set() calls is important here.\n        const pastState = options?.partialize?.(get()) || get();\n        set(...(args as Parameters<typeof set>));\n        temporalHandleSet(pastState);\n      },\n      get,\n      store,\n    );\n  };\n  return configWithTemporal as StateCreator<TState, [], []>;\n}) as unknown as Zundo;\n\nexport type { ZundoOptions, Zundo, TemporalState };\n","import type { StateCreator, StoreApi } from 'zustand';\nimport type { _TemporalState, ZundoOptions } from './types';\n\nexport const temporalStateCreator = <TState>(\n  userSet: StoreApi<TState>['setState'],\n  userGet: StoreApi<TState>['getState'],\n  options?: ZundoOptions<TState>,\n) => {\n  const stateCreator: StateCreator<_TemporalState<TState>, [], []> = (\n    set,\n    get,\n  ) => {\n    return {\n      pastStates: options?.pastStates || [],\n      futureStates: options?.futureStates || [],\n      undo: (steps = 1) => {\n        if (get().pastStates.length) {\n          // userGet must be called before userSet\n          const currentState = options?.partialize?.(userGet()) || userGet();\n\n          const statesToApply = get().pastStates.splice(-steps, steps);\n\n          // If there is length, we know that statesToApply is not empty\n          const nextState = statesToApply.shift()!;\n          userSet(nextState);\n          set({\n            pastStates: get().pastStates,\n            futureStates: get().futureStates.concat(\n              options?.diff?.(currentState, nextState) || currentState,\n              statesToApply.reverse(),\n            ),\n          });\n        }\n      },\n      redo: (steps = 1) => {\n        if (get().futureStates.length) {\n          // userGet must be called before userSet\n          const currentState = options?.partialize?.(userGet()) || userGet();\n\n          const statesToApply = get().futureStates.splice(-steps, steps);\n\n          // If there is length, we know that statesToApply is not empty\n          const nextState = statesToApply.shift()!;\n          userSet(nextState);\n          set({\n            pastStates: get().pastStates.concat(\n              options?.diff?.(currentState, nextState) || currentState,\n              statesToApply.reverse(),\n            ),\n            futureStates: get().futureStates,\n          });\n        }\n      },\n      clear: () => set({ pastStates: [], futureStates: [] }),\n      isTracking: true,\n      pause: () => set({ isTracking: false }),\n      resume: () => set({ isTracking: true }),\n      setOnSave: (_onSave) => set({ _onSave }),\n      // Internal properties\n      _onSave: options?.onSave,\n      _handleSet: (pastState, replace, currentState, deltaState) => {\n        // This naively assumes that only one new state can be added at a time\n        if (options?.limit && get().pastStates.length >= options?.limit) {\n          get().pastStates.shift();\n        }\n\n        get()._onSave?.(pastState, currentState);\n        set({\n          pastStates: get().pastStates.concat(deltaState || pastState),\n          futureStates: [],\n        });\n      },\n    };\n  };\n\n  // Cast to a version of the store that does not include \"temporal\" addition\n  return stateCreator as StateCreator<_TemporalState<TState>, [], []>;\n};\n"],"mappings":"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","names":[]}