• Changed Files
  • packages/core/src/operators/isAnyOf.ts

[refactored] isAnyOf to use combineLatest

Authored by appsforartists on Oct 6 2017, 1:03 AM.



isAnyOf takes an array of potential matches. It is the only operator whose parameters to _reactiveMap don't have natural names (thus, make more sense as an array than a dictionary).

There are four potential solutions:

  • Let _reactiveMap cast matches to a dict, set length on it, and cast it back to an array.
  • Manually iterate over matches as a dict and check them.
  • Use combineLatest directly.
  • Add Array support to _reactiveNextOperator. Since combineLatest supports both kinds of collection, the main cost here is in type complexity:
export type DictOperation<D, T> = (values: { upstream: T } & D) => void;
export type EmittingDictOperation<D, T, U> = (kwargs: { emit: NextChannel<U> }) => DictOperation<D, T>;
export type ArrayOperation<V, T> = (upstream: T, values: Array<V>) => void;
export type EmittingArrayOperation<V, T, U> = (kwargs: { emit: NextChannel<U> }) => ArrayOperation<V, T>;

    _reactiveNextOperator<U, V>(kwargs: _ReactiveNextOperatorArrayArgs<V, T, U>): ObservableWithMotionOperators<U>;
    _reactiveNextOperator<U, D>(kwargs: _ReactiveNextOperatorDictArgs<D, T, U>): ObservableWithMotionOperators<U>;
    _reactiveNextOperator<U, D>({ operation, inputs, ...combineLatestOptions }: _ReactiveNextOperatorDictArgs<D, T, U> | _ReactiveNextOperatorArrayArgs<D, T, U>): ObservableWithMotionOperators<U> {
      return new MotionObservable(
        (observer: Observer<U>) => {
          const innerOperation = operation({
            emit: observer.next.bind(observer),

          const streams: Array<MaybeReactive<D>> | MaybeReactive<D> = isIterable(inputs)
            ? [this, ...inputs] as Array<MaybeReactive<D>>
              // TypeScript doesn't like ...inputs, so we use the longhand version
            : Object.assign(
                { upstream: this },
              ) as MaybeReactive<D>;

          // combineLatest can handle arrays or dicts.  We cast combineLatest
          // and streams to the dict interface, and trust that combineLatest
          // will do the right thing if they are arrays.
          return combineLatest<D, MaybeReactive<D>>(
            streams as MaybeReactive<D>,
            innerOperation as DictOperation<D, T>

I've chosen the simplest route - using combineLatest directly.

Diff Detail

R13 material-motion/material-motion-js
Automatic diff as part of commit; lint not applicable.
Automatic diff as part of commit; unit tests not applicable.
appsforartists created this revision.Oct 6 2017, 1:03 AM
Restricted Application added a reviewer: O2: Material Motion. · View Herald TranscriptOct 6 2017, 1:03 AM
Restricted Application added a project: Material Motion. · View Herald Transcript
Restricted Application added a reviewer: O3: Material JavaScript platform reviewers. · View Herald Transcript
Restricted Application added a reviewer: Material Motion. · View Herald Transcript
Restricted Application completed building Restricted Buildable.Oct 6 2017, 1:07 AM
featherless accepted this revision.Oct 6 2017, 1:59 PM
featherless added a subscriber: featherless.

Thank you for the detailed explanation.

This revision is now accepted and ready to land.Oct 6 2017, 1:59 PM
This revision was automatically updated to reflect the committed changes.