{"version":3,"file":"useBlocker.cjs","names":["Solid","useRouter","BlockerFnArgs","HistoryAction","HistoryLocation","SolidNode","AnyRoute","AnyRouter","ParseRoute","RegisteredRouter","ShouldBlockFnLocation","routeId","TRouteId","fullPath","TFullPath","pathname","params","TAllParams","search","TFullSearchSchema","AnyShouldBlockFnLocation","MakeShouldBlockFnLocationUnion","TRouter","TRoute","BlockerResolver","status","current","next","action","proceed","reset","ShouldBlockFnArgs","ShouldBlockFn","args","Promise","UseBlockerOpts","shouldBlockFn","enableBeforeUnload","disabled","withResolver","TWithResolver","LegacyBlockerFn","LegacyBlockerOpts","blockerFn","condition","_resolveBlockerOpts","opts","undefined","shouldBlock","Boolean","_customBlockerFn","createMemo","useBlocker","Accessor","blockerFnOrOpts","props","merge","router","resolver","setResolver","createSignal","disposeBlock","createEffect","blockerFnComposed","blockerFnArgs","getLocation","location","parsedLocation","parseLocation","matchedRoutes","getMatchedRoutes","foundRoute","routeParams","id","currentLocation","nextLocation","promise","resolve","canNavigateAsync","history","block","onSettled","_resolvePromptBlockerArgs","PromptProps","LegacyPromptProps","BlockComponent","Block","propsWithChildren","children","child","_$memo","TParams"],"sources":["../../src/useBlocker.tsx"],"sourcesContent":["import * as Solid from 'solid-js'\nimport { useRouter } from './useRouter'\nimport type {\n  BlockerFnArgs,\n  HistoryAction,\n  HistoryLocation,\n} from '@tanstack/history'\nimport type { SolidNode } from './route'\nimport type {\n  AnyRoute,\n  AnyRouter,\n  ParseRoute,\n  RegisteredRouter,\n} from '@tanstack/router-core'\n\ntype ShouldBlockFnLocation<\n  out TRouteId,\n  out TFullPath,\n  out TAllParams,\n  out TFullSearchSchema,\n> = {\n  routeId: TRouteId\n  fullPath: TFullPath\n  pathname: string\n  params: TAllParams\n  search: TFullSearchSchema\n}\n\ntype AnyShouldBlockFnLocation = ShouldBlockFnLocation<any, any, any, any>\ntype MakeShouldBlockFnLocationUnion<\n  TRouter extends AnyRouter = RegisteredRouter,\n  TRoute extends AnyRoute = ParseRoute<TRouter['routeTree']>,\n> = TRoute extends any\n  ? ShouldBlockFnLocation<\n      TRoute['id'],\n      TRoute['fullPath'],\n      TRoute['types']['allParams'],\n      TRoute['types']['fullSearchSchema']\n    >\n  : never\n\ntype BlockerResolver<TRouter extends AnyRouter = RegisteredRouter> =\n  | {\n      status: 'blocked'\n      current: MakeShouldBlockFnLocationUnion<TRouter>\n      next: MakeShouldBlockFnLocationUnion<TRouter>\n      action: HistoryAction\n      proceed: () => void\n      reset: () => void\n    }\n  | {\n      status: 'idle'\n      current: undefined\n      next: undefined\n      action: undefined\n      proceed: undefined\n      reset: undefined\n    }\n\ntype ShouldBlockFnArgs<TRouter extends AnyRouter = RegisteredRouter> = {\n  current: MakeShouldBlockFnLocationUnion<TRouter>\n  next: MakeShouldBlockFnLocationUnion<TRouter>\n  action: HistoryAction\n}\n\nexport type ShouldBlockFn<TRouter extends AnyRouter = RegisteredRouter> = (\n  args: ShouldBlockFnArgs<TRouter>,\n) => boolean | Promise<boolean>\nexport type UseBlockerOpts<\n  TRouter extends AnyRouter = RegisteredRouter,\n  TWithResolver extends boolean = boolean,\n> = {\n  shouldBlockFn: ShouldBlockFn<TRouter>\n  enableBeforeUnload?: boolean | (() => boolean)\n  disabled?: boolean\n  withResolver?: TWithResolver\n}\n\ntype LegacyBlockerFn = () => Promise<any> | any\ntype LegacyBlockerOpts = {\n  blockerFn?: LegacyBlockerFn\n  condition?: boolean | any\n}\n\nfunction _resolveBlockerOpts(\n  opts?: UseBlockerOpts | LegacyBlockerOpts | LegacyBlockerFn,\n  condition?: boolean | any,\n): UseBlockerOpts {\n  if (opts === undefined) {\n    return {\n      shouldBlockFn: () => true,\n      withResolver: false,\n    }\n  }\n\n  if ('shouldBlockFn' in opts) {\n    return opts\n  }\n\n  if (typeof opts === 'function') {\n    const shouldBlock = Boolean(condition ?? true)\n\n    const _customBlockerFn = async () => {\n      if (shouldBlock) return await opts()\n      return false\n    }\n\n    return {\n      shouldBlockFn: _customBlockerFn,\n      enableBeforeUnload: shouldBlock,\n      withResolver: false,\n    }\n  }\n\n  const shouldBlock = Solid.createMemo(() => Boolean(opts.condition ?? true))\n\n  const _customBlockerFn = async () => {\n    if (shouldBlock() && opts.blockerFn !== undefined) {\n      return await opts.blockerFn()\n    }\n    return shouldBlock()\n  }\n\n  return {\n    get shouldBlockFn() {\n      return _customBlockerFn\n    },\n    get enableBeforeUnload() {\n      return shouldBlock()\n    },\n    get withResolver() {\n      return opts.blockerFn === undefined\n    },\n  }\n}\n\nexport function useBlocker<\n  TRouter extends AnyRouter = RegisteredRouter,\n  TWithResolver extends boolean = false,\n>(\n  opts: UseBlockerOpts<TRouter, TWithResolver>,\n): TWithResolver extends true ? Solid.Accessor<BlockerResolver<TRouter>> : void\n\n/**\n * @deprecated Use the shouldBlockFn property instead\n */\nexport function useBlocker(\n  blockerFnOrOpts?: LegacyBlockerOpts,\n): Solid.Accessor<BlockerResolver>\n\n/**\n * @deprecated Use the UseBlockerOpts object syntax instead\n */\nexport function useBlocker(\n  blockerFn?: LegacyBlockerFn,\n  condition?: boolean | any,\n): Solid.Accessor<BlockerResolver>\n\nexport function useBlocker(\n  opts?: UseBlockerOpts | LegacyBlockerOpts | LegacyBlockerFn,\n  condition?: boolean | any,\n): Solid.Accessor<BlockerResolver> | void {\n  const props = Solid.merge(\n    {\n      enableBeforeUnload: true,\n      disabled: false,\n      withResolver: false,\n    },\n    _resolveBlockerOpts(opts, condition),\n  )\n\n  const router = useRouter()\n\n  const [resolver, setResolver] = Solid.createSignal<BlockerResolver>({\n    status: 'idle',\n    current: undefined,\n    next: undefined,\n    action: undefined,\n    proceed: undefined,\n    reset: undefined,\n  })\n\n  let disposeBlock: (() => void) | undefined\n\n  Solid.createEffect(\n    () => props.disabled,\n    (disabled) => {\n      // Dispose previous blocker registration when re-running\n      disposeBlock?.()\n      disposeBlock = undefined\n\n      if (disabled) {\n        return\n      }\n\n      const blockerFnComposed = async (blockerFnArgs: BlockerFnArgs) => {\n        function getLocation(\n          location: HistoryLocation,\n        ): AnyShouldBlockFnLocation {\n          const parsedLocation = router.parseLocation(location)\n          const matchedRoutes = router.getMatchedRoutes(parsedLocation.pathname)\n          if (matchedRoutes.foundRoute === undefined) {\n            return {\n              routeId: '__notFound__',\n              fullPath: parsedLocation.pathname,\n              pathname: parsedLocation.pathname,\n              params: matchedRoutes.routeParams,\n              search: parsedLocation.search,\n            }\n          }\n          return {\n            routeId: matchedRoutes.foundRoute.id,\n            fullPath: matchedRoutes.foundRoute.fullPath,\n            pathname: parsedLocation.pathname,\n            params: matchedRoutes.routeParams,\n            search: parsedLocation.search,\n          }\n        }\n\n        const current = getLocation(blockerFnArgs.currentLocation)\n        const next = getLocation(blockerFnArgs.nextLocation)\n\n        if (\n          current.routeId === '__notFound__' &&\n          next.routeId !== '__notFound__'\n        ) {\n          return false\n        }\n\n        const shouldBlock = await props.shouldBlockFn({\n          action: blockerFnArgs.action,\n          current,\n          next,\n        })\n        if (!props.withResolver) {\n          return shouldBlock\n        }\n\n        if (!shouldBlock) {\n          return false\n        }\n\n        const promise = new Promise<boolean>((resolve) => {\n          setResolver({\n            status: 'blocked',\n            current,\n            next,\n            action: blockerFnArgs.action,\n            proceed: () => resolve(false),\n            reset: () => resolve(true),\n          })\n        })\n\n        const canNavigateAsync = await promise\n        setResolver({\n          status: 'idle',\n          current: undefined,\n          next: undefined,\n          action: undefined,\n          proceed: undefined,\n          reset: undefined,\n        })\n\n        return canNavigateAsync\n      }\n\n      disposeBlock = router.history.block({\n        blockerFn: blockerFnComposed,\n        enableBeforeUnload: props.enableBeforeUnload,\n      })\n    },\n  )\n\n  // Clean up on unmount\n  Solid.onSettled(() => {\n    return () => {\n      disposeBlock?.()\n      disposeBlock = undefined\n    }\n  })\n\n  return resolver\n}\n\nconst _resolvePromptBlockerArgs = (\n  props: PromptProps | LegacyPromptProps,\n): UseBlockerOpts => {\n  if ('shouldBlockFn' in props) {\n    return props\n  }\n\n  const shouldBlock = Solid.createMemo(() => Boolean(props.condition ?? true))\n\n  const _customBlockerFn = async () => {\n    if (shouldBlock() && props.blockerFn !== undefined) {\n      return await props.blockerFn()\n    }\n    return shouldBlock\n  }\n\n  return {\n    shouldBlockFn: _customBlockerFn,\n    get enableBeforeUnload() {\n      return shouldBlock()\n    },\n    get withResolver() {\n      return props.blockerFn === undefined\n    },\n  }\n}\n\ninterface BlockComponent {\n  <\n    TRouter extends AnyRouter = RegisteredRouter,\n    TWithResolver extends boolean = boolean,\n  >(\n    opts: PromptProps<TRouter, TWithResolver>,\n  ): SolidNode\n  /**\n   *  @deprecated Use the UseBlockerOpts property instead\n   */\n  (opts: LegacyPromptProps): SolidNode\n}\n\nexport const Block: BlockComponent = function Block(\n  opts: PromptProps | LegacyPromptProps,\n): SolidNode {\n  const propsWithChildren = {\n    get children() {\n      return opts.children\n    },\n  }\n  const args = _resolvePromptBlockerArgs(opts)\n\n  const resolver = useBlocker(args)\n  const children = Solid.createMemo(() => {\n    const child = propsWithChildren.children\n    if (resolver && typeof child === 'function') return child(resolver())\n    return child\n  })\n\n  return <>{children()}</>\n}\n\ntype LegacyPromptProps = {\n  blockerFn?: LegacyBlockerFn\n  condition?: boolean | any\n  children?: SolidNode | ((params: BlockerResolver) => SolidNode)\n}\n\ntype PromptProps<\n  TRouter extends AnyRouter = RegisteredRouter,\n  TWithResolver extends boolean = boolean,\n  TParams = TWithResolver extends true ? BlockerResolver<TRouter> : void,\n> = UseBlockerOpts<TRouter, TWithResolver> & {\n  children?: SolidNode | ((params: TParams) => SolidNode)\n}\n"],"mappings":"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"}