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.
@@ -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
- const performanceTest1 = fs.readFileSync("__tests__/performance.json", "utf8");
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
- console.log("___________");
21
- console.log("Performance test 1. One-way");
22
- JSONParse(performanceTest1);
23
- });
134
+ measureExecTime(() => {
135
+ console.log("___________");
136
+ console.log("Performance test. Round-trip");
137
+ JSONStringify(JSONParse(data));
138
+ });
139
+ }
24
140
 
25
- measureExecTime(() => {
26
- console.log("___________");
27
- console.log("Performance test 1. Round-trip");
28
- JSONStringify(JSONParse(performanceTest1));
29
- });
141
+ main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-with-bigint",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "JS library that allows you to easily serialize and deserialize data with BigInt values",
5
5
  "type": "module",
6
6
  "exports": {