@fable-org/fable-library-js 2.0.0-beta.1 → 2.0.0-beta.3

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/Async.d.ts CHANGED
@@ -20,8 +20,7 @@ export declare function ignore<T>(computation: Async<T>): (ctx: IAsyncContext<un
20
20
  export declare function parallel<T>(computations: Iterable<Async<T>>): (ctx: IAsyncContext<Awaited<T>[]>) => void;
21
21
  export declare function sequential<T>(computations: Iterable<Async<T>>): (ctx: IAsyncContext<T[]>) => void;
22
22
  export declare function sleep(millisecondsDueTime: number): (ctx: IAsyncContext<void>) => void;
23
- export declare function runSynchronously(): never;
24
23
  export declare function start<T>(computation: Async<T>, cancellationToken?: CancellationToken): void;
25
24
  export declare function startImmediate<T>(computation: Async<T>, cancellationToken?: CancellationToken): void;
26
- export declare function startWithContinuations<T>(computation: Async<T>, continuation?: Continuation<T> | CancellationToken, exceptionContinuation?: Continuation<any>, cancellationContinuation?: Continuation<any>, cancelToken?: CancellationToken): void;
25
+ export declare function startWithContinuations<T>(computation: Async<T>, continuation: Continuation<T>, exceptionContinuation: Continuation<any>, cancellationContinuation: Continuation<any>, cancelToken?: CancellationToken): void;
27
26
  export declare function startAsPromise<T>(computation: Async<T>, cancellationToken?: CancellationToken): Promise<T>;
package/Async.js CHANGED
@@ -124,25 +124,18 @@ export function sleep(millisecondsDueTime) {
124
124
  });
125
125
  });
126
126
  }
127
- export function runSynchronously() {
128
- throw new Error("Asynchronous code cannot be run synchronously in JS");
129
- }
130
127
  export function start(computation, cancellationToken) {
131
- return startWithContinuations(computation, cancellationToken);
128
+ return startWithContinuations(computation, emptyContinuation, function (err) { throw err; }, emptyContinuation, cancellationToken);
132
129
  }
133
130
  export function startImmediate(computation, cancellationToken) {
134
131
  return start(computation, cancellationToken);
135
132
  }
136
133
  export function startWithContinuations(computation, continuation, exceptionContinuation, cancellationContinuation, cancelToken) {
137
- if (typeof continuation !== "function") {
138
- cancelToken = continuation;
139
- continuation = undefined;
140
- }
141
134
  const trampoline = new Trampoline();
142
135
  computation({
143
136
  onSuccess: continuation ? continuation : emptyContinuation,
144
- onError: exceptionContinuation ? exceptionContinuation : emptyContinuation,
145
- onCancel: cancellationContinuation ? cancellationContinuation : emptyContinuation,
137
+ onError: exceptionContinuation,
138
+ onCancel: cancellationContinuation,
146
139
  cancelToken: cancelToken ? cancelToken : defaultCancellationToken,
147
140
  trampoline,
148
141
  });
package/BigInt.d.ts CHANGED
@@ -80,6 +80,8 @@ export declare function fromChar(c: string): bigint;
80
80
  export declare function fromString(s: string): bigint;
81
81
  export declare function fromByteArray(bytes: ArrayLike<uint8>): bigint;
82
82
  export declare function toByteArray(value: bigint): number[];
83
+ export declare function toIntN_unchecked(bits: number, x: bigint, signed: boolean): bigint;
84
+ export declare function toIntN(bits: number, x: bigint, signed: boolean): bigint;
83
85
  export declare function toInt8(x: bigint): int8;
84
86
  export declare function toUInt8(x: bigint): uint8;
85
87
  export declare function toInt16(x: bigint): int16;
@@ -92,7 +94,19 @@ export declare function toInt128(x: bigint): int128;
92
94
  export declare function toUInt128(x: bigint): uint128;
93
95
  export declare function toNativeInt(x: bigint): nativeint;
94
96
  export declare function toUNativeInt(x: bigint): unativeint;
95
- export declare function toFloat16(x: bigint): float32;
97
+ export declare function toInt8_unchecked(x: bigint): int8;
98
+ export declare function toUInt8_unchecked(x: bigint): uint8;
99
+ export declare function toInt16_unchecked(x: bigint): int16;
100
+ export declare function toUInt16_unchecked(x: bigint): uint16;
101
+ export declare function toInt32_unchecked(x: bigint): int32;
102
+ export declare function toUInt32_unchecked(x: bigint): uint32;
103
+ export declare function toInt64_unchecked(x: bigint): int64;
104
+ export declare function toUInt64_unchecked(x: bigint): uint64;
105
+ export declare function toInt128_unchecked(x: bigint): int128;
106
+ export declare function toUInt128_unchecked(x: bigint): uint128;
107
+ export declare function toNativeInt_unchecked(x: bigint): nativeint;
108
+ export declare function toUNativeInt_unchecked(x: bigint): unativeint;
109
+ export declare function toFloat16(x: bigint): float16;
96
110
  export declare function toFloat32(x: bigint): float32;
97
111
  export declare function toFloat64(x: bigint): float64;
98
112
  export declare function toDecimal(x: bigint): decimal;
package/BigInt.js CHANGED
@@ -95,18 +95,41 @@ export function fromByteArray(bytes) {
95
95
  export function toByteArray(value) {
96
96
  return toSignedBytes(value, isBigEndian);
97
97
  }
98
- export function toInt8(x) { return Number(BigInt.asIntN(8, x)); }
99
- export function toUInt8(x) { return Number(BigInt.asUintN(8, x)); }
100
- export function toInt16(x) { return Number(BigInt.asIntN(16, x)); }
101
- export function toUInt16(x) { return Number(BigInt.asUintN(16, x)); }
102
- export function toInt32(x) { return Number(BigInt.asIntN(32, x)); }
103
- export function toUInt32(x) { return Number(BigInt.asUintN(32, x)); }
104
- export function toInt64(x) { return BigInt.asIntN(64, x); }
105
- export function toUInt64(x) { return BigInt.asUintN(64, x); }
106
- export function toInt128(x) { return BigInt.asIntN(128, x); }
107
- export function toUInt128(x) { return BigInt.asUintN(128, x); }
108
- export function toNativeInt(x) { return BigInt.asIntN(64, x); }
109
- export function toUNativeInt(x) { return BigInt.asUintN(64, x); }
98
+ export function toIntN_unchecked(bits, x, signed) {
99
+ return signed ? BigInt.asIntN(bits, x) : BigInt.asUintN(bits, x);
100
+ }
101
+ export function toIntN(bits, x, signed) {
102
+ let higher_bits = abs(x) >> BigInt(bits);
103
+ if (higher_bits !== 0n) {
104
+ const s = signed ? "a signed" : "an unsigned";
105
+ throw new Error(`Value was either too large or too small for ${s} ${bits}-bit integer.`);
106
+ }
107
+ return signed ? BigInt.asIntN(bits, x) : BigInt.asUintN(bits, x);
108
+ }
109
+ export function toInt8(x) { return Number(toIntN(8, x, true)); }
110
+ export function toUInt8(x) { return Number(toIntN(8, x, false)); }
111
+ export function toInt16(x) { return Number(toIntN(16, x, true)); }
112
+ export function toUInt16(x) { return Number(toIntN(16, x, false)); }
113
+ export function toInt32(x) { return Number(toIntN(32, x, true)); }
114
+ export function toUInt32(x) { return Number(toIntN(32, x, false)); }
115
+ export function toInt64(x) { return toIntN(64, x, true); }
116
+ export function toUInt64(x) { return toIntN(64, x, false); }
117
+ export function toInt128(x) { return toIntN(128, x, true); }
118
+ export function toUInt128(x) { return toIntN(128, x, false); }
119
+ export function toNativeInt(x) { return toIntN(64, x, true); }
120
+ export function toUNativeInt(x) { return toIntN(64, x, false); }
121
+ export function toInt8_unchecked(x) { return Number(toIntN_unchecked(8, x, true)); }
122
+ export function toUInt8_unchecked(x) { return Number(toIntN_unchecked(8, x, false)); }
123
+ export function toInt16_unchecked(x) { return Number(toIntN_unchecked(16, x, true)); }
124
+ export function toUInt16_unchecked(x) { return Number(toIntN_unchecked(16, x, false)); }
125
+ export function toInt32_unchecked(x) { return Number(toIntN_unchecked(32, x, true)); }
126
+ export function toUInt32_unchecked(x) { return Number(toIntN_unchecked(32, x, false)); }
127
+ export function toInt64_unchecked(x) { return toIntN_unchecked(64, x, true); }
128
+ export function toUInt64_unchecked(x) { return toIntN_unchecked(64, x, false); }
129
+ export function toInt128_unchecked(x) { return toIntN_unchecked(128, x, true); }
130
+ export function toUInt128_unchecked(x) { return toIntN_unchecked(128, x, false); }
131
+ export function toNativeInt_unchecked(x) { return toIntN_unchecked(64, x, true); }
132
+ export function toUNativeInt_unchecked(x) { return toIntN_unchecked(64, x, false); }
110
133
  export function toFloat16(x) { return Number(x); }
111
134
  export function toFloat32(x) { return Number(x); }
112
135
  export function toFloat64(x) { return Number(x); }
package/CHANGELOG.md CHANGED
@@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## Unreleased
9
9
 
10
+ ## 2.0.0-beta.3 - 2025-03-14
11
+
12
+ ### Fixed
13
+
14
+ * [JS/TS] Make `nullArgCheck` report the same error message as on .NET (by @MangelMaxime)
15
+
16
+ ## 2.0.0-beta.2 - 2025-03-03
17
+
18
+ * [JS/TS] Fix #4049: decimal/bigint to integer conversion checks (by @ncave)
19
+ * [JS/TS] Fix `decimal` to `char` conversion checks (by @ManngelMaxime)
20
+ * [JS/TS] Propagate non-captured exception when running `Async.Start` or `Async.StartImmediate` (by @MangelMaxime)
21
+ * [JS/TS] Remove `Async.RunSynchronously` (by @MangelMaxime)
22
+ * [JS/TS] Change signature of `startWithContinuations` to always require all its arguments (by @MangelMaxime)
23
+ * [JS/TS] Fix short `DateTime` and `DateTimeOffset` short format strings (by @MangelMaxime)
24
+ * [JS/TS] Add `C` and `c` format for numeric types (by @MangelMaxime)
25
+ * [JS/TS] Add `B` and `b` format for numeric types (by @MangelMaxime)
26
+ * [JS/TS] Add `n` format for numeric types (by @MangelMaxime)
27
+ * [JS/TS] Fix numeric formats (by @MangelMaxime)
28
+
10
29
  ## 2.0.0-beta.1 - 2025-02-16
11
30
 
12
31
  * Compiled with Fable 5.0.0-alpha.10
@@ -59,7 +78,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
59
78
 
60
79
  * [JS/TS] Fix escaping of `{` and `}` in FormattableString (#3890) (by @roboz0r)
61
80
  * [JS/TS] Fix `uri.Host` to return the host name without the port (by @MangelMaxime)
62
- * [JS/TS] Fix TypeScript compilation by resolving type of `jsOptions` (#3894) (by @ManngelMaxime)
81
+ * [JS/TS] Fix TypeScript compilation by resolving type of `jsOptions` (#3894) (by @MangelMaxime)
63
82
 
64
83
  ## 1.4.3 - 2024-09-04
65
84
 
package/Date.d.ts CHANGED
@@ -16,7 +16,6 @@ export declare function kind(value: IDateTime): number;
16
16
  export declare function unixEpochMillisecondsToTicks(ms: number, offset: number): int64;
17
17
  export declare function ticksToUnixEpochMilliseconds(ticks: number | bigint): number;
18
18
  export declare function dateOffsetToString(offset: number): string;
19
- export declare function dateToHalfUTCString(date: IDateTime, half: "first" | "second"): string;
20
19
  export declare function toString(date: IDateTime | IDateTimeOffset, format?: string, _provider?: any): string;
21
20
  export declare function DateTime(value: number, kind?: DateKind): IDateTime;
22
21
  export declare function fromTicks(ticks: number | bigint, kind?: DateKind): IDateTime;
package/Date.js CHANGED
@@ -91,9 +91,8 @@ function dateToStringWithCustomFormat(date, format, utc) {
91
91
  result += shortDays[dayOfWeek(localizedDate)];
92
92
  break;
93
93
  case 4:
94
- result += longDays[dayOfWeek(localizedDate)];
95
- break;
96
94
  default:
95
+ result += longDays[dayOfWeek(localizedDate)];
97
96
  break;
98
97
  }
99
98
  break;
@@ -112,6 +111,9 @@ function dateToStringWithCustomFormat(date, format, utc) {
112
111
  // DateTime(1, 2, 3, 4, 5, 6, DateTimeKind.Utc).ToString("fffff") => 00000
113
112
  result += ("" + millisecond(localizedDate)).padEnd(tokenLength, "0");
114
113
  }
114
+ else {
115
+ throw "Input string was not in a correct format.";
116
+ }
115
117
  break;
116
118
  case "F":
117
119
  tokenLength = parseRepeatToken(format, cursorPos, "F");
@@ -132,13 +134,14 @@ function dateToStringWithCustomFormat(date, format, utc) {
132
134
  result += padWithZeros(value, 3);
133
135
  }
134
136
  }
137
+ else {
138
+ throw "Input string was not in a correct format.";
139
+ }
135
140
  break;
136
141
  case "g":
137
142
  tokenLength = parseRepeatToken(format, cursorPos, "g");
138
143
  cursorPos += tokenLength;
139
- if (tokenLength <= 2) {
140
- result += "A.D.";
141
- }
144
+ result += "A.D.";
142
145
  break;
143
146
  case "h":
144
147
  tokenLength = parseRepeatToken(format, cursorPos, "h");
@@ -149,11 +152,10 @@ function dateToStringWithCustomFormat(date, format, utc) {
149
152
  result += h1Value ? h1Value : 12;
150
153
  break;
151
154
  case 2:
155
+ default:
152
156
  const h2Value = hour(localizedDate) % 12;
153
157
  result += padWithZeros(h2Value ? h2Value : 12, 2);
154
158
  break;
155
- default:
156
- break;
157
159
  }
158
160
  break;
159
161
  case "H":
@@ -164,9 +166,8 @@ function dateToStringWithCustomFormat(date, format, utc) {
164
166
  result += hour(localizedDate);
165
167
  break;
166
168
  case 2:
167
- result += padWithZeros(hour(localizedDate), 2);
168
- break;
169
169
  default:
170
+ result += padWithZeros(hour(localizedDate), 2);
170
171
  break;
171
172
  }
172
173
  break;
@@ -198,9 +199,8 @@ function dateToStringWithCustomFormat(date, format, utc) {
198
199
  result += minute(localizedDate);
199
200
  break;
200
201
  case 2:
201
- result += padWithZeros(minute(localizedDate), 2);
202
- break;
203
202
  default:
203
+ result += padWithZeros(minute(localizedDate), 2);
204
204
  break;
205
205
  }
206
206
  break;
@@ -218,9 +218,8 @@ function dateToStringWithCustomFormat(date, format, utc) {
218
218
  result += shortMonths[month(localizedDate) - 1];
219
219
  break;
220
220
  case 4:
221
- result += longMonths[month(localizedDate) - 1];
222
- break;
223
221
  default:
222
+ result += longMonths[month(localizedDate) - 1];
224
223
  break;
225
224
  }
226
225
  break;
@@ -232,9 +231,8 @@ function dateToStringWithCustomFormat(date, format, utc) {
232
231
  result += second(localizedDate);
233
232
  break;
234
233
  case 2:
235
- result += padWithZeros(second(localizedDate), 2);
236
- break;
237
234
  default:
235
+ result += padWithZeros(second(localizedDate), 2);
238
236
  break;
239
237
  }
240
238
  break;
@@ -246,9 +244,8 @@ function dateToStringWithCustomFormat(date, format, utc) {
246
244
  result += localizedDate.getHours() < 12 ? "A" : "P";
247
245
  break;
248
246
  case 2:
249
- result += localizedDate.getHours() < 12 ? "AM" : "PM";
250
- break;
251
247
  default:
248
+ result += localizedDate.getHours() < 12 ? "AM" : "PM";
252
249
  break;
253
250
  }
254
251
  break;
@@ -262,16 +259,8 @@ function dateToStringWithCustomFormat(date, format, utc) {
262
259
  case 2:
263
260
  result += padWithZeros(localizedDate.getFullYear() % 100, 2);
264
261
  break;
265
- case 3:
266
- result += padWithZeros(localizedDate.getFullYear(), 3);
267
- break;
268
- case 4:
269
- result += padWithZeros(localizedDate.getFullYear(), 4);
270
- break;
271
- case 5:
272
- result += padWithZeros(localizedDate.getFullYear(), 5);
273
- break;
274
262
  default:
263
+ result += padWithZeros(localizedDate.getFullYear(), tokenLength);
275
264
  break;
276
265
  }
277
266
  break;
@@ -365,12 +354,6 @@ export function dateOffsetToString(offset) {
365
354
  padWithZeros(hours, 2) + ":" +
366
355
  padWithZeros(minutes, 2);
367
356
  }
368
- export function dateToHalfUTCString(date, half) {
369
- const str = date.toISOString();
370
- return half === "first"
371
- ? str.substring(0, str.indexOf("T"))
372
- : str.substring(str.indexOf("T") + 1, str.length - 1);
373
- }
374
357
  function dateToISOString(d, utc) {
375
358
  if (utc) {
376
359
  return d.toISOString();
@@ -399,10 +382,10 @@ function dateToStringWithOffset(date, format) {
399
382
  }
400
383
  else if (format.length === 1) {
401
384
  switch (format) {
402
- case "D":
403
- case "d": return dateToHalfUTCString(d, "first");
404
- case "T":
405
- case "t": return dateToHalfUTCString(d, "second");
385
+ case "D": return dateToString_D(d);
386
+ case "d": return dateToString_d(d);
387
+ case "T": return dateToString_T(toUniversalTime(d));
388
+ case "t": return dateToString_t(toUniversalTime(d));
406
389
  case "O":
407
390
  case "o": return dateToISOStringWithOffset(d, (date.offset ?? 0));
408
391
  default: throw new Error("Unrecognized Date print format");
@@ -412,6 +395,26 @@ function dateToStringWithOffset(date, format) {
412
395
  return dateToStringWithCustomFormat(d, format, true);
413
396
  }
414
397
  }
398
+ function dateToString_D(date) {
399
+ return longDays[dayOfWeek(date)]
400
+ + ", " + padWithZeros(day(date), 2)
401
+ + " " + longMonths[month(date) - 1]
402
+ + " " + year(date);
403
+ }
404
+ function dateToString_d(date) {
405
+ return padWithZeros(month(date), 2)
406
+ + "/" + padWithZeros(day(date), 2)
407
+ + "/" + year(date);
408
+ }
409
+ function dateToString_T(date) {
410
+ return padWithZeros(hour(date), 2)
411
+ + ":" + padWithZeros(minute(date), 2)
412
+ + ":" + padWithZeros(second(date), 2);
413
+ }
414
+ function dateToString_t(date) {
415
+ return padWithZeros(hour(date), 2)
416
+ + ":" + padWithZeros(minute(date), 2);
417
+ }
415
418
  function dateToStringWithKind(date, format) {
416
419
  const utc = date.kind === 1 /* DateKind.UTC */;
417
420
  if (typeof format !== "string") {
@@ -419,12 +422,10 @@ function dateToStringWithKind(date, format) {
419
422
  }
420
423
  else if (format.length === 1) {
421
424
  switch (format) {
422
- case "D":
423
- case "d":
424
- return utc ? dateToHalfUTCString(date, "first") : date.toLocaleDateString();
425
- case "T":
426
- case "t":
427
- return utc ? dateToHalfUTCString(date, "second") : date.toLocaleTimeString();
425
+ case "D": return dateToString_D(date);
426
+ case "d": return dateToString_d(date);
427
+ case "T": return dateToString_T(date);
428
+ case "t": return dateToString_t(date);
428
429
  case "O":
429
430
  case "o":
430
431
  return dateToISOString(date, utc);
package/Decimal.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import Decimal from "./lib/big.js";
2
2
  import { FSharpRef } from "./Types.js";
3
+ import { int8, uint8, int16, uint16, int32, uint32, float16, float32, float64 } from "./Int32.js";
4
+ import { int64, uint64, int128, uint128, nativeint, unativeint } from "./BigInt.js";
3
5
  export default Decimal;
4
6
  export type decimal = Decimal;
5
7
  export declare const get_Zero: Decimal;
@@ -39,6 +41,22 @@ export declare function toString(x: Decimal): string;
39
41
  export declare function tryParse(str: string, defValue: FSharpRef<Decimal>): boolean;
40
42
  export declare function parse(str: string): Decimal;
41
43
  export declare function toNumber(x: Decimal): number;
44
+ export declare function toChar(x: Decimal): string;
45
+ export declare function toInt8(x: Decimal): int8;
46
+ export declare function toUInt8(x: Decimal): uint8;
47
+ export declare function toInt16(x: Decimal): int16;
48
+ export declare function toUInt16(x: Decimal): uint16;
49
+ export declare function toInt32(x: Decimal): int32;
50
+ export declare function toUInt32(x: Decimal): uint32;
51
+ export declare function toInt64(x: Decimal): int64;
52
+ export declare function toUInt64(x: Decimal): uint64;
53
+ export declare function toInt128(x: Decimal): int128;
54
+ export declare function toUInt128(x: Decimal): uint128;
55
+ export declare function toNativeInt(x: Decimal): nativeint;
56
+ export declare function toUNativeInt(x: Decimal): unativeint;
57
+ export declare function toFloat16(x: Decimal): float16;
58
+ export declare function toFloat32(x: Decimal): float32;
59
+ export declare function toFloat64(x: Decimal): float64;
42
60
  export declare function fromIntArray(bits: ArrayLike<number>): Decimal;
43
61
  export declare function fromInts(low: number, mid: number, high: number, signExp: number): Decimal;
44
62
  export declare function fromParts(low: number, mid: number, high: number, isNegative: boolean, scale: number): Decimal;
package/Decimal.js CHANGED
@@ -2,6 +2,8 @@ import Decimal from "./lib/big.js";
2
2
  import { symbol } from "./Numeric.js";
3
3
  import { FSharpRef } from "./Types.js";
4
4
  import { combineHashCodes } from "./Util.js";
5
+ import { fromDecimal } from "./BigInt.js";
6
+ import * as bigInt from "./BigInt.js";
5
7
  Decimal.prototype.GetHashCode = function () {
6
8
  return combineHashCodes([this.s, this.e].concat(this.c));
7
9
  };
@@ -113,6 +115,28 @@ export function parse(str) {
113
115
  export function toNumber(x) {
114
116
  return +x;
115
117
  }
118
+ export function toChar(x) {
119
+ const n = toNumber(x);
120
+ if (n < 0 || n > 65535 || isNaN(n)) {
121
+ throw new Error("Value was either too large or too small for a character.");
122
+ }
123
+ return String.fromCharCode(n);
124
+ }
125
+ export function toInt8(x) { return bigInt.toInt8(fromDecimal(x)); }
126
+ export function toUInt8(x) { return bigInt.toUInt8(fromDecimal(x)); }
127
+ export function toInt16(x) { return bigInt.toInt16(fromDecimal(x)); }
128
+ export function toUInt16(x) { return bigInt.toUInt16(fromDecimal(x)); }
129
+ export function toInt32(x) { return bigInt.toInt32(fromDecimal(x)); }
130
+ export function toUInt32(x) { return bigInt.toUInt32(fromDecimal(x)); }
131
+ export function toInt64(x) { return bigInt.toInt64(fromDecimal(x)); }
132
+ export function toUInt64(x) { return bigInt.toUInt64(fromDecimal(x)); }
133
+ export function toInt128(x) { return bigInt.toInt128(fromDecimal(x)); }
134
+ export function toUInt128(x) { return bigInt.toUInt128(fromDecimal(x)); }
135
+ export function toNativeInt(x) { return bigInt.toNativeInt(fromDecimal(x)); }
136
+ export function toUNativeInt(x) { return bigInt.toUNativeInt(fromDecimal(x)); }
137
+ export function toFloat16(x) { return toNumber(x); }
138
+ export function toFloat32(x) { return toNumber(x); }
139
+ export function toFloat64(x) { return toNumber(x); }
116
140
  function decimalToHex(dec, bitSize) {
117
141
  const hex = new Uint8Array(bitSize / 4 | 0);
118
142
  let hexCount = 1;
package/FSharp.Core.js CHANGED
@@ -2,6 +2,7 @@ import { disposeSafe, defaultOf, structuralHash, equals } from "./Util.js";
2
2
  import { HashIdentity_Structural, ComparisonIdentity_Structural } from "./FSharp.Collections.js";
3
3
  import { value as value_1 } from "./Option.js";
4
4
  import { FSharpChoice$2_Choice2Of2, FSharpChoice$2_Choice1Of2 } from "./Choice.js";
5
+ import { concat } from "./String.js";
5
6
  import { StringBuilder__Append_Z721C83C5 } from "./System.Text.js";
6
7
  export const LanguagePrimitives_GenericEqualityComparer = {
7
8
  "System.Collections.IEqualityComparer.Equals541DA560"(x, y) {
@@ -134,7 +135,7 @@ export function Operators_NullV() {
134
135
  }
135
136
  export function Operators_NullArgCheck(argumentName, value) {
136
137
  if (equals(value, defaultOf())) {
137
- throw new Error(argumentName);
138
+ throw new Error(concat("Value cannot be null. (Parameter \'", argumentName, ..."\')"));
138
139
  }
139
140
  else {
140
141
  return value;
package/List.d.ts CHANGED
@@ -56,7 +56,7 @@ export declare function foldBack<T, State>(folder: ((arg0: T, arg1: State) => St
56
56
  export declare function foldIndexed<State, T>(folder: ((arg0: int32, arg1: State, arg2: T) => State), state: State, xs: FSharpList<T>): State;
57
57
  export declare function fold2<T1, T2, State>(folder: ((arg0: State, arg1: T1, arg2: T2) => State), state: State, xs: FSharpList<T1>, ys: FSharpList<T2>): State;
58
58
  export declare function foldBack2<T1, T2, State>(folder: ((arg0: T1, arg1: T2, arg2: State) => State), xs: FSharpList<T1>, ys: FSharpList<T2>, state: State): State;
59
- export declare function unfold<State, T>(gen: ((arg0: State) => Option<[T, State]>), state: State): FSharpList<T>;
59
+ export declare function unfold<State, T>(generator: ((arg0: State) => Option<[T, State]>), state: State): FSharpList<T>;
60
60
  export declare function iterate<$a>(action: ((arg0: $a) => void), xs: FSharpList<$a>): void;
61
61
  export declare function iterate2<$a, $b>(action: ((arg0: $a, arg1: $b) => void), xs: FSharpList<$a>, ys: FSharpList<$b>): void;
62
62
  export declare function iterateIndexed<$a>(action: ((arg0: int32, arg1: $a) => void), xs: FSharpList<$a>): void;
package/List.js CHANGED
@@ -403,12 +403,12 @@ export function fold2(folder, state, xs, ys) {
403
403
  export function foldBack2(folder, xs, ys, state) {
404
404
  return foldBack2_1(folder, toArray(xs), toArray(ys), state);
405
405
  }
406
- export function unfold(gen, state) {
406
+ export function unfold(generator, state) {
407
407
  const loop = (acc_mut, node_mut) => {
408
408
  loop: while (true) {
409
409
  const acc = acc_mut, node = node_mut;
410
410
  let t;
411
- const matchValue = gen(acc);
411
+ const matchValue = generator(acc);
412
412
  if (matchValue != null) {
413
413
  acc_mut = value_1(matchValue)[1];
414
414
  node_mut = ((t = (new FSharpList(value_1(matchValue)[0], undefined)), (node.tail = t, t)));
package/MapUtil.js CHANGED
@@ -6,6 +6,7 @@ const CaseRules = {
6
6
  SnakeCase: 2,
7
7
  SnakeCaseAllCaps: 3,
8
8
  KebabCase: 4,
9
+ LowerAll: 5,
9
10
  };
10
11
  function dashify(str, separator) {
11
12
  return str.replace(/[a-z]?[A-Z]/g, (m) => m.length === 1
@@ -22,6 +23,8 @@ function changeCase(str, caseRule) {
22
23
  return dashify(str, "_").toUpperCase();
23
24
  case CaseRules.KebabCase:
24
25
  return dashify(str, "-");
26
+ case CaseRules.LowerAll:
27
+ return str.toLowerCase();
25
28
  case CaseRules.None:
26
29
  default:
27
30
  return str;
package/Numeric.d.ts CHANGED
@@ -11,9 +11,10 @@ export interface CustomNumeric extends IComparable<Numeric> {
11
11
  }
12
12
  export type Numeric = number | bigint | CustomNumeric;
13
13
  export declare function isNumeric(x: any): any;
14
+ export declare function isIntegral(x: Numeric): boolean;
14
15
  export declare function compare(x: Numeric, y: number): number;
15
16
  export declare function multiply(x: Numeric, y: number): Numeric;
16
- export declare function toFixed(x: Numeric, dp?: number): string | bigint;
17
- export declare function toPrecision(x: Numeric, sd?: number): string | bigint;
17
+ export declare function toFixed(x: Numeric, dp?: number): string;
18
+ export declare function toPrecision(x: Numeric, sd?: number): string;
18
19
  export declare function toExponential(x: Numeric, dp?: number): string | bigint;
19
20
  export declare function toHex(x: Numeric): string;
package/Numeric.js CHANGED
@@ -2,6 +2,10 @@ export const symbol = Symbol("numeric");
2
2
  export function isNumeric(x) {
3
3
  return typeof x === "number" || typeof x === "bigint" || x?.[symbol];
4
4
  }
5
+ export function isIntegral(x) {
6
+ // Not perfect, because in JS we can't distinguish between 1.0 and 1
7
+ return typeof x === "number" && Number.isInteger(x) || typeof x === "bigint";
8
+ }
5
9
  export function compare(x, y) {
6
10
  if (typeof x === "number") {
7
11
  return x < y ? -1 : (x > y ? 1 : 0);
@@ -29,7 +33,7 @@ export function toFixed(x, dp) {
29
33
  return x.toFixed(dp);
30
34
  }
31
35
  else if (typeof x === "bigint") {
32
- return x;
36
+ return x.toString();
33
37
  }
34
38
  else {
35
39
  return x[symbol]().toFixed(dp);
@@ -40,7 +44,7 @@ export function toPrecision(x, sd) {
40
44
  return x.toPrecision(sd);
41
45
  }
42
46
  else if (typeof x === "bigint") {
43
- return x;
47
+ return x.toString();
44
48
  }
45
49
  else {
46
50
  return x[symbol]().toPrecision(sd);
package/Random.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { class_type } from "./Reflection.js";
2
- import { fromFloat64, op_Addition, toInt32, toFloat64, compare, fromInt32, toInt64 } from "./BigInt.js";
2
+ import { fromFloat64, op_Addition, toInt32_unchecked, toFloat64, compare, fromInt32, toInt64_unchecked } from "./BigInt.js";
3
3
  import { Operators_IsNull } from "./FSharp.Core.js";
4
4
  import { item, fill, setItem } from "./Array.js";
5
5
  function Native_random() {
@@ -103,8 +103,8 @@ export class Seeded {
103
103
  if (minValue > maxValue) {
104
104
  throw new Error("minValue must be less than maxValue");
105
105
  }
106
- const range = toInt64(fromInt32(maxValue - minValue));
107
- return ((compare(range, toInt64(fromInt32(2147483647))) <= 0) ? (~~(Seeded__Sample(this$) * toFloat64(range)) + minValue) : ~~toInt32(toInt64(op_Addition(toInt64(fromFloat64(Seeded__GetSampleForLargeRange(this$) * toFloat64(range))), toInt64(fromInt32(minValue)))))) | 0;
106
+ const range = toInt64_unchecked(fromInt32(maxValue - minValue));
107
+ return ((compare(range, toInt64_unchecked(fromInt32(2147483647))) <= 0) ? (~~(Seeded__Sample(this$) * toFloat64(range)) + minValue) : ~~toInt32_unchecked(toInt64_unchecked(op_Addition(toInt64_unchecked(fromFloat64(Seeded__GetSampleForLargeRange(this$) * toFloat64(range))), toInt64_unchecked(fromInt32(minValue)))))) | 0;
108
108
  }
109
109
  NextDouble() {
110
110
  const this$ = this;
package/Range.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { compare } from "./Util.js";
2
2
  import { unfold, delay } from "./Seq.js";
3
- import { toUInt64, toInt64, op_Addition, fromZero } from "./BigInt.js";
3
+ import { toUInt64_unchecked, toInt64_unchecked, op_Addition, fromZero } from "./BigInt.js";
4
4
  import { op_Addition as op_Addition_1, fromParts } from "./Decimal.js";
5
5
  export function makeRangeStepFunction(step, stop, zero, add) {
6
6
  const stepComparedWithZero = compare(step, zero) | 0;
@@ -27,16 +27,16 @@ export function rangeDouble(start, step, stop) {
27
27
  return integralRangeStep(start, step, stop, 0, (x, y) => (x + y));
28
28
  }
29
29
  export function rangeInt64(start, step, stop) {
30
- return integralRangeStep(start, step, stop, 0n, (x, y) => toInt64(op_Addition(x, y)));
30
+ return integralRangeStep(start, step, stop, 0n, (x, y) => toInt64_unchecked(op_Addition(x, y)));
31
31
  }
32
32
  export function rangeUInt64(start, step, stop) {
33
- return integralRangeStep(start, step, stop, 0n, (x, y) => toUInt64(op_Addition(x, y)));
33
+ return integralRangeStep(start, step, stop, 0n, (x, y) => toUInt64_unchecked(op_Addition(x, y)));
34
34
  }
35
35
  export function rangeChar(start, stop) {
36
36
  const intStop = ~~stop.charCodeAt(0) | 0;
37
- return delay(() => unfold((c) => {
38
- if (c <= intStop) {
39
- return [String.fromCharCode(c), c + 1];
37
+ return delay(() => unfold((i) => {
38
+ if (i <= intStop) {
39
+ return [String.fromCharCode(i & 0xFFFF), i + 1];
40
40
  }
41
41
  else {
42
42
  return undefined;
package/Result.d.ts CHANGED
@@ -9,7 +9,7 @@ export type FSharpResult$2_$cases<T, TError> = {
9
9
  1: ["Error", [TError]];
10
10
  };
11
11
  export declare function FSharpResult$2_Ok<T, TError>(ResultValue: T): FSharpResult$2<T, TError, 0>;
12
- export declare function FSharpResult$2_Error<T, TError>(ErrorValue: TError): FSharpResult$2<T, TError, 1>;
12
+ export declare function FSharpResult$2_Error$<T, TError>(ErrorValue: TError): FSharpResult$2<T, TError, 1>;
13
13
  export declare class FSharpResult$2<T, TError, Tag extends keyof FSharpResult$2_$cases<T, TError>> extends Union<Tag, FSharpResult$2_$cases<T, TError>[Tag][0]> {
14
14
  readonly tag: Tag;
15
15
  readonly fields: FSharpResult$2_$cases<T, TError>[Tag][1];
package/Result.js CHANGED
@@ -6,7 +6,7 @@ import { some } from "./Option.js";
6
6
  export function FSharpResult$2_Ok(ResultValue) {
7
7
  return new FSharpResult$2(0, [ResultValue]);
8
8
  }
9
- export function FSharpResult$2_Error(ErrorValue) {
9
+ export function FSharpResult$2_Error$(ErrorValue) {
10
10
  return new FSharpResult$2(1, [ErrorValue]);
11
11
  }
12
12
  export class FSharpResult$2 extends Union {
@@ -27,7 +27,7 @@ export function Result_Map(mapping, result) {
27
27
  return FSharpResult$2_Ok(mapping(result.fields[0]));
28
28
  }
29
29
  else {
30
- return FSharpResult$2_Error(result.fields[0]);
30
+ return FSharpResult$2_Error$(result.fields[0]);
31
31
  }
32
32
  }
33
33
  export function Result_MapError(mapping, result) {
@@ -35,7 +35,7 @@ export function Result_MapError(mapping, result) {
35
35
  return FSharpResult$2_Ok(result.fields[0]);
36
36
  }
37
37
  else {
38
- return FSharpResult$2_Error(mapping(result.fields[0]));
38
+ return FSharpResult$2_Error$(mapping(result.fields[0]));
39
39
  }
40
40
  }
41
41
  export function Result_Bind(binder, result) {
@@ -43,7 +43,7 @@ export function Result_Bind(binder, result) {
43
43
  return binder(result.fields[0]);
44
44
  }
45
45
  else {
46
- return FSharpResult$2_Error(result.fields[0]);
46
+ return FSharpResult$2_Error$(result.fields[0]);
47
47
  }
48
48
  }
49
49
  export function Result_IsOk(result) {
package/String.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { toString as dateToString } from "./Date.js";
2
- import { compare as numericCompare, isNumeric, multiply, toExponential, toFixed, toHex, toPrecision } from "./Numeric.js";
2
+ import { compare as numericCompare, isNumeric, isIntegral, multiply, toExponential, toFixed, toHex, toPrecision } from "./Numeric.js";
3
3
  import { escape } from "./RegExp.js";
4
4
  import { toString } from "./Types.js";
5
5
  const fsFormatRegExp = /(^|[^%])%([0+\- ]*)(\*|\d+)?(?:\.(\d+))?(\w)/g;
@@ -276,6 +276,17 @@ export function fsFormat(str) {
276
276
  }
277
277
  };
278
278
  }
279
+ function splitIntAndDecimalPart(value) {
280
+ let [repInt, repDecimal] = value.split(".");
281
+ repDecimal === undefined && (repDecimal = "");
282
+ return {
283
+ integral: repInt,
284
+ decimal: repDecimal
285
+ };
286
+ }
287
+ function thousandSeparate(value) {
288
+ return value.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
289
+ }
279
290
  export function format(str, ...args) {
280
291
  let str2;
281
292
  if (typeof str === "object") {
@@ -291,39 +302,99 @@ export function format(str, ...args) {
291
302
  throw new Error("Index must be greater or equal to zero and less than the arguments' length.");
292
303
  }
293
304
  let rep = args[idx];
305
+ let parts;
294
306
  if (isNumeric(rep)) {
295
- precision = precision == null ? null : parseInt(precision, 10);
307
+ precision = precision == "" ? null : parseInt(precision, 10);
296
308
  switch (format) {
309
+ case "b":
310
+ case "B":
311
+ if (!isIntegral(rep)) {
312
+ throw new Error("Format specifier was invalid.");
313
+ }
314
+ rep = (rep >>> 0).toString(2).replace(/^0+/, "").padStart(precision || 1, "0");
315
+ break;
316
+ case "c":
317
+ case "C":
318
+ const isNegative = isLessThan(rep, 0);
319
+ if (isLessThan(rep, 0)) {
320
+ rep = multiply(rep, -1);
321
+ }
322
+ precision = precision == null ? 2 : precision;
323
+ rep = toFixed(rep, precision);
324
+ parts = splitIntAndDecimalPart(rep);
325
+ rep = "¤" + thousandSeparate(parts.integral) + "." + padRight(parts.decimal, precision, "0");
326
+ if (isNegative) {
327
+ rep = "(" + rep + ")";
328
+ }
329
+ break;
330
+ case "d":
331
+ case "D":
332
+ if (!isIntegral(rep)) {
333
+ throw new Error("Format specifier was invalid.");
334
+ }
335
+ rep = String(rep);
336
+ if (precision != null) {
337
+ if (rep.startsWith("-")) {
338
+ rep = "-" + padLeft(rep.substring(1), precision, "0");
339
+ }
340
+ else {
341
+ rep = padLeft(rep, precision, "0");
342
+ }
343
+ }
344
+ break;
345
+ case "e":
346
+ case "E":
347
+ rep = precision != null ? toExponential(rep, precision) : toExponential(rep);
348
+ break;
297
349
  case "f":
298
350
  case "F":
299
351
  precision = precision != null ? precision : 2;
300
352
  rep = toFixed(rep, precision);
353
+ if (precision > 0) {
354
+ parts = splitIntAndDecimalPart(rep);
355
+ rep = parts.integral + "." + padRight(parts.decimal, precision, "0");
356
+ }
301
357
  break;
302
358
  case "g":
303
359
  case "G":
304
360
  rep = precision != null ? toPrecision(rep, precision) : toPrecision(rep);
361
+ // TODO: Check why some numbers are formatted with decimal part
362
+ rep = trimEnd(trimEnd(rep, "0"), ".");
305
363
  break;
306
- case "e":
307
- case "E":
308
- rep = precision != null ? toExponential(rep, precision) : toExponential(rep);
364
+ case "n":
365
+ case "N":
366
+ precision = precision != null ? precision : 2;
367
+ rep = toFixed(rep, precision);
368
+ parts = splitIntAndDecimalPart(rep);
369
+ rep = thousandSeparate(parts.integral) + "." + padRight(parts.decimal, precision, "0");
309
370
  break;
310
371
  case "p":
311
372
  case "P":
312
373
  precision = precision != null ? precision : 2;
313
- rep = toFixed(multiply(rep, 100), precision) + " %";
314
- break;
315
- case "d":
316
- case "D":
317
- rep = precision != null ? padLeft(String(rep), precision, "0") : String(rep);
374
+ rep = toFixed(multiply(rep, 100), precision);
375
+ parts = splitIntAndDecimalPart(rep);
376
+ rep = thousandSeparate(parts.integral) + "." + padRight(parts.decimal, precision, "0") + " %";
318
377
  break;
378
+ case "r":
379
+ case "R":
380
+ throw new Error("The round-trip format is not supported by Fable");
319
381
  case "x":
320
382
  case "X":
321
- rep = precision != null ? padLeft(toHex(rep), precision, "0") : toHex(rep);
383
+ if (!isIntegral(rep)) {
384
+ throw new Error("Format specifier was invalid.");
385
+ }
386
+ precision = precision != null ? precision : 2;
387
+ rep = padLeft(toHex(rep), precision, "0");
322
388
  if (format === "X") {
323
389
  rep = rep.toUpperCase();
324
390
  }
325
391
  break;
326
392
  default:
393
+ // If we have format and were not able to handle it throw
394
+ // See: https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings#standard-format-specifiers
395
+ if (format) {
396
+ throw new Error("Format specifier was invalid.");
397
+ }
327
398
  if (pattern) {
328
399
  let sign = "";
329
400
  rep = pattern.replace(/([0#,]+)(\.[0#]+)?/, (_, intPart, decimalPart) => {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "private": false,
4
4
  "type": "module",
5
5
  "name": "@fable-org/fable-library-js",
6
- "version": "2.0.0-beta.1",
6
+ "version": "2.0.0-beta.3",
7
7
  "description": "Core library used by F# projects compiled with fable.io",
8
8
  "author": "Fable Contributors",
9
9
  "license": "MIT",