rxjs-poll 1.0.0
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/LICENSE +21 -0
- package/README.md +210 -0
- package/dist/cjs/common/config.js +34 -0
- package/dist/cjs/common/config.js.map +1 -0
- package/dist/cjs/common/observables.js +24 -0
- package/dist/cjs/common/observables.js.map +1 -0
- package/dist/cjs/common/utils.js +44 -0
- package/dist/cjs/common/utils.js.map +1 -0
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +4 -0
- package/dist/cjs/poll.js +41 -0
- package/dist/cjs/poll.js.map +1 -0
- package/dist/esm/common/config.js +29 -0
- package/dist/esm/common/config.js.map +1 -0
- package/dist/esm/common/observables.js +20 -0
- package/dist/esm/common/observables.js.map +1 -0
- package/dist/esm/common/utils.js +32 -0
- package/dist/esm/common/utils.js.map +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +4 -0
- package/dist/esm/poll.js +35 -0
- package/dist/esm/poll.js.map +1 -0
- package/dist/types/common/config.d.ts +30 -0
- package/dist/types/common/config.d.ts.map +1 -0
- package/dist/types/common/observables.d.ts +5 -0
- package/dist/types/common/observables.d.ts.map +1 -0
- package/dist/types/common/utils.d.ts +13 -0
- package/dist/types/common/utils.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/poll.d.ts +32 -0
- package/dist/types/poll.d.ts.map +1 -0
- package/package.json +103 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Marin Muštra
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# RxJS Polling Operator
|
|
2
|
+
|
|
3
|
+
Library provides RxJS operator that can do polling on any completed source.
|
|
4
|
+
|
|
5
|
+
**rxjs-poll** features:
|
|
6
|
+
|
|
7
|
+
- Two types of polling; `repeat` and `interval`
|
|
8
|
+
- Delay/retry can be a **static**, **random** or **dynamic** number
|
|
9
|
+
- Any **backoff strategy** you can think of
|
|
10
|
+
- Background mode (browser only) to **pause/resume polling** on page visibility
|
|
11
|
+
- Consecutive rule for **different retry attempts** approach
|
|
12
|
+
- Config **input guard** for unexpected values
|
|
13
|
+
- Supports browser and node environment
|
|
14
|
+
- Compatible with RxJS v7 and v8
|
|
15
|
+
- Provides cjs and esm
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```shell
|
|
20
|
+
npm install rxjs-poll --save
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
Let's say that you want to poll fun facts about cats. This is the request:
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { ajax } from 'rxjs/ajax';
|
|
29
|
+
import { map } from 'rxjs';
|
|
30
|
+
|
|
31
|
+
interface CatFact {
|
|
32
|
+
fact: string;
|
|
33
|
+
length: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const request$ = ajax<CatFact>({ url: 'https://catfact.ninja/fact' }).pipe(
|
|
37
|
+
map(({ response }) => response)
|
|
38
|
+
);
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Default
|
|
42
|
+
|
|
43
|
+
Plug and play, just add an operator to your pipe and poll.
|
|
44
|
+
|
|
45
|
+
[Demo](https://stackblitz.com/edit/rxjs-6nrm8l?devToolsHeight=100&file=index.ts)
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import { poll } from 'rxjs-poll';
|
|
49
|
+
import { takeWhile } from 'rxjs';
|
|
50
|
+
|
|
51
|
+
request$
|
|
52
|
+
.pipe(
|
|
53
|
+
poll(),
|
|
54
|
+
takeWhile(({ length }) => length < 200, true)
|
|
55
|
+
)
|
|
56
|
+
.subscribe({ next: console.log });
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Basic
|
|
60
|
+
|
|
61
|
+
With a config file you can customize polling to your specific needs.
|
|
62
|
+
|
|
63
|
+
[Demo](https://stackblitz.com/edit/rxjs-obywba?devToolsHeight=100&file=index.ts)
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { poll } from 'rxjs-poll';
|
|
67
|
+
import { takeWhile } from 'rxjs';
|
|
68
|
+
|
|
69
|
+
request$
|
|
70
|
+
.pipe(
|
|
71
|
+
poll({
|
|
72
|
+
type: 'interval', // Drops uncompleted source after delay
|
|
73
|
+
retries: Infinity, // Will never throw
|
|
74
|
+
delay: [1000, 2000], // Random delay with min and max values
|
|
75
|
+
}),
|
|
76
|
+
takeWhile(({ length }) => length < 200, true)
|
|
77
|
+
)
|
|
78
|
+
.subscribe({ next: console.log });
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Advance
|
|
82
|
+
|
|
83
|
+
Use delay function when you need complex logic for polling or retrying. The state provides data that can be used for unique backoff strategies.
|
|
84
|
+
|
|
85
|
+
[Demo](https://stackblitz.com/edit/rxjs-awthuj?devtoolsheight=100&file=index.ts)
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { poll } from 'rxjs-poll';
|
|
89
|
+
import { takeWhile } from 'rxjs';
|
|
90
|
+
|
|
91
|
+
request$
|
|
92
|
+
.pipe(
|
|
93
|
+
poll({
|
|
94
|
+
retries: 6,
|
|
95
|
+
delay: ({ polls, consecutiveRetries, error }) => {
|
|
96
|
+
const delay = 1000;
|
|
97
|
+
|
|
98
|
+
if (error) {
|
|
99
|
+
// Exponential backoff strategy
|
|
100
|
+
// With 6 retries, throws after ~1min of consecutive errors
|
|
101
|
+
return Math.pow(2, consecutiveRetries - 1) * delay;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Faster polls initially
|
|
105
|
+
return polls < 5 ? delay * 0.5 : delay;
|
|
106
|
+
},
|
|
107
|
+
}),
|
|
108
|
+
takeWhile(({ length }) => length < 200, true)
|
|
109
|
+
)
|
|
110
|
+
.subscribe({ next: console.log });
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## API
|
|
114
|
+
|
|
115
|
+
### poll(config)
|
|
116
|
+
|
|
117
|
+
It is a mono type operator function that will poll once a **source completes**. If the source is not completed, the operator will wait until that happens. First emission is sent immediately, then the polling will start. Values will emit until stopped by the user.
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
source$.pipe(poll({ type: 'repeat', retries: 10 }));
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### PollConfig
|
|
124
|
+
|
|
125
|
+
Configuration object used to setup polling mechanism. Any non-assigned, negative or invalid values will be replaced with default configuration values.
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
interface PollConfig {
|
|
129
|
+
/**
|
|
130
|
+
* Poller type
|
|
131
|
+
*
|
|
132
|
+
* repeat - polls after current source completes
|
|
133
|
+
* interval - polls in intervals and drops source that is not complete
|
|
134
|
+
*/
|
|
135
|
+
type: 'repeat' | 'interval';
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Delay between polls and retries
|
|
139
|
+
*
|
|
140
|
+
* Use static or random number with min and max values. If you need
|
|
141
|
+
* dynamic number, use function and return either static or random number.
|
|
142
|
+
* Numbers should be positive and finate.
|
|
143
|
+
*/
|
|
144
|
+
delay:
|
|
145
|
+
| number
|
|
146
|
+
| [number | number]
|
|
147
|
+
| ((state: PollState) => number | [number | number]);
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Number of retries
|
|
151
|
+
*
|
|
152
|
+
* Number of retries before it will throw. Number should be positive, but
|
|
153
|
+
* it can be Infinity if you don't care about errors.
|
|
154
|
+
*/
|
|
155
|
+
retries: number;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Retry's counting approach
|
|
159
|
+
*
|
|
160
|
+
* If true, then only consecutive error count will be checked against
|
|
161
|
+
* retires. Consecutive error count is reset to 0 on successful response.
|
|
162
|
+
* If false, then any number of errors will be checked against retires.
|
|
163
|
+
*/
|
|
164
|
+
isConsecutiveRule: boolean;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Pause/resume polling - browser only
|
|
168
|
+
*
|
|
169
|
+
* Polling can be paused/resumed depending on page visibility.
|
|
170
|
+
* ex. If this is false and you switch to another tab, polling is paused.
|
|
171
|
+
* Once you go back, polling resumes.
|
|
172
|
+
*/
|
|
173
|
+
isBackgroundMode: boolan;
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### Defaults
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
const config: PollConfig = {
|
|
181
|
+
type: 'repeat',
|
|
182
|
+
delay: 1000,
|
|
183
|
+
retries: 3,
|
|
184
|
+
isConsecutiveRule: true,
|
|
185
|
+
isBackgroundMode: false,
|
|
186
|
+
};
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### PollState
|
|
190
|
+
|
|
191
|
+
Provided as argument of delay function. Use it to set delay for polls and retries.
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
interface PollState {
|
|
195
|
+
polls: number; // current count of successful polls
|
|
196
|
+
retries: number; // current count of retries
|
|
197
|
+
consecutiveRetries: number; // current count of consecutive retries
|
|
198
|
+
error: any | null; // "any" when retrying and "null" when polling
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// polls + retries = total attempts
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Credits
|
|
205
|
+
|
|
206
|
+
This library is inspired by the [rx-polling](https://github.com/jiayihu/rx-polling) that creates Observable for polling.
|
|
207
|
+
|
|
208
|
+
## License
|
|
209
|
+
|
|
210
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.controlConfig = exports.normalizeConfig = void 0;
|
|
4
|
+
var utils_1 = require("./utils");
|
|
5
|
+
function normalizeConfig(config) {
|
|
6
|
+
var _a;
|
|
7
|
+
return {
|
|
8
|
+
type: (_a = config === null || config === void 0 ? void 0 : config.type) !== null && _a !== void 0 ? _a : exports.controlConfig.type,
|
|
9
|
+
getDelay: (0, utils_1.isFunction)(config === null || config === void 0 ? void 0 : config.delay) ? delayProducer(config.delay) : defaultProducer(config === null || config === void 0 ? void 0 : config.delay),
|
|
10
|
+
retries: (0, utils_1.normalizeNumber)(config === null || config === void 0 ? void 0 : config.retries, exports.controlConfig.retries, false),
|
|
11
|
+
isConsecutiveRule: (0, utils_1.isNil)(config === null || config === void 0 ? void 0 : config.isConsecutiveRule) ? true : config.isConsecutiveRule,
|
|
12
|
+
isBackgroundMode: Boolean(config === null || config === void 0 ? void 0 : config.isBackgroundMode),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
exports.normalizeConfig = normalizeConfig;
|
|
16
|
+
function delayProducer(delayFunc) {
|
|
17
|
+
return function (state) {
|
|
18
|
+
var delay = delayFunc(Object.assign({}, state));
|
|
19
|
+
var normalizedDelay = (0, utils_1.normalizeNumber)(delay, exports.controlConfig.delay);
|
|
20
|
+
return (0, utils_1.sampleNumber)(normalizedDelay);
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function defaultProducer(delay) {
|
|
24
|
+
var normalizedDelay = (0, utils_1.normalizeNumber)(delay, exports.controlConfig.delay);
|
|
25
|
+
return function () { return (0, utils_1.sampleNumber)(normalizedDelay); };
|
|
26
|
+
}
|
|
27
|
+
exports.controlConfig = {
|
|
28
|
+
type: 'repeat',
|
|
29
|
+
delay: 1000,
|
|
30
|
+
retries: 3,
|
|
31
|
+
isConsecutiveRule: true,
|
|
32
|
+
isBackgroundMode: false,
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/common/config.ts"],"names":[],"mappings":";;;AAAA,iCAA8F;AAE9F,SAAgB,eAAe,CAAC,MAAyB;;IACvD,OAAO;QACL,IAAI,EAAE,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,mCAAI,qBAAa,CAAC,IAAI;QACxC,QAAQ,EAAE,IAAA,kBAAU,EAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,CAAC;QAClG,OAAO,EAAE,IAAA,uBAAe,EAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,OAAO,EAAE,qBAAa,CAAC,OAAO,EAAE,KAAK,CAAC;QACvE,iBAAiB,EAAE,IAAA,aAAK,EAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB;QACrF,gBAAgB,EAAE,OAAO,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,gBAAgB,CAAC;KACpD,CAAC;AACJ,CAAC;AARD,0CAQC;AAED,SAAS,aAAa,CAAC,SAAwB;IAC7C,OAAO,UAAC,KAAgB;QACtB,IAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;QAClD,IAAM,eAAe,GAAG,IAAA,uBAAe,EAAC,KAAK,EAAE,qBAAa,CAAC,KAAK,CAAC,CAAC;QAEpE,OAAO,IAAA,oBAAY,EAAC,eAAe,CAAC,CAAC;IACvC,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAkC;IACzD,IAAM,eAAe,GAAG,IAAA,uBAAe,EAAC,KAAK,EAAE,qBAAa,CAAC,KAAK,CAAC,CAAC;IAEpE,OAAO,cAAc,OAAA,IAAA,oBAAY,EAAC,eAAe,CAAC,EAA7B,CAA6B,CAAC;AACrD,CAAC;AAEY,QAAA,aAAa,GAAsB;IAC9C,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,CAAC;IACV,iBAAiB,EAAE,IAAI;IACvB,gBAAgB,EAAE,KAAK;CACxB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getPoller$ = exports.visibilityState$ = void 0;
|
|
4
|
+
var rxjs_1 = require("rxjs");
|
|
5
|
+
var utils_1 = require("./utils");
|
|
6
|
+
exports.visibilityState$ = pageVisibility$().pipe((0, rxjs_1.shareReplay)({ bufferSize: 1, refCount: true }));
|
|
7
|
+
function getPoller$(type, source$, getDelay) {
|
|
8
|
+
var completed$ = source$.pipe((0, rxjs_1.takeLast)(1));
|
|
9
|
+
return type === 'repeat'
|
|
10
|
+
? completed$.pipe((0, rxjs_1.repeat)({
|
|
11
|
+
delay: function () { return (0, rxjs_1.timer)(getDelay()); },
|
|
12
|
+
}))
|
|
13
|
+
: dynamicInterval$(getDelay).pipe((0, rxjs_1.switchMap)(function () { return completed$; }));
|
|
14
|
+
}
|
|
15
|
+
exports.getPoller$ = getPoller$;
|
|
16
|
+
function pageVisibility$() {
|
|
17
|
+
return (0, utils_1.isBrowser)() ? (0, rxjs_1.fromEvent)(document, 'visibilitychange').pipe((0, rxjs_1.startWith)(null), (0, rxjs_1.map)(utils_1.isDocumentVisible)) : (0, rxjs_1.of)(true);
|
|
18
|
+
}
|
|
19
|
+
function dynamicInterval$(getDelay) {
|
|
20
|
+
return (0, rxjs_1.of)(null).pipe((0, rxjs_1.repeat)({
|
|
21
|
+
delay: function () { return (0, rxjs_1.timer)(getDelay()); },
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=observables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observables.js","sourceRoot":"","sources":["../../../src/common/observables.ts"],"names":[],"mappings":";;;AAAA,6BAAkH;AAGlH,iCAAuD;AAE1C,QAAA,gBAAgB,GAAG,eAAe,EAAE,CAAC,IAAI,CAAC,IAAA,kBAAW,EAAC,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAEvG,SAAgB,UAAU,CAAI,IAAc,EAAE,OAAsB,EAAE,QAAsB;IAC1F,IAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,IAAA,eAAQ,EAAC,CAAC,CAAC,CAAC,CAAC;IAE7C,OAAO,IAAI,KAAK,QAAQ;QACtB,CAAC,CAAC,UAAU,CAAC,IAAI,CACb,IAAA,aAAM,EAAC;YACL,KAAK,EAAE,cAAM,OAAA,IAAA,YAAK,EAAC,QAAQ,EAAE,CAAC,EAAjB,CAAiB;SAC/B,CAAC,CACH;QACH,CAAC,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAA,gBAAS,EAAC,cAAM,OAAA,UAAU,EAAV,CAAU,CAAC,CAAC,CAAC;AACnE,CAAC;AAVD,gCAUC;AAED,SAAS,eAAe;IACtB,OAAO,IAAA,iBAAS,GAAE,CAAC,CAAC,CAAC,IAAA,gBAAS,EAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAA,gBAAS,EAAC,IAAI,CAAC,EAAE,IAAA,UAAG,EAAC,yBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAA,SAAE,EAAC,IAAI,CAAC,CAAC;AACxH,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAsB;IAC9C,OAAO,IAAA,SAAE,EAAC,IAAI,CAAC,CAAC,IAAI,CAClB,IAAA,aAAM,EAAC;QACL,KAAK,EAAE,cAAM,OAAA,IAAA,YAAK,EAAC,QAAQ,EAAE,CAAC,EAAjB,CAAiB;KAC/B,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isDocumentVisible = exports.isBrowser = exports.isNil = exports.isFunction = exports.randomNumber = exports.sampleNumber = exports.normalizeNumber = void 0;
|
|
4
|
+
function normalizeNumber(value, defaultValue, isFinite) {
|
|
5
|
+
if (defaultValue === void 0) { defaultValue = 0; }
|
|
6
|
+
if (isFinite === void 0) { isFinite = true; }
|
|
7
|
+
if (Array.isArray(value)) {
|
|
8
|
+
return value.map(function (n) { return normalizeNumber(n, defaultValue); });
|
|
9
|
+
}
|
|
10
|
+
var singleValue = value !== null && value !== void 0 ? value : defaultValue;
|
|
11
|
+
if (Number.isNaN(singleValue)) {
|
|
12
|
+
singleValue = defaultValue;
|
|
13
|
+
}
|
|
14
|
+
if (isFinite && !Number.isFinite(singleValue)) {
|
|
15
|
+
singleValue = defaultValue;
|
|
16
|
+
}
|
|
17
|
+
return Math.abs(singleValue);
|
|
18
|
+
}
|
|
19
|
+
exports.normalizeNumber = normalizeNumber;
|
|
20
|
+
function sampleNumber(value) {
|
|
21
|
+
return Array.isArray(value) ? randomNumber.apply(void 0, value) : value;
|
|
22
|
+
}
|
|
23
|
+
exports.sampleNumber = sampleNumber;
|
|
24
|
+
function randomNumber(min, max) {
|
|
25
|
+
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
26
|
+
}
|
|
27
|
+
exports.randomNumber = randomNumber;
|
|
28
|
+
function isFunction(value) {
|
|
29
|
+
return typeof value === 'function';
|
|
30
|
+
}
|
|
31
|
+
exports.isFunction = isFunction;
|
|
32
|
+
function isNil(value) {
|
|
33
|
+
return value == null;
|
|
34
|
+
}
|
|
35
|
+
exports.isNil = isNil;
|
|
36
|
+
function isBrowser() {
|
|
37
|
+
return typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
38
|
+
}
|
|
39
|
+
exports.isBrowser = isBrowser;
|
|
40
|
+
function isDocumentVisible() {
|
|
41
|
+
return !document.hidden;
|
|
42
|
+
}
|
|
43
|
+
exports.isDocumentVisible = isDocumentVisible;
|
|
44
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/common/utils.ts"],"names":[],"mappings":";;;AAOA,SAAgB,eAAe,CAC7B,KAAkC,EAClC,YAAgB,EAChB,QAAe;IADf,6BAAA,EAAA,gBAAgB;IAChB,yBAAA,EAAA,eAAe;IAEf,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,UAAC,CAAC,IAAK,OAAA,eAAe,CAAC,CAAC,EAAE,YAAY,CAAC,EAAhC,CAAgC,CAAW,CAAC;IACtE,CAAC;IAED,IAAI,WAAW,GAAG,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,YAAY,CAAC;IAExC,IAAI,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9B,WAAW,GAAG,YAAY,CAAC;IAC7B,CAAC;IAED,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9C,WAAW,GAAG,YAAY,CAAC;IAC7B,CAAC;IAED,OAAO,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAC/B,CAAC;AApBD,0CAoBC;AAED,SAAgB,YAAY,CAAC,KAAsB;IACjD,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,eAAI,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC;AAC/D,CAAC;AAFD,oCAEC;AAED,SAAgB,YAAY,CAAC,GAAW,EAAE,GAAW;IACnD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;AAC3D,CAAC;AAFD,oCAEC;AAED,SAAgB,UAAU,CAAC,KAAU;IACnC,OAAO,OAAO,KAAK,KAAK,UAAU,CAAC;AACrC,CAAC;AAFD,gCAEC;AAED,SAAgB,KAAK,CAAC,KAAU;IAE9B,OAAO,KAAK,IAAI,IAAI,CAAC;AACvB,CAAC;AAHD,sBAGC;AAED,SAAgB,SAAS;IACvB,OAAO,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,WAAW,CAAC;AACjF,CAAC;AAFD,8BAEC;AAED,SAAgB,iBAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;AAC1B,CAAC;AAFD,8CAEC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.poll = void 0;
|
|
4
|
+
var poll_1 = require("./poll");
|
|
5
|
+
Object.defineProperty(exports, "poll", { enumerable: true, get: function () { return poll_1.poll; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AACA,+BAA8B;AAArB,4FAAA,IAAI,OAAA"}
|
package/dist/cjs/poll.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.poll = void 0;
|
|
4
|
+
var rxjs_1 = require("rxjs");
|
|
5
|
+
var config_1 = require("./common/config");
|
|
6
|
+
var observables_1 = require("./common/observables");
|
|
7
|
+
function poll(config) {
|
|
8
|
+
return function (source$) {
|
|
9
|
+
var _a = (0, config_1.normalizeConfig)(config), type = _a.type, retries = _a.retries, isBackgroundMode = _a.isBackgroundMode, isConsecutiveRule = _a.isConsecutiveRule, getDelay = _a.getDelay;
|
|
10
|
+
var retryKey = isConsecutiveRule ? 'consecutiveRetries' : 'retries';
|
|
11
|
+
var state = {
|
|
12
|
+
polls: 0,
|
|
13
|
+
retries: 0,
|
|
14
|
+
consecutiveRetries: 0,
|
|
15
|
+
error: null,
|
|
16
|
+
};
|
|
17
|
+
var nextPollDelay = function () {
|
|
18
|
+
state.polls += 1;
|
|
19
|
+
return getDelay(state);
|
|
20
|
+
};
|
|
21
|
+
var visibility$ = isBackgroundMode ? (0, rxjs_1.of)(true) : observables_1.visibilityState$;
|
|
22
|
+
var poller$ = (0, observables_1.getPoller$)(type, source$, nextPollDelay);
|
|
23
|
+
return visibility$.pipe((0, rxjs_1.switchMap)(function (isVisible) {
|
|
24
|
+
return isVisible
|
|
25
|
+
? poller$.pipe((0, rxjs_1.retry)({
|
|
26
|
+
delay: function (error) {
|
|
27
|
+
state.error = error;
|
|
28
|
+
state.retries += 1;
|
|
29
|
+
state.consecutiveRetries += 1;
|
|
30
|
+
return state[retryKey] > retries ? (0, rxjs_1.throwError)(function () { return error; }) : (0, rxjs_1.timer)(getDelay(state));
|
|
31
|
+
},
|
|
32
|
+
}), (0, rxjs_1.tap)(function () {
|
|
33
|
+
state.error = null;
|
|
34
|
+
state.consecutiveRetries = 0;
|
|
35
|
+
}))
|
|
36
|
+
: rxjs_1.EMPTY;
|
|
37
|
+
}));
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
exports.poll = poll;
|
|
41
|
+
//# sourceMappingURL=poll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poll.js","sourceRoot":"","sources":["../../src/poll.ts"],"names":[],"mappings":";;;AAAA,6BAAqG;AAErG,0CAAmF;AACnF,oDAAoE;AA8BpE,SAAgB,IAAI,CAAI,MAAyB;IAC/C,OAAO,UAAC,OAAO;QACP,IAAA,KAAmE,IAAA,wBAAe,EAAC,MAAM,CAAC,EAAxF,IAAI,UAAA,EAAE,OAAO,aAAA,EAAE,gBAAgB,sBAAA,EAAE,iBAAiB,uBAAA,EAAE,QAAQ,cAA4B,CAAC;QACjG,IAAM,QAAQ,GAAa,iBAAiB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAAS,CAAC;QAChF,IAAM,KAAK,GAAc;YACvB,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,CAAC;YACV,kBAAkB,EAAE,CAAC;YACrB,KAAK,EAAE,IAAI;SACZ,CAAC;QAEF,IAAM,aAAa,GAAG;YACpB,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;YAEjB,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC,CAAC;QAEF,IAAM,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,IAAA,SAAE,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,8BAAgB,CAAC;QACnE,IAAM,OAAO,GAAG,IAAA,wBAAU,EAAC,IAAI,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;QAEzD,OAAO,WAAW,CAAC,IAAI,CACrB,IAAA,gBAAS,EAAC,UAAC,SAAS;YAClB,OAAA,SAAS;gBACP,CAAC,CAAC,OAAO,CAAC,IAAI,CACV,IAAA,YAAK,EAAC;oBACJ,KAAK,YAAC,KAAK;wBAET,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;wBACpB,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;wBACnB,KAAK,CAAC,kBAAkB,IAAI,CAAC,CAAC;wBAG9B,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,IAAA,iBAAU,EAAC,cAAM,OAAA,KAAK,EAAL,CAAK,CAAC,CAAC,CAAC,CAAC,IAAA,YAAK,EAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;oBACtF,CAAC;iBACF,CAAC,EACF,IAAA,UAAG,EAAC;oBACF,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;oBACnB,KAAK,CAAC,kBAAkB,GAAG,CAAC,CAAC;gBAC/B,CAAC,CAAC,CACH;gBACH,CAAC,CAAC,YAAK;QAlBT,CAkBS,CACV,CACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AA5CD,oBA4CC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { isFunction, isNil, normalizeNumber, sampleNumber } from './utils';
|
|
2
|
+
export function normalizeConfig(config) {
|
|
3
|
+
return {
|
|
4
|
+
type: config?.type ?? controlConfig.type,
|
|
5
|
+
getDelay: isFunction(config?.delay) ? delayProducer(config.delay) : defaultProducer(config?.delay),
|
|
6
|
+
retries: normalizeNumber(config?.retries, controlConfig.retries, false),
|
|
7
|
+
isConsecutiveRule: isNil(config?.isConsecutiveRule) ? true : config.isConsecutiveRule,
|
|
8
|
+
isBackgroundMode: Boolean(config?.isBackgroundMode),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function delayProducer(delayFunc) {
|
|
12
|
+
return (state) => {
|
|
13
|
+
const delay = delayFunc(Object.assign({}, state));
|
|
14
|
+
const normalizedDelay = normalizeNumber(delay, controlConfig.delay);
|
|
15
|
+
return sampleNumber(normalizedDelay);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function defaultProducer(delay) {
|
|
19
|
+
const normalizedDelay = normalizeNumber(delay, controlConfig.delay);
|
|
20
|
+
return () => sampleNumber(normalizedDelay);
|
|
21
|
+
}
|
|
22
|
+
export const controlConfig = {
|
|
23
|
+
type: 'repeat',
|
|
24
|
+
delay: 1000,
|
|
25
|
+
retries: 3,
|
|
26
|
+
isConsecutiveRule: true,
|
|
27
|
+
isBackgroundMode: false,
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/common/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAO,eAAe,EAAE,YAAY,EAAgB,MAAM,SAAS,CAAC;AAE9F,MAAM,UAAU,eAAe,CAAC,MAAyB;IACvD,OAAO;QACL,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI,aAAa,CAAC,IAAI;QACxC,QAAQ,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC;QAClG,OAAO,EAAE,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC;QACvE,iBAAiB,EAAE,KAAK,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB;QACrF,gBAAgB,EAAE,OAAO,CAAC,MAAM,EAAE,gBAAgB,CAAC;KACpD,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,SAAwB;IAC7C,OAAO,CAAC,KAAgB,EAAU,EAAE;QAClC,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;QAClD,MAAM,eAAe,GAAG,eAAe,CAAC,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;QAEpE,OAAO,YAAY,CAAC,eAAe,CAAC,CAAC;IACvC,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAkC;IACzD,MAAM,eAAe,GAAG,eAAe,CAAC,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IAEpE,OAAO,GAAW,EAAE,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAsB;IAC9C,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,CAAC;IACV,iBAAiB,EAAE,IAAI;IACvB,gBAAgB,EAAE,KAAK;CACxB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { fromEvent, map, of, repeat, shareReplay, startWith, switchMap, takeLast, timer } from 'rxjs';
|
|
2
|
+
import { isBrowser, isDocumentVisible } from './utils';
|
|
3
|
+
export const visibilityState$ = pageVisibility$().pipe(shareReplay({ bufferSize: 1, refCount: true }));
|
|
4
|
+
export function getPoller$(type, source$, getDelay) {
|
|
5
|
+
const completed$ = source$.pipe(takeLast(1));
|
|
6
|
+
return type === 'repeat'
|
|
7
|
+
? completed$.pipe(repeat({
|
|
8
|
+
delay: () => timer(getDelay()),
|
|
9
|
+
}))
|
|
10
|
+
: dynamicInterval$(getDelay).pipe(switchMap(() => completed$));
|
|
11
|
+
}
|
|
12
|
+
function pageVisibility$() {
|
|
13
|
+
return isBrowser() ? fromEvent(document, 'visibilitychange').pipe(startWith(null), map(isDocumentVisible)) : of(true);
|
|
14
|
+
}
|
|
15
|
+
function dynamicInterval$(getDelay) {
|
|
16
|
+
return of(null).pipe(repeat({
|
|
17
|
+
delay: () => timer(getDelay()),
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=observables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observables.js","sourceRoot":"","sources":["../../../src/common/observables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,GAAG,EAAc,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAGlH,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEvD,MAAM,CAAC,MAAM,gBAAgB,GAAG,eAAe,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAEvG,MAAM,UAAU,UAAU,CAAI,IAAc,EAAE,OAAsB,EAAE,QAAsB;IAC1F,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7C,OAAO,IAAI,KAAK,QAAQ;QACtB,CAAC,CAAC,UAAU,CAAC,IAAI,CACb,MAAM,CAAC;YACL,KAAK,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;SAC/B,CAAC,CACH;QACH,CAAC,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;AACxH,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAsB;IAC9C,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAClB,MAAM,CAAC;QACL,KAAK,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;KAC/B,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function normalizeNumber(value, defaultValue = 0, isFinite = true) {
|
|
2
|
+
if (Array.isArray(value)) {
|
|
3
|
+
return value.map((n) => normalizeNumber(n, defaultValue));
|
|
4
|
+
}
|
|
5
|
+
let singleValue = value ?? defaultValue;
|
|
6
|
+
if (Number.isNaN(singleValue)) {
|
|
7
|
+
singleValue = defaultValue;
|
|
8
|
+
}
|
|
9
|
+
if (isFinite && !Number.isFinite(singleValue)) {
|
|
10
|
+
singleValue = defaultValue;
|
|
11
|
+
}
|
|
12
|
+
return Math.abs(singleValue);
|
|
13
|
+
}
|
|
14
|
+
export function sampleNumber(value) {
|
|
15
|
+
return Array.isArray(value) ? randomNumber(...value) : value;
|
|
16
|
+
}
|
|
17
|
+
export function randomNumber(min, max) {
|
|
18
|
+
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
19
|
+
}
|
|
20
|
+
export function isFunction(value) {
|
|
21
|
+
return typeof value === 'function';
|
|
22
|
+
}
|
|
23
|
+
export function isNil(value) {
|
|
24
|
+
return value == null;
|
|
25
|
+
}
|
|
26
|
+
export function isBrowser() {
|
|
27
|
+
return typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
28
|
+
}
|
|
29
|
+
export function isDocumentVisible() {
|
|
30
|
+
return !document.hidden;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/common/utils.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,eAAe,CAC7B,KAAkC,EAClC,YAAY,GAAG,CAAC,EAChB,QAAQ,GAAG,IAAI;IAEf,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,YAAY,CAAC,CAAW,CAAC;IACtE,CAAC;IAED,IAAI,WAAW,GAAG,KAAK,IAAI,YAAY,CAAC;IAExC,IAAI,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9B,WAAW,GAAG,YAAY,CAAC;IAC7B,CAAC;IAED,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9C,WAAW,GAAG,YAAY,CAAC;IAC7B,CAAC;IAED,OAAO,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAsB;IACjD,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,GAAW;IACnD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAU;IACnC,OAAO,OAAO,KAAK,KAAK,UAAU,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,KAAU;IAE9B,OAAO,KAAK,IAAI,IAAI,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,WAAW,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC"}
|
package/dist/esm/poll.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { EMPTY, of, retry, switchMap, tap, throwError, timer } from 'rxjs';
|
|
2
|
+
import { normalizeConfig } from './common/config';
|
|
3
|
+
import { getPoller$, visibilityState$ } from './common/observables';
|
|
4
|
+
export function poll(config) {
|
|
5
|
+
return (source$) => {
|
|
6
|
+
const { type, retries, isBackgroundMode, isConsecutiveRule, getDelay } = normalizeConfig(config);
|
|
7
|
+
const retryKey = isConsecutiveRule ? 'consecutiveRetries' : 'retries';
|
|
8
|
+
const state = {
|
|
9
|
+
polls: 0,
|
|
10
|
+
retries: 0,
|
|
11
|
+
consecutiveRetries: 0,
|
|
12
|
+
error: null,
|
|
13
|
+
};
|
|
14
|
+
const nextPollDelay = () => {
|
|
15
|
+
state.polls += 1;
|
|
16
|
+
return getDelay(state);
|
|
17
|
+
};
|
|
18
|
+
const visibility$ = isBackgroundMode ? of(true) : visibilityState$;
|
|
19
|
+
const poller$ = getPoller$(type, source$, nextPollDelay);
|
|
20
|
+
return visibility$.pipe(switchMap((isVisible) => isVisible
|
|
21
|
+
? poller$.pipe(retry({
|
|
22
|
+
delay(error) {
|
|
23
|
+
state.error = error;
|
|
24
|
+
state.retries += 1;
|
|
25
|
+
state.consecutiveRetries += 1;
|
|
26
|
+
return state[retryKey] > retries ? throwError(() => error) : timer(getDelay(state));
|
|
27
|
+
},
|
|
28
|
+
}), tap(() => {
|
|
29
|
+
state.error = null;
|
|
30
|
+
state.consecutiveRetries = 0;
|
|
31
|
+
}))
|
|
32
|
+
: EMPTY));
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=poll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poll.js","sourceRoot":"","sources":["../../src/poll.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAA4B,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAErG,OAAO,EAAE,eAAe,EAAmC,MAAM,iBAAiB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AA8BpE,MAAM,UAAU,IAAI,CAAI,MAAyB;IAC/C,OAAO,CAAC,OAAO,EAAE,EAAE;QACjB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;QACjG,MAAM,QAAQ,GAAa,iBAAiB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAAS,CAAC;QAChF,MAAM,KAAK,GAAc;YACvB,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,CAAC;YACV,kBAAkB,EAAE,CAAC;YACrB,KAAK,EAAE,IAAI;SACZ,CAAC;QAEF,MAAM,aAAa,GAAG,GAAW,EAAE;YACjC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;YAEjB,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC,CAAC;QAEF,MAAM,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC;QACnE,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;QAEzD,OAAO,WAAW,CAAC,IAAI,CACrB,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CACtB,SAAS;YACP,CAAC,CAAC,OAAO,CAAC,IAAI,CACV,KAAK,CAAC;gBACJ,KAAK,CAAC,KAAK;oBAET,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;oBACpB,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;oBACnB,KAAK,CAAC,kBAAkB,IAAI,CAAC,CAAC;oBAG9B,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;gBACtF,CAAC;aACF,CAAC,EACF,GAAG,CAAC,GAAG,EAAE;gBACP,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;gBACnB,KAAK,CAAC,kBAAkB,GAAG,CAAC,CAAC;YAC/B,CAAC,CAAC,CACH;YACH,CAAC,CAAC,KAAK,CACV,CACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Nil, UnsafeMinMax } from './utils';
|
|
2
|
+
export declare function normalizeConfig(config?: PollConfig | Nil): NormalizedPollConfig;
|
|
3
|
+
export declare const controlConfig: ControlPollConfig;
|
|
4
|
+
export type ControlPollConfig = {
|
|
5
|
+
delay: number;
|
|
6
|
+
} & Omit<NormalizedPollConfig, 'getDelay'>;
|
|
7
|
+
export type NormalizedPollConfig = {
|
|
8
|
+
type: PollType;
|
|
9
|
+
getDelay: DelayProducer;
|
|
10
|
+
retries: number;
|
|
11
|
+
isConsecutiveRule: boolean;
|
|
12
|
+
isBackgroundMode: boolean;
|
|
13
|
+
};
|
|
14
|
+
export type PollConfig = {
|
|
15
|
+
type?: PollType | Nil;
|
|
16
|
+
delay?: number | UnsafeMinMax | PollDelayFunc | Nil;
|
|
17
|
+
retries?: number | Nil;
|
|
18
|
+
isConsecutiveRule?: boolean | Nil;
|
|
19
|
+
isBackgroundMode?: boolean | Nil;
|
|
20
|
+
};
|
|
21
|
+
export type PollType = 'repeat' | 'interval';
|
|
22
|
+
export type PollDelayFunc = (state: PollState) => number | UnsafeMinMax | Nil;
|
|
23
|
+
type DelayProducer = (state: PollState) => number;
|
|
24
|
+
export type PollState = {
|
|
25
|
+
polls: number;
|
|
26
|
+
error: any | null;
|
|
27
|
+
} & Record<RetryKey, number>;
|
|
28
|
+
export type RetryKey = 'retries' | 'consecutiveRetries';
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/common/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,GAAG,EAAiC,YAAY,EAAE,MAAM,SAAS,CAAC;AAE9F,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,GAAG,GAAG,oBAAoB,CAQ/E;AAiBD,eAAO,MAAM,aAAa,EAAE,iBAM3B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,IAAI,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAC;AAE3C,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gBAAgB,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,CAAC,EAAE,QAAQ,GAAG,GAAG,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,aAAa,GAAG,GAAG,CAAC;IACpD,OAAO,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,GAAG,GAAG,CAAC;IAClC,gBAAgB,CAAC,EAAE,OAAO,GAAG,GAAG,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;AAC7C,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,SAAS,KAAK,MAAM,GAAG,YAAY,GAAG,GAAG,CAAC;AAC9E,KAAK,aAAa,GAAG,CAAC,KAAK,EAAE,SAAS,KAAK,MAAM,CAAC;AAElD,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;CACnB,GAAG,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAE7B,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import { PollType } from './config';
|
|
3
|
+
export declare const visibilityState$: Observable<boolean>;
|
|
4
|
+
export declare function getPoller$<T>(type: PollType, source$: Observable<T>, getDelay: () => number): Observable<T>;
|
|
5
|
+
//# sourceMappingURL=observables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observables.d.ts","sourceRoot":"","sources":["../../../src/common/observables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,UAAU,EAAkE,MAAM,MAAM,CAAC;AAElH,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGpC,eAAO,MAAM,gBAAgB,qBAAyE,CAAC;AAEvG,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAU3G"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function normalizeNumber(value: number | Nil, defaultValue?: number, isFinite?: boolean): number;
|
|
2
|
+
export declare function normalizeNumber(value: UnsafeMinMax | Nil, defaultValue?: number, isFinite?: boolean): MinMax;
|
|
3
|
+
export declare function normalizeNumber(value: number | UnsafeMinMax | Nil, defaultValue?: number, isFinite?: boolean): number | MinMax;
|
|
4
|
+
export declare function sampleNumber(value: number | MinMax): number;
|
|
5
|
+
export declare function randomNumber(min: number, max: number): number;
|
|
6
|
+
export declare function isFunction(value: any): value is (...args: any[]) => any;
|
|
7
|
+
export declare function isNil(value: any): value is Nil;
|
|
8
|
+
export declare function isBrowser(): boolean;
|
|
9
|
+
export declare function isDocumentVisible(): boolean;
|
|
10
|
+
export type Nil = null | undefined;
|
|
11
|
+
export type MinMax = [number, number];
|
|
12
|
+
export type UnsafeMinMax = [number | Nil, number | Nil];
|
|
13
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/common/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;AACxG,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,GAAG,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;AAC9G,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,GAAG,EAClC,YAAY,CAAC,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,OAAO,GACjB,MAAM,GAAG,MAAM,CAAC;AAuBnB,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAEvE;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,IAAI,GAAG,CAG9C;AAED,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED,MAAM,MAAM,GAAG,GAAG,IAAI,GAAG,SAAS,CAAC;AACnC,MAAM,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACtC,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { MonoTypeOperatorFunction } from 'rxjs';
|
|
2
|
+
import { PollConfig } from './common/config';
|
|
3
|
+
import { Nil } from './common/utils';
|
|
4
|
+
/**
|
|
5
|
+
* ### RxJS Poll Operator
|
|
6
|
+
*
|
|
7
|
+
* Polls source using "repeat" or "interval" approach. First emission is sent immediately, \
|
|
8
|
+
* then the polling will start. Values will emit until stopped by the user.
|
|
9
|
+
*
|
|
10
|
+
* Read {@link https://www.npmjs.com/package/rxjs-poll|docs} for more info.
|
|
11
|
+
*
|
|
12
|
+
* #### Example
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { poll } from 'rxjs-poll';
|
|
16
|
+
* import { takeWhile } from 'rxjs';
|
|
17
|
+
*
|
|
18
|
+
* request$
|
|
19
|
+
* .pipe(
|
|
20
|
+
* poll(),
|
|
21
|
+
* takeWhile(({ isDone }) => !isDone, true)
|
|
22
|
+
* )
|
|
23
|
+
* .subscribe();
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @param config - {@link PollConfig} object used for polling configuration
|
|
27
|
+
*
|
|
28
|
+
* @return A function that returns an Observable that will resubscribe to the source on \
|
|
29
|
+
* complete or error
|
|
30
|
+
*/
|
|
31
|
+
export declare function poll<T>(config?: PollConfig | Nil): MonoTypeOperatorFunction<T>;
|
|
32
|
+
//# sourceMappingURL=poll.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poll.d.ts","sourceRoot":"","sources":["../../src/poll.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,wBAAwB,EAAgD,MAAM,MAAM,CAAC;AAErG,OAAO,EAAmB,UAAU,EAAuB,MAAM,iBAAiB,CAAC;AAEnF,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,UAAU,GAAG,GAAG,GAAG,wBAAwB,CAAC,CAAC,CAAC,CA4C9E"}
|
package/package.json
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "rxjs-poll",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "RxJS operator for polling",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"rxjs",
|
|
7
|
+
"operator",
|
|
8
|
+
"poll",
|
|
9
|
+
"polling",
|
|
10
|
+
"long-polling",
|
|
11
|
+
"network",
|
|
12
|
+
"http",
|
|
13
|
+
"ajax"
|
|
14
|
+
],
|
|
15
|
+
"author": {
|
|
16
|
+
"name": "Marin Muštra",
|
|
17
|
+
"url": "https://www.linkedin.com/in/marin-mustra"
|
|
18
|
+
},
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/mmustra/rxjs-poll.git"
|
|
23
|
+
},
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/mmustra/rxjs-poll/issues"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"release": "release-it",
|
|
29
|
+
"build": "npm run util:clean && npm run build:esm && npm run build:cjs && npm run build:types && npm run util:packageJson",
|
|
30
|
+
"build:esm": "tsc -p ./ts-configs/tsconfig.esm.json",
|
|
31
|
+
"build:cjs": "tsc -p ./ts-configs/tsconfig.cjs.json",
|
|
32
|
+
"build:types": "tsc -p ./ts-configs/tsconfig.types.json",
|
|
33
|
+
"prepare": "is-ci || husky",
|
|
34
|
+
"prepublishOnly": "npm run build",
|
|
35
|
+
"test": "jest --verbose",
|
|
36
|
+
"lint": "eslint ./src ./tests --ext .js,.ts",
|
|
37
|
+
"lint:fix": "npm run lint -- --fix",
|
|
38
|
+
"util:packageJson": "ts-node ./scripts/generate-package-json.ts",
|
|
39
|
+
"util:clean": "fse remove ./dist",
|
|
40
|
+
"util:commitlint": "commitlint",
|
|
41
|
+
"util:lint-staged": "lint-staged"
|
|
42
|
+
},
|
|
43
|
+
"main": "./dist/cjs/index.js",
|
|
44
|
+
"module": "./dist/esm/index.js",
|
|
45
|
+
"types": "./dist/types/index.d.ts",
|
|
46
|
+
"sideEffects": false,
|
|
47
|
+
"files": [
|
|
48
|
+
"dist/**/*"
|
|
49
|
+
],
|
|
50
|
+
"exports": {
|
|
51
|
+
".": {
|
|
52
|
+
"types": "./dist/types/index.d.ts",
|
|
53
|
+
"node": "./dist/cjs/index.js",
|
|
54
|
+
"require": "./dist/cjs/index.js",
|
|
55
|
+
"import": "./dist/esm/index.js",
|
|
56
|
+
"default": "./dist/esm/index.js"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": "^20"
|
|
61
|
+
},
|
|
62
|
+
"lint-staged": {
|
|
63
|
+
"*.{js,ts}": [
|
|
64
|
+
"npm run lint:fix"
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
"peerDependencies": {
|
|
68
|
+
"rxjs": "^7 || ^8 || ^8.0.0-alpha.0 || ^8.0.0-beta.0 || ^8.0.0-rc.0"
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@atao60/fse-cli": "^0.1.9",
|
|
72
|
+
"@commitlint/cli": "^19.3.0",
|
|
73
|
+
"@commitlint/config-conventional": "^19.2.2",
|
|
74
|
+
"@commitlint/types": "^19.0.3",
|
|
75
|
+
"@release-it/conventional-changelog": "^8.0.1",
|
|
76
|
+
"@types/fs-extra": "^11.0.4",
|
|
77
|
+
"@types/jest": "^29.5.12",
|
|
78
|
+
"@types/node": "^20.12.10",
|
|
79
|
+
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
|
80
|
+
"@typescript-eslint/parser": "^7.8.0",
|
|
81
|
+
"eslint": "^8.57.0",
|
|
82
|
+
"eslint-config-prettier": "^9.1.0",
|
|
83
|
+
"eslint-config-xo": "^0.45.0",
|
|
84
|
+
"eslint-config-xo-typescript": "^4.0.0",
|
|
85
|
+
"eslint-plugin-import": "^2.29.1",
|
|
86
|
+
"eslint-plugin-jest-formatting": "^3.1.0",
|
|
87
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
88
|
+
"eslint-plugin-simple-import-sort": "^12.1.0",
|
|
89
|
+
"eslint-plugin-unused-imports": "^3.2.0",
|
|
90
|
+
"fs-extra": "^11.2.0",
|
|
91
|
+
"husky": "^9.0.11",
|
|
92
|
+
"is-ci": "^3.0.1",
|
|
93
|
+
"jest": "^29.7.0",
|
|
94
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
95
|
+
"jest-environment-node": "^29.7.0",
|
|
96
|
+
"lint-staged": "^15.2.2",
|
|
97
|
+
"release-it": "^17.2.1",
|
|
98
|
+
"rxjs": "^7.8.1",
|
|
99
|
+
"ts-jest": "^29.1.2",
|
|
100
|
+
"ts-node": "^10.9.2",
|
|
101
|
+
"typescript": "^5.4.5"
|
|
102
|
+
}
|
|
103
|
+
}
|