@qubit-ltd/json 1.1.4 → 1.2.1

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/README.md CHANGED
@@ -6,26 +6,26 @@
6
6
  [![CircleCI](https://dl.circleci.com/status-badge/img/gh/Haixing-Hu/js-json/tree/master.svg?style=shield)](https://dl.circleci.com/status-badge/redirect/gh/Haixing-Hu/js-json/tree/master)
7
7
  [![Coverage Status](https://coveralls.io/repos/github/Haixing-Hu/js-json/badge.svg?branch=master)](https://coveralls.io/github/Haixing-Hu/js-json?branch=master)
8
8
 
9
- [@qubit-ltd/json] is a JavaScript library that extends the functionality of the
9
+ [@qubit-ltd/json] is a JavaScript library that extends the functionality of the
10
10
  standard JSON object, providing robust support for working with numbers that
11
- exceed JavaScripts safe range. It offers enhanced parsing and stringifying
11
+ exceed JavaScript's safe range. It offers enhanced parsing and stringifying
12
12
  capabilities, making it ideal for handling large datasets and complex numerical
13
- operations while adhering to JSONs structure.
13
+ operations while adhering to JSON's structure.
14
14
 
15
15
  ## Key Features
16
16
 
17
- - `BigInt` Support: When parsing JSON strings, numbers outside JavaScripts safe
17
+ - **`BigInt` Support**: When parsing JSON strings, numbers outside JavaScript's safe
18
18
  integer range are automatically converted to the native `BigInt`, ensuring
19
19
  precision is maintained.
20
- - `LosslessNumber` Handling: For floating-point numbers that cannot be accurately
20
+ - **`LosslessNumber` Handling**: For floating-point numbers that cannot be accurately
21
21
  represented in JavaScript, this library introduces the `LosslessNumber` object.
22
22
  This lightweight object preserves the full precision of the number as a string,
23
23
  allowing flexible conversion to number or `BigInt` for mathematical operations.
24
- - Accurate Stringification: During the stringify process, `BigInt` values are
25
- serialized as strings without the n suffix, maintaining compatibility with
24
+ - **Accurate Stringification**: During the stringify process, `BigInt` values are
25
+ serialized as strings without the "n" suffix, maintaining compatibility with
26
26
  the standard JSON format. Similarly, `LosslessNumber` objects are serialized
27
27
  using their internal string representation.
28
- - Collection Serialization: JavaScripts native collections like `Set` and `Map`
28
+ - **Collection Serialization**: JavaScript's native collections like `Set` and `Map`
29
29
  are seamlessly serialized as arrays, allowing for better compatibility with
30
30
  JSON structures.
31
31
 
@@ -55,42 +55,86 @@ collections like Set and Map.
55
55
  ```javascript
56
56
  import Json from '@qubit-ltd/json';
57
57
 
58
- // parse numbers outside the safe range
58
+ // Parse numbers outside the safe range
59
59
  const str1 = '{"decimal":2.370,"big_int":9123372036854000123,"big_float":2.3e+500}';
60
- const obj1 = Json.parse(text);
60
+ const obj1 = Json.parse(str1);
61
61
  console.log(obj1.decimal); // 2.37
62
62
  console.log(obj1.big_int); // 9123372036854000123n
63
63
  console.log(obj1.big_float); // LosslessNumber { value: '2.3e+500', isLosslessNumber: true }
64
64
  console.log(String(obj1.big_float)); // '2.3e+500'
65
65
 
66
- // stringify numbers outside the safe range
66
+ // Stringify numbers outside the safe range
67
67
  const json1 = Json.stringify(obj1);
68
68
  console.log(json1); // '{"decimal":2.37,"big_int":9123372036854000123,"big_float":"2.3e+500"}'
69
69
 
70
- // stringify collections
70
+ // Stringify collections
71
71
  const obj2 = {
72
72
  x: new Set([{ a: 1 }, { b: 2 }, { c: 3 }]),
73
73
  y: new Map([[1, { a: 2 }], [2, { b: 4 }]]),
74
74
  };
75
- const json2 = Json.stringify(obj);
75
+ const json2 = Json.stringify(obj2);
76
76
  console.log(json2); // '{"x":[{"a":1},{"b":2},{"c":3}],"y":[[1,{"a":2}],[2,{"b":4}]]}'
77
77
 
78
- const json3 = Json.stringify(obj, null, 2);
79
- console.log(json3); //
78
+ // Pretty-print with indentation
79
+ const json3 = Json.stringify(obj2, null, 2);
80
+ console.log(json3);
81
+ /* Output:
82
+ {
83
+ "x": [
84
+ {
85
+ "a": 1
86
+ },
87
+ {
88
+ "b": 2
89
+ },
90
+ {
91
+ "c": 3
92
+ }
93
+ ],
94
+ "y": [
95
+ [
96
+ 1,
97
+ {
98
+ "a": 2
99
+ }
100
+ ],
101
+ [
102
+ 2,
103
+ {
104
+ "b": 4
105
+ }
106
+ ]
107
+ ]
108
+ }
109
+ */
80
110
  ```
81
111
 
82
112
  ### LosslessNumber Class
83
113
 
84
- The LosslessNumber class is used to handle floating-point numbers with full
114
+ The `LosslessNumber` class is used to handle floating-point numbers with full
85
115
  precision, avoiding truncation or rounding issues.
86
116
 
87
117
  ```javascript
88
118
  import Json from '@qubit-ltd/json';
119
+ import { LosslessNumber } from '@qubit-ltd/json';
120
+
121
+ // Parse a number with high precision
89
122
  const parsed = Json.parse('{"float": 1.234567891234567891234}');
90
123
  console.log(parsed.float); // LosslessNumber { value: '1.234567891234567891234' }
91
124
 
92
125
  // Convert LosslessNumber to standard number
93
- console.log(parsed.float.valueOf()); // 1.2345678912345679 (standard JS number)
126
+ console.log(parsed.float.valueOf()); // 1.2345678912345679 (standard JS number, precision loss)
127
+
128
+ // Create a LosslessNumber directly
129
+ const largeNumber = new LosslessNumber('9876543210.123456789012345678901234567890');
130
+ console.log(largeNumber.toString()); // '9876543210.123456789012345678901234567890'
131
+ console.log(largeNumber.valueOf()); // 9876543210.123457 (standard JS number with precision loss)
132
+
133
+ // Mathematical operations
134
+ const num1 = new LosslessNumber('1234567890.123456789');
135
+ const num2 = 100;
136
+ // For math operations, LosslessNumber is converted to standard number (with potential precision loss)
137
+ console.log(num1 * num2); // 123456789012.34578
94
138
  ```
95
139
 
96
140
  ### Utility Functions
@@ -100,7 +144,7 @@ numbers and ensure safe conversions.
100
144
 
101
145
  #### `isBigInt(value)`
102
146
 
103
- Checks if a string represents a `BigInt` (i.e., ends with an n suffix).
147
+ Checks if a string represents a `BigInt` (i.e., ends with an "n" suffix).
104
148
 
105
149
  ```javascript
106
150
  import { isBigInt } from '@qubit-ltd/json';
@@ -118,6 +162,8 @@ import { isInteger } from '@qubit-ltd/json';
118
162
 
119
163
  console.log(isInteger('12345')); // true
120
164
  console.log(isInteger('123.45')); // false
165
+ console.log(isInteger('123e5')); // true (12300000 is an integer)
166
+ console.log(isInteger('123e-5')); // false (0.00123 is not an integer)
121
167
  ```
122
168
 
123
169
  #### `isNumber(value)`
@@ -131,19 +177,26 @@ console.log(isNumber('12345')); // true
131
177
  console.log(isNumber('-123.45')); // true
132
178
  console.log(isNumber('1.23e-11')); // true
133
179
  console.log(isNumber('abc')); // false
180
+ console.log(isNumber('123abc')); // false
181
+ console.log(isNumber('0xFF')); // false (hexadecimal notation not supported)
134
182
  ```
135
183
 
136
184
  #### `isSafeNumber(value, options)`
137
185
 
138
- Checks if a string represents a number within JavaScripts safe range.
186
+ Checks if a string represents a number within JavaScript's safe range.
139
187
 
140
188
  ```javascript
141
189
  import { isSafeNumber } from '@qubit-ltd/json';
142
190
 
143
191
  console.log(isSafeNumber('12345')); // true
144
- console.log(isSafeNumber('12345678901234567890')); // false
145
- console.log(isSafeNumber('123.45678901234567890')); // false
146
- console.log(isSafeNumber('123.45678901234567890', { approx: true, requiredDigits: 16 })); // true
192
+ console.log(isSafeNumber('12345678901234567890')); // false (too large for JavaScript's number type)
193
+ console.log(isSafeNumber('123.45678901234567890')); // false (too many significant digits)
194
+
195
+ // With options
196
+ console.log(isSafeNumber('123.45678901234567890', {
197
+ approx: true, // Allow approximate representation
198
+ requiredDigits: 16 // Require at least 16 digits of precision
199
+ })); // true
147
200
  ```
148
201
 
149
202
  #### `getUnsafeReason(value)`
@@ -151,11 +204,11 @@ console.log(isSafeNumber('123.45678901234567890', { approx: true, requiredDigits
151
204
  Explains why a number represented by a string is unsafe, returning one of the
152
205
  following reasons:
153
206
 
154
- - `'overflow'`
155
- - `'underflow'`
156
- - `'truncate_integer'`
157
- - `'truncate_float'`
158
- - `'none'`: when the value is safe
207
+ - `'overflow'`: The number is too large to be represented in JavaScript
208
+ - `'underflow'`: The number is too small to be represented in JavaScript
209
+ - `'truncate_integer'`: The integer part would be truncated if converted to a JavaScript number
210
+ - `'truncate_float'`: The floating-point part would lose precision if converted to a JavaScript number
211
+ - `'none'`: The value is safe to convert to a JavaScript number
159
212
 
160
213
  ```javascript
161
214
  import { getUnsafeReason } from '@qubit-ltd/json';
@@ -170,7 +223,7 @@ console.log(getUnsafeReason('1e-324')); // Output: 'underflow'
170
223
  #### `toSafeNumberOrThrow(value, options)`
171
224
 
172
225
  Converts a string into a number if it is safe to do so. Throws an error if the
173
- number is unsafe, explaining the reason.
226
+ number is unsafe, explaining the reason. This is useful for validating numeric inputs.
174
227
 
175
228
  ```javascript
176
229
  import { toSafeNumberOrThrow } from '@qubit-ltd/json';
@@ -181,7 +234,93 @@ try {
181
234
  console.error(e.message); // Output: 'Cannot safely convert to number: the value '-12345678901234567890' would truncate integer and become -12345678901234567000'
182
235
  }
183
236
 
237
+ // Safe conversion example
184
238
  console.log(toSafeNumberOrThrow('9007199254740991')); // Output: 9007199254740991
239
+
240
+ // With options
241
+ try {
242
+ console.log(toSafeNumberOrThrow('123.45678901234567890', {
243
+ approx: false, // Do not allow approximate representation
244
+ requiredDigits: 20 // Require at least 20 digits of precision
245
+ }));
246
+ } catch (e) {
247
+ console.error(e.message); // Will throw error about precision loss
248
+ }
249
+ ```
250
+
251
+ ## Advanced Usage
252
+
253
+ ### Custom Parsing Options
254
+
255
+ You can customize how numbers are parsed using options:
256
+
257
+ ```javascript
258
+ import Json from '@qubit-ltd/json';
259
+
260
+ const json = '{"bigInt": 9007199254740993, "largeFloat": 1.234567890123456789}';
261
+
262
+ // Use custom parsing options
263
+ const result = Json.parse(json, {
264
+ useBigInt: true, // Default is true - convert large integers to BigInt
265
+ losslessNumbers: true, // Default is true - use LosslessNumber for high-precision floats
266
+ });
267
+
268
+ console.log(typeof result.bigInt); // 'bigint'
269
+ console.log(result.bigInt); // 9007199254740993n
270
+ console.log(result.largeFloat); // LosslessNumber { value: '1.234567890123456789' }
271
+
272
+ // Disable custom number handling
273
+ const standardResult = Json.parse(json, {
274
+ useBigInt: false,
275
+ losslessNumbers: false,
276
+ });
277
+
278
+ console.log(typeof standardResult.bigInt); // 'number'
279
+ console.log(standardResult.bigInt); // 9007199254740992 (precision loss!)
280
+ console.log(standardResult.largeFloat); // 1.2345678901234568 (precision loss!)
281
+ ```
282
+
283
+ ### Custom Stringification Options
284
+
285
+ You can customize how values are stringified:
286
+
287
+ ```javascript
288
+ import Json from '@qubit-ltd/json';
289
+
290
+ const data = {
291
+ bigInt: BigInt('9007199254740993'),
292
+ largeFloat: new LosslessNumber('1.234567890123456789'),
293
+ set: new Set([1, 2, 3]),
294
+ map: new Map([['a', 1], ['b', 2]]),
295
+ };
296
+
297
+ // Default stringification (handles BigInt, LosslessNumber, Set, Map)
298
+ console.log(Json.stringify(data));
299
+ // '{"bigInt":9007199254740993,"largeFloat":"1.234567890123456789","set":[1,2,3],"map":[["a",1],["b",2]]}'
300
+
301
+ // With custom options and indentation
302
+ console.log(Json.stringify(data, null, 2));
303
+ /* Output:
304
+ {
305
+ "bigInt": 9007199254740993,
306
+ "largeFloat": "1.234567890123456789",
307
+ "set": [
308
+ 1,
309
+ 2,
310
+ 3
311
+ ],
312
+ "map": [
313
+ [
314
+ "a",
315
+ 1
316
+ ],
317
+ [
318
+ "b",
319
+ 2
320
+ ]
321
+ ]
322
+ }
323
+ */
185
324
  ```
186
325
 
187
326
  ## <span id="contributing">Contributing</span>
@@ -189,6 +328,45 @@ console.log(toSafeNumberOrThrow('9007199254740991')); // Output: 90071992547409
189
328
  If you find any issues or have suggestions for improvements, please feel free
190
329
  to open an issue or submit a pull request to the [GitHub repository].
191
330
 
331
+ ### Development Setup
332
+
333
+ 1. Clone the repository:
334
+ ```sh
335
+ git clone https://github.com/Haixing-Hu/js-json.git
336
+ cd js-json
337
+ ```
338
+
339
+ 2. Install dependencies:
340
+ ```sh
341
+ yarn install
342
+ ```
343
+
344
+ 3. Run tests:
345
+ ```sh
346
+ yarn test
347
+ ```
348
+
349
+ 4. Build the library:
350
+ ```sh
351
+ yarn build
352
+ ```
353
+
354
+ ### Release Process
355
+
356
+ 1. Update version in package.json
357
+ 2. Run tests and linting:
358
+ ```sh
359
+ yarn lint && yarn test
360
+ ```
361
+ 3. Build the library:
362
+ ```sh
363
+ yarn build:all
364
+ ```
365
+ 4. Publish to npm:
366
+ ```sh
367
+ yarn deploy
368
+ ```
369
+
192
370
  ## <span id="license">License</span>
193
371
 
194
372
  [@qubit-ltd/json] is distributed under the Apache 2.0 license.
package/README.zh_CN.md CHANGED
@@ -16,7 +16,7 @@
16
16
  确保精度不丢失。
17
17
  - **`LosslessNumber` 处理**:对于无法在 JavaScript 中准确表示的浮点数,该库引入了 `LosslessNumber` 对象。
18
18
  这个轻量级对象以字符串形式保存完整的数值精度,允许灵活地转换为数字或 `BigInt` 进行数学运算。
19
- - **精确的字符串化**:在字符串化过程中,`BigInt` 值会作为字符串序列化,不带 n 后缀,以保持与标准 JSON 格式的兼容性。
19
+ - **精确的字符串化**:在字符串化过程中,`BigInt` 值会作为字符串序列化,不带 "n" 后缀,以保持与标准 JSON 格式的兼容性。
20
20
  同样,`LosslessNumber` 对象使用其内部字符串表示进行序列化。
21
21
  - **集合序列化**:JavaScript 原生的集合类型如 `Set` 和 `Map` 会无缝地序列化为数组,以便更好地与 JSON 结构兼容。
22
22
 
@@ -43,28 +43,58 @@ yarn add @qubit-ltd/json
43
43
  ```javascript
44
44
  import Json from '@qubit-ltd/json';
45
45
 
46
- // parse numbers outside the safe range
46
+ // 解析超出安全范围的数字
47
47
  const str1 = '{"decimal":2.370,"big_int":9123372036854000123,"big_float":2.3e+500}';
48
- const obj1 = Json.parse(text);
48
+ const obj1 = Json.parse(str1);
49
49
  console.log(obj1.decimal); // 2.37
50
50
  console.log(obj1.big_int); // 9123372036854000123n
51
51
  console.log(obj1.big_float); // LosslessNumber { value: '2.3e+500', isLosslessNumber: true }
52
52
  console.log(String(obj1.big_float)); // '2.3e+500'
53
53
 
54
- // stringify numbers outside the safe range
54
+ // 序列化超出安全范围的数字
55
55
  const json1 = Json.stringify(obj1);
56
56
  console.log(json1); // '{"decimal":2.37,"big_int":9123372036854000123,"big_float":"2.3e+500"}'
57
57
 
58
- // stringify collections
58
+ // 序列化集合类型
59
59
  const obj2 = {
60
60
  x: new Set([{ a: 1 }, { b: 2 }, { c: 3 }]),
61
61
  y: new Map([[1, { a: 2 }], [2, { b: 4 }]]),
62
62
  };
63
- const json2 = Json.stringify(obj);
63
+ const json2 = Json.stringify(obj2);
64
64
  console.log(json2); // '{"x":[{"a":1},{"b":2},{"c":3}],"y":[[1,{"a":2}],[2,{"b":4}]]}'
65
65
 
66
- const json3 = Json.stringify(obj, null, 2);
67
- console.log(json3); //
66
+ // 格式化输出(带缩进)
67
+ const json3 = Json.stringify(obj2, null, 2);
68
+ console.log(json3);
69
+ /* 输出:
70
+ {
71
+ "x": [
72
+ {
73
+ "a": 1
74
+ },
75
+ {
76
+ "b": 2
77
+ },
78
+ {
79
+ "c": 3
80
+ }
81
+ ],
82
+ "y": [
83
+ [
84
+ 1,
85
+ {
86
+ "a": 2
87
+ }
88
+ ],
89
+ [
90
+ 2,
91
+ {
92
+ "b": 4
93
+ }
94
+ ]
95
+ ]
96
+ }
97
+ */
68
98
  ```
69
99
 
70
100
  ### LosslessNumber 类
@@ -73,11 +103,25 @@ console.log(json3); //
73
103
 
74
104
  ```javascript
75
105
  import Json from '@qubit-ltd/json';
106
+ import { LosslessNumber } from '@qubit-ltd/json';
107
+
108
+ // 解析高精度数字
76
109
  const parsed = Json.parse('{"float": 1.234567891234567891234}');
77
110
  console.log(parsed.float); // LosslessNumber { value: '1.234567891234567891234' }
78
111
 
79
- // Convert LosslessNumber to standard number
80
- console.log(parsed.float.valueOf()); // 1.2345678912345679 (standard JS number)
112
+ // LosslessNumber 转换为标准数字
113
+ console.log(parsed.float.valueOf()); // 1.2345678912345679(标准 JS 数字,有精度损失)
114
+
115
+ // 直接创建 LosslessNumber
116
+ const largeNumber = new LosslessNumber('9876543210.123456789012345678901234567890');
117
+ console.log(largeNumber.toString()); // '9876543210.123456789012345678901234567890'
118
+ console.log(largeNumber.valueOf()); // 9876543210.123457(标准 JS 数字,有精度损失)
119
+
120
+ // 数学运算
121
+ const num1 = new LosslessNumber('1234567890.123456789');
122
+ const num2 = 100;
123
+ // 对于数学运算,LosslessNumber 会转换为标准数字(可能有精度损失)
124
+ console.log(num1 * num2); // 123456789012.34578
81
125
  ```
82
126
 
83
127
  ### 实用函数
@@ -104,6 +148,8 @@ import { isInteger } from '@qubit-ltd/json';
104
148
 
105
149
  console.log(isInteger('12345')); // true
106
150
  console.log(isInteger('123.45')); // false
151
+ console.log(isInteger('123e5')); // true(12300000 是整数)
152
+ console.log(isInteger('123e-5')); // false(0.00123 不是整数)
107
153
  ```
108
154
 
109
155
  #### `isNumber(value)`
@@ -117,6 +163,8 @@ console.log(isNumber('12345')); // true
117
163
  console.log(isNumber('-123.45')); // true
118
164
  console.log(isNumber('1.23e-11')); // true
119
165
  console.log(isNumber('abc')); // false
166
+ console.log(isNumber('123abc')); // false
167
+ console.log(isNumber('0xFF')); // false(不支持十六进制表示法)
120
168
  ```
121
169
 
122
170
  #### `isSafeNumber(value, options)`
@@ -127,34 +175,39 @@ console.log(isNumber('abc')); // false
127
175
  import { isSafeNumber } from '@qubit-ltd/json';
128
176
 
129
177
  console.log(isSafeNumber('12345')); // true
130
- console.log(isSafeNumber('12345678901234567890')); // false
131
- console.log(isSafeNumber('123.45678901234567890')); // false
132
- console.log(isSafeNumber('123.45678901234567890', { approx: true, requiredDigits: 16 })); // true
178
+ console.log(isSafeNumber('12345678901234567890')); // false(对于 JavaScript 的数字类型来说太大)
179
+ console.log(isSafeNumber('123.45678901234567890')); // false(有效数字太多)
180
+
181
+ // 使用选项
182
+ console.log(isSafeNumber('123.45678901234567890', {
183
+ approx: true, // 允许近似表示
184
+ requiredDigits: 16 // 要求至少保留 16 位有效数字精度
185
+ })); // true
133
186
  ```
134
187
 
135
188
  #### `getUnsafeReason(value)`
136
189
 
137
190
  解释为什么由字符串表示的数字不安全,返回以下原因之一:
138
191
 
139
- - `'overflow'`(溢出)
140
- - `'underflow'`(下溢)
141
- - `'truncate_integer'`(整数截断)
142
- - `'truncate_float'`(浮点数截断)
143
- - `'none'`:当值是安全时
192
+ - `'overflow'`(溢出):数字太大,超出了 JavaScript 可表示的范围
193
+ - `'underflow'`(下溢):数字太小,低于 JavaScript 可表示的范围
194
+ - `'truncate_integer'`(整数截断):如果转换为 JavaScript 数字,整数部分会被截断
195
+ - `'truncate_float'`(浮点数截断):如果转换为 JavaScript 数字,浮点部分会失去精度
196
+ - `'none'`:值是安全的,可以安全地转换为 JavaScript 数字
144
197
 
145
198
  ```javascript
146
199
  import { getUnsafeReason } from '@qubit-ltd/json';
147
200
 
148
- console.log(getUnsafeReason('12345')); // Output: 'none'
149
- console.log(getUnsafeReason('12345678901234567890')); // Output: 'truncate_integer'
150
- console.log(getUnsafeReason('-12345678901234567890.123')); // Output: 'truncate_float'
151
- console.log(getUnsafeReason('-1e+1000')); // Output: 'overflow'
152
- console.log(getUnsafeReason('1e-324')); // Output: 'underflow'
201
+ console.log(getUnsafeReason('12345')); // 输出: 'none'
202
+ console.log(getUnsafeReason('12345678901234567890')); // 输出: 'truncate_integer'
203
+ console.log(getUnsafeReason('-12345678901234567890.123')); // 输出: 'truncate_float'
204
+ console.log(getUnsafeReason('-1e+1000')); // 输出: 'overflow'
205
+ console.log(getUnsafeReason('1e-324')); // 输出: 'underflow'
153
206
  ```
154
207
 
155
208
  #### `toSafeNumberOrThrow(value, options)`
156
209
 
157
- 如果可以安全转换,将字符串转换为数字。如果数字不安全,则抛出错误并解释原因。
210
+ 如果可以安全转换,将字符串转换为数字。如果数字不安全,则抛出错误并解释原因。这对于验证数字输入非常有用。
158
211
 
159
212
  ```javascript
160
213
  import { toSafeNumberOrThrow } from '@qubit-ltd/json';
@@ -162,16 +215,141 @@ import { toSafeNumberOrThrow } from '@qubit-ltd/json';
162
215
  try {
163
216
  console.log(toSafeNumberOrThrow('-12345678901234567890'));
164
217
  } catch (e) {
165
- console.error(e.message); // Output: 'Cannot safely convert to number: the value '-12345678901234567890' would truncate integer and become -12345678901234567000'
218
+ console.error(e.message); // 输出: 'Cannot safely convert to number: the value '-12345678901234567890' would truncate integer and become -12345678901234567000'
166
219
  }
167
220
 
168
- console.log(toSafeNumberOrThrow('9007199254740991')); // Output: 9007199254740991
221
+ // 安全转换示例
222
+ console.log(toSafeNumberOrThrow('9007199254740991')); // 输出: 9007199254740991
223
+
224
+ // 使用选项
225
+ try {
226
+ console.log(toSafeNumberOrThrow('123.45678901234567890', {
227
+ approx: false, // 不允许近似表示
228
+ requiredDigits: 20 // 要求至少保留 20 位有效数字精度
229
+ }));
230
+ } catch (e) {
231
+ console.error(e.message); // 将抛出关于精度损失的错误
232
+ }
233
+ ```
234
+
235
+ ## 高级用法
236
+
237
+ ### 自定义解析选项
238
+
239
+ 您可以使用选项自定义数字的解析方式:
240
+
241
+ ```javascript
242
+ import Json from '@qubit-ltd/json';
243
+
244
+ const json = '{"bigInt": 9007199254740993, "largeFloat": 1.234567890123456789}';
245
+
246
+ // 使用自定义解析选项
247
+ const result = Json.parse(json, {
248
+ useBigInt: true, // 默认为 true - 将大整数转换为 BigInt
249
+ losslessNumbers: true, // 默认为 true - 为高精度浮点数使用 LosslessNumber
250
+ });
251
+
252
+ console.log(typeof result.bigInt); // 'bigint'
253
+ console.log(result.bigInt); // 9007199254740993n
254
+ console.log(result.largeFloat); // LosslessNumber { value: '1.234567890123456789' }
255
+
256
+ // 禁用自定义数字处理
257
+ const standardResult = Json.parse(json, {
258
+ useBigInt: false,
259
+ losslessNumbers: false,
260
+ });
261
+
262
+ console.log(typeof standardResult.bigInt); // 'number'
263
+ console.log(standardResult.bigInt); // 9007199254740992(精度损失!)
264
+ console.log(standardResult.largeFloat); // 1.2345678901234568(精度损失!)
265
+ ```
266
+
267
+ ### 自定义字符串化选项
268
+
269
+ 您可以自定义值的字符串化方式:
270
+
271
+ ```javascript
272
+ import Json from '@qubit-ltd/json';
273
+
274
+ const data = {
275
+ bigInt: BigInt('9007199254740993'),
276
+ largeFloat: new LosslessNumber('1.234567890123456789'),
277
+ set: new Set([1, 2, 3]),
278
+ map: new Map([['a', 1], ['b', 2]]),
279
+ };
280
+
281
+ // 默认字符串化(处理 BigInt、LosslessNumber、Set、Map)
282
+ console.log(Json.stringify(data));
283
+ // '{"bigInt":9007199254740993,"largeFloat":"1.234567890123456789","set":[1,2,3],"map":[["a",1],["b",2]]}'
284
+
285
+ // 使用自定义选项和缩进
286
+ console.log(Json.stringify(data, null, 2));
287
+ /* 输出:
288
+ {
289
+ "bigInt": 9007199254740993,
290
+ "largeFloat": "1.234567890123456789",
291
+ "set": [
292
+ 1,
293
+ 2,
294
+ 3
295
+ ],
296
+ "map": [
297
+ [
298
+ "a",
299
+ 1
300
+ ],
301
+ [
302
+ "b",
303
+ 2
304
+ ]
305
+ ]
306
+ }
307
+ */
169
308
  ```
170
309
 
171
310
  ## <span id="contributing">贡献</span>
172
311
 
173
312
  如果您发现任何问题或有改进建议,请随时在 [GitHub 仓库] 上提交 issue 或 pull request。
174
313
 
314
+ ### 开发设置
315
+
316
+ 1. 克隆仓库:
317
+ ```sh
318
+ git clone https://github.com/Haixing-Hu/js-json.git
319
+ cd js-json
320
+ ```
321
+
322
+ 2. 安装依赖:
323
+ ```sh
324
+ yarn install
325
+ ```
326
+
327
+ 3. 运行测试:
328
+ ```sh
329
+ yarn test
330
+ ```
331
+
332
+ 4. 构建库:
333
+ ```sh
334
+ yarn build
335
+ ```
336
+
337
+ ### 发布流程
338
+
339
+ 1. 更新 package.json 中的版本号
340
+ 2. 运行测试和 lint 检查:
341
+ ```sh
342
+ yarn lint && yarn test
343
+ ```
344
+ 3. 构建库:
345
+ ```sh
346
+ yarn build:all
347
+ ```
348
+ 4. 发布到 npm:
349
+ ```sh
350
+ yarn deploy
351
+ ```
352
+
175
353
  ## <span id="license">许可证</span>
176
354
 
177
355
  [@qubit-ltd/json] 根据 Apache 2.0 许可证分发。详情请参阅 [LICENSE](LICENSE) 文件。
@@ -187,7 +365,7 @@ console.log(toSafeNumberOrThrow('9007199254740991')); // Output: 90071992547409
187
365
  我们对这些贡献者的工作表示感谢,这些工作对本库功能的实现起到了至关重要的作用。
188
366
 
189
367
  [@qubit-ltd/json]: https://npmjs.com/package/@qubit-ltd/json
190
- [GitHub repository]: https://github.com/Haixing-Hu/js-json
368
+ [GitHub 仓库]: https://github.com/Haixing-Hu/js-json
191
369
  [Why does JSON.parse corrupt large numbers and how to solve this?]: https://jsoneditoronline.org/indepth/parse/why-does-json-parse-corrupt-large-numbers/
192
370
  [json-bigint]: https://github.com/sidorares/json-bigint
193
371
  [lossless-json]: https://github.com/josdejong/lossless-json