@raoh/core 0.9.0-dev.15.20261004151401.ge5893e0cc07d
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/LICENSE +184 -0
- package/README.md +254 -0
- package/dist/catalog.d.ts +5 -0
- package/dist/catalog.js +7 -0
- package/dist/copy.d.ts +11 -0
- package/dist/copy.js +30 -0
- package/dist/decimal.d.ts +36 -0
- package/dist/decimal.js +148 -0
- package/dist/decoder.d.ts +83 -0
- package/dist/decoder.js +178 -0
- package/dist/encode.d.ts +28 -0
- package/dist/encode.js +45 -0
- package/dist/float.d.ts +58 -0
- package/dist/float.js +257 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +14 -0
- package/dist/input.d.ts +78 -0
- package/dist/input.js +465 -0
- package/dist/issue.d.ts +85 -0
- package/dist/issue.js +130 -0
- package/dist/messages.d.ts +59 -0
- package/dist/messages.js +225 -0
- package/dist/meta.d.ts +23 -0
- package/dist/meta.js +128 -0
- package/dist/path.d.ts +48 -0
- package/dist/path.js +118 -0
- package/dist/scalars.d.ts +140 -0
- package/dist/scalars.js +427 -0
- package/dist/set.d.ts +22 -0
- package/dist/set.js +61 -0
- package/dist/structure.d.ts +153 -0
- package/dist/structure.js +397 -0
- package/dist/text.d.ts +32 -0
- package/dist/text.js +204 -0
- package/dist/wire.d.ts +36 -0
- package/dist/wire.js +92 -0
- package/package.json +54 -0
package/dist/float.js
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// IEEE 754 binary32 and binary64 values as the Raoh Specification reads and writes them.
|
|
2
|
+
import { JsonNumber } from "./input.js";
|
|
3
|
+
import { tagOf } from "./copy.js";
|
|
4
|
+
const EXACT_INTEGER = 2n ** 53n;
|
|
5
|
+
/** 10^0 to 10^22, each an exact binary64, written as literals rather than computed with `**`. */
|
|
6
|
+
const POWERS_OF_TEN = [
|
|
7
|
+
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20,
|
|
8
|
+
1e21, 1e22,
|
|
9
|
+
];
|
|
10
|
+
const FORMATS = {
|
|
11
|
+
32: { precision: 24, minExponent: -126, maxExponent: 127 },
|
|
12
|
+
64: { precision: 53, minExponent: -1022, maxExponent: 1023 },
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* A float, kept with its width, as an issue's metadata holds one: the width decides how it is
|
|
16
|
+
* written in a message, so that a float32 bound of 0.1 reads `0.1` and not the binary64 digits of
|
|
17
|
+
* the same value.
|
|
18
|
+
*/
|
|
19
|
+
export class Float {
|
|
20
|
+
value;
|
|
21
|
+
width;
|
|
22
|
+
constructor(value, width) {
|
|
23
|
+
this.value = width === 32 ? Math.fround(value) : value;
|
|
24
|
+
this.width = width;
|
|
25
|
+
}
|
|
26
|
+
get [Symbol.toStringTag]() {
|
|
27
|
+
return tagOf("Float");
|
|
28
|
+
}
|
|
29
|
+
valueOf() {
|
|
30
|
+
return this.value;
|
|
31
|
+
}
|
|
32
|
+
/** The message form: the canonical decimal, written as Java writes a float. */
|
|
33
|
+
toString() {
|
|
34
|
+
return floatMessageForm(this.value, this.width);
|
|
35
|
+
}
|
|
36
|
+
/** The observation of the float: its canonical decimal, or a tag where JSON cannot carry it. */
|
|
37
|
+
toJSON() {
|
|
38
|
+
return floatJson(this.value, this.width);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A float as the Raoh Specification observes it: its canonical decimal as a JSON number, or a
|
|
43
|
+
* tag, `{"float": "-0"}`, `{"float": "NaN"}`, `{"float": "+Infinity"}` or
|
|
44
|
+
* `{"float": "-Infinity"}`, where JSON cannot carry it.
|
|
45
|
+
*/
|
|
46
|
+
export function floatJson(value, width) {
|
|
47
|
+
if (Number.isNaN(value))
|
|
48
|
+
return { float: "NaN" };
|
|
49
|
+
if (value === Infinity)
|
|
50
|
+
return { float: "+Infinity" };
|
|
51
|
+
if (value === -Infinity)
|
|
52
|
+
return { float: "-Infinity" };
|
|
53
|
+
if (Object.is(value, -0))
|
|
54
|
+
return { float: "-0" };
|
|
55
|
+
return new JsonNumber(value === 0 ? "0" : floatMessageForm(value, width));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The float of the given width nearest to ±coefficient × 10^exponent, rounding to nearest with
|
|
59
|
+
* ties to even, once: `Infinity` (with the sign) where it rounds beyond the largest finite value.
|
|
60
|
+
* The number is read exactly, so a float32 is not rounded through a binary64 first.
|
|
61
|
+
*/
|
|
62
|
+
export function nearestFloat(negative, coefficient, exponent, width) {
|
|
63
|
+
const sign = negative ? -1 : 1;
|
|
64
|
+
if (coefficient === 0n) {
|
|
65
|
+
return negative ? -0 : 0;
|
|
66
|
+
}
|
|
67
|
+
// Clinger's fast path: an integer below 2^53 and a power of ten up to 10^22 are both exact
|
|
68
|
+
// binary64 values, so one multiplication or division rounds the number once.
|
|
69
|
+
if (width === 64 && coefficient < EXACT_INTEGER && exponent >= -22 && exponent <= 22) {
|
|
70
|
+
const digits = Number(coefficient);
|
|
71
|
+
const power = POWERS_OF_TEN[Math.abs(exponent)];
|
|
72
|
+
return sign * (exponent >= 0 ? digits * power : digits / power);
|
|
73
|
+
}
|
|
74
|
+
// Far enough beyond either end of binary64 that the answer is known without the arithmetic.
|
|
75
|
+
const magnitude = coefficient.toString().length - 1 + exponent;
|
|
76
|
+
if (magnitude > 400) {
|
|
77
|
+
return sign * Infinity;
|
|
78
|
+
}
|
|
79
|
+
if (magnitude < -400) {
|
|
80
|
+
return negative ? -0 : 0;
|
|
81
|
+
}
|
|
82
|
+
let numerator = coefficient;
|
|
83
|
+
let denominator = 1n;
|
|
84
|
+
if (exponent >= 0) {
|
|
85
|
+
numerator *= 10n ** BigInt(exponent);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
denominator = 10n ** BigInt(-exponent);
|
|
89
|
+
}
|
|
90
|
+
const { precision, minExponent, maxExponent } = FORMATS[width];
|
|
91
|
+
// The binary exponent of the leading bit: 2^e <= numerator / denominator < 2^(e+1).
|
|
92
|
+
let e = bitLength(numerator) - bitLength(denominator);
|
|
93
|
+
if (compareWithPowerOfTwo(numerator, denominator, e) < 0) {
|
|
94
|
+
e -= 1;
|
|
95
|
+
}
|
|
96
|
+
let shift = Math.max(e, minExponent) - (precision - 1);
|
|
97
|
+
let n = numerator;
|
|
98
|
+
let d = denominator;
|
|
99
|
+
if (shift >= 0) {
|
|
100
|
+
d <<= BigInt(shift);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
n <<= BigInt(-shift);
|
|
104
|
+
}
|
|
105
|
+
let mantissa = n / d;
|
|
106
|
+
const twice = 2n * (n - mantissa * d);
|
|
107
|
+
if (twice > d || (twice === d && (mantissa & 1n) === 1n)) {
|
|
108
|
+
mantissa += 1n;
|
|
109
|
+
}
|
|
110
|
+
if (mantissa === 1n << BigInt(precision)) {
|
|
111
|
+
mantissa >>= 1n;
|
|
112
|
+
shift += 1;
|
|
113
|
+
}
|
|
114
|
+
if (bitLength(mantissa) - 1 + shift > maxExponent) {
|
|
115
|
+
return sign * Infinity;
|
|
116
|
+
}
|
|
117
|
+
return sign * Number(mantissa) * 2 ** shift;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* The canonical decimal of a finite, non-zero float as `digits × 10^exponent`, with no trailing
|
|
121
|
+
* zero in `digits`: the decimal of the least length that rounds to the float, the one closest to
|
|
122
|
+
* it, ties going to the even coefficient; where one digit is enough, the closest decimal of one or
|
|
123
|
+
* two digits, so that the least float64 is `4.9E-324` rather than `5E-324`.
|
|
124
|
+
*/
|
|
125
|
+
export function canonicalDecimal(value, width) {
|
|
126
|
+
const magnitude = Math.abs(value);
|
|
127
|
+
const [numerator, denominator] = exactly(magnitude);
|
|
128
|
+
let leading = Math.floor(Math.log10(magnitude));
|
|
129
|
+
// log10 is near enough to be off by one at most; settle it exactly.
|
|
130
|
+
while (compareWithPowerOfTen(numerator, denominator, leading) < 0) {
|
|
131
|
+
leading -= 1;
|
|
132
|
+
}
|
|
133
|
+
while (compareWithPowerOfTen(numerator, denominator, leading + 1) >= 0) {
|
|
134
|
+
leading += 1;
|
|
135
|
+
}
|
|
136
|
+
for (let length = 1; length <= 17; length += 1) {
|
|
137
|
+
const grid = leading - length + 1;
|
|
138
|
+
const coefficient = nearestOnGrid(numerator, denominator, grid);
|
|
139
|
+
if (nearestFloat(false, coefficient, grid, width) !== magnitude) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (length > 1) {
|
|
143
|
+
return stripped(coefficient, grid);
|
|
144
|
+
}
|
|
145
|
+
// One digit reaches the float, so two may come closer, and the closest of those is
|
|
146
|
+
// as close as any decimal of one or two digits.
|
|
147
|
+
return stripped(nearestOnGrid(numerator, denominator, grid - 1), grid - 1);
|
|
148
|
+
}
|
|
149
|
+
throw new Error(`no decimal of up to 17 digits rounds to ${value}`);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* The message form of a float: its canonical decimal, plain with at least one digit after the
|
|
153
|
+
* point where the first digit's exponent is from -3 to 6, and otherwise one digit, a point, the
|
|
154
|
+
* others (at least one), `E` and the exponent; `0.0`, `-0.0`, `NaN`, `Infinity`, `-Infinity`.
|
|
155
|
+
*/
|
|
156
|
+
export function floatMessageForm(value, width) {
|
|
157
|
+
if (Number.isNaN(value)) {
|
|
158
|
+
return "NaN";
|
|
159
|
+
}
|
|
160
|
+
if (value === Infinity) {
|
|
161
|
+
return "Infinity";
|
|
162
|
+
}
|
|
163
|
+
if (value === -Infinity) {
|
|
164
|
+
return "-Infinity";
|
|
165
|
+
}
|
|
166
|
+
if (value === 0) {
|
|
167
|
+
return Object.is(value, -0) ? "-0.0" : "0.0";
|
|
168
|
+
}
|
|
169
|
+
const sign = value < 0 ? "-" : "";
|
|
170
|
+
const { digits, exponent } = canonicalDecimal(value, width);
|
|
171
|
+
const first = exponent + digits.length - 1;
|
|
172
|
+
if (first < -3 || first > 6) {
|
|
173
|
+
return `${sign}${digits[0]}.${digits.slice(1) || "0"}E${first}`;
|
|
174
|
+
}
|
|
175
|
+
if (exponent >= 0) {
|
|
176
|
+
return `${sign}${digits}${"0".repeat(exponent)}.0`;
|
|
177
|
+
}
|
|
178
|
+
const point = digits.length + exponent;
|
|
179
|
+
if (point > 0) {
|
|
180
|
+
return `${sign}${digits.slice(0, point)}.${digits.slice(point)}`;
|
|
181
|
+
}
|
|
182
|
+
return `${sign}0.${"0".repeat(-point)}${digits}`;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* -1, 0 or 1 as `a` comes before, with or after `b` in the float order of the value model: -∞,
|
|
186
|
+
* the negative values, -0, +0, the positive values, +∞, and last NaN.
|
|
187
|
+
*/
|
|
188
|
+
export function compareFloats(a, b) {
|
|
189
|
+
const aNaN = Number.isNaN(a);
|
|
190
|
+
const bNaN = Number.isNaN(b);
|
|
191
|
+
if (aNaN || bNaN) {
|
|
192
|
+
return aNaN === bNaN ? 0 : aNaN ? 1 : -1;
|
|
193
|
+
}
|
|
194
|
+
if (a !== b) {
|
|
195
|
+
return a < b ? -1 : 1;
|
|
196
|
+
}
|
|
197
|
+
if (a === 0) {
|
|
198
|
+
const aNegative = Object.is(a, -0);
|
|
199
|
+
return aNegative === Object.is(b, -0) ? 0 : aNegative ? -1 : 1;
|
|
200
|
+
}
|
|
201
|
+
return 0;
|
|
202
|
+
}
|
|
203
|
+
/** Whether the two are the same float: +0 and -0 differ, and NaN is NaN. */
|
|
204
|
+
export function sameFloat(a, b) {
|
|
205
|
+
return Object.is(a, b);
|
|
206
|
+
}
|
|
207
|
+
function bitLength(n) {
|
|
208
|
+
return n === 0n ? 0 : n.toString(2).length;
|
|
209
|
+
}
|
|
210
|
+
/** The sign of numerator / denominator - 2^e. */
|
|
211
|
+
function compareWithPowerOfTwo(numerator, denominator, e) {
|
|
212
|
+
const left = e >= 0 ? numerator : numerator << BigInt(-e);
|
|
213
|
+
const right = e >= 0 ? denominator << BigInt(e) : denominator;
|
|
214
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
215
|
+
}
|
|
216
|
+
/** The sign of numerator / denominator - 10^e. */
|
|
217
|
+
function compareWithPowerOfTen(numerator, denominator, e) {
|
|
218
|
+
const left = e >= 0 ? numerator : numerator * 10n ** BigInt(-e);
|
|
219
|
+
const right = e >= 0 ? denominator * 10n ** BigInt(e) : denominator;
|
|
220
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
221
|
+
}
|
|
222
|
+
/** A finite, positive binary64 as an exact fraction. */
|
|
223
|
+
function exactly(magnitude) {
|
|
224
|
+
const view = new DataView(new ArrayBuffer(8));
|
|
225
|
+
view.setFloat64(0, magnitude);
|
|
226
|
+
const bits = view.getBigUint64(0);
|
|
227
|
+
const biased = Number((bits >> 52n) & 0x7ffn);
|
|
228
|
+
const fraction = bits & ((1n << 52n) - 1n);
|
|
229
|
+
const mantissa = biased === 0 ? fraction : fraction | (1n << 52n);
|
|
230
|
+
const exponent = (biased === 0 ? 1 : biased) - 1075;
|
|
231
|
+
return exponent >= 0 ? [mantissa << BigInt(exponent), 1n] : [mantissa, 1n << BigInt(-exponent)];
|
|
232
|
+
}
|
|
233
|
+
/** The integer nearest numerator / (denominator × 10^grid), ties to even. */
|
|
234
|
+
function nearestOnGrid(numerator, denominator, grid) {
|
|
235
|
+
let n = numerator;
|
|
236
|
+
let d = denominator;
|
|
237
|
+
if (grid >= 0) {
|
|
238
|
+
d *= 10n ** BigInt(grid);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
n *= 10n ** BigInt(-grid);
|
|
242
|
+
}
|
|
243
|
+
let q = n / d;
|
|
244
|
+
const twice = 2n * (n - q * d);
|
|
245
|
+
if (twice > d || (twice === d && (q & 1n) === 1n)) {
|
|
246
|
+
q += 1n;
|
|
247
|
+
}
|
|
248
|
+
return q;
|
|
249
|
+
}
|
|
250
|
+
function stripped(coefficient, exponent) {
|
|
251
|
+
let digits = coefficient.toString();
|
|
252
|
+
while (digits.length > 1 && digits.endsWith("0")) {
|
|
253
|
+
digits = digits.slice(0, -1);
|
|
254
|
+
exponent += 1;
|
|
255
|
+
}
|
|
256
|
+
return { digits, exponent };
|
|
257
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { Decimal } from "./decimal.ts";
|
|
2
|
+
export { Chain, Decoder, type Run, decoder, nullable, recover, recoverWith, withDefault } from "./decoder.ts";
|
|
3
|
+
export * as encode from "./encode.ts";
|
|
4
|
+
export { Float, type Width } from "./float.ts";
|
|
5
|
+
export { JsonNumber, type Kind, kindOf, parse, stringify } from "./input.ts";
|
|
6
|
+
export { Issue, type IssueInit, Issues, type Failed, type Ok, type Result, failed, ok } from "./issue.ts";
|
|
7
|
+
export { INVALID_FORMAT_JSON, type MessageResolver, Messages } from "./messages.ts";
|
|
8
|
+
export { messageForm, same } from "./meta.ts";
|
|
9
|
+
export { Path, type Segment } from "./path.ts";
|
|
10
|
+
export { BoolDecoder, BoundedDecoder, DecimalDecoder, DoubleDecoder, FloatDecoder, IntDecoder, LongDecoder, StringDecoder, bool, decimal, double, float, int, long, string, } from "./scalars.ts";
|
|
11
|
+
export { ValueSet } from "./set.ts";
|
|
12
|
+
export { type IssueWire, issueWire, type Wire } from "./wire.ts";
|
|
13
|
+
export { ABSENT, DictDecoder, Field, ListDecoder, NULL, ObjectDecoder, type Presence, type ReadWith, dict, discriminate, discriminateBy, enumOf, field, flat, list, literal, object, oneOf, optionalField, optionalNullableField, presentWith, strict, } from "./structure.ts";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Raoh for TypeScript: decoders that turn untyped boundary input into typed domain values.
|
|
2
|
+
export { Decimal } from "./decimal.js";
|
|
3
|
+
export { Chain, Decoder, decoder, nullable, recover, recoverWith, withDefault } from "./decoder.js";
|
|
4
|
+
export * as encode from "./encode.js";
|
|
5
|
+
export { Float } from "./float.js";
|
|
6
|
+
export { JsonNumber, kindOf, parse, stringify } from "./input.js";
|
|
7
|
+
export { Issue, Issues, failed, ok } from "./issue.js";
|
|
8
|
+
export { INVALID_FORMAT_JSON, Messages } from "./messages.js";
|
|
9
|
+
export { messageForm, same } from "./meta.js";
|
|
10
|
+
export { Path } from "./path.js";
|
|
11
|
+
export { BoolDecoder, BoundedDecoder, DecimalDecoder, DoubleDecoder, FloatDecoder, IntDecoder, LongDecoder, StringDecoder, bool, decimal, double, float, int, long, string, } from "./scalars.js";
|
|
12
|
+
export { ValueSet } from "./set.js";
|
|
13
|
+
export { issueWire } from "./wire.js";
|
|
14
|
+
export { ABSENT, DictDecoder, Field, ListDecoder, NULL, ObjectDecoder, dict, discriminate, discriminateBy, enumOf, field, flat, list, literal, object, oneOf, optionalField, optionalNullableField, presentWith, strict, } from "./structure.js";
|
package/dist/input.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/** A number of the input model: the text it is written with. */
|
|
2
|
+
export declare class JsonNumber {
|
|
3
|
+
readonly lexeme: string;
|
|
4
|
+
constructor(lexeme: string);
|
|
5
|
+
get [Symbol.toStringTag](): string;
|
|
6
|
+
toString(): string;
|
|
7
|
+
/**
|
|
8
|
+
* The number for `JSON.stringify` to write as this text. Where the engine has no
|
|
9
|
+
* `JSON.rawJSON`, a JavaScript number is given in its place only where the text it is written
|
|
10
|
+
* as denotes the same number; for one it would change, such as an integer beyond 2^53, this
|
|
11
|
+
* throws rather than write another number.
|
|
12
|
+
*/
|
|
13
|
+
toJSON(): unknown;
|
|
14
|
+
}
|
|
15
|
+
/** The kinds of value of the input model, and `missing` for no value at all. */
|
|
16
|
+
export type Kind = "null" | "boolean" | "number" | "string" | "array" | "object" | "missing";
|
|
17
|
+
/**
|
|
18
|
+
* The kind of `value`, as an issue's `actual` names it.
|
|
19
|
+
*
|
|
20
|
+
* This is where a JavaScript value is read as a value of the input model, for a decoder and for
|
|
21
|
+
* {@link stringify} alike. A string is one only where it is a sequence of Unicode scalar values;
|
|
22
|
+
* an object is a `Map` of string keys, or an object whose data are its own properties, plain or an
|
|
23
|
+
* instance of a class of the program's. A value that holds its data elsewhere — a `Date`, a `Set`,
|
|
24
|
+
* a `String` or `Number` object, a typed array, a function — is no value of the input model, and
|
|
25
|
+
* reading it as an object of no members, or of its characters, would read something it is not.
|
|
26
|
+
*
|
|
27
|
+
* @throws {TypeError} for a value that is no value of the input model
|
|
28
|
+
*/
|
|
29
|
+
export declare function kindOf(value: unknown): Kind;
|
|
30
|
+
/**
|
|
31
|
+
* The elements of an array of the input model, in order.
|
|
32
|
+
*
|
|
33
|
+
* @throws {TypeError} for an array with a hole, a place no value is at, which no JSON text writes
|
|
34
|
+
*/
|
|
35
|
+
export declare function elementsOf(value: readonly unknown[]): unknown[];
|
|
36
|
+
/** Whether `value` is an object of the input model. */
|
|
37
|
+
export declare function isObject(value: unknown): value is object;
|
|
38
|
+
/**
|
|
39
|
+
* The lexeme of a number of the input model; `undefined` for a JavaScript number that no JSON
|
|
40
|
+
* text writes (NaN or an infinity). An integer is written in full, as `BigInt` writes it, so that
|
|
41
|
+
* 1e21 read by `JSON.parse` is still an integer to an integer decoder. A `Decimal` is written at its
|
|
42
|
+
* scale, so that `decimal()` reads back the decimal it is, trailing zeros and all.
|
|
43
|
+
*/
|
|
44
|
+
export declare function lexemeOf(value: unknown): string | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* The members of an object of the input model, in order; a member whose value is `undefined` is
|
|
47
|
+
* absent.
|
|
48
|
+
*
|
|
49
|
+
* @throws {TypeError} for a `Map` with a key that is not a string, and for a name that is not a
|
|
50
|
+
* sequence of Unicode scalar values: no JSON text names a member so
|
|
51
|
+
*/
|
|
52
|
+
export declare function membersOf(value: object): [string, unknown][];
|
|
53
|
+
/** The member of an object of the input model, or `undefined` where it is absent. */
|
|
54
|
+
export declare function memberOf(value: object, name: string): unknown;
|
|
55
|
+
/**
|
|
56
|
+
* Reads a JSON text (RFC 8259) into the input model: every number a {@link JsonNumber} holding its
|
|
57
|
+
* lexeme, and every object a `Map` holding its members in the order written.
|
|
58
|
+
*
|
|
59
|
+
* @throws {SyntaxError} where the text is not JSON, an object repeats a member name, or a string
|
|
60
|
+
* holds an unpaired surrogate, none of which is in the input model
|
|
61
|
+
*/
|
|
62
|
+
export declare function parse(text: string): unknown;
|
|
63
|
+
/**
|
|
64
|
+
* Writes a value of the input model as JSON text, as {@link parse} reads it back: every number as
|
|
65
|
+
* its lexeme, and every object's members in their order, a `Map`'s as it holds them. This is how
|
|
66
|
+
* a value is handed on to what reads JSON text and not JavaScript values, such as a module across
|
|
67
|
+
* a boundary, without a number rounded or a member moved: `JSON.stringify` writes a `Map` as `{}`
|
|
68
|
+
* and an object's integer-like member names before its others.
|
|
69
|
+
*
|
|
70
|
+
* What it writes, `parse` reads, as the value it was: a value is read as {@link kindOf} reads one,
|
|
71
|
+
* the same way a decoder reads it, so what the input model has no place for is refused here rather
|
|
72
|
+
* than written as text `parse` refuses or as some other value.
|
|
73
|
+
*
|
|
74
|
+
* @throws {TypeError} for `undefined` where a value has to be, a hole in an array, a number that is
|
|
75
|
+
* NaN or an infinity, a string or member name holding an unpaired surrogate, and any value that
|
|
76
|
+
* is no value of the input model
|
|
77
|
+
*/
|
|
78
|
+
export declare function stringify(value: unknown): string;
|