{"version":3,"sources":["../src/AmigaErrorBoundary.module.css","../src/AmigaErrorBoundary.tsx"],"names":["root","noBlink","portal","title","message","code","details","Component","jsx","jsxs","useState","useEffect","createPortal","useCallback"],"mappings":"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","file":"index.cjs","sourcesContent":["/* CSS variables (defaults inlined inside var() so any wrapping ancestor that\n * sets --ragm-* gets inherited — declaring them directly on .root would block\n * theming via CSS-only. */\n\n.root {\n  position: relative;\n  z-index: var(--ragm-z-index, 9999);\n  box-sizing: border-box;\n  border: var(--ragm-border-width, 6px) var(--ragm-border-style, solid) var(--ragm-fg, #ff2222);\n  background-color: var(--ragm-bg, #000000);\n  color: var(--ragm-fg, #ff2222);\n  padding: var(--ragm-padding, 24px);\n  text-align: center;\n  font-family: var(--ragm-font-family, \"Times New Roman\", Times, serif);\n  font-size: var(--ragm-font-size, 18px);\n  font-weight: var(--ragm-font-weight, 400);\n  line-height: var(--ragm-line-height, 1.4);\n\n  animation-name: ragm-blink;\n  animation-duration: var(--ragm-blink-duration, 1s);\n  animation-timing-function: step-end;\n  animation-iteration-count: infinite;\n  animation-direction: alternate;\n}\n\n.root * {\n  box-sizing: border-box;\n}\n\n.noBlink {\n  animation: none;\n}\n\n.portal {\n  position: fixed;\n  inset: 0;\n  z-index: var(--ragm-z-index, 9999);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  flex-direction: column;\n  padding: var(--ragm-portal-padding, 0);\n  background-color: var(--ragm-bg, #000000);\n  color: var(--ragm-fg, #ff2222);\n  border: var(--ragm-border-width, 6px) var(--ragm-border-style, solid) var(--ragm-fg, #ff2222);\n  font-family: var(--ragm-font-family, \"Times New Roman\", Times, serif);\n  font-size: var(--ragm-font-size, 18px);\n  font-weight: var(--ragm-font-weight, 400);\n  line-height: var(--ragm-line-height, 1.4);\n  text-align: center;\n\n  animation-name: ragm-blink;\n  animation-duration: var(--ragm-blink-duration, 1s);\n  animation-timing-function: step-end;\n  animation-iteration-count: infinite;\n  animation-direction: alternate;\n}\n\n.portal .root {\n  border: 0;\n  background: transparent;\n  animation: none;\n  padding: var(--ragm-padding, 24px);\n  max-width: var(--ragm-max-width, 760px);\n  width: 100%;\n}\n\n.title {\n  margin: 0 0 12px;\n}\n\n.message {\n  margin: 0 0 12px;\n}\n\n.code {\n  font-family: var(--ragm-mono-family, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);\n  word-break: break-word;\n}\n\n.details {\n  text-align: left;\n  margin: 16px auto 0;\n  padding: 12px;\n  border: 1px dashed var(--ragm-fg, #ff2222);\n  font-size: 0.85em;\n  max-width: var(--ragm-details-max-width, 100%);\n}\n\n.details summary {\n  cursor: pointer;\n  font-weight: bold;\n  margin-bottom: 8px;\n  user-select: none;\n}\n\n.details pre {\n  margin: 0;\n  white-space: pre-wrap;\n  word-break: break-word;\n  font-family: var(--ragm-mono-family, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);\n  font-size: 12px;\n}\n\n@keyframes ragm-blink {\n  0% {\n    border-color: var(--ragm-fg, #ff2222);\n  }\n  50% {\n    border-color: var(--ragm-bg, #000000);\n  }\n  100% {\n    border-color: var(--ragm-fg, #ff2222);\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .root,\n  .portal {\n    animation: none;\n  }\n}\n","import { Component, useCallback, useEffect, useState } from \"react\";\nimport type { CSSProperties, ErrorInfo, ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport styles from \"./AmigaErrorBoundary.module.css\";\n\nexport interface AmigaFallbackRenderProps {\n  error: Error;\n  errorInfo: ErrorInfo | null;\n  resetErrorBoundary: () => void;\n}\n\nexport type AmigaPortalTarget = boolean | string | HTMLElement;\n\nexport interface AmigaErrorBoundaryProps {\n  children?: ReactNode;\n\n  /** Render-prop fallback. Takes priority over `fallback`. */\n  fallbackRender?: (props: AmigaFallbackRenderProps) => ReactNode;\n\n  /** Static fallback ReactNode rendered when an error is caught. */\n  fallback?: ReactNode;\n\n  /** Called when an error is caught. Useful for logging or error reporting. */\n  onError?: (error: Error, errorInfo: ErrorInfo) => void;\n\n  /** Called when the boundary is reset (imperatively or via resetKeys change). */\n  onReset?: (details: { reason: \"imperative\" | \"keys\" }) => void;\n\n  /** When any value in this array changes (shallow equality), the boundary auto-resets. */\n  resetKeys?: ReadonlyArray<unknown>;\n\n  /** Force the error UI to render even without a real error. Useful for showcase/preview. */\n  show?: boolean;\n\n  /** A pre-built error to display when `show` is true (or to override the caught one). */\n  error?: Error;\n\n  /**\n   * Render the error UI through a React portal at the document level (Amiga-style takeover).\n   *  - `false` (default): render inline where the boundary is mounted.\n   *  - `true`: render in a portal under a div appended to `document.body`.\n   *  - `string`: id of the portal container element (created if missing).\n   *  - `HTMLElement`: explicit portal target.\n   */\n  portal?: AmigaPortalTarget;\n\n  /** Title text. Default: \"Software Failure. Press left mouse button to continue.\" */\n  title?: ReactNode;\n\n  /** Override the message line. Receives the caught error. Default: \"Guru Meditation: {error.message}\". */\n  formatGuru?: (error: Error) => ReactNode;\n\n  /** Show collapsible details with the component stack. Default: true. */\n  showDetails?: boolean;\n\n  /** Disable the blink animation. Default: false. */\n  noBlink?: boolean;\n\n  /** Extra class name applied to the root element. */\n  className?: string;\n\n  /** Inline styles applied to the root element. Useful to set CSS variables. */\n  style?: CSSProperties;\n}\n\ninterface State {\n  error: Error | null;\n  errorInfo: ErrorInfo | null;\n}\n\nconst DEFAULT_TITLE = \"Software Failure. Press left mouse button to continue.\";\n\nfunction shallowDiff(a: ReadonlyArray<unknown> | undefined, b: ReadonlyArray<unknown> | undefined): boolean {\n  if (a === b) return false;\n  if (!a || !b) return true;\n  if (a.length !== b.length) return true;\n  for (let i = 0; i < a.length; i += 1) {\n    if (!Object.is(a[i], b[i])) return true;\n  }\n  return false;\n}\n\nexport class AmigaErrorBoundary extends Component<AmigaErrorBoundaryProps, State> {\n  static displayName = \"AmigaErrorBoundary\";\n\n  override state: State = { error: null, errorInfo: null };\n\n  static getDerivedStateFromError(error: Error): Partial<State> {\n    return { error };\n  }\n\n  override componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n    this.setState({ errorInfo });\n    this.props.onError?.(error, errorInfo);\n  }\n\n  override componentDidUpdate(prevProps: AmigaErrorBoundaryProps) {\n    if (this.state.error !== null && shallowDiff(prevProps.resetKeys, this.props.resetKeys)) {\n      this.resetWithReason(\"keys\");\n    }\n  }\n\n  resetErrorBoundary = () => {\n    this.resetWithReason(\"imperative\");\n  };\n\n  private resetWithReason(reason: \"imperative\" | \"keys\") {\n    if (this.state.error === null && this.state.errorInfo === null) return;\n    this.setState({ error: null, errorInfo: null });\n    this.props.onReset?.({ reason });\n  }\n\n  override render() {\n    const { error: caught, errorInfo } = this.state;\n    const {\n      show = false,\n      error: forcedError,\n      fallback,\n      fallbackRender,\n      children,\n      portal,\n      title,\n      formatGuru,\n      showDetails,\n      noBlink,\n      className,\n      style,\n    } = this.props;\n\n    const errorToShow: Error | null =\n      caught ?? (show ? (forcedError ?? new Error(\"Software Failure\")) : null);\n\n    if (!errorToShow) {\n      return children ?? null;\n    }\n\n    let node: ReactNode;\n\n    if (fallbackRender) {\n      node = fallbackRender({\n        error: errorToShow,\n        errorInfo,\n        resetErrorBoundary: this.resetErrorBoundary,\n      });\n    } else if (fallback !== undefined) {\n      node = fallback;\n    } else {\n      node = (\n        <DefaultGuru\n          error={errorToShow}\n          errorInfo={errorInfo}\n          title={title}\n          formatGuru={formatGuru}\n          showDetails={showDetails ?? true}\n          noBlink={noBlink ?? false}\n          className={className}\n          style={style}\n          portaled={Boolean(portal)}\n        />\n      );\n    }\n\n    if (portal) {\n      return <PortalWrapper target={portal}>{node}</PortalWrapper>;\n    }\n\n    return node;\n  }\n}\n\ninterface DefaultGuruProps {\n  error: Error;\n  errorInfo: ErrorInfo | null;\n  title?: ReactNode;\n  formatGuru?: (error: Error) => ReactNode;\n  showDetails: boolean;\n  noBlink: boolean;\n  className?: string;\n  style?: CSSProperties;\n  portaled: boolean;\n}\n\nfunction DefaultGuru({\n  error,\n  errorInfo,\n  title,\n  formatGuru,\n  showDetails,\n  noBlink,\n  className,\n  style,\n  portaled,\n}: DefaultGuruProps) {\n  const message = formatGuru ? formatGuru(error) : error.message || error.toString();\n  const classes = [styles.root, noBlink && !portaled ? styles.noBlink : null, className]\n    .filter(Boolean)\n    .join(\" \");\n  return (\n    <div role=\"alert\" aria-live=\"assertive\" className={classes} style={style}>\n      <p className={styles.title}>{title ?? DEFAULT_TITLE}</p>\n      <p className={styles.message}>\n        Guru Meditation: <span className={styles.code}>{message}</span>\n      </p>\n      {showDetails && errorInfo?.componentStack ? (\n        <details className={styles.details}>\n          <summary>Component stack</summary>\n          <pre>\n            <code>{errorInfo.componentStack}</code>\n          </pre>\n        </details>\n      ) : null}\n    </div>\n  );\n}\n\ninterface PortalWrapperProps {\n  target: AmigaPortalTarget;\n  children: ReactNode;\n}\n\nfunction PortalWrapper({ target, children }: PortalWrapperProps) {\n  const [container, setContainer] = useState<HTMLElement | null>(null);\n\n  useEffect(() => {\n    if (typeof document === \"undefined\") return;\n\n    if (target instanceof HTMLElement) {\n      setContainer(target);\n      return;\n    }\n\n    const id = typeof target === \"string\" ? target : \"amiga-guru\";\n    let el = document.getElementById(id);\n    let created = false;\n\n    if (!el) {\n      el = document.createElement(\"div\");\n      el.id = id;\n      document.body.appendChild(el);\n      created = true;\n    }\n\n    setContainer(el);\n\n    return () => {\n      if (created && el?.parentNode) {\n        el.parentNode.removeChild(el);\n      }\n    };\n  }, [target]);\n\n  if (!container) return null;\n\n  return createPortal(<div className={styles.portal}>{children}</div>, container);\n}\n\n/**\n * Imperatively trigger an Amiga Guru Meditation from a function component.\n * Returns a callback that re-throws the given error during render so the\n * nearest <AmigaErrorBoundary> can catch it.\n */\nexport function useAmigaGuru() {\n  const [, setState] = useState<unknown>();\n  return useCallback((error: unknown) => {\n    setState(() => {\n      throw error instanceof Error ? error : new Error(String(error));\n    });\n  }, []);\n}\n"]}