json-with-bigint 3.0.0 → 3.1.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/__tests__/performance.js +124 -12
- package/package.json +1 -1
- package/__tests__/performance.json +0 -1319112
package/__tests__/performance.js
CHANGED
|
@@ -2,7 +2,115 @@
|
|
|
2
2
|
const { performance } = require("perf_hooks");
|
|
3
3
|
const { JSONParse, JSONStringify } = require("../json-with-bigint.cjs");
|
|
4
4
|
|
|
5
|
-
const fs = require("fs");
|
|
5
|
+
const fs = require("fs").promises;
|
|
6
|
+
const https = require("https");
|
|
7
|
+
|
|
8
|
+
// JSON is located in a separate GitHub repo here (click Raw to see the URL below):
|
|
9
|
+
// https://github.com/Ivan-Korolenko/json-with-bigint.performance.json/blob/main/performance.json
|
|
10
|
+
const JSON_URL =
|
|
11
|
+
"https://raw.githubusercontent.com/Ivan-Korolenko/json-with-bigint.performance.json/refs/heads/main/performance.json";
|
|
12
|
+
const JSON_LOCAL_FILEPATH = "__tests__/performance.json";
|
|
13
|
+
|
|
14
|
+
async function fetchJSON(url, maxRetries = 3, delay = 1000) {
|
|
15
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
16
|
+
try {
|
|
17
|
+
const response = await new Promise((resolve, reject) => {
|
|
18
|
+
https
|
|
19
|
+
.get(url, (res) => {
|
|
20
|
+
if (res.statusCode >= 500 && res.statusCode < 600) {
|
|
21
|
+
reject(new Error(`Server error ${res.statusCode}: Retrying...`));
|
|
22
|
+
} else if (res.statusCode !== 200) {
|
|
23
|
+
reject(
|
|
24
|
+
new Error(
|
|
25
|
+
`Request failed with status ${res.statusCode} ${res.statusMessage}`
|
|
26
|
+
)
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let data = "";
|
|
31
|
+
res.on("data", (chunk) => {
|
|
32
|
+
data += chunk;
|
|
33
|
+
});
|
|
34
|
+
res.on("end", () => resolve(data));
|
|
35
|
+
})
|
|
36
|
+
.on("error", reject);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
return JSON.parse(response);
|
|
40
|
+
} catch (error) {
|
|
41
|
+
if (attempt < maxRetries) {
|
|
42
|
+
console.warn(`Attempt ${attempt} failed: ${error.message}`);
|
|
43
|
+
await new Promise((res) =>
|
|
44
|
+
setTimeout(res, delay * Math.pow(2, attempt - 1))
|
|
45
|
+
); // Exponential backoff
|
|
46
|
+
} else {
|
|
47
|
+
console.error("Max retries reached. Fetch failed:", error);
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function saveJSONToFile(filePath, data) {
|
|
55
|
+
try {
|
|
56
|
+
const jsonString = JSON.stringify(data, null, 2);
|
|
57
|
+
const tempPath = `${filePath}.tmp`;
|
|
58
|
+
|
|
59
|
+
await fs.writeFile(tempPath, jsonString, "utf8");
|
|
60
|
+
await fs.rename(tempPath, filePath); // Atomic write
|
|
61
|
+
console.log(`✅ JSON data saved to ${filePath}`);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.error("Error saving JSON to file:", error);
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function fetchAndSaveJSON(url, filePath) {
|
|
69
|
+
try {
|
|
70
|
+
const jsonData = await fetchJSON(url);
|
|
71
|
+
|
|
72
|
+
await saveJSONToFile(filePath, jsonData);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.error("❌ Operation failed:", error);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// If the file was downloaded earlier, use it. Otherwise, download
|
|
79
|
+
// After n attempts, give up and throw an error
|
|
80
|
+
async function readPerformanceJSON(
|
|
81
|
+
filePath,
|
|
82
|
+
encoding,
|
|
83
|
+
maxAttempts = 3,
|
|
84
|
+
attempt = 0
|
|
85
|
+
) {
|
|
86
|
+
if (attempt === maxAttempts)
|
|
87
|
+
throw new Error(
|
|
88
|
+
`Reading performance JSON failed after ${attempt} attempts. Check download URL, file availability on that URL, and local filepath`
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const data = await fs.readFile(filePath, encoding);
|
|
93
|
+
|
|
94
|
+
return data;
|
|
95
|
+
} catch (error) {
|
|
96
|
+
if (error.code === "ENOENT") {
|
|
97
|
+
console.log(
|
|
98
|
+
`File not found. Downloading... (Attempt ${attempt + 1}/${maxAttempts})`
|
|
99
|
+
);
|
|
100
|
+
await fetchAndSaveJSON(JSON_URL, filePath);
|
|
101
|
+
|
|
102
|
+
return await readPerformanceJSON(
|
|
103
|
+
filePath,
|
|
104
|
+
encoding,
|
|
105
|
+
maxAttempts,
|
|
106
|
+
attempt + 1
|
|
107
|
+
);
|
|
108
|
+
} else {
|
|
109
|
+
console.error("Error reading file:", error);
|
|
110
|
+
throw error; // Re-throw to avoid silent failures
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
6
114
|
|
|
7
115
|
const measureExecTime = (fn) => {
|
|
8
116
|
const startTime = performance.now();
|
|
@@ -14,16 +122,20 @@ const measureExecTime = (fn) => {
|
|
|
14
122
|
console.log("Time: ", endTime - startTime);
|
|
15
123
|
};
|
|
16
124
|
|
|
17
|
-
|
|
125
|
+
async function main() {
|
|
126
|
+
const data = await readPerformanceJSON(JSON_LOCAL_FILEPATH, "utf8");
|
|
127
|
+
|
|
128
|
+
measureExecTime(() => {
|
|
129
|
+
console.log("___________");
|
|
130
|
+
console.log("Performance test. One-way");
|
|
131
|
+
JSONParse(data);
|
|
132
|
+
});
|
|
18
133
|
|
|
19
|
-
measureExecTime(() => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
});
|
|
134
|
+
measureExecTime(() => {
|
|
135
|
+
console.log("___________");
|
|
136
|
+
console.log("Performance test. Round-trip");
|
|
137
|
+
JSONStringify(JSONParse(data));
|
|
138
|
+
});
|
|
139
|
+
}
|
|
24
140
|
|
|
25
|
-
|
|
26
|
-
console.log("___________");
|
|
27
|
-
console.log("Performance test 1. Round-trip");
|
|
28
|
-
JSONStringify(JSONParse(performanceTest1));
|
|
29
|
-
});
|
|
141
|
+
main();
|