@zodiac-ui/ng-observable
Version:
Create powerful reactive components with Angular. AoT compatible and Ivy ready.
1,059 lines (1,040 loc) • 29.2 kB
JavaScript
import { Subject, Observable, Subscription, from, BehaviorSubject, asapScheduler, isObservable } from 'rxjs';
import { InjectionToken, Injectable, isDevMode, Inject, ChangeDetectorRef, Optional } from '@angular/core';
import { debounceTime, take, filter } from 'rxjs/operators';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @param {?} derivedCtor
* @param {?} baseCtors
* @return {?}
*/
function applyMixins(derivedCtor, baseCtors) {
baseCtors.forEach((/**
* @param {?} baseCtor
* @return {?}
*/
baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach((/**
* @param {?} name
* @return {?}
*/
name => {
Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name) || {});
}));
}));
}
/** @type {?} */
const mixins = Symbol();
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @template T
*/
class Callable extends Function {
/**
* @param {?} fn
*/
constructor(fn) {
super();
return Object.setPrototypeOf(fn, new.target.prototype);
}
}
var _a;
// WARNING: interface has both a type and a value, skipping emit
/**
* A subject that implements both `Subject<T>` and `Function` interfaces. Using this subject in place of a normal
* method turns all invocations of that method into an observable stream without needing to modify the source of
* the caller. When called with multiple arguments it will emit the arguments as an array.
*
* \@usageNotes
*
* Basic usage
*
* ```ts
* const subject = new InvokeSubject<string>() // single argument
* const subject2 = new InvokeSubject<[string, number]>() // multiple arguments
*
* subject("message")
* subject2("message", 42)
*
* // with custom invoke function
* const subject3 = new InvokeSubject<string>(function () {
* subject3.next("message") // call "next" to emit value
* })
* ```
*
* Convert `\@HostListener` and `(event)` bindings into observable streams
*
* ```ts
* \@Component({
* template: `<input type="text" (input)="inputChanges($event)" />`
* })
* export class MyComponent implements OnDestroy {
* \@HostListener("click", ["$event"])
* readonly hostClick = new InvokeSubject<MouseEvent>()
* readonly inputChanges = new InvokeSubject<Event>()
*
* constructor() {
* hostClick.subscribe(event => console.log(event))
* inputChanges.subscribe(event => console.log(event))
* }
* }
* ```
*
* \@publicApi
* @template T
*/
class InvokeSubject extends Callable {
/**
* Creates a new `InvokeSubject` instance
*
* @param {?=} nextFn A function to be called when the subject is invoked
*
*/
constructor(nextFn) {
super(nextFn ? nextFn : (/**
* @param {...?} args
* @return {?}
*/
(...args) => {
/** @type {?} */
const len = args.length;
if (len === 0) {
this.next();
}
else if (len === 1) {
this.next(args[0]);
}
else {
this.next(args);
}
}));
Object.assign(this, new Subject());
}
}
_a = mixins;
InvokeSubject[_a] = applyMixins(InvokeSubject, [Observable, Subject]);
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @param {...?} flags
* @return {?}
*/
function createMask(...flags) {
/** @type {?} */
let len = flags.length;
/** @type {?} */
let count = 0;
while (len--) {
count += flags[len];
}
return count;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Future API for declaring lifecycle hooks at runtime without extending a base class. Will
* become available if/when Angular supports runtime lifecycle hooks that work AoT or when
* the compiler can be configured to add lifecycle features without adding them to the class.
*
* @param {...?} flags Enum flags for toggling which lifecycle hooks to enable
*
* @return {?}
*/
function UseHooks(...flags) {
/** @type {?} */
const features = createMask(...flags);
return (/**
* @param {?} target
* @return {?}
*/
function (target) {
if (features & 1) {
target.prototype.ngOnChanges = new InvokeSubject(target.prototype.ngOnChanges);
}
if (features & 2) {
target.prototype.ngOnInit = new InvokeSubject(target.prototype.ngOnInit);
}
if (features & 4) {
target.prototype.ngDoCheck = new InvokeSubject(target.prototype.ngDoCheck);
}
if (features & 8) {
target.prototype.ngAfterContentInit = new InvokeSubject(target.prototype.ngAfterContentInit);
}
if (features & 16) {
target.prototype.ngAfterContentChecked = new InvokeSubject(target.prototype.ngAfterContentChecked);
}
if (features & 32) {
target.prototype.ngAfterViewInit = new InvokeSubject(target.prototype.ngAfterViewInit);
}
if (features & 64) {
target.prototype.ngAfterViewChecked = new InvokeSubject(target.prototype.ngAfterViewChecked);
}
if (features & 128) {
target.prototype.ngOnDestroy = new InvokeSubject(target.prototype.ngOnDestroy);
}
});
}
var _a$1;
/**
* Implements all of the builtin lifecycle hooks provided by Angular and makes them observable.
*
* \@usageNotes
*
* ```ts
* \@Component()
* export class MyComponent extends NgObservable {
* constructor() {
* ngOnInit(this).subscribe(() => {
* console.log("ngOnInit")
* })
* }
* }
* ```
*
* \@publicApi
* @abstract
*/
class NgObservable {
/**
* OnChanges lifecycle hook
*
* @param {?} changes Simple changes can be strongly typed where input props are known
* @return {?}
*/
ngOnChanges(changes) {
((/** @type {?} */ (this.ngOnChanges))).next([this, changes]);
}
/**
* OnInit lifecycle hook
* @return {?}
*/
ngOnInit() {
((/** @type {?} */ (this.ngOnInit))).next(this);
}
/**
* ngDoCheck lifecycle hook
* @return {?}
*/
ngDoCheck() {
((/** @type {?} */ (this.ngDoCheck))).next(this);
}
/**
* ngAfterContentInit lifecycle hook
* @return {?}
*/
ngAfterContentInit() {
((/** @type {?} */ (this.ngAfterContentInit))).next(this);
}
/**
* ngAfterContentChecked lifecycle hook
* @return {?}
*/
ngAfterContentChecked() {
((/** @type {?} */ (this.ngAfterContentChecked))).next(this);
}
/**
* ngAfterViewInit lifecycle hook
* @return {?}
*/
ngAfterViewInit() {
((/** @type {?} */ (this.ngAfterViewInit))).next(this);
}
/**
* ngAfterViewChecked lifecycle hook
* @return {?}
*/
ngAfterViewChecked() {
((/** @type {?} */ (this.ngAfterViewChecked))).next(this);
}
/**
* ngOnDestroy lifecycle hook
* @return {?}
*/
ngOnDestroy() {
((/** @type {?} */ (this.ngOnDestroy))).next(this);
}
}
_a$1 = mixins;
NgObservable[_a$1] = UseHooks(255)(NgObservable);
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {number} */
const StateChangeStrategy = {
/**
* If detached, reattaches the `ChangeDetectorRef` and allows `OnPush` and `Default` change
* detection strategies to trigger change detection. If using "noop" zones, this setting has
* no effect.
*/
REATTACH: 0,
/**
* When using this strategy, the `ChangeDetectorRef` is automatically detached after the first render.
* All change detection must be performed manually by calling `detectChanges` on `ChangeDetectorRef`
* or by using {@link StateFactory} and calling {@link State#next}.
*
*/
DETACH: 1,
};
StateChangeStrategy[StateChangeStrategy.REATTACH] = 'REATTACH';
StateChangeStrategy[StateChangeStrategy.DETACH] = 'DETACH';
/**
* Provider token for {\@link StateChangeStrategy}
* @type {?}
*/
const STATE_CHANGE_STRATEGY = new InjectionToken("STATE_CHANGE_STRATEGY");
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Configures the change detection strategy for the current injector when used with {\@link StateFactory}
*
* When using `DETACH` mode the change detector is detached after the first
* change detection run and each component must manually call `State#next`
* or `ChangeDetectorRef#detectChanges` afterwards to
* re-render the template. This behaviour ignores any setting of
* `ChangeDetectionStrategy` at the compiler or component level. `REATTACH`
* will reattach the `ChangeDetectorRef` when the `State` is instantiated.
*
* @see {\@link StateChangeStrategy.DETACH} / {\@link StateChangeStrategy.REATTACH}
*
* \@usageNotes
*
* ```typescript
* \@Component({
* providers: [
* useStateChangeStrategy(
* StateChangeStrategy.DETACH, // or REATTACH
* ),
* ],
* })
* export class AppComponent {}
* ```
*
* \@publicApi
*
* @param {?} strategy A flag to determine the change detection strategy that should be used.
*
* @return {?}
*/
function useStateChangeStrategy(strategy) {
return {
provide: STATE_CHANGE_STRATEGY,
useValue: strategy,
};
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @param {?} obj
* @return {?}
*/
function isCompletionObserver(obj) {
return typeof obj && typeof obj["complete"] === "function";
}
/**
* @param {?} obj
* @return {?}
*/
function isUnsubscribable(obj) {
return typeof obj && typeof obj["unsubscribe"] === "function";
}
/**
* @param {?} teardown
* @return {?}
*/
function isTeardownLogic(teardown) {
return (teardown === null ||
typeof teardown === "undefined" ||
(typeof teardown === "function" || typeof teardown["unsubscribe"] === "function"));
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @param {?} sub
* @return {?}
*/
function createStream(sub) {
return (/**
* @param {...?} targets
* @return {?}
*/
function stream(...targets) {
return (/**
* @param {...?} sources
* @return {?}
*/
function (...sources) {
for (const source of sources) {
sub.add(from(source).subscribe((/**
* @param {?} value
* @return {?}
*/
value => {
for (const target of targets) {
if (typeof target === "function") {
target(value);
}
else {
target.next(value);
}
}
})));
}
});
});
}
// WARNING: interface has both a type and a value, skipping emit
/**
* Automatically subscribes to source observables and forwards their values to target observers while
* discarding error and completion events. Cleans up all subscriptions when the stream completes by manually calling `complete`
* or when the bound injector is destroyed.
*
* \@usageNotes
*
* Basic usage
*
* ```ts
* const stream = new Stream()
* const dest = new Subject()
* const source = interval(1000)
*
* stream(dest)(source)
*
* stream.sink = source
* stream.add(source)
*
* // unsubscribe from all sources
* stream.complete()
* ```
*
* With `State`
*
* ```typescript
*
* \@Component({
* viewProviders: [StateFactory] // or providers
* })
* export class MyComponent {
* count: number
*
* constructor(stateFactory: StateFactory) {
* const state = stateFactory.create(this)
*
* // update count once per second
* // automatically unsubscribe when component is destroyed
* stream(state)(interval(1000).pipe(
* map(count => ({ count }))
* ))
* }
* }
* ```
*
* \@publicApi
*/
class Stream extends Callable {
constructor() {
/** @type {?} */
const sub = new Subscription();
super(createStream(sub));
this.sub = sub;
}
/**
* A subscription or an observable of teardown logic that will be cleaned up
* when the stream ends.
* @param {?} sinkable
* @return {?}
*/
set sink(sinkable) {
if (!sinkable) {
return;
}
if (isTeardownLogic(sinkable)) {
this.sub.add(sinkable);
}
else if (Array.isArray(sinkable)) {
for (const stream of sinkable) {
this.sink = stream;
}
}
else {
this.sink = from(sinkable).subscribe((/**
* @param {?} stream
* @return {?}
*/
stream => {
this.sink = stream;
}));
}
}
/**
* Alternative to {\@link sink}
*
* @param {...?} sinkables A series of {\@link Sinkable} to be cleaned up when the stream ends.
* @return {?}
*/
add(...sinkables) {
this.sink = sinkables;
}
/**
* Completes the stream and unsubscribes from all sources.
* @return {?}
*/
complete() {
this.sub.unsubscribe();
}
/**
* `OnDestroy` hook called by Angular when the bound injector is destroyed
* @return {?}
*/
ngOnDestroy() {
this.complete();
}
}
Stream.decorators = [
{ type: Injectable }
];
/** @nocollapse */
Stream.ctorParameters = () => [];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* State object for bound `valueRef`. State changes mutate the original object in-place and notifies any observers
* with a new object reference.
*
* @see {\@link StateFactory}
*
* \@usageNotes
*
* \@publicApi
* @template T
*/
class State extends BehaviorSubject {
/**
* Creates a new State `instance`.
*
* @param {?} valueRef The mutable value object reference to apply state changes to.
* @param {?} markForCheck Notifier that schedules change detection to run on the next microtask.
*/
constructor(valueRef, markForCheck) {
super(Object.create(valueRef));
this.valueRef = valueRef;
this.next = (/**
* @param {?=} partialState
* @return {?}
*/
(partialState) => {
this.patchValue(partialState);
markForCheck();
});
this.patchValue = (/**
* @param {?=} partialState
* @return {?}
*/
(partialState) => {
Object.assign(valueRef, partialState);
super.next(Object.create(valueRef));
});
}
}
/**
* Reactive state management for Angular components and directives.
*
* @see {\@link State}
*
* \@usageNotes
*
* Create a `State<T>` instance by passing the component instance as an argument. All mutations to
* the internal component state should be handled with this service so that observers can be notified
* of changes.
*
* ```typescript
* export interface MyProps {
* title: string
* }
*
* export interface MyState extends MyProps {
* model: string
* }
*
* \@Component({
* viewProviders: [StateFactory, Stream] // or providers
* })
* export class MyComponent implements MyState {
* \@Input()
* title: string
* model: string
*
* constructor(\@Self() stateFactory: StateFactory<MyState>, \@Self() stream: Stream) {
* const state = stateFactory.create(this)
*
* // Imperative usage
* state.next({
* model: "app"
* })
*
* // Reactive usage
* stream(state)(of({ model: "app" }))
* }
* }
* ```
*
* ### Connecting `\@Input()` properties
*
* Changes received from `\@Input()` properties can be mapped onto the state to keep state observers up to date:
*
* ```ts
* \@Component()
* export class MyComponent extends NgObservable implements MyState {
* \@Input()
* value: any
* mappedValue: any
*
* constructor(\@Self() stateFactory: StateFactory<MyState>, \@Self() stream: Stream) {
* const state = stateFactory.create(this)
*
* // assuming 1:1 map between inputs and state
* stream(state)(mapInputsToState(this))
*
* // map inputs to some other value
* stream(state)(mapInputsToState(this).pipe(
* map((props) => ({
* mappedValue: props.value
* }))
* )
* }
* }
* ```
*
* \@publicApi
* @template T
*/
class StateFactory {
/**
* Creates an instance of `StateFactory`
*
* @param {?} strategy The {\@link StateChangeStrategy} to be used. It will wither detach or reattach
* the `ChangeDetectorRef` if one is provided.
*
* @param {?=} cdr The `ChangeDetectorRef` for the current view.
*
*/
constructor(strategy, cdr) {
this.stream = new Stream();
this.cdr = cdr;
this.strategy = strategy;
this.checkNoChanges = isDevMode();
}
/**
* Creates an instance of {\@link State} bound to the given `valueRef`. Performs change detection when notified
* by `markForCheck`.
*
* @param {?} valueRef The mutable value object reference to apply state changes to.
* @return {?}
*/
create(valueRef) {
const { cdr, strategy, stream, checkNoChanges } = this;
/** @type {?} */
const markForCheck = new InvokeSubject();
/** @type {?} */
const state = new State(valueRef, markForCheck);
/** @type {?} */
const shouldDetach = strategy === StateChangeStrategy.DETACH;
if (cdr) {
/** @type {?} */
const detectChanges = (/**
* @return {?}
*/
() => {
cdr.detectChanges();
if (checkNoChanges) {
cdr.checkNoChanges();
}
});
if (shouldDetach) {
cdr.detach();
}
else {
cdr.reattach();
}
Promise.resolve().then((/**
* @return {?}
*/
() => {
if (shouldDetach) {
detectChanges();
}
stream(detectChanges)(debounceTime(0, asapScheduler)(markForCheck));
}));
}
return state;
}
/**
* Cleanup when the injector is destroyed
* @return {?}
*/
ngOnDestroy() {
this.stream.complete();
}
}
StateFactory.decorators = [
{ type: Injectable }
];
/** @nocollapse */
StateFactory.ctorParameters = () => [
{ type: StateChangeStrategy, decorators: [{ type: Inject, args: [STATE_CHANGE_STRATEGY,] }] },
{ type: ChangeDetectorRef, decorators: [{ type: Optional }] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @template T
* @param {?} prototype
* @param {?} key
* @param {?} mapper
* @return {?}
*/
function makePropertyMapper(prototype, key, mapper) {
Object.defineProperty(prototype, key, {
/**
* @return {?}
*/
set() {
/** @type {?} */
const getValue = mapper();
Object.defineProperty(this, key, {
/**
* @return {?}
*/
get() {
return getValue(Object.create(this));
},
enumerable: true,
});
},
enumerable: true,
configurable: true,
});
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @param {?} decorator
* @return {?}
*/
function makePropDecorator(decorator) {
return decorator;
}
/**
* @template R, T, U
* @param {?} selectorFactory
* @return {?}
*/
function computed(selectorFactory) {
return (/**
* @param {?} target
* @param {?} propertyKey
* @return {?}
*/
function (target, propertyKey) {
makePropertyMapper(target, propertyKey, selectorFactory);
});
}
/**
* @param {?} target
* @param {?} propertyKey
* @param {?} name
* @return {?}
*/
function decorateLifecycle(target, propertyKey, name) {
/** @type {?} */
const originalHook = target[name];
target[name] = new InvokeSubject((/**
* @this {?}
* @param {...?} args
* @return {?}
*/
function (...args) {
this[propertyKey].apply(this, args);
originalHook.apply(this, args);
}));
}
/**
* @template T
* @return {?}
*/
function ngOnChanges() {
return (/**
* @param {?} target
* @param {?} propertyKey
* @return {?}
*/
function (target, propertyKey) {
return decorateLifecycle(target, propertyKey, "ngOnChanges");
});
}
/**
* @template T
* @return {?}
*/
function ngOnInit() {
return (/**
* @param {?} target
* @param {?} propertyKey
* @return {?}
*/
function (target, propertyKey) {
return decorateLifecycle(target, propertyKey, "ngOnInit");
});
}
/**
* @template T
* @return {?}
*/
function ngAfterContentChecked() {
return (/**
* @param {?} target
* @param {?} propertyKey
* @return {?}
*/
function (target, propertyKey) {
return decorateLifecycle(target, propertyKey, "ngAfterContentChecked");
});
}
/**
* @template T
* @return {?}
*/
function ngAfterViewChecked() {
return (/**
* @param {?} target
* @param {?} propertyKey
* @return {?}
*/
function (target, propertyKey) {
return decorateLifecycle(target, propertyKey, "ngAfterViewChecked");
});
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @template U, V
* @param {?} source
* @param {?} name
* @param {?=} once
* @param {?=} pipes
* @return {?}
*/
function createLifecycleHook(source, name, once, pipes = [filter((/**
* @param {?} inst
* @return {?}
*/
inst => inst === source))]) {
/** @type {?} */
const hook = source[name];
if (once) {
pipes.push(take(1));
}
if (isObservable(hook)) {
return ((/** @type {?} */ (hook))).pipe(...pipes);
}
else {
console.error(`${name} is not an observable! Error context: `, source);
throw new Error();
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @template T
* @param {?} source
* @return {?}
*/
function ngDoCheck(source) {
return createLifecycleHook(source, "ngDoCheck");
}
/**
* @template T
* @param {?} source
* @return {?}
*/
function ngAfterContentInit(source) {
return createLifecycleHook(source, "ngAfterContentInit", true);
}
/**
* @template T
* @param {?} source
* @return {?}
*/
function ngAfterViewInit(source) {
return createLifecycleHook(source, "ngAfterViewInit", true);
}
/**
* @template T
* @param {?} source
* @return {?}
*/
function ngOnDestroy(source) {
return createLifecycleHook(source, "ngOnDestroy", true);
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// WARNING: interface has both a type and a value, skipping emit
/**
* \@Annotation
* \@publicApi
* @type {?}
*/
const Computed = makePropDecorator(computed)
/**
* Type of the NgOnChangesDecorator decorator / constructor function.
*
* @publicApi
*/
;
// WARNING: interface has both a type and a value, skipping emit
/**
* \@Annotation
* \@publicApi
* @type {?}
*/
const NgOnChanges = makePropDecorator(ngOnChanges)
/**
* Type of the NgOnChangesDecorator decorator / constructor function.
*
* @publicApi
*/
;
// WARNING: interface has both a type and a value, skipping emit
/**
* \@Annotation
* \@publicApi
* @type {?}
*/
const NgOnInit = makePropDecorator(ngOnInit)
/**
* Type of the NgOnChangesDecorator decorator / constructor function.
*
* @publicApi
*/
;
// WARNING: interface has both a type and a value, skipping emit
/**
* \@Annotation
* \@publicApi
* @type {?}
*/
const NgDoCheck = makePropDecorator(ngDoCheck)
/**
* Type of the NgOnChangesDecorator decorator / constructor function.
*
* @publicApi
*/
;
// WARNING: interface has both a type and a value, skipping emit
/**
* \@Annotation
* \@publicApi
* @type {?}
*/
const NgAfterContentInit = makePropDecorator(ngAfterContentInit)
/**
* Type of the NgOnChangesDecorator decorator / constructor function.
*
* @publicApi
*/
;
// WARNING: interface has both a type and a value, skipping emit
/**
* \@Annotation
* \@publicApi
* @type {?}
*/
const NgAfterContentChecked = makePropDecorator(ngAfterContentChecked)
/**
* Type of the NgOnChangesDecorator decorator / constructor function.
*
* @publicApi
*/
;
// WARNING: interface has both a type and a value, skipping emit
/**
* \@Annotation
* \@publicApi
* @type {?}
*/
const NgAfterViewInit = makePropDecorator(ngAfterViewInit)
/**
* Type of the NgOnChangesDecorator decorator / constructor function.
*
* @publicApi
*/
;
// WARNING: interface has both a type and a value, skipping emit
/**
* \@Annotation
* \@publicApi
* @type {?}
*/
const NgAfterViewChecked = makePropDecorator(ngAfterViewChecked)
/**
* Type of the NgOnChangesDecorator decorator / constructor function.
*
* @publicApi
*/
;
// WARNING: interface has both a type and a value, skipping emit
/**
* \@Annotation
* \@publicApi
* @type {?}
*/
const NgOnDestroy = makePropDecorator(ngOnDestroy);
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Convenience function for cleaning up multiple subscriptions.
*
* @param {...?} unsubscribables A series of subscriptions or completable subjects to unsubscribe from.
* @return {?}
*/
function unsubscribe(...unsubscribables) {
for (const subscriber of unsubscribables) {
if (isCompletionObserver(subscriber)) {
subscriber.complete();
}
if (isUnsubscribable(subscriber)) {
subscriber.unsubscribe();
}
}
}
export { Computed, InvokeSubject, NgAfterContentChecked, NgAfterContentInit, NgAfterViewChecked, NgAfterViewInit, NgDoCheck, NgObservable, NgOnChanges, NgOnDestroy, NgOnInit, STATE_CHANGE_STRATEGY, State, StateChangeStrategy, StateFactory, Stream, unsubscribe, useStateChangeStrategy, Callable as ɵa, makePropDecorator as ɵb, computed as ɵc, ngOnChanges as ɵd, ngOnInit as ɵe, ngAfterContentChecked as ɵf, ngAfterViewChecked as ɵg, ngDoCheck as ɵh, ngAfterContentInit as ɵi, ngAfterViewInit as ɵj, ngOnDestroy as ɵk, createLifecycleHook as ɵl };
//# sourceMappingURL=zodiac-ui-ng-observable.js.map