<commit_before>// @flow

// A task that either returns, or errors
export opaque type Task<
  +Arg,
  +Inbound,
  +InboundError = mixed,
  +Result = Inbound,
  +Error = InboundError
>: $ReadOnly<{
  // This declaration is the public API

  type: string,
  payload: Arg,

  map<ResultPrime>(
    successTransform: (Result) => ResultPrime
  ): Task<Arg, Inbound, InboundError, ResultPrime, Error>,

  bimap<ResultPrime, ErrorPrime>(
    successTransform: (Result) => ResultPrime,
    errorTransform: (Error) => ErrorPrime
  ): Task<Arg, Inbound, InboundError, ResultPrime, ErrorPrime>,

  chain<ResultPrime, ErrorPrime>(
    chainTransform: (Result) => Task<*, *, *, ResultPrime, ErrorPrime>
  ): Task<Arg, Inbound, InboundError, ResultPrime, Error | ErrorPrime>
}> = $ReadOnly<{
  // This declaration is the private API.

  kind: 'regular',
  type: string,
  payload: Arg,

  /*
   * This is a little tricky. This `run` takes a lambda and calls either
   * the success or error handlers based on the result. We need this so
   * we can substitute applying effectful functions for mocking results
   * in test.
   */
  run(
    BiApplicative<Inbound, InboundError>,
    (Result) => mixed,
    (Error) => mixed
  ): mixed,

  map<ResultPrime>(
    successTransform: (Result) => ResultPrime
  ): Task<Arg, Inbound, InboundError, ResultPrime, Error>,

  bimap<ResultPrime, ErrorPrime>(
    successTransform: (Result) => ResultPrime,
    errorTransform: (Error) => ErrorPrime
  ): Task<Arg, Inbound, InboundError, ResultPrime, ErrorPrime>,

  chain<ResultPrime, ErrorPrime>(
    chainTransform: (Result) => Task<*, *, *, ResultPrime, ErrorPrime>
  ): Task<Arg, Inbound, InboundError, ResultPrime, Error | ErrorPrime>
}>;

// A function that does some side-effect when run.
export type Effector<Inbound, InboundError> = (
  (Inbound) => mixed,
  (InboundError) => mixed
) => mixed;

// A function that runs an effector for some environment.
// In test, we provide one that doesn't call the effectful
// function, instead providing a mock response.
export type BiApplicative<S, E> = (
  Effector<S, E>,
  (S) => mixed,
  (E) => mixed
) => mixed;

// Private API for running a task. Do not use this directly.
// We need this because Task is an opaque type, and we
// hide `.run` outside this file.
export function _run<Inbound, InboundError, Result, ErrorT>(
  task: Task<*, Inbound, InboundError, Result, ErrorT>,
  fnApplication: BiApplicative<Inbound, InboundError>,
  success: Result => mixed,
  error: ErrorT => mixed
): mixed {
  if (typeof task.run !== 'function') {
    throw new Error('Attempted to run something that is not a task.');
  }
  return task.run(fnApplication, success, error);
}

/*
 * A function that takes some Arg and returns a new task.
 */
export type TaskCreator<
  Arg,
  Inbound,
  InboundError = mixed,
  Result = Inbound,
  Error = InboundError
> = Arg => Task<Arg, Inbound, InboundError> & $ReadOnly<{|type: string|}>;

/**
 * A group of tasks, all of different types
 */
export type AnyTask = Task<any, any, any>;
export type AnyTasks = $ReadOnlyArray<AnyTask>;

/**
 * Tasks whose type must be disambiguated from their use
 * (because they were dynamically hoisted using `withTask`, for instance).
 */
export type MixedTask = Task<mixed, mixed>;
export type MixedTasks = $ReadOnlyArray<MixedTask>;

type Callback<Error, Result> = (err?: Error, res: Result) => mixed;

/**
 * ## `Task.fromCallback`
 * Returns a task-creator from a function that returns a promise.
 *
 * `arg => Promise<string[]>` -> `arg => Task<string[]>`.
 *
 * Uses the second arg as a label for debugging.
 */
export function fromPromise<Arg, +Inbound>(
  fn: Arg => Promise<Inbound>,
  label: string
): TaskCreator<Arg, Inbound, mixed, Inbound, mixed> {
  const creator = outbound =>
    taskCreator_(
      (success, error) => fn(outbound).then(success, error),
      outbound,
      label
    );
  creator.type = label;
  return (creator: any);
}

/**
 * `Task.fromCallback`
 *
 * Turn a node-style callback function:
 *     `(arg, cb: (err, res) => void) => void`)
 * into a task creator of the same type.
 *
 * Uses the second arg as a label for debugging.
 */
export function fromCallback<Arg, +Inbound, +ErrorT>(
  fn: (Arg, Callback<ErrorT, Inbound>) => mixed,
  label: string
): TaskCreator<Arg, Inbound, ErrorT> {
  const creator = (outbound: Arg) =>
    taskCreator_(
      (success, error) =>
        fn(outbound, (err, result) => (err ? error(err) : success(result))),
      outbound,
      label
    );
  creator.type = label;
  return (creator: any);
}

export type EffectReport = 'start' | 'success' | 'error';

/*
 * This is the private constructor for creating a Task object. End users
 * probably want to use `Task.fromCallback` or `task.fromPromise`.
 * It adds instrumentation to the effector, and also attaches some info
 * useful for making assertions in test.
 */
export function taskCreator_<Arg, Inbound, InboundError>(
  effector: ((Inbound) => mixed, (InboundError) => mixed) => mixed,
  payload: Arg,
  label: string
): Task<Arg, Inbound, InboundError, Inbound, InboundError> {
  // Instrument the task with reporting
  const effectorPrime = (success, error) => {
    reportEffects('start', newTask, payload);
    return effector(
      result => {
        reportEffects('success', newTask, result);
        return success(result);
      },
      reason => {
        reportEffects('error', newTask, reason);
        return error(reason);
      }
    );
  };

  effectorPrime.payload = payload;
  effectorPrime.type = label;

  const newTask = _task(
    payload,
    (runEffect, success, error) => runEffect(effectorPrime, success, error),
    label
  );

  return newTask;
}
<commit_msg>Fix(Core): expose InboundError type param on fromPromise creator<commit_after>// @flow

// A task that either returns, or errors
export opaque type Task<
  +Arg,
  +Inbound,
  +InboundError = mixed,
  +Result = Inbound,
  +Error = InboundError
>: $ReadOnly<{
  // This declaration is the public API

  type: string,
  payload: Arg,

  map<ResultPrime>(
    successTransform: (Result) => ResultPrime
  ): Task<Arg, Inbound, InboundError, ResultPrime, Error>,

  bimap<ResultPrime, ErrorPrime>(
    successTransform: (Result) => ResultPrime,
    errorTransform: (Error) => ErrorPrime
  ): Task<Arg, Inbound, InboundError, ResultPrime, ErrorPrime>,

  chain<ResultPrime, ErrorPrime>(
    chainTransform: (Result) => Task<*, *, *, ResultPrime, ErrorPrime>
  ): Task<Arg, Inbound, InboundError, ResultPrime, Error | ErrorPrime>
}> = $ReadOnly<{
  // This declaration is the private API.

  kind: 'regular',
  type: string,
  payload: Arg,

  /*
   * This is a little tricky. This `run` takes a lambda and calls either
   * the success or error handlers based on the result. We need this so
   * we can substitute applying effectful functions for mocking results
   * in test.
   */
  run(
    BiApplicative<Inbound, InboundError>,
    (Result) => mixed,
    (Error) => mixed
  ): mixed,

  map<ResultPrime>(
    successTransform: (Result) => ResultPrime
  ): Task<Arg, Inbound, InboundError, ResultPrime, Error>,

  bimap<ResultPrime, ErrorPrime>(
    successTransform: (Result) => ResultPrime,
    errorTransform: (Error) => ErrorPrime
  ): Task<Arg, Inbound, InboundError, ResultPrime, ErrorPrime>,

  chain<ResultPrime, ErrorPrime>(
    chainTransform: (Result) => Task<*, *, *, ResultPrime, ErrorPrime>
  ): Task<Arg, Inbound, InboundError, ResultPrime, Error | ErrorPrime>
}>;

// A function that does some side-effect when run.
export type Effector<Inbound, InboundError> = (
  (Inbound) => mixed,
  (InboundError) => mixed
) => mixed;

// A function that runs an effector for some environment.
// In test, we provide one that doesn't call the effectful
// function, instead providing a mock response.
export type BiApplicative<S, E> = (
  Effector<S, E>,
  (S) => mixed,
  (E) => mixed
) => mixed;

// Private API for running a task. Do not use this directly.
// We need this because Task is an opaque type, and we
// hide `.run` outside this file.
export function _run<Inbound, InboundError, Result, ErrorT>(
  task: Task<*, Inbound, InboundError, Result, ErrorT>,
  fnApplication: BiApplicative<Inbound, InboundError>,
  success: Result => mixed,
  error: ErrorT => mixed
): mixed {
  if (typeof task.run !== 'function') {
    throw new Error('Attempted to run something that is not a task.');
  }
  return task.run(fnApplication, success, error);
}

/*
 * A function that takes some Arg and returns a new task.
 */
export type TaskCreator<
  Arg,
  +Inbound,
  +InboundError = mixed,
  -Result = Inbound,
  -Error = InboundError
> = Arg => Task<Arg, Inbound, InboundError> & $ReadOnly<{|type: string|}>;

/**
 * A group of tasks, all of different types
 */
export type AnyTask = Task<any, any, any>;
export type AnyTasks = $ReadOnlyArray<AnyTask>;

/**
 * Tasks whose type must be disambiguated from their use
 * (because they were dynamically hoisted using `withTask`, for instance).
 */
export type MixedTask = Task<mixed, mixed>;
export type MixedTasks = $ReadOnlyArray<MixedTask>;

type Callback<Error, Result> = (err?: Error, res: Result) => mixed;

/**
 * ## `Task.fromCallback`
 * Returns a task-creator from a function that returns a promise.
 *
 * `arg => Promise<string[]>` -> `arg => Task<string[]>`.
 *
 * Uses the second arg as a label for debugging.
 */
export function fromPromise<Arg, -Inbound, -InboundError>(
  fn: Arg => Promise<Inbound>,
  label: string
): TaskCreator<Arg, Inbound, InboundError> {
  const creator = outbound =>
    taskCreator_(
      (success, error) => fn(outbound).then(success, error),
      outbound,
      label
    );
  creator.type = label;
  return (creator: any);
}

/**
 * `Task.fromCallback`
 *
 * Turn a node-style callback function:
 *     `(arg, cb: (err, res) => void) => void`)
 * into a task creator of the same type.
 *
 * Uses the second arg as a label for debugging.
 */
export function fromCallback<Arg, +Inbound, +InboundError>(
  fn: (Arg, Callback<InboundError, Inbound>) => mixed,
  label: string
): TaskCreator<Arg, Inbound, InboundError> {
  const creator = (outbound: Arg) =>
    taskCreator_(
      (success, error) =>
        fn(outbound, (err, result) => (err ? error(err) : success(result))),
      outbound,
      label
    );
  creator.type = label;
  return (creator: any);
}

export type EffectReport = 'start' | 'success' | 'error';

/*
 * This is the private constructor for creating a Task object. End users
 * probably want to use `Task.fromCallback` or `task.fromPromise`.
 * It adds instrumentation to the effector, and also attaches some info
 * useful for making assertions in test.
 */
export function taskCreator_<Arg, +Inbound, +InboundError>(
  effector: ((Inbound) => mixed, (InboundError) => mixed) => mixed,
  payload: Arg,
  label: string
): Task<Arg, Inbound, InboundError> {
  // Instrument the task with reporting
  const effectorPrime = (success, error) => {
    reportEffects('start', newTask, payload);
    return effector(
      result => {
        reportEffects('success', newTask, result);
        return success(result);
      },
      reason => {
        reportEffects('error', newTask, reason);
        return error(reason);
      }
    );
  };

  effectorPrime.payload = payload;
  effectorPrime.type = label;

  const newTask = _task(
    payload,
    (runEffect, success, error) => runEffect(effectorPrime, success, error),
    label
  );

  return newTask;
}

{'fraction_non_alphanumeric': 0.1301811215604319, 'fraction_numerical': 0.0, 'mean_word_length': 3.720509658857378, 'pattern_counts': {'":': 0, '<': 87, '<?xml version=': 0, '>': 165, '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': '1828532', 'n_tokens_mistral': 3618, 'n_tokens_neox': 3497, 'n_words': 1172}