Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move to typescript #70

Closed
alexreardon opened this issue Jul 24, 2019 · 2 comments · Fixed by #72
Closed

Move to typescript #70

alexreardon opened this issue Jul 24, 2019 · 2 comments · Fixed by #72

Comments

@alexreardon
Copy link
Owner

alexreardon commented Jul 24, 2019

Here is what I am thinking so far:

export type EqualityFn = (newArgs: unknown[], lastArgs: unknown[]) => boolean;

function areInputsEqual(
  newInputs: unknown[],
  lastInputs: unknown[],
): boolean {
  // no checks needed if the inputs length has changed
  if (newInputs.length !== lastInputs.length) {
    return false;
  }
  // Using for loop for speed. It generally performs better than array.every
  // https://github.com/alexreardon/memoize-one/pull/59

  for (let i = 0; i < newInputs.length; i++) {
    // using shallow equality check
    if (newInputs[i] !== lastInputs[i]) {
      return false;
    }
  }
  return true;
}


export default function memoizeOne<ResultFn extends (this: unknown, ...newArgs: unknown[]) => ReturnType<ResultFn>>(
  this: unknown,
  resultFn: ResultFn,
  isEqual: EqualityFn = areInputsEqual,
): ResultFn {
  let lastThis: unknown;
  let lastArgs: unknown[] = [];
  let lastResult: ReturnType<ResultFn>;
  let calledOnce: boolean = false;

  // breaking cache when context (this) or arguments change
  function memoized(this: unknown, ...newArgs: unknown[]): ReturnType<ResultFn> {
    if (calledOnce && lastThis === this && isEqual(newArgs, lastArgs)) {
      return lastResult;
    }

    // Throwing during an assignment aborts the assignment: https://codepen.io/alexreardon/pen/RYKoaz
    // Doing the lastResult assignment first so that if it throws
    // nothing will be overwritten
    lastResult = resultFn.apply(this, newArgs);
    calledOnce = true;
    lastThis = this;
    lastArgs = newArgs;
    return lastResult;
  }

  return (memoized as ResultFn);
}

playground

@alexreardon
Copy link
Owner Author

Need to consider what build changes to be made, and how to continue to support flow consumers

@TrySound
Copy link
Contributor

Same as before
https://github.com/renatorib/react-powerplug/blob/master/package.json#L16
https://github.com/renatorib/react-powerplug/tree/master/src

Or just copy this flow file to the dist.

@alexreardon alexreardon mentioned this issue Aug 19, 2019
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants