evg_observable 1.9.45 → 1.9.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +227 -41
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,9 +6,49 @@ EVG Observable
|
|
|
6
6
|
EVG Observable - is a light library for simple use.
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
|
+
## Navigation
|
|
10
|
+
|
|
11
|
+
- [What is EVG Observable?](#what-is-evg-observable)
|
|
12
|
+
- [Installation](#installation)
|
|
13
|
+
- [Node.js](#nodejs)
|
|
14
|
+
- [Browser](#browser)
|
|
15
|
+
- [Usage](#usage)
|
|
16
|
+
- [Observable simple usage](#observable-simple-usage)
|
|
17
|
+
- [Browser simple usage](#browser-simple-usage)
|
|
18
|
+
- [Observable pipe usage](#observable-pipe-usage)
|
|
19
|
+
- [Ordered observable](#ordered-observable)
|
|
20
|
+
- [Collector](#collector)
|
|
21
|
+
- [Advanced Usage Example](#advanced-usage-example)
|
|
22
|
+
- [Methods](#methods)
|
|
23
|
+
- [Observable](#observable)
|
|
24
|
+
- [Observable.pipe()](#observablepipe)
|
|
25
|
+
- [Inbound filters](#inbound-filters)
|
|
26
|
+
- [Observable subscriber](#observable-subscriber)
|
|
27
|
+
- [Ordered observable](#ordered-observable-1)
|
|
28
|
+
- [Ordered observable subscriber](#ordered-observable-subscriber)
|
|
29
|
+
- [Collector](#collector-1)
|
|
30
|
+
- [License](#license)
|
|
31
|
+
|
|
9
32
|
## What is EVG Observable?
|
|
10
33
|
|
|
11
|
-
EVG Observable is a
|
|
34
|
+
EVG Observable is a robust, lightweight library designed for handling asynchronous events. What sets it apart is its
|
|
35
|
+
compact size alongside a wealth of powerful features that facilitate efficient event management. Here are some specific
|
|
36
|
+
features that make it stand out from the rest:
|
|
37
|
+
|
|
38
|
+
1. **Multi-observable subscription**: With EVG Observable, you are not limited to adding only listeners to your
|
|
39
|
+
subscribers. Now, you have the option to add other observables as well.
|
|
40
|
+
|
|
41
|
+
2. **Multi-subscriber capability**: The library allows you to subscribe any number of subscribers to an observable. This
|
|
42
|
+
works with both listeners and observables.
|
|
43
|
+
|
|
44
|
+
3. **Extended pipe chain**: The flexibility of EVG Observable extends to pipe chains as well. You can now add any number
|
|
45
|
+
of filters in a pipe chain whereas previously you were limited to just one.
|
|
46
|
+
|
|
47
|
+
4. **Inbound and outbound filters**: In addition to existing outbound pipes, the library now supports inbound filters as
|
|
48
|
+
well, providing you greater control over your data flow.
|
|
49
|
+
|
|
50
|
+
5. **Flexible switch-case in pipes**: Whether you are dealing with outbound pipes or inbound filters, a flexible
|
|
51
|
+
switch-case logic has been introduced for better data handling.
|
|
12
52
|
|
|
13
53
|
## Installation
|
|
14
54
|
|
|
@@ -19,7 +59,9 @@ EVG Observable is a compact, lightweight library designed for handling asynchron
|
|
|
19
59
|
$ npm install evg_observable
|
|
20
60
|
|
|
21
61
|
### Browser
|
|
62
|
+
|
|
22
63
|
```html
|
|
64
|
+
|
|
23
65
|
<script src="https://unpkg.com/evg_observable/repo/evg_observable.js"></script>
|
|
24
66
|
```
|
|
25
67
|
|
|
@@ -344,45 +386,190 @@ observable$.next('SOME DATA');
|
|
|
344
386
|
// To unsubscribe one subscriber, you can use: collector.unsubscribe(subscriber).
|
|
345
387
|
```
|
|
346
388
|
|
|
389
|
+
### Advanced Usage Example
|
|
390
|
+
|
|
391
|
+
The following TypeScript example demonstrates how the extended implementation could be used, incorporating all the new
|
|
392
|
+
updates:
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
// Import the Observable library
|
|
396
|
+
import {Observable} from "evg_observable/src/outLib/Observable";
|
|
397
|
+
|
|
398
|
+
// Constants representing different hair colors
|
|
399
|
+
const HAIR = {
|
|
400
|
+
BLOND: "BLOND",
|
|
401
|
+
BLACK: "BLACK",
|
|
402
|
+
BROWN: "BROWN",
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Constants for gender
|
|
406
|
+
const GENDER = {
|
|
407
|
+
MAN: "MAN",
|
|
408
|
+
WOMAN: "WOMAN"
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// Constants for different occupations
|
|
412
|
+
const MAJOR = {
|
|
413
|
+
DOCTOR: "DOCTOR",
|
|
414
|
+
DRIVER: "DRIVER",
|
|
415
|
+
CHILD: "CHILD",
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// Definition of the "Person" class
|
|
419
|
+
class Person {
|
|
420
|
+
constructor(
|
|
421
|
+
public name: string,
|
|
422
|
+
public age: number,
|
|
423
|
+
public gender: string,
|
|
424
|
+
public major: string,
|
|
425
|
+
public hairColor: string) {
|
|
426
|
+
|
|
427
|
+
this.hairColor = hairColor;
|
|
428
|
+
this.name = name;
|
|
429
|
+
this.age = age;
|
|
430
|
+
this.gender = gender;
|
|
431
|
+
this.major = major;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// Create Observables for individual person, men and women
|
|
436
|
+
const personal$ = new Observable<Person>(null);
|
|
437
|
+
const men$ = new Observable<Person>(null)
|
|
438
|
+
const women$ = new Observable<Person>(null)
|
|
439
|
+
|
|
440
|
+
// Define various filters to be used later
|
|
441
|
+
const youngAgeFilter = (person: Person) => person.age > 17;
|
|
442
|
+
const oldAgeFilter = (person: Person) => person.age < 60;
|
|
443
|
+
const menFilter = (person: Person) => person.gender === GENDER.MAN;
|
|
444
|
+
const womenFilter = (person: Person) => person.gender === GENDER.WOMAN;
|
|
445
|
+
const blondFilter = (person: Person) => person.hairColor === HAIR.BLOND;
|
|
446
|
+
const blackFilter = (person: Person) => person.hairColor === HAIR.BLACK;
|
|
447
|
+
|
|
448
|
+
// Callback function to execute when some man is ready to work
|
|
449
|
+
const manReadyToWork = (worker: Person) => {
|
|
450
|
+
console.log("MAN ==> is ready to work:", worker.name, worker.age, worker.major);
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
// Callback function to execute when some woman is ready to work
|
|
454
|
+
const womanReadyToWork = (worker: Person) => {
|
|
455
|
+
console.log("WOMAN ==> is ready to work:", worker.name, worker.age, worker.major);
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
// Callback function to execute for people with black or blond hair
|
|
459
|
+
const blondAndBlack = (person: Person) => {
|
|
460
|
+
console.log("PERSON ==> only black or blond:", person.name, person.age, person.hairColor);
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
// Apply the filters to men$ and women$
|
|
464
|
+
men$.addFilter()
|
|
465
|
+
.filter(menFilter);
|
|
466
|
+
|
|
467
|
+
women$.addFilter()
|
|
468
|
+
.filter(womenFilter);
|
|
469
|
+
|
|
470
|
+
// Subscribe the callback function to the created Observables
|
|
471
|
+
men$.subscribe(manReadyToWork);
|
|
472
|
+
women$.subscribe(womanReadyToWork);
|
|
473
|
+
|
|
474
|
+
// Stream the list of people by applying the age filters
|
|
475
|
+
personal$.pipe()
|
|
476
|
+
.emitByPositive(youngAgeFilter)
|
|
477
|
+
.emitByPositive(oldAgeFilter)
|
|
478
|
+
.subscribe([men$, women$]);
|
|
479
|
+
|
|
480
|
+
// Stream the list of people considering the hair color
|
|
481
|
+
personal$.pipe()
|
|
482
|
+
.switch()
|
|
483
|
+
.case(blackFilter)
|
|
484
|
+
.case(blondFilter)
|
|
485
|
+
.subscribe(blondAndBlack);
|
|
486
|
+
|
|
487
|
+
// Start streaming the list of people
|
|
488
|
+
personal$.stream([
|
|
489
|
+
new Person('Alex', 35, GENDER.MAN, MAJOR.DOCTOR, HAIR.BLOND),
|
|
490
|
+
new Person('John', 45, GENDER.MAN, MAJOR.DRIVER, HAIR.BLACK),
|
|
491
|
+
new Person('Alice', 30, GENDER.WOMAN, MAJOR.DOCTOR, HAIR.BROWN),
|
|
492
|
+
new Person('Sophia', 36, GENDER.WOMAN, MAJOR.DRIVER, HAIR.BLOND),
|
|
493
|
+
new Person('Matthew', 15, GENDER.MAN, MAJOR.CHILD, HAIR.BROWN),
|
|
494
|
+
new Person('Emily', 17, GENDER.WOMAN, MAJOR.CHILD, HAIR.BLACK),
|
|
495
|
+
new Person('James', 40, GENDER.MAN, MAJOR.DOCTOR, HAIR.BLOND),
|
|
496
|
+
new Person('Emma', 35, GENDER.WOMAN, MAJOR.DRIVER, HAIR.BROWN),
|
|
497
|
+
new Person('Michael', 15, GENDER.MAN, MAJOR.CHILD, HAIR.BLACK),
|
|
498
|
+
new Person('Olivia', 16, GENDER.WOMAN, MAJOR.CHILD, HAIR.BLOND)
|
|
499
|
+
]);
|
|
500
|
+
|
|
501
|
+
// This is the result of handling persons:
|
|
502
|
+
// MAN ==> is ready to work: Alex 35 DOCTOR
|
|
503
|
+
// PERSON ==> only black or blond: Alex 35 BLOND
|
|
504
|
+
// MAN ==> is ready to work: John 45 DRIVER
|
|
505
|
+
// PERSON ==> only black or blond: John 45 BLACK
|
|
506
|
+
// WOMAN ==> is ready to work: Alice 30 DOCTOR
|
|
507
|
+
// WOMAN ==> is ready to work: Sophia 36 DRIVER
|
|
508
|
+
// PERSON ==> only black or blond: Sophia 36 BLOND
|
|
509
|
+
// PERSON ==> only black or blond: Emily 17 BLACK
|
|
510
|
+
// MAN ==> is ready to work: James 40 DOCTOR
|
|
511
|
+
// PERSON ==> only black or blond: James 40 BLOND
|
|
512
|
+
// WOMAN ==> is ready to work: Emma 35 DRIVER
|
|
513
|
+
// PERSON ==> only black or blond: Michael 15 BLACK
|
|
514
|
+
// PERSON ==> only black or blond: Olivia 16 BLOND
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
In this example, we are using the Observable Library to handle a list of people, applying various filters to deal with
|
|
518
|
+
different scenarios. This flexibility and ability to handle complex, intersecting conditions is what makes EVG
|
|
519
|
+
Observable an invaluable tool for managing asynchronous events.
|
|
520
|
+
Built with the developer's needs in mind, EVG Observable provides a wealth of capabilities at your disposal, making
|
|
521
|
+
event handling a breeze.
|
|
522
|
+
|
|
347
523
|
## Methods
|
|
348
524
|
|
|
349
525
|
### Observable
|
|
350
526
|
|
|
351
|
-
| method | will return
|
|
352
|
-
|
|
353
|
-
| `.subscribe(listener)` | subscriber
|
|
354
|
-
| `.unSubscribe(subscriber)` | void
|
|
355
|
-
| `.unsubscribeAll()` | void
|
|
356
|
-
| `.next(value)` | void
|
|
357
|
-
| `.stream(value[])` | void
|
|
358
|
-
| `.getValue()` | value
|
|
359
|
-
| `.size()` | number
|
|
360
|
-
| `.disable()` | void
|
|
361
|
-
| `.enable()` | void
|
|
362
|
-
| `.isEnable` | boolean
|
|
363
|
-
| `.destroy()` | void
|
|
364
|
-
| `.isDestroyed` | boolean
|
|
365
|
-
| `.pipe()` | pipe condition object | returns an object with which you can customize the subscriber's behavior
|
|
527
|
+
| method | will return | description |
|
|
528
|
+
|:---------------------------|:----------------------|:---------------------------------------------------------------------------------|
|
|
529
|
+
| `.subscribe(listener)` | subscriber | subscribe listener to observable |
|
|
530
|
+
| `.unSubscribe(subscriber)` | void | unsubscribe listener from observable |
|
|
531
|
+
| `.unsubscribeAll()` | void | unsubscribe all listeners from the current observable |
|
|
532
|
+
| `.next(value)` | void | emit data to listeners |
|
|
533
|
+
| `.stream(value[])` | void | pass data to listeners in parts of the array |
|
|
534
|
+
| `.getValue()` | value | will return the last value sent, or the value that was set during initialization |
|
|
535
|
+
| `.size()` | number | will return the current number of subscribers |
|
|
536
|
+
| `.disable()` | void | disable emission |
|
|
537
|
+
| `.enable()` | void | enable emission |
|
|
538
|
+
| `.isEnable` | boolean | read-only field that shows the state of the observer |
|
|
539
|
+
| `.destroy()` | void | unsubscribe all listeners from the current observable and destroy it |
|
|
540
|
+
| `.isDestroyed` | boolean | read-only field that shows the kill state of the observer |
|
|
541
|
+
| `.pipe()` | pipe condition object | returns an object with which you can customize the subscriber's behavior |
|
|
366
542
|
|
|
367
543
|
### Observable`.pipe()`
|
|
368
544
|
|
|
369
|
-
| method
|
|
370
|
-
|
|
371
|
-
| `.setOnce()`
|
|
372
|
-
| `.unsubscribeByNegative(*condition)` | pipe
|
|
373
|
-
| `.unsubscribeByPositive(*condition)` | pipe
|
|
374
|
-
| `.emitByNegative(*condition)`
|
|
375
|
-
| `.emitByPositive(*condition)`
|
|
376
|
-
| `.emitMatch(*condition)`
|
|
377
|
-
| `.
|
|
545
|
+
| method | will return | description |
|
|
546
|
+
|:-------------------------------------|:------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
547
|
+
| `.setOnce()` | pipe object | observable will send a value to the subscriber only once, and the subscriber will unsubscribe. |
|
|
548
|
+
| `.unsubscribeByNegative(*condition)` | pipe object | observable will send a value to the subscriber as long as the condition is positive, on the first negative result, the subscriber will unsubscribe |
|
|
549
|
+
| `.unsubscribeByPositive(*condition)` | pipe object | observable will send a value to the subscriber as long as the condition is negative, on the first positive result, the subscriber will unsubscribe |
|
|
550
|
+
| `.emitByNegative(*condition)` | pipe object | observable will send a value to the listener only if condition returns "false", there is no automatic unsubscription |
|
|
551
|
+
| `.emitByPositive(*condition)` | pipe object | observable will send a value to the listener only if condition returns "true", there is no automatic unsubscription |
|
|
552
|
+
| `.emitMatch(*condition)` | pipe object | observable will send a value to the subscriber only if the return value of the condition matches the data being sent, in this case, there is no automatic unsubscription |
|
|
553
|
+
| `.switch()` | SwitchCase object | transitions the pipe into switch-case mode. In this mode, only the first condition that returns a positive result is triggered, and all others are ignored. This allows you to handle multiple cases more conveniently. |
|
|
554
|
+
| `.case(*condition)` | PipeCase object | Adds a condition to the chain of cases. The entire chain operates on the principle of "OR". This is different from other pipe methods which, when chained, operate on the principle of "AND". |
|
|
555
|
+
| `.subscribe(listener)` | subscriber | subscribe listener to observable |
|
|
556
|
+
_*condition_ - this is a function that should return a value that will affect the behavior of the subscriber
|
|
557
|
+
|
|
558
|
+
### Inbound filters
|
|
378
559
|
|
|
560
|
+
| Method | Will Return | Description |
|
|
561
|
+
|:----------------------|:---------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
562
|
+
| `.addFilter()` | InboundFilter object | Transitions the Observable into the mode of adding inbound filters. |
|
|
563
|
+
| `.filter(*condition)` | InboundFilter object | Part of the filter chain that operates on the principle of "AND". If the condition returns `true`, the filter passes the data along the chain. |
|
|
564
|
+
| `.switch()` | InboundFilter object | Transitions the filter into switch-case mode. In this mode, only the first condition that returns a positive result is triggered, and all others are ignored.
|
|
565
|
+
| `.case(*condition)` | InboundFilter object | Adds a condition to the chain of cases that operate on the principle of "OR". This is different from other filter methods which, when chained, operate on the principle of "AND". |
|
|
379
566
|
_*condition_ - this is a function that should return a value that will affect the behavior of the subscriber
|
|
380
567
|
|
|
381
568
|
### Observable subscriber
|
|
382
569
|
|
|
383
|
-
| method
|
|
384
|
-
|
|
385
|
-
| `.unsubscribe()` | void
|
|
570
|
+
| method | will return | description |
|
|
571
|
+
|:-----------------|:------------|:-------------------------------------|
|
|
572
|
+
| `.unsubscribe()` | void | unsubscribe listener from observable |
|
|
386
573
|
|
|
387
574
|
### Ordered observable
|
|
388
575
|
|
|
@@ -392,24 +579,23 @@ Has the same methods as Observable.
|
|
|
392
579
|
|
|
393
580
|
Has the same methods as subscriber. But there is an "order" field and two new methods.
|
|
394
581
|
|
|
395
|
-
| field
|
|
396
|
-
|
|
582
|
+
| field | type | description |
|
|
583
|
+
|:---------|:-------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
397
584
|
| `.order` | number | Determines the order in which the subscriber is called, the subscriber with the lowest ordinal number is called first, the subscriber with the highest ordinal number is called last. |
|
|
398
585
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
|
402
|
-
| `.
|
|
403
|
-
| `.setDescendingSort()` | boolean | set order by descending sort |
|
|
586
|
+
| method | will return | description |
|
|
587
|
+
|:-----------------------|:------------|:-----------------------------|
|
|
588
|
+
| `.setAscendingSort()` | boolean | set order by ascending sort |
|
|
589
|
+
| `.setDescendingSort()` | boolean | set order by descending sort |
|
|
404
590
|
|
|
405
591
|
### Collector
|
|
406
592
|
|
|
407
|
-
| method
|
|
408
|
-
|
|
409
|
-
| `.collect( ...subscribers)` | void
|
|
410
|
-
| `.unsubscribe(subscriber)`
|
|
411
|
-
| `.unsubscribeAll()`
|
|
412
|
-
| `.destroy()`
|
|
593
|
+
| method | will return | description |
|
|
594
|
+
|:----------------------------|:------------|:---------------------------------------------------|
|
|
595
|
+
| `.collect( ...subscribers)` | void | collects subscribers |
|
|
596
|
+
| `.unsubscribe(subscriber)` | void | unsubscribe a subscriber from it's observable |
|
|
597
|
+
| `.unsubscribeAll()` | void | unsubscribe all subscribers from their observables |
|
|
598
|
+
| `.destroy()` | void | unsubscribe all subscribers and destroy collector |
|
|
413
599
|
|
|
414
600
|
## License
|
|
415
601
|
|