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 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"}
@@ -0,0 +1,4 @@
1
+ {
2
+ "type": "commonjs",
3
+ "sideEffects": false
4
+ }
@@ -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,2 @@
1
+ export { poll } from './poll';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,4 @@
1
+ {
2
+ "type": "module",
3
+ "sideEffects": false
4
+ }
@@ -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,3 @@
1
+ export type { PollConfig, PollDelayFunc, PollState, PollType } from './common/config';
2
+ export { poll } from './poll';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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
+ }