Skip to content

Commit cc64c16

Browse files
fix(fetch): polling completed and cleanup of operators
1 parent 522f2ca commit cc64c16

File tree

13 files changed

+248
-174
lines changed

13 files changed

+248
-174
lines changed

package-lock.json

Lines changed: 102 additions & 107 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
"eslint-plugin-prettier": "5.2.1",
4545
"eslint-plugin-security": "3.0.1",
4646
"eslint-plugin-vitest": "0.5.4",
47-
"fetch-mock": "11.1.3",
47+
"fetch-mock": "12.0.0",
4848
"happy-dom": "15.7.4",
4949
"husky": "9.1.6",
5050
"lint-staged": "15.2.10",

packages/operators/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
},
2020
"dependencies": {
2121
"@rxjs-collection/observables": "*",
22+
"fast-equals": "^5.0.1",
2223
"rxjs": "7.8.1"
2324
},
2425
"devDependencies": {

packages/operators/src/fetch/autoPagination.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ export const autoPagination = ({ resolveRoute }) => {
88
concatMap(({ url }) => {
99
return from(resolveRoute(url)).pipe(
1010
download(),
11-
expand(resp => {
12-
return from(resolveRoute(url, resp)).pipe(
11+
expand(resp =>
12+
from(resolveRoute(url, resp)).pipe(
1313
filter(url => !!url),
1414
download()
15-
);
16-
})
15+
)
16+
)
1717
);
1818
}),
1919
map(resp => resp.clone())

packages/operators/src/fetch/download.test.js

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,29 @@ import { resolveJSON } from './resolve.js';
88

99
describe('download operator', function () {
1010
beforeEach(function () {
11-
fetchMock.get(
11+
fetchMock.mockGlobal().get(
1212
'https://httpbin.org/my-url-fast',
13-
new Response(JSON.stringify({ hello: 'fast world' }), {
14-
status: 200,
15-
headers: {
16-
'Content-type': 'application/json'
17-
}
18-
}),
19-
{
20-
delay: 1000
21-
}
13+
() => {
14+
return new Response(JSON.stringify({ hello: 'fast world' }), {
15+
status: 200,
16+
headers: { 'Content-type': 'application/json' }
17+
});
18+
},
19+
{ delay: 1000 }
2220
);
2321
});
2422

2523
afterEach(function () {
26-
fetchMock.restore();
24+
fetchMock.unmockGlobal();
2725
});
2826

2927
test('successfull download - indirect json resolve', () =>
3028
new Promise(done => {
3129
of('https://httpbin.org/my-url-fast')
3230
.pipe(download(), log(false), resolveJSON(), log(false))
3331
.subscribe({
34-
next: data => {
35-
expect(data).deep.equal({ hello: 'fast world' });
36-
},
37-
complete: e => done()
32+
next: data => expect(data).deep.equal({ hello: 'fast world' }),
33+
complete: () => done()
3834
});
3935
}));
4036

@@ -43,9 +39,7 @@ describe('download operator', function () {
4339
of('https://httpbin.org/my-url-fast')
4440
.pipe(downloadJSON(), log(false))
4541
.subscribe({
46-
next: data => {
47-
expect(data).deep.equal({ hello: 'fast world' });
48-
},
42+
next: data => expect(data).deep.equal({ hello: 'fast world' }),
4943
complete: () => done()
5044
});
5145
}));
Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
1-
import { concatMap, delay as delayOperator, EMPTY, expand, of } from 'rxjs';
1+
import { delay, expand, of } from 'rxjs';
22

3+
import { log } from '../log';
34
import { download } from './download';
5+
import { distinctUntilResponseChanged } from './response';
46

5-
export const polling = ({ validateResult, delay = 1000 }) => {
7+
export const polling = (timeout = 1000) => {
68
return source =>
79
source.pipe(
8-
concatMap(({ url }) => {
9-
return of(url).pipe(
10-
download(),
11-
expand(data => {
12-
if (validateResult(data)) {
13-
return of(url).pipe(delayOperator(delay), download());
14-
}
15-
return EMPTY;
16-
})
17-
);
18-
})
10+
download(),
11+
expand(resp => of(resp.url).pipe(delay(timeout), download())),
12+
distinctUntilResponseChanged()
1913
);
2014
};

packages/operators/src/fetch/polling.test.js

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,40 @@
1-
import { concatAll, map, of } from 'rxjs';
2-
import { beforeEach, describe, expect, test } from 'vitest';
1+
import fetchMock from 'fetch-mock';
2+
import { of, take } from 'rxjs';
3+
import { afterEach, beforeEach, describe, expect, test } from 'vitest';
34

5+
import { log } from '../log';
46
import { polling } from './polling';
7+
import { resolveJSON } from './resolve';
58

69
describe('polling', function () {
710
beforeEach(function () {
8-
//
11+
let counter = 0;
12+
fetchMock.mockGlobal().get('https://httpbin.org/my-url-fast', () => {
13+
if (counter++ < 2) {
14+
return new Response(JSON.stringify({ hello: 'fast world' }), {
15+
status: 200,
16+
headers: { 'Content-type': 'application/json' }
17+
});
18+
}
19+
return new Response(JSON.stringify({ hello: 'faster world' }), {
20+
status: 200,
21+
headers: { 'Content-type': 'application/json' }
22+
});
23+
});
24+
});
25+
26+
afterEach(function () {
27+
fetchMock.unmockGlobal();
928
});
1029

1130
test('auto polling', async function () {
31+
const expected = [{ hello: 'fast world' }, { hello: 'faster world' }];
32+
1233
return new Promise(done => {
13-
of({ url: new URL('https://dummyjson.com/products') })
14-
.pipe(
15-
polling({
16-
validateResult: data => {
17-
return data.total > data.skip + data.limit;
18-
}
19-
})
20-
// map(({ data: { products } }) => products),
21-
// concatAll()
22-
)
34+
of(new URL('https://httpbin.org/my-url-fast'))
35+
.pipe(polling(), log(false), resolveJSON(), log(false), take(2))
2336
.subscribe({
24-
next: e => console.log('aha'),
37+
next: e => expect(e).deep.include(expected.shift()),
2538
complete: () => done()
2639
});
2740
});
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import { concatMap } from 'rxjs';
22

3-
import { log } from '../log';
43
import { networkRetry } from './retry';
54

65
export const request = () => {
76
return source =>
87
source.pipe(
98
concatMap(req => fetch(req)),
10-
log(false),
119
networkRetry()
1210
);
1311
};

packages/operators/src/fetch/request.test.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { request } from './request.js';
88
describe('request observable with default operators', function () {
99
beforeEach(function () {
1010
let counter = 0;
11-
fetchMock.get(
11+
fetchMock.mockGlobal().get(
1212
'https://httpbin.org/my-url-fast',
1313
() => {
1414
return new Response(JSON.stringify({ hello: 'fast world' }), {
@@ -21,17 +21,15 @@ describe('request observable with default operators', function () {
2121
});
2222

2323
afterEach(function () {
24-
fetchMock.restore();
24+
fetchMock.unmockGlobal();
2525
});
2626

2727
test('successfull request', () =>
2828
new Promise(done => {
2929
of('https://httpbin.org/my-url-fast')
3030
.pipe(request(), log(false))
3131
.subscribe({
32-
next: resp => {
33-
expect(resp).deep.includes({ ok: true });
34-
},
32+
next: resp => expect(resp).deep.includes({ ok: true }),
3533
complete: () => done()
3634
});
3735
}));
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { of } from 'rxjs';
2+
import { afterEach, test, describe, beforeEach, expect } from 'vitest';
3+
4+
import { log } from '../log';
5+
import { resolveJSON, resolveText } from './resolve';
6+
7+
describe('resolver', function () {
8+
beforeEach(function () {
9+
//
10+
});
11+
12+
afterEach(function () {
13+
//
14+
});
15+
16+
test('resolve json', () => {
17+
return new Promise(done => {
18+
of(new Response(JSON.stringify({ hello: 'world' })))
19+
.pipe(resolveJSON(), log(false))
20+
.subscribe({
21+
next: e => expect(e).includes({ hello: 'world' }),
22+
complete: () => done()
23+
});
24+
});
25+
});
26+
27+
test('resolve text', () => {
28+
return new Promise(done => {
29+
of(new Response('hello world'))
30+
.pipe(resolveText(), log(false))
31+
.subscribe({
32+
next: e => expect(e).toBe('hello world'),
33+
complete: () => done()
34+
});
35+
});
36+
});
37+
});

0 commit comments

Comments
 (0)