@badisi/ngx-safe-subscribe 3.0.2 → 4.0.1

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 CHANGED
@@ -1,17 +1,39 @@
1
- # @badisi/ngx-safe-subscribe
2
-
3
- Automatically unsubscribe from RxJS observables in Angular components.
4
-
5
- [![npm](https://img.shields.io/npm/v/@badisi/ngx-safe-subscribe?color=blue&logo=npm)](https://www.npmjs.com/package/@badisi/ngx-safe-subscribe)
6
- [![Download](https://img.shields.io/npm/dw/@badisi/ngx-safe-subscribe.svg?color=7986CB&logo=npm)](https://npmcharts.com/compare/@badisi/ngx-safe-subscribe?minimal=true)
7
- [![License](https://img.shields.io/npm/l/@badisi/ngx-safe-subscribe.svg?color=ff69b4)](https://github.com/Badisi/ngx-safe-subscribe/blob/main/LICENSE)
8
-
9
- <!--[![peerDependency Status](https://david-dm.org/badisi/ngx-safe-subscribe/peer-status.svg)](https://david-dm.org/badisi/ngx-safe-subscribe?type=peer)-->
1
+ <h1 align="center">
2
+ @badisi/ngx-safe-subscribe
3
+ </h1>
4
+
5
+ <p align="center">
6
+ <i>⛑️ Automatically unsubscribe from RxJS observables in Angular components.</i><br/>
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/package/@badisi/ngx-safe-subscribe">
11
+ <img src="https://img.shields.io/npm/v/@badisi/ngx-safe-subscribe?color=blue&logo=npm" alt="npm version" />
12
+ </a>
13
+ <a href="https://npmcharts.com/compare/@badisi/ngx-safe-subscribe?minimal=true">
14
+ <img src="https://img.shields.io/npm/dw/@badisi/ngx-safe-subscribe.svg?color=7986CB&logo=npm" alt="npm donwloads" />
15
+ </a>
16
+ <a href="https://github.com/Badisi/ngx-safe-subscribe/blob/main/LICENSE">
17
+ <img src="https://img.shields.io/npm/l/@badisi/ngx-safe-subscribe.svg?color=ff69b4" alt="license" />
18
+ </a>
19
+ </p>
20
+
21
+ <p align="center">
22
+ <a href="https://github.com/Badisi/ngx-safe-subscribe/actions/workflows/ci_tests.yml">
23
+ <img src="https://github.com/Badisi/ngx-safe-subscribe/actions/workflows/ci_tests.yml/badge.svg" alt="build status" />
24
+ </a>
25
+ <a href="https://github.com/badisi/ngx-safe-subscribe/blob/main/CONTRIBUTING.md#-submitting-a-pull-request-pr">
26
+ <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs welcome" />
27
+ </a>
28
+ </p>
29
+
30
+ <hr/>
10
31
 
11
32
  :zap: *Angular <= 13 version available [here](https://github.com/Badisi/ngx-safe-subscribe/releases/tag/2.2.9)*
12
33
 
13
34
  :zap: *RxJS 5.x version available [here](https://github.com/Badisi/ngx-safe-subscribe/tree/rxjs-5x)*
14
35
 
36
+ <hr/>
15
37
 
16
38
  ## Installation
17
39
 
@@ -27,49 +49,68 @@ yarn add @badisi/ngx-safe-subscribe
27
49
 
28
50
  SafeSubscribe is an augmentation method of Observable.
29
51
 
30
- Calling **safeSubscribe** instead of **subscribe** will automatically unsubscribe your observable at component destroy.
31
-
32
- ---------------------------------------
33
-
34
- :warning: At least a noop **ngOnDestroy** is required - but type checking will make sure you never forget about it :wink:
35
-
36
- ---------------------------------------
37
-
38
- ### safeSubscribe(target: any, next: Function, error: Function, complete: Function): Subscription
39
-
40
- __Arguments__
41
-
42
- * `target` - A reference to the object that is holding the observable.
43
- * `next` - A handler for each delivered value. Called zero or more times after execution starts.
44
- * `error` - A handler for an error notification. An error halts execution of the observable instance.
45
- * `complete` - A handler for the execution-complete notification. Delayed values can continue to be delivered to the next handler after execution is complete.
46
-
47
- __Return__
48
-
49
- * A `Subscription` object.
52
+ Calling `safeSubscribe` instead of `subscribe` will automatically unsubscribe your observable at component destroy.
50
53
 
51
- __Example__
54
+ #### Example with Angular components
52
55
 
53
56
  ```ts
54
- import { Component, OnInit, OnDestroy } from '@angular/core';
55
- import { Observable, interval } from 'rxjs';
56
- import '@badisi/ngx-safe-subscribe';
57
+ import { Component, OnInit } from '@angular/core';
58
+ import { SafeSubscribe } from '@badisi/ngx-safe-subscribe';
59
+ import { interval } from 'rxjs';
57
60
 
61
+ @SafeSubscribe()
58
62
  @Component({
59
63
  selector: 'app-component'
60
64
  })
61
- export class AppComponent implements OnInit, OnDestroy {
65
+ export class AppComponent implements OnInit {
62
66
  ngOnInit() {
63
67
  interval(1000).safeSubscribe(this, () => {
64
68
  console.log('This log will stop on component destroy.')
65
69
  });
66
70
  }
71
+ }
72
+ ```
73
+
74
+ #### Example with simple class objects
67
75
 
68
- // /!\ At least a noop ngOnDestroy is required for SafeSubscribe to work !
69
- ngOnDestroy() {}
76
+ ```ts
77
+ import { SafeSubscribe } from '@badisi/ngx-safe-subscribe';
78
+ import { interval } from 'rxjs';
79
+
80
+ @SafeSubscribe('destroy')
81
+ export class MyObject {
82
+ constructor() {
83
+ interval(1000).safeSubscribe(this, () => {
84
+ console.log('This log will stop on object destroy.')
85
+ });
86
+ }
87
+ destroy() {}
70
88
  }
71
89
  ```
72
90
 
91
+ ## Api
92
+
93
+ ### @SafeSubscribe(destructorName)
94
+
95
+ __Arguments__
96
+
97
+ * `destructorName: string` *(default: "ngOnDestroy")* - The name of the method that will be called when the object is supposed to be destroyed.
98
+
99
+ ---
100
+
101
+ ### Observable.safeSubscribe(target, ...arguments): Subscription
102
+
103
+ __Arguments__
104
+
105
+ * `target: any` - A reference to the object that is holding the observable.
106
+ * `observerOrNext?: Observer|Function` - Either an observer with methods to be called, or the first of three possible handlers, which is the handler for each value emitted from the subscribed Observable.
107
+ * `error?: Function` - A handler for a terminal event resulting from an error. If no error handler is provided, the error will be thrown asynchronously as unhandled.
108
+ * `complete?: Function` - A handler for a terminal event resulting from successful completion.
109
+
110
+ __Return__
111
+
112
+ * A `Subscription` reference to the registered handler.
113
+
73
114
  ## Purpose
74
115
 
75
116
  To quote a great [article](https://netbasal.com/when-to-unsubscribe-in-angular-d61c6b21bad3) from **Netanel Basal** :
@@ -94,3 +135,21 @@ There are a few exceptional observables where you don't need to unsubscribe :
94
135
  However, as stated in the official Angular documentation :
95
136
 
96
137
  > Feel free to unsubscribe anyway. It is harmless and never a bad practice !
138
+
139
+ ## Contributing
140
+
141
+ #### > Want to Help ?
142
+
143
+ Want to file a bug, contribute some code or improve documentation ? Excellent!
144
+
145
+ But please read up first on the guidelines for [contributing][contributing], and learn about submission process, coding rules and more.
146
+
147
+ #### > Code of Conduct
148
+
149
+ Please read and follow the [Code of Conduct][codeofconduct] and help me keep this project open and inclusive.
150
+
151
+
152
+
153
+
154
+ [contributing]: https://github.com/badisi/latest-version/blob/main/CONTRIBUTING.md
155
+ [codeofconduct]: https://github.com/badisi/latest-version/blob/main/CODE_OF_CONDUCT.md
@@ -1,23 +1,30 @@
1
1
  import { Observable, Subscription } from 'rxjs';
2
- export function safeSubscribe(target, next, error, complete) {
3
- const sub = this.subscribe(next, error, complete);
2
+ const HAS_DECORATOR = Symbol('__safeSubscribeDecorator');
3
+ const SUBSCRIPTION = Symbol('__safeSubscribeSubscription$');
4
+ export function SafeSubscribe(destructorName = 'ngOnDestroy') {
5
+ return (classType) => {
6
+ const originalDestroy = classType.prototype[destructorName];
7
+ classType.prototype[destructorName] = function () {
8
+ originalDestroy && originalDestroy.call(this);
9
+ this[SUBSCRIPTION]?.unsubscribe();
10
+ this[SUBSCRIPTION] = null;
11
+ };
12
+ classType.prototype[HAS_DECORATOR] = true;
13
+ };
14
+ }
15
+ export function safeSubscribe(target, ...args) {
16
+ const sub = this.subscribe(...args);
4
17
  if (target) {
5
- if (!('_subscriptionFromSafeSubscribe$' in target)) {
6
- target._subscriptionFromSafeSubscribe$ = new Subscription();
7
- const originalDestroy = target.ngOnDestroy;
8
- if (!originalDestroy) {
9
- console.warn(`${target.constructor.name} must implement OnDestroy otherwise Observable<T>.safeSubscribe will have no effect.`);
10
- }
11
- target.ngOnDestroy = function () {
12
- if (originalDestroy && (typeof originalDestroy === 'function')) {
13
- originalDestroy.apply(this, arguments);
14
- }
15
- target._subscriptionFromSafeSubscribe$.unsubscribe();
16
- };
18
+ const hasDecorator = Object.getPrototypeOf(target)[HAS_DECORATOR];
19
+ if (!hasDecorator) {
20
+ throw new Error(`${target.constructor.name} class must be decorated with @SafeSubscribe() otherwise Observable<T>.safeSubscribe() will have no effect.`);
21
+ }
22
+ if (!target[SUBSCRIPTION]) {
23
+ target[SUBSCRIPTION] = new Subscription();
17
24
  }
18
- target._subscriptionFromSafeSubscribe$.add(sub);
25
+ target[SUBSCRIPTION].add(sub);
19
26
  }
20
27
  return sub;
21
28
  }
22
29
  Observable.prototype.safeSubscribe = safeSubscribe;
23
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXNhZmUtc3Vic2NyaWJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vbmd4LXNhZmUtc3Vic2NyaWJlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBYWhELE1BQU0sVUFBVSxhQUFhLENBQ3pCLE1BQXdCLEVBQ3hCLElBQXlCLEVBQ3pCLEtBQTRCLEVBQzVCLFFBQXFCO0lBRXJCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNsRCxJQUFJLE1BQU0sRUFBRTtRQUNSLElBQUksQ0FBQyxDQUFDLGlDQUFpQyxJQUFJLE1BQU0sQ0FBQyxFQUFFO1lBQ2hELE1BQU0sQ0FBQywrQkFBK0IsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1lBRTVELE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUM7WUFDM0MsSUFBSSxDQUFDLGVBQWUsRUFBRTtnQkFDbEIsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFJLE1BQWMsQ0FBQyxXQUFXLENBQUMsSUFBSSxzRkFBc0YsQ0FBQyxDQUFDO2FBQzNJO1lBQ0QsTUFBTSxDQUFDLFdBQVcsR0FBRztnQkFDakIsSUFBSSxlQUFlLElBQUksQ0FBQyxPQUFPLGVBQWUsS0FBSyxVQUFVLENBQUMsRUFBRTtvQkFDNUQsZUFBZSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7aUJBQzFDO2dCQUNELE1BQU0sQ0FBQywrQkFBK0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN6RCxDQUFDLENBQUM7U0FDTDtRQUNELE1BQU0sQ0FBQywrQkFBK0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7S0FDbkQ7SUFDRCxPQUFPLEdBQUcsQ0FBQztBQUNmLENBQUM7QUFDRCxVQUFVLENBQUMsU0FBUyxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuZGVjbGFyZSBtb2R1bGUgJ3J4anMvaW50ZXJuYWwvT2JzZXJ2YWJsZScge1xuICAgIGludGVyZmFjZSBPYnNlcnZhYmxlPFQ+IHtcbiAgICAgICAgc2FmZVN1YnNjcmliZTogdHlwZW9mIHNhZmVTdWJzY3JpYmU7XG4gICAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNhZmVTdWJzY3JpYmFibGUge1xuICAgIF9zdWJzY3JpcHRpb25Gcm9tU2FmZVN1YnNjcmliZSQ/OiBTdWJzY3JpcHRpb247XG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNhZmVTdWJzY3JpYmU8VD4oXG4gICAgdGFyZ2V0OiBTYWZlU3Vic2NyaWJhYmxlLFxuICAgIG5leHQ/OiAodmFsdWU6IFQpID0+IHZvaWQsXG4gICAgZXJyb3I/OiAoZXJyb3I6IGFueSkgPT4gdm9pZCxcbiAgICBjb21wbGV0ZT86ICgpID0+IHZvaWRcbik6IFN1YnNjcmlwdGlvbiB7XG4gICAgY29uc3Qgc3ViID0gdGhpcy5zdWJzY3JpYmUobmV4dCwgZXJyb3IsIGNvbXBsZXRlKTtcbiAgICBpZiAodGFyZ2V0KSB7XG4gICAgICAgIGlmICghKCdfc3Vic2NyaXB0aW9uRnJvbVNhZmVTdWJzY3JpYmUkJyBpbiB0YXJnZXQpKSB7XG4gICAgICAgICAgICB0YXJnZXQuX3N1YnNjcmlwdGlvbkZyb21TYWZlU3Vic2NyaWJlJCA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxEZXN0cm95ID0gdGFyZ2V0Lm5nT25EZXN0cm95O1xuICAgICAgICAgICAgaWYgKCFvcmlnaW5hbERlc3Ryb3kpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYCR7KHRhcmdldCBhcyBhbnkpLmNvbnN0cnVjdG9yLm5hbWV9IG11c3QgaW1wbGVtZW50IE9uRGVzdHJveSBvdGhlcndpc2UgT2JzZXJ2YWJsZTxUPi5zYWZlU3Vic2NyaWJlIHdpbGwgaGF2ZSBubyBlZmZlY3QuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0YXJnZXQubmdPbkRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKG9yaWdpbmFsRGVzdHJveSAmJiAodHlwZW9mIG9yaWdpbmFsRGVzdHJveSA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxEZXN0cm95LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRhcmdldC5fc3Vic2NyaXB0aW9uRnJvbVNhZmVTdWJzY3JpYmUkLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHRhcmdldC5fc3Vic2NyaXB0aW9uRnJvbVNhZmVTdWJzY3JpYmUkLmFkZChzdWIpO1xuICAgIH1cbiAgICByZXR1cm4gc3ViO1xufVxuT2JzZXJ2YWJsZS5wcm90b3R5cGUuc2FmZVN1YnNjcmliZSA9IHNhZmVTdWJzY3JpYmU7XG4iXX0=
30
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXNhZmUtc3Vic2NyaWJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vbmd4LXNhZmUtc3Vic2NyaWJlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRWhELE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO0FBQ3pELE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO0FBUTVELE1BQU0sVUFBVSxhQUFhLENBQUMsY0FBYyxHQUFFLGFBQWE7SUFDdkQsT0FBTyxDQUFDLFNBQW1CLEVBQUUsRUFBRTtRQUMzQixNQUFNLGVBQWUsR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzVELFNBQVMsQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLEdBQUc7WUFDbEMsZUFBZSxJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDOUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxJQUFJLENBQUM7UUFDOUIsQ0FBQyxDQUFBO1FBQ0QsU0FBUyxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsR0FBRyxJQUFJLENBQUM7SUFDOUMsQ0FBQyxDQUFDO0FBQ04sQ0FBQztBQUVELE1BQU0sVUFBVSxhQUFhLENBQXlCLE1BQVcsRUFBRSxHQUFHLElBQVM7SUFDM0UsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO0lBQ3BDLElBQUksTUFBTSxFQUFFO1FBQ1IsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUMsWUFBWSxFQUFFO1lBQ2YsTUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSw2R0FBNkcsQ0FBQyxDQUFDO1NBQzVKO1FBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsRUFBRTtZQUN2QixNQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztTQUM3QztRQUNELE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7S0FDakM7SUFDRCxPQUFPLEdBQUcsQ0FBQztBQUNmLENBQUM7QUFDRCxVQUFVLENBQUMsU0FBUyxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuY29uc3QgSEFTX0RFQ09SQVRPUiA9IFN5bWJvbCgnX19zYWZlU3Vic2NyaWJlRGVjb3JhdG9yJyk7XG5jb25zdCBTVUJTQ1JJUFRJT04gPSBTeW1ib2woJ19fc2FmZVN1YnNjcmliZVN1YnNjcmlwdGlvbiQnKTtcblxuZGVjbGFyZSBtb2R1bGUgJ3J4anMvaW50ZXJuYWwvT2JzZXJ2YWJsZScge1xuICAgIGludGVyZmFjZSBPYnNlcnZhYmxlPFQ+IHtcbiAgICAgICAgc2FmZVN1YnNjcmliZTogdHlwZW9mIHNhZmVTdWJzY3JpYmU7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gU2FmZVN1YnNjcmliZShkZXN0cnVjdG9yTmFtZSA9J25nT25EZXN0cm95Jyk6IENsYXNzRGVjb3JhdG9yIHtcbiAgICByZXR1cm4gKGNsYXNzVHlwZTogRnVuY3Rpb24pID0+IHtcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxEZXN0cm95ID0gY2xhc3NUeXBlLnByb3RvdHlwZVtkZXN0cnVjdG9yTmFtZV07XG4gICAgICAgIGNsYXNzVHlwZS5wcm90b3R5cGVbZGVzdHJ1Y3Rvck5hbWVdID0gZnVuY3Rpb24gKHRoaXM6IGFueSkge1xuICAgICAgICAgICAgb3JpZ2luYWxEZXN0cm95ICYmIG9yaWdpbmFsRGVzdHJveS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgdGhpc1tTVUJTQ1JJUFRJT05dPy51bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgdGhpc1tTVUJTQ1JJUFRJT05dID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjbGFzc1R5cGUucHJvdG90eXBlW0hBU19ERUNPUkFUT1JdID0gdHJ1ZTtcbiAgICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2FmZVN1YnNjcmliZTxUPih0aGlzOiBPYnNlcnZhYmxlPFQ+LCB0YXJnZXQ6IGFueSwgLi4uYXJnczogYW55KTogU3Vic2NyaXB0aW9uIHtcbiAgICBjb25zdCBzdWIgPSB0aGlzLnN1YnNjcmliZSguLi5hcmdzKTtcbiAgICBpZiAodGFyZ2V0KSB7XG4gICAgICAgIGNvbnN0IGhhc0RlY29yYXRvciA9IE9iamVjdC5nZXRQcm90b3R5cGVPZih0YXJnZXQpW0hBU19ERUNPUkFUT1JdO1xuICAgICAgICBpZiAoIWhhc0RlY29yYXRvcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3RhcmdldC5jb25zdHJ1Y3Rvci5uYW1lfSBjbGFzcyBtdXN0IGJlIGRlY29yYXRlZCB3aXRoIEBTYWZlU3Vic2NyaWJlKCkgb3RoZXJ3aXNlIE9ic2VydmFibGU8VD4uc2FmZVN1YnNjcmliZSgpIHdpbGwgaGF2ZSBubyBlZmZlY3QuYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0YXJnZXRbU1VCU0NSSVBUSU9OXSkge1xuICAgICAgICAgICAgdGFyZ2V0W1NVQlNDUklQVElPTl0gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGFyZ2V0W1NVQlNDUklQVElPTl0uYWRkKHN1Yik7XG4gICAgfVxuICAgIHJldHVybiBzdWI7XG59XG5PYnNlcnZhYmxlLnByb3RvdHlwZS5zYWZlU3Vic2NyaWJlID0gc2FmZVN1YnNjcmliZTtcbiJdfQ==
@@ -1,22 +1,30 @@
1
1
  import { Subscription, Observable } from 'rxjs';
2
2
 
3
- function safeSubscribe(target, next, error, complete) {
4
- const sub = this.subscribe(next, error, complete);
3
+ const HAS_DECORATOR = Symbol('__safeSubscribeDecorator');
4
+ const SUBSCRIPTION = Symbol('__safeSubscribeSubscription$');
5
+ function SafeSubscribe(destructorName = 'ngOnDestroy') {
6
+ return (classType) => {
7
+ const originalDestroy = classType.prototype[destructorName];
8
+ classType.prototype[destructorName] = function () {
9
+ var _a;
10
+ originalDestroy && originalDestroy.call(this);
11
+ (_a = this[SUBSCRIPTION]) === null || _a === void 0 ? void 0 : _a.unsubscribe();
12
+ this[SUBSCRIPTION] = null;
13
+ };
14
+ classType.prototype[HAS_DECORATOR] = true;
15
+ };
16
+ }
17
+ function safeSubscribe(target, ...args) {
18
+ const sub = this.subscribe(...args);
5
19
  if (target) {
6
- if (!('_subscriptionFromSafeSubscribe$' in target)) {
7
- target._subscriptionFromSafeSubscribe$ = new Subscription();
8
- const originalDestroy = target.ngOnDestroy;
9
- if (!originalDestroy) {
10
- console.warn(`${target.constructor.name} must implement OnDestroy otherwise Observable<T>.safeSubscribe will have no effect.`);
11
- }
12
- target.ngOnDestroy = function () {
13
- if (originalDestroy && (typeof originalDestroy === 'function')) {
14
- originalDestroy.apply(this, arguments);
15
- }
16
- target._subscriptionFromSafeSubscribe$.unsubscribe();
17
- };
20
+ const hasDecorator = Object.getPrototypeOf(target)[HAS_DECORATOR];
21
+ if (!hasDecorator) {
22
+ throw new Error(`${target.constructor.name} class must be decorated with @SafeSubscribe() otherwise Observable<T>.safeSubscribe() will have no effect.`);
23
+ }
24
+ if (!target[SUBSCRIPTION]) {
25
+ target[SUBSCRIPTION] = new Subscription();
18
26
  }
19
- target._subscriptionFromSafeSubscribe$.add(sub);
27
+ target[SUBSCRIPTION].add(sub);
20
28
  }
21
29
  return sub;
22
30
  }
@@ -26,5 +34,5 @@ Observable.prototype.safeSubscribe = safeSubscribe;
26
34
  * Generated bundle index. Do not edit.
27
35
  */
28
36
 
29
- export { safeSubscribe };
37
+ export { SafeSubscribe, safeSubscribe };
30
38
  //# sourceMappingURL=badisi-ngx-safe-subscribe.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"badisi-ngx-safe-subscribe.mjs","sources":["../../ngx-safe-subscribe.ts","../../badisi-ngx-safe-subscribe.ts"],"sourcesContent":["import { Observable, Subscription } from 'rxjs';\n\ndeclare module 'rxjs/internal/Observable' {\n interface Observable<T> {\n safeSubscribe: typeof safeSubscribe;\n }\n}\n\nexport interface SafeSubscribable {\n _subscriptionFromSafeSubscribe$?: Subscription;\n ngOnDestroy(): void;\n}\n\nexport function safeSubscribe<T>(\n target: SafeSubscribable,\n next?: (value: T) => void,\n error?: (error: any) => void,\n complete?: () => void\n): Subscription {\n const sub = this.subscribe(next, error, complete);\n if (target) {\n if (!('_subscriptionFromSafeSubscribe$' in target)) {\n target._subscriptionFromSafeSubscribe$ = new Subscription();\n\n const originalDestroy = target.ngOnDestroy;\n if (!originalDestroy) {\n console.warn(`${(target as any).constructor.name} must implement OnDestroy otherwise Observable<T>.safeSubscribe will have no effect.`);\n }\n target.ngOnDestroy = function () {\n if (originalDestroy && (typeof originalDestroy === 'function')) {\n originalDestroy.apply(this, arguments);\n }\n target._subscriptionFromSafeSubscribe$.unsubscribe();\n };\n }\n target._subscriptionFromSafeSubscribe$.add(sub);\n }\n return sub;\n}\nObservable.prototype.safeSubscribe = safeSubscribe;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './ngx-safe-subscribe';\n"],"names":[],"mappings":";;AAaM,SAAU,aAAa,CACzB,MAAwB,EACxB,IAAyB,EACzB,KAA4B,EAC5B,QAAqB,EAAA;AAErB,IAAA,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;AAClD,IAAA,IAAI,MAAM,EAAE;AACR,QAAA,IAAI,EAAE,iCAAiC,IAAI,MAAM,CAAC,EAAE;AAChD,YAAA,MAAM,CAAC,+BAA+B,GAAG,IAAI,YAAY,EAAE,CAAC;AAE5D,YAAA,MAAM,eAAe,GAAG,MAAM,CAAC,WAAW,CAAC;YAC3C,IAAI,CAAC,eAAe,EAAE;gBAClB,OAAO,CAAC,IAAI,CAAC,CAAI,EAAA,MAAc,CAAC,WAAW,CAAC,IAAI,CAAsF,oFAAA,CAAA,CAAC,CAAC;AAC3I,aAAA;YACD,MAAM,CAAC,WAAW,GAAG,YAAA;gBACjB,IAAI,eAAe,KAAK,OAAO,eAAe,KAAK,UAAU,CAAC,EAAE;AAC5D,oBAAA,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AAC1C,iBAAA;AACD,gBAAA,MAAM,CAAC,+BAA+B,CAAC,WAAW,EAAE,CAAC;AACzD,aAAC,CAAC;AACL,SAAA;AACD,QAAA,MAAM,CAAC,+BAA+B,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACnD,KAAA;AACD,IAAA,OAAO,GAAG,CAAC;AACf,CAAC;AACD,UAAU,CAAC,SAAS,CAAC,aAAa,GAAG,aAAa;;ACvClD;;AAEG;;;;"}
1
+ {"version":3,"file":"badisi-ngx-safe-subscribe.mjs","sources":["../../ngx-safe-subscribe.ts","../../badisi-ngx-safe-subscribe.ts"],"sourcesContent":["import { Observable, Subscription } from 'rxjs';\n\nconst HAS_DECORATOR = Symbol('__safeSubscribeDecorator');\nconst SUBSCRIPTION = Symbol('__safeSubscribeSubscription$');\n\ndeclare module 'rxjs/internal/Observable' {\n interface Observable<T> {\n safeSubscribe: typeof safeSubscribe;\n }\n}\n\nexport function SafeSubscribe(destructorName ='ngOnDestroy'): ClassDecorator {\n return (classType: Function) => {\n const originalDestroy = classType.prototype[destructorName];\n classType.prototype[destructorName] = function (this: any) {\n originalDestroy && originalDestroy.call(this);\n this[SUBSCRIPTION]?.unsubscribe();\n this[SUBSCRIPTION] = null;\n }\n classType.prototype[HAS_DECORATOR] = true;\n };\n}\n\nexport function safeSubscribe<T>(this: Observable<T>, target: any, ...args: any): Subscription {\n const sub = this.subscribe(...args);\n if (target) {\n const hasDecorator = Object.getPrototypeOf(target)[HAS_DECORATOR];\n if (!hasDecorator) {\n throw new Error(`${target.constructor.name} class must be decorated with @SafeSubscribe() otherwise Observable<T>.safeSubscribe() will have no effect.`);\n }\n if (!target[SUBSCRIPTION]) {\n target[SUBSCRIPTION] = new Subscription();\n }\n target[SUBSCRIPTION].add(sub);\n }\n return sub;\n}\nObservable.prototype.safeSubscribe = safeSubscribe;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './ngx-safe-subscribe';\n"],"names":[],"mappings":";;AAEA,MAAM,aAAa,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAC;AACzD,MAAM,YAAY,GAAG,MAAM,CAAC,8BAA8B,CAAC,CAAC;AAQ5C,SAAA,aAAa,CAAC,cAAc,GAAE,aAAa,EAAA;IACvD,OAAO,CAAC,SAAmB,KAAI;QAC3B,MAAM,eAAe,GAAG,SAAS,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;AAC5D,QAAA,SAAS,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,YAAA;;AAClC,YAAA,eAAe,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC9C,YAAA,CAAA,EAAA,GAAA,IAAI,CAAC,YAAY,CAAC,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,WAAW,EAAE,CAAC;AAClC,YAAA,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;AAC9B,SAAC,CAAA;AACD,QAAA,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;AAC9C,KAAC,CAAC;AACN,CAAC;SAEe,aAAa,CAAyB,MAAW,EAAE,GAAG,IAAS,EAAA;IAC3E,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;AACpC,IAAA,IAAI,MAAM,EAAE;QACR,MAAM,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC;QAClE,IAAI,CAAC,YAAY,EAAE;YACf,MAAM,IAAI,KAAK,CAAC,CAAG,EAAA,MAAM,CAAC,WAAW,CAAC,IAAI,CAA6G,2GAAA,CAAA,CAAC,CAAC;AAC5J,SAAA;AACD,QAAA,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE;AACvB,YAAA,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,YAAY,EAAE,CAAC;AAC7C,SAAA;QACD,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACjC,KAAA;AACD,IAAA,OAAO,GAAG,CAAC;AACf,CAAC;AACD,UAAU,CAAC,SAAS,CAAC,aAAa,GAAG,aAAa;;ACrClD;;AAEG;;;;"}
@@ -1,22 +1,29 @@
1
1
  import { Subscription, Observable } from 'rxjs';
2
2
 
3
- function safeSubscribe(target, next, error, complete) {
4
- const sub = this.subscribe(next, error, complete);
3
+ const HAS_DECORATOR = Symbol('__safeSubscribeDecorator');
4
+ const SUBSCRIPTION = Symbol('__safeSubscribeSubscription$');
5
+ function SafeSubscribe(destructorName = 'ngOnDestroy') {
6
+ return (classType) => {
7
+ const originalDestroy = classType.prototype[destructorName];
8
+ classType.prototype[destructorName] = function () {
9
+ originalDestroy && originalDestroy.call(this);
10
+ this[SUBSCRIPTION]?.unsubscribe();
11
+ this[SUBSCRIPTION] = null;
12
+ };
13
+ classType.prototype[HAS_DECORATOR] = true;
14
+ };
15
+ }
16
+ function safeSubscribe(target, ...args) {
17
+ const sub = this.subscribe(...args);
5
18
  if (target) {
6
- if (!('_subscriptionFromSafeSubscribe$' in target)) {
7
- target._subscriptionFromSafeSubscribe$ = new Subscription();
8
- const originalDestroy = target.ngOnDestroy;
9
- if (!originalDestroy) {
10
- console.warn(`${target.constructor.name} must implement OnDestroy otherwise Observable<T>.safeSubscribe will have no effect.`);
11
- }
12
- target.ngOnDestroy = function () {
13
- if (originalDestroy && (typeof originalDestroy === 'function')) {
14
- originalDestroy.apply(this, arguments);
15
- }
16
- target._subscriptionFromSafeSubscribe$.unsubscribe();
17
- };
19
+ const hasDecorator = Object.getPrototypeOf(target)[HAS_DECORATOR];
20
+ if (!hasDecorator) {
21
+ throw new Error(`${target.constructor.name} class must be decorated with @SafeSubscribe() otherwise Observable<T>.safeSubscribe() will have no effect.`);
22
+ }
23
+ if (!target[SUBSCRIPTION]) {
24
+ target[SUBSCRIPTION] = new Subscription();
18
25
  }
19
- target._subscriptionFromSafeSubscribe$.add(sub);
26
+ target[SUBSCRIPTION].add(sub);
20
27
  }
21
28
  return sub;
22
29
  }
@@ -26,5 +33,5 @@ Observable.prototype.safeSubscribe = safeSubscribe;
26
33
  * Generated bundle index. Do not edit.
27
34
  */
28
35
 
29
- export { safeSubscribe };
36
+ export { SafeSubscribe, safeSubscribe };
30
37
  //# sourceMappingURL=badisi-ngx-safe-subscribe.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"badisi-ngx-safe-subscribe.mjs","sources":["../../ngx-safe-subscribe.ts","../../badisi-ngx-safe-subscribe.ts"],"sourcesContent":["import { Observable, Subscription } from 'rxjs';\n\ndeclare module 'rxjs/internal/Observable' {\n interface Observable<T> {\n safeSubscribe: typeof safeSubscribe;\n }\n}\n\nexport interface SafeSubscribable {\n _subscriptionFromSafeSubscribe$?: Subscription;\n ngOnDestroy(): void;\n}\n\nexport function safeSubscribe<T>(\n target: SafeSubscribable,\n next?: (value: T) => void,\n error?: (error: any) => void,\n complete?: () => void\n): Subscription {\n const sub = this.subscribe(next, error, complete);\n if (target) {\n if (!('_subscriptionFromSafeSubscribe$' in target)) {\n target._subscriptionFromSafeSubscribe$ = new Subscription();\n\n const originalDestroy = target.ngOnDestroy;\n if (!originalDestroy) {\n console.warn(`${(target as any).constructor.name} must implement OnDestroy otherwise Observable<T>.safeSubscribe will have no effect.`);\n }\n target.ngOnDestroy = function () {\n if (originalDestroy && (typeof originalDestroy === 'function')) {\n originalDestroy.apply(this, arguments);\n }\n target._subscriptionFromSafeSubscribe$.unsubscribe();\n };\n }\n target._subscriptionFromSafeSubscribe$.add(sub);\n }\n return sub;\n}\nObservable.prototype.safeSubscribe = safeSubscribe;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './ngx-safe-subscribe';\n"],"names":[],"mappings":";;AAaM,SAAU,aAAa,CACzB,MAAwB,EACxB,IAAyB,EACzB,KAA4B,EAC5B,QAAqB,EAAA;AAErB,IAAA,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;AAClD,IAAA,IAAI,MAAM,EAAE;AACR,QAAA,IAAI,EAAE,iCAAiC,IAAI,MAAM,CAAC,EAAE;AAChD,YAAA,MAAM,CAAC,+BAA+B,GAAG,IAAI,YAAY,EAAE,CAAC;AAE5D,YAAA,MAAM,eAAe,GAAG,MAAM,CAAC,WAAW,CAAC;YAC3C,IAAI,CAAC,eAAe,EAAE;gBAClB,OAAO,CAAC,IAAI,CAAC,CAAI,EAAA,MAAc,CAAC,WAAW,CAAC,IAAI,CAAsF,oFAAA,CAAA,CAAC,CAAC;AAC3I,aAAA;YACD,MAAM,CAAC,WAAW,GAAG,YAAA;gBACjB,IAAI,eAAe,KAAK,OAAO,eAAe,KAAK,UAAU,CAAC,EAAE;AAC5D,oBAAA,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AAC1C,iBAAA;AACD,gBAAA,MAAM,CAAC,+BAA+B,CAAC,WAAW,EAAE,CAAC;AACzD,aAAC,CAAC;AACL,SAAA;AACD,QAAA,MAAM,CAAC,+BAA+B,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACnD,KAAA;AACD,IAAA,OAAO,GAAG,CAAC;AACf,CAAC;AACD,UAAU,CAAC,SAAS,CAAC,aAAa,GAAG,aAAa;;ACvClD;;AAEG;;;;"}
1
+ {"version":3,"file":"badisi-ngx-safe-subscribe.mjs","sources":["../../ngx-safe-subscribe.ts","../../badisi-ngx-safe-subscribe.ts"],"sourcesContent":["import { Observable, Subscription } from 'rxjs';\n\nconst HAS_DECORATOR = Symbol('__safeSubscribeDecorator');\nconst SUBSCRIPTION = Symbol('__safeSubscribeSubscription$');\n\ndeclare module 'rxjs/internal/Observable' {\n interface Observable<T> {\n safeSubscribe: typeof safeSubscribe;\n }\n}\n\nexport function SafeSubscribe(destructorName ='ngOnDestroy'): ClassDecorator {\n return (classType: Function) => {\n const originalDestroy = classType.prototype[destructorName];\n classType.prototype[destructorName] = function (this: any) {\n originalDestroy && originalDestroy.call(this);\n this[SUBSCRIPTION]?.unsubscribe();\n this[SUBSCRIPTION] = null;\n }\n classType.prototype[HAS_DECORATOR] = true;\n };\n}\n\nexport function safeSubscribe<T>(this: Observable<T>, target: any, ...args: any): Subscription {\n const sub = this.subscribe(...args);\n if (target) {\n const hasDecorator = Object.getPrototypeOf(target)[HAS_DECORATOR];\n if (!hasDecorator) {\n throw new Error(`${target.constructor.name} class must be decorated with @SafeSubscribe() otherwise Observable<T>.safeSubscribe() will have no effect.`);\n }\n if (!target[SUBSCRIPTION]) {\n target[SUBSCRIPTION] = new Subscription();\n }\n target[SUBSCRIPTION].add(sub);\n }\n return sub;\n}\nObservable.prototype.safeSubscribe = safeSubscribe;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './ngx-safe-subscribe';\n"],"names":[],"mappings":";;AAEA,MAAM,aAAa,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAC;AACzD,MAAM,YAAY,GAAG,MAAM,CAAC,8BAA8B,CAAC,CAAC;AAQ5C,SAAA,aAAa,CAAC,cAAc,GAAE,aAAa,EAAA;IACvD,OAAO,CAAC,SAAmB,KAAI;QAC3B,MAAM,eAAe,GAAG,SAAS,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;AAC5D,QAAA,SAAS,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,YAAA;AAClC,YAAA,eAAe,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC9C,YAAA,IAAI,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;AAClC,YAAA,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;AAC9B,SAAC,CAAA;AACD,QAAA,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;AAC9C,KAAC,CAAC;AACN,CAAC;SAEe,aAAa,CAAyB,MAAW,EAAE,GAAG,IAAS,EAAA;IAC3E,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;AACpC,IAAA,IAAI,MAAM,EAAE;QACR,MAAM,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC;QAClE,IAAI,CAAC,YAAY,EAAE;YACf,MAAM,IAAI,KAAK,CAAC,CAAG,EAAA,MAAM,CAAC,WAAW,CAAC,IAAI,CAA6G,2GAAA,CAAA,CAAC,CAAC;AAC5J,SAAA;AACD,QAAA,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE;AACvB,YAAA,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,YAAY,EAAE,CAAC;AAC7C,SAAA;QACD,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACjC,KAAA;AACD,IAAA,OAAO,GAAG,CAAC;AACf,CAAC;AACD,UAAU,CAAC,SAAS,CAAC,aAAa,GAAG,aAAa;;ACrClD;;AAEG;;;;"}
@@ -1,11 +1,8 @@
1
- import { Subscription } from 'rxjs';
1
+ import { Observable, Subscription } from 'rxjs';
2
2
  declare module 'rxjs/internal/Observable' {
3
3
  interface Observable<T> {
4
4
  safeSubscribe: typeof safeSubscribe;
5
5
  }
6
6
  }
7
- export interface SafeSubscribable {
8
- _subscriptionFromSafeSubscribe$?: Subscription;
9
- ngOnDestroy(): void;
10
- }
11
- export declare function safeSubscribe<T>(target: SafeSubscribable, next?: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription;
7
+ export declare function SafeSubscribe(destructorName?: string): ClassDecorator;
8
+ export declare function safeSubscribe<T>(this: Observable<T>, target: any, ...args: any): Subscription;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@badisi/ngx-safe-subscribe",
3
- "version": "3.0.2",
3
+ "version": "4.0.1",
4
4
  "description": "Easy way to automatically unsubscribe from RxJS observables in Angular components",
5
5
  "homepage": "https://github.com/badisi/ngx-safe-subscribe",
6
6
  "license": "MIT",
@@ -23,8 +23,8 @@
23
23
  "safesubscribe"
24
24
  ],
25
25
  "peerDependencies": {
26
- "@angular/core": ">=14.0.0",
27
- "rxjs": ">=6.0.0"
26
+ "@angular/core": ">= 14.0.0",
27
+ "rxjs": ">= 6.0.0"
28
28
  },
29
29
  "module": "fesm2015/badisi-ngx-safe-subscribe.mjs",
30
30
  "es2020": "fesm2020/badisi-ngx-safe-subscribe.mjs",