Skip to content

Commit 81c1dc4

Browse files
committed
chore(server): code cleanup
1 parent 1cbcf5e commit 81c1dc4

13 files changed

+125
-151
lines changed

server/app.js

Lines changed: 41 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ import Fastify from "fastify";
22
import frameworksRouter from "./src/frameworks/frameworksRouter.js";
33
import cspRouter from "./src/csp/cspRouter.js";
44
import staticRouter from "./src/static/staticRouter.js";
5-
import * as ejs from "ejs";
6-
import * as fastifyView from "@fastify/view";
5+
import ejs from "ejs";
6+
import fastifyView from "@fastify/view";
77
import minifier from "html-minifier";
88
import { Stream } from "node:stream";
99
import toArray from "stream-to-array";
1010
import zlib from "node:zlib";
11-
import { getSizeRouter } from "./src/responseSize/responseSizeRouter.js";
11+
import { responseSizeRouter } from "./src/responseSize/responseSizeRouter.js";
12+
import { createResponseSizeDecorator } from "./src/responseSize/responseSizeDecorator.js";
1213

1314
/**
1415
* Builds the server but does not start it. Need it for testing API
@@ -20,38 +21,15 @@ function buildServer(options = {}) {
2021

2122
fastify.register(fastifyView, {
2223
engine: {
23-
ejs: ejs,
24+
ejs,
2425
},
2526
options: {
2627
useHtmlMinifier: minifier,
2728
},
2829
});
2930

30-
fastify.decorate("responseSize", {
31-
use_compression: false,
32-
size_uncompressed: 0,
33-
size_compressed: 0,
34-
get: function() {
35-
return {
36-
use_compression: this.use_compression,
37-
size_uncompressed: this.size_uncompressed,
38-
size_compressed: this.size_compressed,
39-
};
40-
},
41-
reset: function() {
42-
this.size_uncompressed = 0;
43-
this.size_compressed = 0;
44-
},
45-
enableCompression: function(val) {
46-
this.use_compression = val;
47-
},
48-
add: function(uncompressed, compressed) {
49-
this.size_uncompressed += uncompressed;
50-
this.size_compressed += compressed;
51-
},
52-
});
53-
54-
fastify.register(getSizeRouter);
31+
fastify.decorate("responseSize", createResponseSizeDecorator());
32+
fastify.register(responseSizeRouter);
5533

5634
fastify.addHook("onSend", async (request, reply, payload) => {
5735
// const MISSING_HEADERS_AND_HTTP = 99;
@@ -72,42 +50,42 @@ function buildServer(options = {}) {
7250

7351
if (request.url.startsWith("/css") || reply.statusCode != 200 || !fastify.responseSize.use_compression) {
7452
return payload;
53+
}
54+
55+
if (typeof payload == "string") {
56+
let { uncompressed, compressed } = getSizeInfo(payload);
57+
fastify.responseSize.add(uncompressed, compressed);
58+
console.log(
59+
`onSend: ${request.url} as string with uncompressed size ${uncompressed} sum uncompressed ${fastify.responseSize.size_uncompressed}, compressed ${fastify.responseSize.size_compressed}`
60+
);
61+
} else if (payload instanceof Stream) {
62+
return toArray(payload)
63+
.then((chunks) => {
64+
const buffer = Buffer.concat(chunks);
65+
if (buffer.length >= 1024) {
66+
let out = zlib.brotliCompressSync(buffer);
67+
let { uncompressed, compressed } = getSizeInfo(buffer, out);
68+
fastify.responseSize.add(uncompressed, compressed);
69+
console.log(
70+
`onSend: ${request.url} as stream with uncompressed size ${uncompressed} compressed ${compressed} sum uncompressed ${fastify.responseSize.size_uncompressed}, compressed ${fastify.responseSize.size_compressed}`
71+
);
72+
return out;
73+
} else {
74+
let { uncompressed, compressed } = getSizeInfo(buffer);
75+
fastify.responseSize.add(uncompressed, compressed);
76+
console.log(
77+
`onSend: ${request.url} as stream with uncompressed size ${uncompressed} (not compressed since below threshold) sum uncompressed ${fastify.responseSize.size_uncompressed}, compressed ${fastify.responseSize.size_compressed}`
78+
);
79+
return buffer;
80+
}
81+
})
82+
.catch((error) => {
83+
console.log("onSend: Error", error);
84+
});
7585
} else {
76-
if (typeof payload == "string") {
77-
let { uncompressed, compressed } = getSizeInfo(payload);
78-
fastify.responseSize.add(uncompressed, compressed);
79-
console.log(
80-
`onSend: ${request.url} as string with uncompressed size ${uncompressed} sum uncompressed ${fastify.responseSize.size_uncompressed}, compressed ${fastify.responseSize.size_compressed}`
81-
);
82-
} else if (payload instanceof Stream) {
83-
return toArray(payload)
84-
.then((chunks) => {
85-
const buffer = Buffer.concat(chunks);
86-
if (buffer.length >= 1024) {
87-
let out = zlib.brotliCompressSync(buffer);
88-
let { uncompressed, compressed } = getSizeInfo(buffer, out);
89-
fastify.responseSize.add(uncompressed, compressed);
90-
console.log(
91-
`onSend: ${request.url} as stream with uncompressed size ${uncompressed} compressed ${compressed} sum uncompressed ${fastify.responseSize.size_uncompressed}, compressed ${fastify.responseSize.size_compressed}`
92-
);
93-
return out;
94-
} else {
95-
let { uncompressed, compressed } = getSizeInfo(buffer);
96-
fastify.responseSize.add(uncompressed, compressed);
97-
console.log(
98-
`onSend: ${request.url} as stream with uncompressed size ${uncompressed} (not compressed since below threshold) sum uncompressed ${fastify.responseSize.size_uncompressed}, compressed ${fastify.responseSize.size_compressed}`
99-
);
100-
return buffer;
101-
}
102-
})
103-
.catch((error) => {
104-
console.log("onSend: Error", error);
105-
});
106-
} else {
107-
console.log("onSend: Unknown payload type", typeof payload, payload);
108-
}
109-
return payload;
86+
console.log("onSend: Unknown payload type", typeof payload, payload);
11087
}
88+
return payload;
11189
});
11290

11391
fastify.addHook("onRequest", (request, reply, done) => {

server/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const PORT = 8080;
55
const server = buildServer();
66

77
try {
8-
await server.listen({ port: PORT}); //, host: '0.0.0.0' });
8+
await server.listen({ port: PORT }); //, host: '0.0.0.0' });
99
console.log(`Server running on port ${PORT}`);
1010
} catch (error) {
1111
server.log.error(error);

server/src/csp/cspControllers.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
let violations = [];
2-
let isCSPEnabled = false;
1+
// @ts-check
32

43
/**
54
* @typedef {import("fastify").FastifyRequest} Request
65
* @typedef {import("fastify").FastifyReply} Reply
76
*/
87

8+
/** @type {string[]} */
9+
const violations = [];
10+
let isCSPEnabled = false;
11+
912
/**
1013
* @param {Request} request
1114
* @param {Reply} reply
1215
*/
13-
export function getCSP(_request, reply) {
16+
export function getCSP(request, reply) {
1417
console.log("CSP violations recorded for", violations);
1518
reply.send(violations);
1619
}
@@ -24,6 +27,7 @@ export function addCSP(request, reply) {
2427

2528
console.log("/CSP", body);
2629

30+
// @ts-expect-error - It's better to use a validator
2731
const uri = body["csp-report"]["document-uri"];
2832
const frameworkRegEx = /((non-)?keyed\/.*?\/)/;
2933
let framework = uri.match(frameworkRegEx)[0];
@@ -39,9 +43,9 @@ export function addCSP(request, reply) {
3943
* @param {Request} request
4044
* @param {Reply} reply
4145
*/
42-
export function enableCSP(_request, reply) {
43-
console.log("/startCSP");
44-
violations = [];
46+
export function enableCSP(request, reply) {
47+
console.log("/enableCSP");
48+
violations.length = 0;
4549
isCSPEnabled = true;
4650
reply.send("OK");
4751
}
@@ -50,9 +54,9 @@ export function enableCSP(_request, reply) {
5054
* @param {Request} request
5155
* @param {Reply} reply
5256
*/
53-
export function disableCSP(_request, reply) {
54-
console.log("/endCSP");
55-
violations = [];
57+
export function disableCSP(request, reply) {
58+
console.log("/disableCSP");
59+
violations.length = 0;
5660
isCSPEnabled = false;
5761
reply.send("OK");
5862
}

server/src/csp/cspRouter.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import { addCSP, disableCSP, enableCSP, getCSP } from "./cspControllers.js";
22

33
/**
4-
* A plugin that provide encapsulated routes
54
* @param {import("fastify").FastifyInstance} fastify
65
*/
76
async function routes(fastify) {
87
fastify.addContentTypeParser(
98
"application/csp-report",
109
{ parseAs: "string" },
11-
fastify.getDefaultJsonParser("ignore", "ignore"),
10+
fastify.getDefaultJsonParser("ignore", "ignore")
1211
);
1312

1413
fastify.get("/enable", enableCSP);

server/src/frameworks/frameworksControllers.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,7 @@ export async function getFrameworksVersions(request, reply) {
1919

2020
performance.mark("End");
2121

22-
const executionTime = performance.measure(
23-
"/ls duration measurement",
24-
"Start",
25-
"End",
26-
).duration;
22+
const executionTime = performance.measure("/ls duration measurement", "Start", "End").duration;
2723

2824
console.log(`/ls duration: ${executionTime}ms`);
2925

@@ -36,5 +32,5 @@ export async function getFrameworksVersions(request, reply) {
3632
* @param {Reply} reply
3733
*/
3834
export async function generateAndServeIndex(request, reply) {
39-
return reply.view("templates/index.ejs", {frameworks: await prepareFrameworkData()});
35+
return reply.view("templates/index.ejs", { frameworks: await prepareFrameworkData() });
4036
}

server/src/frameworks/frameworksRouter.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { getFrameworksVersions } from "./frameworksControllers.js";
22

33
/**
4-
* A plugin that provide encapsulated routes
54
* @param {import("fastify").FastifyInstance} fastify
65
*/
76
async function routes(fastify) {

server/src/frameworks/frameworksServices.js

Lines changed: 12 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,7 @@ class PackageJSONProvider {
2222
*/
2323
async getPackageJSON(keyedDir, framework) {
2424
try {
25-
const packageJSONPath = path.join(
26-
this.#frameworksDir,
27-
keyedDir,
28-
framework,
29-
"package.json",
30-
);
25+
const packageJSONPath = path.join(this.#frameworksDir, keyedDir, framework, "package.json");
3126
const packageJSON = await fs.promises.readFile(packageJSONPath, "utf8");
3227
return JSON.parse(packageJSON);
3328
} catch (error) {
@@ -46,16 +41,8 @@ class PackageJSONProvider {
4641
*/
4742
async getPackageLockJSON(keyedDir, framework) {
4843
try {
49-
const packageLockJSONPath = path.join(
50-
this.#frameworksDir,
51-
keyedDir,
52-
framework,
53-
"package-lock.json",
54-
);
55-
const packageLockJSON = await fs.promises.readFile(
56-
packageLockJSONPath,
57-
"utf8",
58-
);
44+
const packageLockJSONPath = path.join(this.#frameworksDir, keyedDir, framework, "package-lock.json");
45+
const packageLockJSON = await fs.promises.readFile(packageLockJSONPath, "utf8");
5946
return JSON.parse(packageLockJSON);
6047
} catch (error) {
6148
if (error.code === "ENOENT") {
@@ -75,8 +62,7 @@ function isFrameworkDir(keyedDir, framework) {
7562
const frameworkPath = path.resolve(frameworksDirectory, keyedDir, framework);
7663
const packageJSONPath = path.resolve(frameworkPath, "package.json");
7764
const packageLockJSONPath = path.resolve(frameworkPath, "package-lock.json");
78-
const exists =
79-
fs.existsSync(packageJSONPath) && fs.existsSync(packageLockJSONPath);
65+
const exists = fs.existsSync(packageJSONPath) && fs.existsSync(packageLockJSONPath);
8066

8167
return exists;
8268
}
@@ -94,19 +80,12 @@ export async function loadFrameworkInfo(keyedDir, framework) {
9480
type: keyedDir,
9581
directory: framework,
9682
};
97-
const packageJSON = await packageJSONProvider.getPackageJSON(
98-
keyedDir,
99-
framework,
100-
);
101-
const packageLockJSON = await packageJSONProvider.getPackageLockJSON(
102-
keyedDir,
103-
framework,
104-
);
83+
const packageJSON = await packageJSONProvider.getPackageJSON(keyedDir, framework);
84+
const packageLockJSON = await packageJSONProvider.getPackageLockJSON(keyedDir, framework);
10585

10686
const benchmarkData = packageJSON["js-framework-benchmark"];
10787
if (!benchmarkData) {
108-
result.error =
109-
"package.json must contain a 'js-framework-benchmark' property";
88+
result.error = "package.json must contain a 'js-framework-benchmark' property";
11089
return result;
11190
}
11291

@@ -117,11 +96,9 @@ export async function loadFrameworkInfo(keyedDir, framework) {
11796

11897
for (const packageName of packageNames) {
11998
if (packageLockJSON.dependencies?.[packageName]) {
120-
result.versions[packageName] =
121-
packageLockJSON.dependencies[packageName].version;
99+
result.versions[packageName] = packageLockJSON.dependencies[packageName].version;
122100
} else if (packageLockJSON.packages?.[`node_modules/${packageName}`]) {
123-
result.versions[packageName] =
124-
packageLockJSON.packages[`node_modules/${packageName}`].version;
101+
result.versions[packageName] = packageLockJSON.packages[`node_modules/${packageName}`].version;
125102
} else {
126103
result.versions[packageName] = "ERROR: Not found in package-lock";
127104
}
@@ -130,17 +107,13 @@ export async function loadFrameworkInfo(keyedDir, framework) {
130107
result.frameworkVersionString = buildFrameworkVersionString(
131108
framework,
132109
packageNames.map((name) => result.versions[name]).join(" + "),
133-
keyedDir,
110+
keyedDir
134111
);
135112

136113
copyProps(result, benchmarkData);
137114
} else if (typeof benchmarkData.frameworkVersion === "string") {
138115
result.version = benchmarkData.frameworkVersion;
139-
result.frameworkVersionString = buildFrameworkVersionString(
140-
framework,
141-
result.version,
142-
keyedDir,
143-
);
116+
result.frameworkVersionString = buildFrameworkVersionString(framework, result.version, keyedDir);
144117

145118
copyProps(result, benchmarkData);
146119
} else {
@@ -155,9 +128,7 @@ export async function loadFrameworkVersions() {
155128
const resultsProm = [];
156129

157130
for (const keyedType of keyedTypes) {
158-
const directories = await fs.promises.readdir(
159-
path.resolve(frameworksDirectory, keyedType),
160-
);
131+
const directories = await fs.promises.readdir(path.resolve(frameworksDirectory, keyedType));
161132

162133
for (const directory of directories) {
163134
if (!isFrameworkDir(keyedType, directory)) {

server/src/frameworks/helpers/copyProps.js

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,14 @@
1414
* @param {BenchmarkData} benchmarkData
1515
*/
1616
export function copyProps(result, benchmarkData) {
17-
const {
18-
issues,
19-
customURL,
20-
frameworkHomeURL,
21-
useShadowRoot,
22-
useRowShadowRoot,
23-
shadowRootName,
24-
buttonsInShadowRoot,
25-
} = benchmarkData;
17+
const { issues, customURL, frameworkHomeURL, useShadowRoot, useRowShadowRoot, shadowRootName, buttonsInShadowRoot } =
18+
benchmarkData;
2619

2720
result.issues = issues;
2821
result.customURL = customURL;
2922
result.frameworkHomeURL = frameworkHomeURL;
3023
result.useShadowRoot = useShadowRoot;
3124
result.useRowShadowRoot = useRowShadowRoot;
32-
result.shadowRootName = useShadowRoot
33-
? shadowRootName ?? "main-element"
34-
: undefined;
35-
result.buttonsInShadowRoot = useShadowRoot
36-
? buttonsInShadowRoot ?? true
37-
: undefined;
25+
result.shadowRootName = useShadowRoot ? (shadowRootName ?? "main-element") : undefined;
26+
result.buttonsInShadowRoot = useShadowRoot ? (buttonsInShadowRoot ?? true) : undefined;
3827
}

0 commit comments

Comments
 (0)