Skip to content

Commit 3a19fd5

Browse files
authored
Merge pull request #66 from bartholomej/fix/cache
Server: Make services stateless to eliminate shared state mutations
2 parents bcb8e54 + 09ddcff commit 3a19fd5

File tree

7 files changed

+261
-91
lines changed

7 files changed

+261
-91
lines changed

.github/pull_request_template.md

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
1-
## What's new and why I made this pull request?
1+
## Description
22

3-
-
3+
<!-- Briefly describe the changes and the motivation behind them. -->
44

5-
## Pull request type
5+
## Type of change
66

7-
What kind of change does this PR introduce?
7+
- [ ] Bug fix
8+
- [ ] New feature
9+
- [ ] Refactoring (no functional changes)
10+
- [ ] Code style update
11+
- [ ] Build / CI related changes
12+
- [ ] Documentation update
13+
- [ ] Tests
14+
- [ ] Other
815

9-
```
10-
[ ] Bugfix
11-
[ ] Feature
12-
[ ] Code style update (formatting, local variables)
13-
[ ] Refactoring (no functional changes, no api changes)
14-
[ ] Build related changes
15-
[ ] CI related changes
16-
[ ] Documentation content changes
17-
[ ] Tests
18-
[ ] Other
19-
```
16+
## Related Issues
17+
18+
<!-- Closes #... -->
19+
20+
## Checklist
21+
22+
- [ ] I have performed a self-review of my code
23+
- [ ] My changes generate no new warnings
24+
- [ ] I have added tests that prove my fix is effective or that my feature works

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
"description": "ČSFD API in JavaScript. Amazing NPM library for scrapping csfd.cz :)",
55
"author": "BART! <[email protected]>",
66
"scripts": {
7-
"start": "tsc -w",
7+
"dev": "tsc -w",
8+
"start": "yarn dev",
9+
"server": "tsx server",
810
"prebuild": "rimraf dist",
911
"build": "tsdown --config-loader unconfig && cp README.md dist/ && cp LICENSE dist/",
1012
"build:server": "npx esbuild ./server.ts --outfile=dist/server.mjs --format=esm --sourcemap && node scripts/server-mod.js",
@@ -50,7 +52,7 @@
5052
"eslint-config-google": "^0.14.0",
5153
"eslint-config-prettier": "^10.1.8",
5254
"eslint-plugin-prettier": "^5.5.4",
53-
"express": "^5.1.0",
55+
"express": "^5.2.0",
5456
"express-rate-limit": "^8.2.1",
5557
"express-slow-down": "^3.0.1",
5658
"globals": "^16.5.0",
@@ -59,7 +61,7 @@
5961
"prettier": "^3.7.3",
6062
"rimraf": "^6.1.2",
6163
"tsdown": "^0.15.11",
62-
"tsx": "^4.20.6",
64+
"tsx": "^4.21.0",
6365
"typescript": "^5.9.3",
6466
"vitest": "^4.0.14"
6567
},

src/services/cinema.service.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ import {
1111
} from './../helpers/cinema.helper';
1212

1313
export class CinemaScraper {
14-
private cinema: CSFDCinema[];
15-
1614
public async cinemas(
1715
district: number = 1,
1816
period: CSFDCinemaPeriod = 'today',
@@ -25,11 +23,10 @@ export class CinemaScraper {
2523

2624
const contentNode = cinemasHtml.querySelectorAll('#snippet--cinemas section[id*="cinema-"]');
2725

28-
this.buildCinemas(contentNode);
29-
return this.cinema;
26+
return this.buildCinemas(contentNode);
3027
}
3128

32-
private buildCinemas(contentNode: HTMLElement[]) {
29+
private buildCinemas(contentNode: HTMLElement[]): CSFDCinema[] {
3330
const cinemas: CSFDCinema[] = [];
3431

3532
contentNode.forEach((x) => {
@@ -45,6 +42,6 @@ export class CinemaScraper {
4542
cinemas.push(cinema);
4643
});
4744

48-
this.cinema = cinemas;
45+
return cinemas;
4946
}
5047
}

src/services/creator.service.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import { HTMLElement, parse } from 'node-html-parser';
22
import { CSFDCreator } from '../dto/creator';
33
import { fetchPage } from '../fetchers';
4-
import { getCreatorBio, getCreatorBirthdayInfo, getCreatorFilms, getCreatorName, getCreatorPhoto } from '../helpers/creator.helper';
4+
import {
5+
getCreatorBio,
6+
getCreatorBirthdayInfo,
7+
getCreatorFilms,
8+
getCreatorName,
9+
getCreatorPhoto
10+
} from '../helpers/creator.helper';
511
import { creatorUrl } from '../vars';
612

713
export class CreatorScraper {
8-
private person: CSFDCreator;
9-
1014
public async creator(creatorId: number, optionsRequest?: RequestInit): Promise<CSFDCreator> {
1115
const id = Number(creatorId);
1216
if (isNaN(id)) {
@@ -19,12 +23,11 @@ export class CreatorScraper {
1923

2024
const asideNode = creatorHtml.querySelector('.creator-about');
2125
const filmsNode = creatorHtml.querySelector('.creator-filmography');
22-
this.buildCreator(+creatorId, asideNode, filmsNode);
23-
return this.person;
26+
return this.buildCreator(+creatorId, asideNode, filmsNode);
2427
}
2528

26-
private buildCreator(id: number, asideEl: HTMLElement, filmsNode: HTMLElement) {
27-
this.person = {
29+
private buildCreator(id: number, asideEl: HTMLElement, filmsNode: HTMLElement): CSFDCreator {
30+
return {
2831
id,
2932
name: getCreatorName(asideEl),
3033
birthday: getCreatorBirthdayInfo(asideEl)?.birthday,

src/services/movie.service.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ import {
2626
import { movieUrl } from '../vars';
2727

2828
export class MovieScraper {
29-
private film: CSFDMovie;
30-
3129
public async movie(movieId: number, optionsRequest?: RequestInit): Promise<CSFDMovie> {
3230
const id = Number(movieId);
3331
if (isNaN(id)) {
@@ -42,8 +40,7 @@ export class MovieScraper {
4240
const asideNode = movieHtml.querySelector('.aside-movie-profile');
4341
const movieNode = movieHtml.querySelector('.main-movie-profile');
4442
const jsonLd = movieHtml.querySelector('script[type="application/ld+json"]').innerText;
45-
this.buildMovie(+movieId, movieNode, asideNode, pageClasses, jsonLd);
46-
return this.film;
43+
return this.buildMovie(+movieId, movieNode, asideNode, pageClasses, jsonLd);
4744
}
4845

4946
private buildMovie(
@@ -52,8 +49,8 @@ export class MovieScraper {
5249
asideEl: HTMLElement,
5350
pageClasses: string[],
5451
jsonLd: string
55-
) {
56-
this.film = {
52+
): CSFDMovie {
53+
return {
5754
id: movieId,
5855
title: getMovieTitle(el),
5956
year: getMovieYear(jsonLd),

src/services/user-ratings.service.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ import {
1616
import { userRatingsUrl } from '../vars';
1717

1818
export class UserRatingsScraper {
19-
private films: CSFDUserRatings[] = [];
20-
2119
public async userRatings(
2220
user: string | number,
2321
config?: CSFDUserRatingConfig,
@@ -45,7 +43,7 @@ export class UserRatingsScraper {
4543

4644
const items = parse(response);
4745
const movies = items.querySelectorAll('.box-user-rating .table-container tbody tr');
48-
allMovies = [...this.getPage(config, movies)];
46+
allMovies = [...allMovies, ...this.getPage(config, movies)];
4947

5048
// Sleep
5149
if (config.allPagesDelay) {
@@ -59,6 +57,7 @@ export class UserRatingsScraper {
5957
}
6058

6159
private getPage(config: CSFDUserRatingConfig, movies: HTMLElement[]) {
60+
const films: CSFDUserRatings[] = [];
6261
if (config) {
6362
if (config.includesOnly?.length && config.excludes?.length) {
6463
console.warn(
@@ -76,23 +75,23 @@ export class UserRatingsScraper {
7675
// Filtering includesOnly
7776
if (config?.includesOnly?.length) {
7877
if (config.includesOnly.some((include) => type === include)) {
79-
this.buildUserRatings(el);
78+
films.push(this.buildUserRatings(el));
8079
}
8180
// Filter exludes
8281
} else if (config?.excludes?.length) {
8382
if (!config.excludes.some((exclude) => type === exclude)) {
84-
this.buildUserRatings(el);
83+
films.push(this.buildUserRatings(el));
8584
}
8685
} else {
8786
// Without filtering
88-
this.buildUserRatings(el);
87+
films.push(this.buildUserRatings(el));
8988
}
9089
}
91-
return this.films;
90+
return films;
9291
}
9392

94-
private buildUserRatings(el: HTMLElement) {
95-
this.films.push({
93+
private buildUserRatings(el: HTMLElement): CSFDUserRatings {
94+
return {
9695
id: getUserRatingId(el),
9796
title: getUserRatingTitle(el),
9897
year: getUserRatingYear(el),
@@ -101,6 +100,6 @@ export class UserRatingsScraper {
101100
colorRating: getUserRatingColorRating(el) as CSFDColorRating,
102101
userDate: getUserRatingDate(el),
103102
userRating: getUserRating(el) as CSFDStars
104-
});
103+
};
105104
}
106105
}

0 commit comments

Comments
 (0)