[6a3a178] | 1 | /*
|
---|
| 2 | * This file and its definitions are needed just so that ESDoc sees these
|
---|
| 3 | * JSDoc documentation comments. Originally they were meant for some TypeScript
|
---|
| 4 | * interfaces, but TypeScript strips away JSDoc comments near interfaces. Hence,
|
---|
| 5 | * we need these bogus classes, which are not stripped away. This file on the
|
---|
| 6 | * other hand, is not included in the release bundle.
|
---|
| 7 | */
|
---|
| 8 | import { Observer, TeardownLogic } from './internal/types';
|
---|
| 9 | import { Observable } from './internal/Observable';
|
---|
| 10 | import './internal/observable/dom/MiscJSDoc';
|
---|
| 11 |
|
---|
| 12 | /**
|
---|
| 13 | * We need this JSDoc comment for affecting ESDoc.
|
---|
| 14 | * @extends {Ignored}
|
---|
| 15 | * @hide true
|
---|
| 16 | */
|
---|
| 17 | export class ObservableDoc {
|
---|
| 18 | /**
|
---|
| 19 | * Creates a new Observable, that will execute the specified function when an
|
---|
| 20 | * {@link Observer} subscribes to it.
|
---|
| 21 | *
|
---|
| 22 | * <span class="informal">Create custom Observable, that does whatever you like.</span>
|
---|
| 23 | *
|
---|
| 24 | * ![](create.png)
|
---|
| 25 | *
|
---|
| 26 | * `create` converts an `onSubscription` function to an actual Observable.
|
---|
| 27 | * Whenever someone subscribes to that Observable, the function will be called
|
---|
| 28 | * with an {@link Observer} instance as a first and only parameter. `onSubscription` should
|
---|
| 29 | * then invoke the Observers `next`, `error` and `complete` methods.
|
---|
| 30 | *
|
---|
| 31 | * Calling `next` with a value will emit that value to the observer. Calling `complete`
|
---|
| 32 | * means that Observable finished emitting and will not do anything else.
|
---|
| 33 | * Calling `error` means that something went wrong - value passed to `error` method should
|
---|
| 34 | * provide details on what exactly happened.
|
---|
| 35 | *
|
---|
| 36 | * A well-formed Observable can emit as many values as it needs via `next` method,
|
---|
| 37 | * but `complete` and `error` methods can be called only once and nothing else can be called
|
---|
| 38 | * thereafter. If you try to invoke `next`, `complete` or `error` methods after created
|
---|
| 39 | * Observable already completed or ended with an error, these calls will be ignored to
|
---|
| 40 | * preserve so called *Observable Contract*. Note that you are not required to call
|
---|
| 41 | * `complete` at any point - it is perfectly fine to create an Observable that never ends,
|
---|
| 42 | * depending on your needs.
|
---|
| 43 | *
|
---|
| 44 | * `onSubscription` can optionally return either a function or an object with
|
---|
| 45 | * `unsubscribe` method. In both cases function or method will be called when
|
---|
| 46 | * subscription to Observable is being cancelled and should be used to clean up all
|
---|
| 47 | * resources. So, for example, if you are using `setTimeout` in your custom
|
---|
| 48 | * Observable, when someone unsubscribes, you can clear planned timeout, so that
|
---|
| 49 | * it does not fire needlessly and browser (or other environment) does not waste
|
---|
| 50 | * computing power on timing event that no one will listen to anyways.
|
---|
| 51 | *
|
---|
| 52 | * Most of the times you should not need to use `create`, because existing
|
---|
| 53 | * operators allow you to create an Observable for most of the use cases.
|
---|
| 54 | * That being said, `create` is low-level mechanism allowing you to create
|
---|
| 55 | * any Observable, if you have very specific needs.
|
---|
| 56 | *
|
---|
| 57 | * **TypeScript signature issue**
|
---|
| 58 | *
|
---|
| 59 | * Because Observable extends class which already has defined static `create` function,
|
---|
| 60 | * but with different type signature, it was impossible to assign proper signature to
|
---|
| 61 | * `Observable.create`. Because of that, it has very general type `Function` and thus
|
---|
| 62 | * function passed to `create` will not be type checked, unless you explicitly state
|
---|
| 63 | * what signature it should have.
|
---|
| 64 | *
|
---|
| 65 | * When using TypeScript we recommend to declare type signature of function passed to
|
---|
| 66 | * `create` as `(observer: Observer) => TeardownLogic`, where {@link Observer}
|
---|
| 67 | * and {@link TeardownLogic} are interfaces provided by the library.
|
---|
| 68 | *
|
---|
| 69 | * @example <caption>Emit three numbers, then complete.</caption>
|
---|
| 70 | * var observable = Rx.Observable.create(function (observer) {
|
---|
| 71 | * observer.next(1);
|
---|
| 72 | * observer.next(2);
|
---|
| 73 | * observer.next(3);
|
---|
| 74 | * observer.complete();
|
---|
| 75 | * });
|
---|
| 76 | * observable.subscribe(
|
---|
| 77 | * value => console.log(value),
|
---|
| 78 | * err => {},
|
---|
| 79 | * () => console.log('this is the end')
|
---|
| 80 | * );
|
---|
| 81 | *
|
---|
| 82 | * // Logs
|
---|
| 83 | * // 1
|
---|
| 84 | * // 2
|
---|
| 85 | * // 3
|
---|
| 86 | * // "this is the end"
|
---|
| 87 | *
|
---|
| 88 | *
|
---|
| 89 | * @example <caption>Emit an error</caption>
|
---|
| 90 | * const observable = Rx.Observable.create((observer) => {
|
---|
| 91 | * observer.error('something went really wrong...');
|
---|
| 92 | * });
|
---|
| 93 | *
|
---|
| 94 | * observable.subscribe(
|
---|
| 95 | * value => console.log(value), // will never be called
|
---|
| 96 | * err => console.log(err),
|
---|
| 97 | * () => console.log('complete') // will never be called
|
---|
| 98 | * );
|
---|
| 99 | *
|
---|
| 100 | * // Logs
|
---|
| 101 | * // "something went really wrong..."
|
---|
| 102 | *
|
---|
| 103 | *
|
---|
| 104 | * @example <caption>Return unsubscribe function</caption>
|
---|
| 105 | *
|
---|
| 106 | * const observable = Rx.Observable.create(observer => {
|
---|
| 107 | * const id = setTimeout(() => observer.next('...'), 5000); // emit value after 5s
|
---|
| 108 | *
|
---|
| 109 | * return () => { clearTimeout(id); console.log('cleared!'); };
|
---|
| 110 | * });
|
---|
| 111 | *
|
---|
| 112 | * const subscription = observable.subscribe(value => console.log(value));
|
---|
| 113 | *
|
---|
| 114 | * setTimeout(() => subscription.unsubscribe(), 3000); // cancel subscription after 3s
|
---|
| 115 | *
|
---|
| 116 | * // Logs:
|
---|
| 117 | * // "cleared!" after 3s
|
---|
| 118 | *
|
---|
| 119 | * // Never logs "..."
|
---|
| 120 | *
|
---|
| 121 | *
|
---|
| 122 | * @see {@link empty}
|
---|
| 123 | * @see {@link never}
|
---|
| 124 | * @see {@link of}
|
---|
| 125 | * @see {@link throw}
|
---|
| 126 | *
|
---|
| 127 | * @param {function(observer: Observer): TeardownLogic} onSubscription A
|
---|
| 128 | * function that accepts an Observer, and invokes its `next`,
|
---|
| 129 | * `error`, and `complete` methods as appropriate, and optionally returns some
|
---|
| 130 | * logic for cleaning up resources.
|
---|
| 131 | * @return {Observable} An Observable that, whenever subscribed, will execute the
|
---|
| 132 | * specified function.
|
---|
| 133 | * @static true
|
---|
| 134 | * @name create
|
---|
| 135 | * @owner Observable
|
---|
| 136 | * @nocollapse
|
---|
| 137 | */
|
---|
| 138 | static create<T>(onSubscription: <R>(observer: Observer<R>) => TeardownLogic): Observable<T> {
|
---|
| 139 | return new Observable<T>(onSubscription);
|
---|
| 140 | }
|
---|
| 141 | }
|
---|
| 142 |
|
---|
| 143 | /**
|
---|
| 144 | * An interface for a consumer of push-based notifications delivered by an
|
---|
| 145 | * {@link Observable}.
|
---|
| 146 | *
|
---|
| 147 | * ```ts
|
---|
| 148 | * interface Observer<T> {
|
---|
| 149 | * closed?: boolean;
|
---|
| 150 | * next: (value: T) => void;
|
---|
| 151 | * error: (err: any) => void;
|
---|
| 152 | * complete: () => void;
|
---|
| 153 | * }
|
---|
| 154 | * ```
|
---|
| 155 | *
|
---|
| 156 | * An object conforming to the Observer interface is usually
|
---|
| 157 | * given to the `observable.subscribe(observer)` method, and the Observable will
|
---|
| 158 | * call the Observer's `next(value)` method to provide notifications. A
|
---|
| 159 | * well-behaved Observable will call an Observer's `complete()` method exactly
|
---|
| 160 | * once or the Observer's `error(err)` method exactly once, as the last
|
---|
| 161 | * notification delivered.
|
---|
| 162 | *
|
---|
| 163 | * @interface
|
---|
| 164 | * @name Observer
|
---|
| 165 | * @noimport true
|
---|
| 166 | */
|
---|
| 167 | export class ObserverDoc<T> {
|
---|
| 168 | /**
|
---|
| 169 | * An optional flag to indicate whether this Observer, when used as a
|
---|
| 170 | * subscriber, has already been unsubscribed from its Observable.
|
---|
| 171 | * @type {boolean}
|
---|
| 172 | */
|
---|
| 173 | closed: boolean = false;
|
---|
| 174 | /**
|
---|
| 175 | * The callback to receive notifications of type `next` from the Observable,
|
---|
| 176 | * with a value. The Observable may call this method 0 or more times.
|
---|
| 177 | * @param {T} value The `next` value.
|
---|
| 178 | * @return {void}
|
---|
| 179 | */
|
---|
| 180 | next(value: T): void {
|
---|
| 181 | return void 0;
|
---|
| 182 | }
|
---|
| 183 | /**
|
---|
| 184 | * The callback to receive notifications of type `error` from the Observable,
|
---|
| 185 | * with an attached {@link Error}. Notifies the Observer that the Observable
|
---|
| 186 | * has experienced an error condition.
|
---|
| 187 | * @param {any} err The `error` exception.
|
---|
| 188 | * @return {void}
|
---|
| 189 | */
|
---|
| 190 | error(err: any): void {
|
---|
| 191 | return void 0;
|
---|
| 192 | }
|
---|
| 193 | /**
|
---|
| 194 | * The callback to receive a valueless notification of type `complete` from
|
---|
| 195 | * the Observable. Notifies the Observer that the Observable has finished
|
---|
| 196 | * sending push-based notifications.
|
---|
| 197 | * @return {void}
|
---|
| 198 | */
|
---|
| 199 | complete(): void {
|
---|
| 200 | return void 0;
|
---|
| 201 | }
|
---|
| 202 | }
|
---|
| 203 |
|
---|
| 204 | /**
|
---|
| 205 | * `SubscribableOrPromise` interface describes values that behave like either
|
---|
| 206 | * Observables or Promises. Every operator that accepts arguments annotated
|
---|
| 207 | * with this interface, can be also used with parameters that are not necessarily
|
---|
| 208 | * RxJS Observables.
|
---|
| 209 | *
|
---|
| 210 | * Following types of values might be passed to operators expecting this interface:
|
---|
| 211 | *
|
---|
| 212 | * ## Observable
|
---|
| 213 | *
|
---|
| 214 | * RxJS {@link Observable} instance.
|
---|
| 215 | *
|
---|
| 216 | * ## Observable-like (Subscribable)
|
---|
| 217 | *
|
---|
| 218 | * This might be any object that has `Symbol.observable` method. This method,
|
---|
| 219 | * when called, should return object with `subscribe` method on it, which should
|
---|
| 220 | * behave the same as RxJS `Observable.subscribe`.
|
---|
| 221 | *
|
---|
| 222 | * `Symbol.observable` is part of https://github.com/tc39/proposal-observable proposal.
|
---|
| 223 | * Since currently it is not supported natively, and every symbol is equal only to itself,
|
---|
| 224 | * you should use https://github.com/blesh/symbol-observable polyfill, when implementing
|
---|
| 225 | * custom Observable-likes.
|
---|
| 226 | *
|
---|
| 227 | * **TypeScript Subscribable interface issue**
|
---|
| 228 | *
|
---|
| 229 | * Although TypeScript interface claims that Subscribable is an object that has `subscribe`
|
---|
| 230 | * method declared directly on it, passing custom objects that have `subscribe`
|
---|
| 231 | * method but not `Symbol.observable` method will fail at runtime. Conversely, passing
|
---|
| 232 | * objects with `Symbol.observable` but without `subscribe` will fail at compile time
|
---|
| 233 | * (if you use TypeScript).
|
---|
| 234 | *
|
---|
| 235 | * TypeScript has problem supporting interfaces with methods defined as symbol
|
---|
| 236 | * properties. To get around that, you should implement `subscribe` directly on
|
---|
| 237 | * passed object, and make `Symbol.observable` method simply return `this`. That way
|
---|
| 238 | * everything will work as expected, and compiler will not complain. If you really
|
---|
| 239 | * do not want to put `subscribe` directly on your object, you will have to type cast
|
---|
| 240 | * it to `any`, before passing it to an operator.
|
---|
| 241 | *
|
---|
| 242 | * When this issue is resolved, Subscribable interface will only permit Observable-like
|
---|
| 243 | * objects with `Symbol.observable` defined, no matter if they themselves implement
|
---|
| 244 | * `subscribe` method or not.
|
---|
| 245 | *
|
---|
| 246 | * ## ES6 Promise
|
---|
| 247 | *
|
---|
| 248 | * Promise can be interpreted as Observable that emits value and completes
|
---|
| 249 | * when it is resolved or errors when it is rejected.
|
---|
| 250 | *
|
---|
| 251 | * ## Promise-like (Thenable)
|
---|
| 252 | *
|
---|
| 253 | * Promises passed to operators do not have to be native ES6 Promises.
|
---|
| 254 | * They can be implementations from popular Promise libraries, polyfills
|
---|
| 255 | * or even custom ones. They just need to have `then` method that works
|
---|
| 256 | * as the same as ES6 Promise `then`.
|
---|
| 257 | *
|
---|
| 258 | * @example <caption>Use merge and then map with non-RxJS observable</caption>
|
---|
| 259 | * const nonRxJSObservable = {
|
---|
| 260 | * subscribe(observer) {
|
---|
| 261 | * observer.next(1000);
|
---|
| 262 | * observer.complete();
|
---|
| 263 | * },
|
---|
| 264 | * [Symbol.observable]() {
|
---|
| 265 | * return this;
|
---|
| 266 | * }
|
---|
| 267 | * };
|
---|
| 268 | *
|
---|
| 269 | * Rx.Observable.merge(nonRxJSObservable)
|
---|
| 270 | * .map(value => "This value is " + value)
|
---|
| 271 | * .subscribe(result => console.log(result)); // Logs "This value is 1000"
|
---|
| 272 | *
|
---|
| 273 | *
|
---|
| 274 | * @example <caption>Use combineLatest with ES6 Promise</caption>
|
---|
| 275 | * Rx.Observable.combineLatest(Promise.resolve(5), Promise.resolve(10), Promise.resolve(15))
|
---|
| 276 | * .subscribe(
|
---|
| 277 | * value => console.log(value),
|
---|
| 278 | * err => {},
|
---|
| 279 | * () => console.log('the end!')
|
---|
| 280 | * );
|
---|
| 281 | * // Logs
|
---|
| 282 | * // [5, 10, 15]
|
---|
| 283 | * // "the end!"
|
---|
| 284 | *
|
---|
| 285 | *
|
---|
| 286 | * @interface
|
---|
| 287 | * @name SubscribableOrPromise
|
---|
| 288 | * @noimport true
|
---|
| 289 | */
|
---|
| 290 | export class SubscribableOrPromiseDoc<T> {
|
---|
| 291 |
|
---|
| 292 | }
|
---|
| 293 |
|
---|
| 294 | /**
|
---|
| 295 | * `ObservableInput` interface describes all values that are either an
|
---|
| 296 | * {@link SubscribableOrPromise} or some kind of collection of values that
|
---|
| 297 | * can be transformed to Observable emitting that values. Every operator that
|
---|
| 298 | * accepts arguments annotated with this interface, can be also used with
|
---|
| 299 | * parameters that are not necessarily RxJS Observables.
|
---|
| 300 | *
|
---|
| 301 | * `ObservableInput` extends {@link SubscribableOrPromise} with following types:
|
---|
| 302 | *
|
---|
| 303 | * ## Array
|
---|
| 304 | *
|
---|
| 305 | * Arrays can be interpreted as observables that emit all values in array one by one,
|
---|
| 306 | * from left to right, and then complete immediately.
|
---|
| 307 | *
|
---|
| 308 | * ## Array-like
|
---|
| 309 | *
|
---|
| 310 | * Arrays passed to operators do not have to be built-in JavaScript Arrays. They
|
---|
| 311 | * can be also, for example, `arguments` property available inside every function,
|
---|
| 312 | * [DOM NodeList](https://developer.mozilla.org/pl/docs/Web/API/NodeList),
|
---|
| 313 | * or, actually, any object that has `length` property (which is a number)
|
---|
| 314 | * and stores values under non-negative (zero and up) integers.
|
---|
| 315 | *
|
---|
| 316 | * ## ES6 Iterable
|
---|
| 317 | *
|
---|
| 318 | * Operators will accept both built-in and custom ES6 Iterables, by treating them as
|
---|
| 319 | * observables that emit all its values in order of iteration and then complete
|
---|
| 320 | * when iteration ends. Note that contrary to arrays, Iterables do not have to
|
---|
| 321 | * necessarily be finite, so creating Observables that never complete is possible as well.
|
---|
| 322 | *
|
---|
| 323 | * Note that you can make iterator an instance of Iterable by having it return itself
|
---|
| 324 | * in `Symbol.iterator` method. It means that every operator accepting Iterables accepts,
|
---|
| 325 | * though indirectly, iterators themselves as well. All native ES6 iterators are instances
|
---|
| 326 | * of Iterable by default, so you do not have to implement their `Symbol.iterator` method
|
---|
| 327 | * yourself.
|
---|
| 328 | *
|
---|
| 329 | * **TypeScript Iterable interface issue**
|
---|
| 330 | *
|
---|
| 331 | * TypeScript `ObservableInput` interface actually lacks type signature for Iterables,
|
---|
| 332 | * because of issues it caused in some projects (see [this issue](https://github.com/ReactiveX/rxjs/issues/2306)).
|
---|
| 333 | * If you want to use Iterable as argument for operator, cast it to `any` first.
|
---|
| 334 | * Remember of course that, because of casting, you have to yourself ensure that passed
|
---|
| 335 | * argument really implements said interface.
|
---|
| 336 | *
|
---|
| 337 | *
|
---|
| 338 | * @example <caption>Use merge with arrays</caption>
|
---|
| 339 | * Rx.Observable.merge([1, 2], [4], [5, 6])
|
---|
| 340 | * .subscribe(
|
---|
| 341 | * value => console.log(value),
|
---|
| 342 | * err => {},
|
---|
| 343 | * () => console.log('ta dam!')
|
---|
| 344 | * );
|
---|
| 345 | *
|
---|
| 346 | * // Logs
|
---|
| 347 | * // 1
|
---|
| 348 | * // 2
|
---|
| 349 | * // 3
|
---|
| 350 | * // 4
|
---|
| 351 | * // 5
|
---|
| 352 | * // 6
|
---|
| 353 | * // "ta dam!"
|
---|
| 354 | *
|
---|
| 355 | *
|
---|
| 356 | * @example <caption>Use merge with array-like</caption>
|
---|
| 357 | * Rx.Observable.merge({0: 1, 1: 2, length: 2}, {0: 3, length: 1})
|
---|
| 358 | * .subscribe(
|
---|
| 359 | * value => console.log(value),
|
---|
| 360 | * err => {},
|
---|
| 361 | * () => console.log('nice, huh?')
|
---|
| 362 | * );
|
---|
| 363 | *
|
---|
| 364 | * // Logs
|
---|
| 365 | * // 1
|
---|
| 366 | * // 2
|
---|
| 367 | * // 3
|
---|
| 368 | * // "nice, huh?"
|
---|
| 369 | *
|
---|
| 370 | * @example <caption>Use merge with an Iterable (Map)</caption>
|
---|
| 371 | * const firstMap = new Map([[1, 'a'], [2, 'b']]);
|
---|
| 372 | * const secondMap = new Map([[3, 'c'], [4, 'd']]);
|
---|
| 373 | *
|
---|
| 374 | * Rx.Observable.merge(
|
---|
| 375 | * firstMap, // pass Iterable
|
---|
| 376 | * secondMap.values() // pass iterator, which is itself an Iterable
|
---|
| 377 | * ).subscribe(
|
---|
| 378 | * value => console.log(value),
|
---|
| 379 | * err => {},
|
---|
| 380 | * () => console.log('yup!')
|
---|
| 381 | * );
|
---|
| 382 | *
|
---|
| 383 | * // Logs
|
---|
| 384 | * // [1, "a"]
|
---|
| 385 | * // [2, "b"]
|
---|
| 386 | * // "c"
|
---|
| 387 | * // "d"
|
---|
| 388 | * // "yup!"
|
---|
| 389 | *
|
---|
| 390 | * @example <caption>Use from with generator (returning infinite iterator)</caption>
|
---|
| 391 | * // infinite stream of incrementing numbers
|
---|
| 392 | * const infinite = function* () {
|
---|
| 393 | * let i = 0;
|
---|
| 394 | *
|
---|
| 395 | * while (true) {
|
---|
| 396 | * yield i++;
|
---|
| 397 | * }
|
---|
| 398 | * };
|
---|
| 399 | *
|
---|
| 400 | * Rx.Observable.from(infinite())
|
---|
| 401 | * .take(3) // only take 3, cause this is infinite
|
---|
| 402 | * .subscribe(
|
---|
| 403 | * value => console.log(value),
|
---|
| 404 | * err => {},
|
---|
| 405 | * () => console.log('ta dam!')
|
---|
| 406 | * );
|
---|
| 407 | *
|
---|
| 408 | * // Logs
|
---|
| 409 | * // 0
|
---|
| 410 | * // 1
|
---|
| 411 | * // 2
|
---|
| 412 | * // "ta dam!"
|
---|
| 413 | *
|
---|
| 414 | * @interface
|
---|
| 415 | * @name ObservableInput
|
---|
| 416 | * @noimport true
|
---|
| 417 | */
|
---|
| 418 | export class ObservableInputDoc<T> {
|
---|
| 419 |
|
---|
| 420 | }
|
---|
| 421 |
|
---|
| 422 | /**
|
---|
| 423 | *
|
---|
| 424 | * This interface describes what should be returned by function passed to Observable
|
---|
| 425 | * constructor or static {@link create} function. Value of that interface will be used
|
---|
| 426 | * to cancel subscription for given Observable.
|
---|
| 427 | *
|
---|
| 428 | * `TeardownLogic` can be:
|
---|
| 429 | *
|
---|
| 430 | * ## Function
|
---|
| 431 | *
|
---|
| 432 | * Function that takes no parameters. When consumer of created Observable calls `unsubscribe`,
|
---|
| 433 | * that function will be called
|
---|
| 434 | *
|
---|
| 435 | * ## AnonymousSubscription
|
---|
| 436 | *
|
---|
| 437 | * `AnonymousSubscription` is simply an object with `unsubscribe` method on it. That method
|
---|
| 438 | * will work the same as function
|
---|
| 439 | *
|
---|
| 440 | * ## void
|
---|
| 441 | *
|
---|
| 442 | * If created Observable does not have any resources to clean up, function does not have to
|
---|
| 443 | * return anything.
|
---|
| 444 | *
|
---|
| 445 | * @interface
|
---|
| 446 | * @name TeardownLogic
|
---|
| 447 | * @noimport true
|
---|
| 448 | */
|
---|
| 449 | export class TeardownLogicDoc {
|
---|
| 450 |
|
---|
| 451 | }
|
---|