<commit_before>import type {
  Middleware,
  Dispatch,
  AnyAction,
  Action,
  ThunkDispatch,
  MiddlewareAPI,
} from '@reduxjs/toolkit'
import { createAction, nanoid } from '@reduxjs/toolkit'

import type {
  ActionListener,
  AddListenerOverloads,
  BaseActionCreator,
  AnyActionListenerPredicate,
  CreateListenerMiddlewareOptions,
  ConditionFunction,
  ListenerPredicate,
  TypedActionCreator,
  TypedAddListener,
  TypedAddListenerAction,
  TypedCreateListenerEntry,
  RemoveListenerAction,
  FallbackAddListenerOptions,
  ListenerEntry,
  ListenerErrorHandler,
  Unsubscribe,
  MiddlewarePhase,
  WithMiddlewareType,
  TakePattern,
  ListenerErrorInfo,
  TaskExecutor,
  ForkedTask,
} from './types'

import { TaskAbortError } from './exceptions'
import { Outcome } from './outcome'
export type { Outcome, Ok, Error } from './outcome';
export { TaskAbortError } from './exceptions'
export type {
  ActionListener,
  ActionListenerMiddleware,
  ActionListenerMiddlewareAPI,
  ActionListenerOptions,
  CreateListenerMiddlewareOptions,
  MiddlewarePhase,
  When,
  ListenerErrorHandler,
  TypedAddListener,
  TypedAddListenerAction,
  Unsubscribe,
  TaskExecutor,
  ForkedTask,
  AsyncTaskExecutor,
  SyncTaskExecutor,
} from './types'

function assertFunction(
  func: unknown,
  expected: string
): asserts func is (...args: unknown[]) => unknown {
  if (typeof func !== 'function') {
    throw new TypeError(`${expected} is not a function`)
  }
}

const defaultWhen: MiddlewarePhase = 'afterReducer'
const actualMiddlewarePhases = ['beforeReducer', 'afterReducer'] as const

function assertActive(signal: AbortSignal, reason?: string) {
  if (signal.aborted) {
    throw new TaskAbortError(reason)
  }
}

function createDelay(signal: AbortSignal) {
  return function delay(timeoutMs: number): Promise<void> {
    return new Promise((resolve, reject) => {
      assertActive(signal)

      setTimeout(() => {
        try {
          assertActive(signal)
        } catch (err) {
          reject(err)
        }
        resolve()
      }, timeoutMs)
    })
  }
}

function createFork(parentAbortSignal: AbortSignal) {
  return function fork<T>(childJobExecutor: TaskExecutor<T>): ForkedTask<T> {
    const childAbortController = new AbortController()
    const promise = Outcome.wrap(
      new Promise<T>((resolve, reject) => {
        assertActive(parentAbortSignal)
        Promise.resolve(childJobExecutor()).then((val) => {
          assertActive(parentAbortSignal)
          assertActive(childAbortController.signal)
          resolve(val)
        }, reject)
      })
    )

    return {
      promise,
      controller: childAbortController,
    }
  }
}

function createTakePattern<S>(
  addListener: AddListenerOverloads<Unsubscribe, S, Dispatch<AnyAction>>,
  signal: AbortSignal
): TakePattern<S> {
  /**
   * A function that takes an ActionListenerPredicate and an optional timeout,<commit_msg>refactor(action-listener-,): simplify createDelay<commit_after>import type {
  Middleware,
  Dispatch,
  AnyAction,
  Action,
  ThunkDispatch,
  MiddlewareAPI,
} from '@reduxjs/toolkit'
import { createAction, nanoid } from '@reduxjs/toolkit'

import type {
  ActionListener,
  AddListenerOverloads,
  BaseActionCreator,
  AnyActionListenerPredicate,
  CreateListenerMiddlewareOptions,
  ConditionFunction,
  ListenerPredicate,
  TypedActionCreator,
  TypedAddListener,
  TypedAddListenerAction,
  TypedCreateListenerEntry,
  RemoveListenerAction,
  FallbackAddListenerOptions,
  ListenerEntry,
  ListenerErrorHandler,
  Unsubscribe,
  MiddlewarePhase,
  WithMiddlewareType,
  TakePattern,
  ListenerErrorInfo,
  TaskExecutor,
  ForkedTask,
} from './types'

import { TaskAbortError } from './exceptions'
import { Outcome } from './outcome'
export type { Outcome, Ok, Error } from './outcome';
export { TaskAbortError } from './exceptions'
export type {
  ActionListener,
  ActionListenerMiddleware,
  ActionListenerMiddlewareAPI,
  ActionListenerOptions,
  CreateListenerMiddlewareOptions,
  MiddlewarePhase,
  When,
  ListenerErrorHandler,
  TypedAddListener,
  TypedAddListenerAction,
  Unsubscribe,
  TaskExecutor,
  ForkedTask,
  AsyncTaskExecutor,
  SyncTaskExecutor,
} from './types'

function assertFunction(
  func: unknown,
  expected: string
): asserts func is (...args: unknown[]) => unknown {
  if (typeof func !== 'function') {
    throw new TypeError(`${expected} is not a function`)
  }
}

const defaultWhen: MiddlewarePhase = 'afterReducer'
const actualMiddlewarePhases = ['beforeReducer', 'afterReducer'] as const

function assertActive(signal: AbortSignal, reason?: string) {
  if (signal.aborted) {
    throw new TaskAbortError(reason)
  }
}

function createDelay(signal: AbortSignal) {
  return async function delay(timeoutMs: number): Promise<void> {
    assertActive(signal)
    await new Promise((resolve) =>setTimeout(resolve, timeoutMs))
    assertActive(signal)
  }
}

function createFork(parentAbortSignal: AbortSignal) {
  return function fork<T>(childJobExecutor: TaskExecutor<T>): ForkedTask<T> {
    const childAbortController = new AbortController()
    const promise = Outcome.wrap(
      new Promise<T>((resolve, reject) => {
        assertActive(parentAbortSignal)
        Promise.resolve(childJobExecutor()).then((val) => {
          assertActive(parentAbortSignal)
          assertActive(childAbortController.signal)
          resolve(val)
        }, reject)
      })
    )

    return {
      promise,
      controller: childAbortController,
    }
  }
}

function createTakePattern<S>(
  addListener: AddListenerOverloads<Unsubscribe, S, Dispatch<AnyAction>>,
  signal: AbortSignal
): TakePattern<S> {
  /**
   * A function that takes an ActionListenerPredicate and an optional timeout,
{'fraction_non_alphanumeric': 0.0988666085440279, 'fraction_numerical': 0.0, 'mean_word_length': 4.267217630853994, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4325529', 'n_tokens_mistral': 1707, 'n_tokens_neox': 1706, 'n_words': 376}