/** @license * Copyright 2016 - present The Material Motion Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ import { MotionObservable, } from '../../observables/proxies'; import { Constructor, EmittingOperation, NextChannel, Observable, ObservableWithMotionOperators, Observer, } from '../../types'; export type _NextOperatorArgs = { operation: EmittingOperation, }; export interface MotionNextOperable extends Observable { _nextOperator(kwargs: _NextOperatorArgs): ObservableWithMotionOperators; } export function withNextOperator>>(superclass: S): S & Constructor> { return class extends superclass implements MotionNextOperable { /** * `_nextOperator` is sugar for creating an operator that reads and writes * from the `next` channel. It encapsulates the stream creation and * subscription boilerplate required for most operators. * * Its argument `operation` should receive a value from the parent stream's * `next` channel, transform it, and use the supplied callback to emit the * result to the observer's `next` channel. */ _nextOperator({ operation }: _NextOperatorArgs): ObservableWithMotionOperators { return new MotionObservable( (observer: Observer) => { const innerOperation = operation({ emit: observer.next.bind(observer), }); const subscription = this.subscribe( (value: T) => innerOperation({ upstream: value }) ); return subscription.unsubscribe; } ); } }; }