functionalscript 0.33.0 → 0.35.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/README.md +27 -14
- package/fs/asserts/module.f.d.ts +1 -1
- package/fs/asserts/module.f.js +4 -1
- package/fs/base64/proof.f.d.ts +1 -0
- package/fs/base64/proof.f.js +25 -56
- package/fs/base_n/module.f.js +11 -5
- package/fs/base_n/proof.f.d.ts +1 -0
- package/fs/base_n/proof.f.js +12 -1
- package/fs/bnf/data/module.f.d.ts +0 -103
- package/fs/bnf/data/module.f.js +10 -246
- package/fs/bnf/data/proof.f.d.ts +0 -10
- package/fs/bnf/data/proof.f.js +2 -642
- package/fs/bnf/descent/module.f.d.ts +56 -0
- package/fs/bnf/descent/module.f.js +119 -0
- package/fs/bnf/descent/proof.f.d.ts +5 -0
- package/fs/bnf/descent/proof.f.js +296 -0
- package/fs/bnf/ll1/module.f.d.ts +72 -0
- package/fs/bnf/ll1/module.f.js +153 -0
- package/fs/bnf/ll1/proof.f.d.ts +9 -0
- package/fs/bnf/ll1/proof.f.js +358 -0
- package/fs/cas/cli/module.f.d.ts +6 -0
- package/fs/cas/cli/module.f.js +56 -0
- package/fs/cas/cli/proof.f.d.ts +14 -0
- package/fs/cas/cli/proof.f.js +149 -0
- package/fs/cas/mcp/module.f.d.ts +9 -17
- package/fs/cas/mcp/module.f.js +123 -96
- package/fs/cas/mcp/proof.f.d.ts +12 -1
- package/fs/cas/mcp/proof.f.js +199 -32
- package/fs/cas/module.f.d.ts +35 -15
- package/fs/cas/module.f.js +168 -131
- package/fs/cas/proof.f.d.ts +16 -13
- package/fs/cas/proof.f.js +255 -121
- package/fs/ci/config/module.f.d.ts +14 -14
- package/fs/ci/config/module.f.js +14 -14
- package/fs/djs/tokenizer-new/module.f.js +1 -1
- package/fs/djs/tokenizer-new/proof.f.d.ts +2 -0
- package/fs/djs/tokenizer-new/proof.f.js +357 -229
- package/fs/effects/list/module.f.d.ts +31 -0
- package/fs/effects/list/module.f.js +16 -0
- package/fs/effects/module.f.d.ts +11 -5
- package/fs/effects/module.f.js +16 -6
- package/fs/effects/node/module.f.d.ts +29 -3
- package/fs/effects/node/module.f.js +35 -1
- package/fs/effects/node/module.js +32 -18
- package/fs/effects/node/virtual/module.f.js +57 -0
- package/fs/effects/proof.f.d.ts +4 -0
- package/fs/effects/proof.f.js +18 -1
- package/fs/fjs/module.f.js +2 -8
- package/fs/html/module.f.js +6 -8
- package/fs/mcp/module.f.d.ts +1 -1
- package/fs/mcp/stdio/module.f.d.ts +8 -0
- package/fs/mcp/stdio/module.f.js +33 -6
- package/fs/mcp/stdio/proof.f.d.ts +3 -0
- package/fs/mcp/stdio/proof.f.js +52 -1
- package/fs/mime/module.f.d.ts +101 -5
- package/fs/mime/module.f.js +159 -6
- package/fs/mime/proof.f.d.ts +25 -0
- package/fs/mime/proof.f.js +193 -3
- package/fs/text/code_point/module.f.d.ts +39 -2
- package/fs/text/code_point/module.f.js +74 -2
- package/fs/text/code_point/proof.f.d.ts +8 -0
- package/fs/text/code_point/proof.f.js +72 -0
- package/fs/text/module.f.d.ts +11 -1
- package/fs/text/module.f.js +13 -3
- package/fs/text/proof.f.d.ts +6 -0
- package/fs/text/proof.f.js +25 -2
- package/fs/text/utf16/module.f.js +4 -26
- package/fs/text/utf8/module.f.d.ts +27 -0
- package/fs/text/utf8/module.f.js +8 -14
- package/fs/types/bit_vec/module.f.d.ts +20 -2
- package/fs/types/bit_vec/module.f.js +77 -27
- package/fs/types/bit_vec/proof.f.d.ts +8 -0
- package/fs/types/bit_vec/proof.f.js +24 -6
- package/fs/types/function/operator/module.f.d.ts +26 -0
- package/fs/types/list/module.f.d.ts +3 -0
- package/fs/types/nullable/module.f.d.ts +9 -5
- package/fs/types/nullable/module.f.js +19 -0
- package/fs/types/result/module.d.ts +2 -4
- package/fs/types/result/module.js +9 -3
- package/package.json +3 -3
- package/issues/demo/data/data.f.js +0 -12
- package/issues/demo/data/shared.f.js +0 -3
- package/issues/demo/fs/app.js +0 -4
- package/issues/demo/fs/math.f.js +0 -4
- package/issues/demo/sample/proof.f.js +0 -13
- /package/{issues → todo}/031-json.f.d.ts +0 -0
- /package/{issues → todo}/031-json.f.js +0 -0
- /package/{issues → todo}/proof.f.d.ts +0 -0
- /package/{issues → todo}/proof.f.js +0 -0
|
@@ -23,10 +23,11 @@
|
|
|
23
23
|
*/
|
|
24
24
|
import { bitLength, divUp, mask, maxLength, xor } from "../bigint/module.f.js";
|
|
25
25
|
import { flip, identity } from "../function/module.f.js";
|
|
26
|
-
import {
|
|
26
|
+
import { iterable, map } from "../list/module.f.js";
|
|
27
27
|
import { asBase, asNominal } from "../nominal/module.f.js";
|
|
28
28
|
import { repeat as mRepeat } from "../monoid/module.f.js";
|
|
29
29
|
import { cmp, max, min } from "../function/compare/module.f.js";
|
|
30
|
+
import { mapUnwrap } from "../nullable/module.f.js";
|
|
30
31
|
/**
|
|
31
32
|
* Maximum length of a bit vector in bits (1_048_576 = 0x10_0000).
|
|
32
33
|
* This limit is enforced by Bun's `bigint` size constraint, the minimal limit
|
|
@@ -133,6 +134,64 @@ const op = (norm) => (op) => ap => bp => {
|
|
|
133
134
|
const { a, b } = norm(au)(bu)(len);
|
|
134
135
|
return vec(len)(op(a)(b));
|
|
135
136
|
};
|
|
137
|
+
const unpackEmpty = { length: 0n, uint: 0n };
|
|
138
|
+
const listToVecOp = (unpackConcat) => ({
|
|
139
|
+
init: { len: 0n, stack: [] },
|
|
140
|
+
update: (v, { len, stack }) => {
|
|
141
|
+
len += v.length;
|
|
142
|
+
if (len > maxLength) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
let i = 0;
|
|
146
|
+
while (true) {
|
|
147
|
+
if (stack.length <= i) {
|
|
148
|
+
stack = [...stack, v];
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
const old = stack[i];
|
|
152
|
+
if (old.length === 0n) {
|
|
153
|
+
stack = stack.toSpliced(i, 1, v);
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
stack = stack.toSpliced(i, 1, unpackEmpty);
|
|
157
|
+
v = unpackConcat(old)(v);
|
|
158
|
+
i++;
|
|
159
|
+
}
|
|
160
|
+
return { len, stack };
|
|
161
|
+
},
|
|
162
|
+
end: ({ stack }) => pack(stack.reduce((p, c) => unpackConcat(c)(p), unpackEmpty))
|
|
163
|
+
});
|
|
164
|
+
/**
|
|
165
|
+
* Concatenates a list of unpacked vectors using a binary-counter accumulator,
|
|
166
|
+
* giving O(n log n) total `bigint` shifting work instead of the O(n²) of a
|
|
167
|
+
* naive left fold.
|
|
168
|
+
*
|
|
169
|
+
* Slot `i` of `result` holds an already-combined run of the most recent
|
|
170
|
+
* `2 ** i` elements. Each arriving element "carries" upward, merging only with
|
|
171
|
+
* runs of comparable size — exactly like incrementing a binary number — so
|
|
172
|
+
* every merge joins two runs of similar length. Left-to-right element order is
|
|
173
|
+
* preserved: `unpackConcat(old)(cur)` keeps the earlier run on the left, and
|
|
174
|
+
* the final reduce prepends higher (earlier) slots in front of accumulated
|
|
175
|
+
* later runs. An empty list yields `unpackEmpty`.
|
|
176
|
+
*
|
|
177
|
+
* This is the bit-vector analogue of a builder that accumulates appended pieces
|
|
178
|
+
* and materializes the combined result on demand, such as `StringBuilder`
|
|
179
|
+
* (Java, C#) or `strings.Builder` (Go).
|
|
180
|
+
*/
|
|
181
|
+
const unpackListToVec = (unpackConcat) => {
|
|
182
|
+
const { init, update, end } = listToVecOp(unpackConcat);
|
|
183
|
+
return (list) => {
|
|
184
|
+
let result = init;
|
|
185
|
+
for (const e of iterable(list)) {
|
|
186
|
+
const candidate = update(e, result);
|
|
187
|
+
if (candidate === null) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
result = candidate;
|
|
191
|
+
}
|
|
192
|
+
return end(result);
|
|
193
|
+
};
|
|
194
|
+
};
|
|
136
195
|
const bo = ({ front, removeFront, norm, uintCmp, unpackSplit, unpackConcatUint }) => {
|
|
137
196
|
const unpackPopFront = (len) => {
|
|
138
197
|
const m = mask(len);
|
|
@@ -142,8 +201,9 @@ const bo = ({ front, removeFront, norm, uintCmp, unpackSplit, unpackConcatUint }
|
|
|
142
201
|
return [uint & m, { length: v.length - len, uint: rest }];
|
|
143
202
|
};
|
|
144
203
|
};
|
|
145
|
-
const unpackConcat =
|
|
146
|
-
length: a.length + b.length,
|
|
204
|
+
const unpackConcat = a => b => ({
|
|
205
|
+
length: a.length + b.length,
|
|
206
|
+
uint: unpackConcatUint(a)(b)
|
|
147
207
|
});
|
|
148
208
|
const popFront = len => {
|
|
149
209
|
const f = unpackPopFront(len);
|
|
@@ -157,11 +217,13 @@ const bo = ({ front, removeFront, norm, uintCmp, unpackSplit, unpackConcatUint }
|
|
|
157
217
|
const bu = unpack(b);
|
|
158
218
|
return pack(unpackConcat(au)(bu));
|
|
159
219
|
};
|
|
220
|
+
const tryListToVec = (list) => unpackListToVec(unpackConcat)(map(unpack)(list));
|
|
160
221
|
return {
|
|
161
222
|
front,
|
|
162
223
|
removeFront,
|
|
163
224
|
concat,
|
|
164
|
-
|
|
225
|
+
tryListToVec,
|
|
226
|
+
listToVec: mapUnwrap(tryListToVec),
|
|
165
227
|
xor: op(norm)(xor),
|
|
166
228
|
unpackPopFront,
|
|
167
229
|
popFront,
|
|
@@ -232,7 +294,16 @@ export const msb = bo({
|
|
|
232
294
|
unpackSplit: len => ({ length, uint }) => [uint >> (length - len), uint],
|
|
233
295
|
unpackConcatUint: flip(lsbUnpackConcatUint),
|
|
234
296
|
});
|
|
235
|
-
|
|
297
|
+
/**
|
|
298
|
+
* Converts a list of unsigned 8-bit integers to a bit vector using the provided
|
|
299
|
+
* bit order, like `u8ListToVec`, but returns `null` instead of throwing when the
|
|
300
|
+
* result would exceed `maxLength`.
|
|
301
|
+
*
|
|
302
|
+
* @param bo The bit order for the conversion
|
|
303
|
+
* @param list The list of unsigned 8-bit integers to be converted.
|
|
304
|
+
* @returns The resulting vector, or `null` if it would exceed `maxLength`.
|
|
305
|
+
*/
|
|
306
|
+
export const tryU8ListToVec = ({ unpackConcat }) => (list) => unpackListToVec(unpackConcat)(map((b) => ({ length: 8n, uint: BigInt(b) }))(list));
|
|
236
307
|
/**
|
|
237
308
|
* Converts a list of unsigned 8-bit integers to a bit vector using the provided bit order.
|
|
238
309
|
*
|
|
@@ -240,28 +311,7 @@ const unpackEmpty = { length: 0n, uint: 0n };
|
|
|
240
311
|
* @param list The list of unsigned 8-bit integers to be converted.
|
|
241
312
|
* @returns The resulting vector based on the provided bit order.
|
|
242
313
|
*/
|
|
243
|
-
export const u8ListToVec = (
|
|
244
|
-
let result = [];
|
|
245
|
-
for (const b of iterable(list)) {
|
|
246
|
-
let v = { length: 8n, uint: BigInt(b) };
|
|
247
|
-
let i = 0;
|
|
248
|
-
while (true) {
|
|
249
|
-
if (result.length <= i) {
|
|
250
|
-
result = [...result, v];
|
|
251
|
-
break;
|
|
252
|
-
}
|
|
253
|
-
const old = result[i];
|
|
254
|
-
if (old.length === 0n) {
|
|
255
|
-
result = result.toSpliced(i, 1, v);
|
|
256
|
-
break;
|
|
257
|
-
}
|
|
258
|
-
result = result.toSpliced(i, 1, unpackEmpty);
|
|
259
|
-
v = unpackConcat(old)(v);
|
|
260
|
-
i++;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
return pack(result.reduce((p, c) => unpackConcat(c)(p), unpackEmpty));
|
|
264
|
-
};
|
|
314
|
+
export const u8ListToVec = (bo) => mapUnwrap(tryU8ListToVec(bo));
|
|
265
315
|
const unpackChunkList = ({ unpackSplit }) => (n) => {
|
|
266
316
|
const divUpN2 = divUp(n << 1n);
|
|
267
317
|
return u => {
|
|
@@ -46,6 +46,14 @@ export declare const proof: {
|
|
|
46
46
|
emptyVec: () => void;
|
|
47
47
|
};
|
|
48
48
|
u8ListToVec: () => () => void;
|
|
49
|
+
tryListToVecOverflow: () => void;
|
|
50
|
+
listToVecOverflow: {
|
|
51
|
+
throw: () => void;
|
|
52
|
+
};
|
|
53
|
+
u8ListToVecOverflow: {
|
|
54
|
+
try: () => void;
|
|
55
|
+
throw: () => void;
|
|
56
|
+
};
|
|
49
57
|
u8ListUnaligned: () => void;
|
|
50
58
|
chunkList: {
|
|
51
59
|
empty: () => void;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { assertEq } from "../../asserts/module.f.js";
|
|
1
2
|
import { mask } from "../bigint/module.f.js";
|
|
2
3
|
import { asBase, asNominal } from "../nominal/module.f.js";
|
|
3
|
-
import { length, empty, uint, vec, lsb, msb, repeat, vec8, u8ListToVec, u8List, chunkList, fromSentinel } from "./module.f.js";
|
|
4
|
+
import { length, empty, uint, vec, lsb, msb, repeat, vec8, maxLength, u8ListToVec, tryU8ListToVec, u8List, chunkList, fromSentinel } from "./module.f.js";
|
|
4
5
|
import { repeat as listRepeat, toArray } from "../list/module.f.js";
|
|
5
6
|
const unsafeVec = (a) => asNominal(a);
|
|
6
7
|
// 0x8 = 0b1000 = 0 + 8
|
|
@@ -11,11 +12,6 @@ const unsafeVec = (a) => asNominal(a);
|
|
|
11
12
|
// 0xD = 0b1101 = 5 + 8
|
|
12
13
|
// 0xE = 0b1110 = 6 + 8
|
|
13
14
|
// 0xF = 0b1111 = 7 + 8
|
|
14
|
-
const assertEq = (a, b) => {
|
|
15
|
-
if (a !== b) {
|
|
16
|
-
throw [a, b];
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
15
|
const assertEq2 = ([a0, a1], [b0, b1]) => {
|
|
20
16
|
assertEq(a0, b0);
|
|
21
17
|
assertEq(a1, b1);
|
|
@@ -504,6 +500,28 @@ export const proof = {
|
|
|
504
500
|
}
|
|
505
501
|
};
|
|
506
502
|
},
|
|
503
|
+
tryListToVecOverflow: () => {
|
|
504
|
+
const list = [vec(maxLength)(1n), vec(1n)(1n)];
|
|
505
|
+
assertEq(lsb.tryListToVec(list), null);
|
|
506
|
+
assertEq(msb.tryListToVec(list), null);
|
|
507
|
+
},
|
|
508
|
+
listToVecOverflow: {
|
|
509
|
+
// Same oversized input, but through the throwing `listToVec` wrapper.
|
|
510
|
+
throw: () => {
|
|
511
|
+
const list = { first: vec(maxLength + 1n)(1n), tail: null };
|
|
512
|
+
lsb.listToVec(list);
|
|
513
|
+
},
|
|
514
|
+
},
|
|
515
|
+
u8ListToVecOverflow: {
|
|
516
|
+
// 131_073 bytes is 8 bits past `maxLength`; same null/throw split as
|
|
517
|
+
// `tryListToVec`/`listToVec` above, exercised through the byte-list API.
|
|
518
|
+
try: () => {
|
|
519
|
+
assertEq(tryU8ListToVec(msb)(listRepeat(0x12)(131_073)), null);
|
|
520
|
+
},
|
|
521
|
+
throw: () => {
|
|
522
|
+
u8ListToVec(msb)(listRepeat(0x12)(131_073));
|
|
523
|
+
},
|
|
524
|
+
},
|
|
507
525
|
u8ListUnaligned: () => {
|
|
508
526
|
const x = vec(9n)(0x83n);
|
|
509
527
|
const a = toArray(u8List(msb)(x));
|
|
@@ -12,6 +12,32 @@ export declare const logicalNot: Unary<boolean, boolean>;
|
|
|
12
12
|
export type Equal<T> = Binary<T, T, boolean>;
|
|
13
13
|
export declare const strictEqual: <T>(a: T) => (b: T) => boolean;
|
|
14
14
|
export type Scan<I, O> = (input: I) => readonly [O, Scan<I, O>];
|
|
15
|
+
/**
|
|
16
|
+
* One step of a stream transducer: given an `input` symbol and the `prior`
|
|
17
|
+
* state, produce an `output` and the next state. It both maps an input stream
|
|
18
|
+
* to an output stream and threads state, so it models tokenizers, decoders, and
|
|
19
|
+
* other stream-to-stream stages.
|
|
20
|
+
*
|
|
21
|
+
* This is the *shape* of a [Mealy machine](https://en.wikipedia.org/wiki/Mealy_machine)
|
|
22
|
+
* — a [finite-state transducer](https://en.wikipedia.org/wiki/Finite-state_transducer)
|
|
23
|
+
* — but only its signature. The state `S` (and `I`, `O`) is an arbitrary type,
|
|
24
|
+
* not a finite set, so a `StateScan` is strictly more expressive than a Mealy
|
|
25
|
+
* machine — its power is the power of `S`:
|
|
26
|
+
* - a finite `S`/`I`/`O` recovers the classical finite-state machine (e.g. the
|
|
27
|
+
* DFA states in `../../../fsm/module.f.ts`);
|
|
28
|
+
* - an `S` that is a stack makes it a
|
|
29
|
+
* [pushdown / stack machine](https://en.wikipedia.org/wiki/Pushdown_automaton)
|
|
30
|
+
* (context-free power — balanced brackets, nested structure, the AST tier);
|
|
31
|
+
* - an unbounded `S` like `bigint` can count, which no finite automaton can.
|
|
32
|
+
*
|
|
33
|
+
* And `O` may be a list (0+ symbols per input), not the single symbol strict
|
|
34
|
+
* Mealy emits. (Functional/coalgebraic usage still calls this `(input, state)
|
|
35
|
+
* => [output, state]` shape a "Mealy machine", finiteness aside.)
|
|
36
|
+
*
|
|
37
|
+
* A {@link Fold} is the output-less special case (state only); driving a
|
|
38
|
+
* `StateScan` over a `List` is `stateScan` in `../../list/module.f.ts`, and
|
|
39
|
+
* {@link stateScanToScan} hides the state to recover a {@link Scan}.
|
|
40
|
+
*/
|
|
15
41
|
export type StateScan<I, S, O> = (input: I, prior: S) => readonly [O, S];
|
|
16
42
|
export declare const stateScanToScan: <I, S, O>(op: StateScan<I, S, O>) => (prior: S) => Scan<I, O>;
|
|
17
43
|
export declare const foldToScan: <I, O>(fold: Fold<I, O>) => (prior: O) => Scan<I, O>;
|
|
@@ -4,6 +4,9 @@ type NotLazy<T> = Result<T> | Concat<T> | readonly T[];
|
|
|
4
4
|
type Empty = null;
|
|
5
5
|
export type Result<T> = Empty | NonEmpty<T>;
|
|
6
6
|
export type Thunk<T> = () => List<T>;
|
|
7
|
+
/**
|
|
8
|
+
* See also https://en.wikipedia.org/wiki/Cons#Lists
|
|
9
|
+
*/
|
|
7
10
|
export type NonEmpty<T> = {
|
|
8
11
|
readonly first: T;
|
|
9
12
|
readonly tail: List<T>;
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utilities for nullable (`null`/`undefined`) value handling.
|
|
3
|
-
*
|
|
4
|
-
* @module
|
|
5
|
-
*/
|
|
6
1
|
import type { Option } from '../option/module.f.ts';
|
|
7
2
|
export type Nullable<T> = T | null;
|
|
8
3
|
export declare const map: <T, R>(f: (value: T) => R) => (value: Nullable<T>) => Nullable<R>;
|
|
@@ -15,3 +10,12 @@ export declare const toOption: <T>(value: Nullable<T>) => Option<T>;
|
|
|
15
10
|
* property/index lookups) and FunctionalScript (which uses `null` for absence).
|
|
16
11
|
*/
|
|
17
12
|
export declare const fromUndefined: <T>(value: T | undefined) => Nullable<T>;
|
|
13
|
+
/**
|
|
14
|
+
* Extracts the value from a `Nullable`, asserting that it is not `null`.
|
|
15
|
+
*/
|
|
16
|
+
export declare const unwrap: <T>(value: Nullable<T>) => T;
|
|
17
|
+
/**
|
|
18
|
+
* Lifts a function that signals failure with `null` into one that asserts
|
|
19
|
+
* success instead, unwrapping the result.
|
|
20
|
+
*/
|
|
21
|
+
export declare const mapUnwrap: <I, T>(f: (i: I) => Nullable<T>) => import("../function/module.f.ts").Func<I, T>;
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for nullable (`null`/`undefined`) value handling.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { assert } from "../../asserts/module.f.js";
|
|
7
|
+
import { fn } from "../function/module.f.js";
|
|
1
8
|
export const map = f => value => value === null ? null : f(value);
|
|
2
9
|
export const match = f => none => value => value === null ? none() : f(value);
|
|
3
10
|
export const toOption = (value) => value === null ? [] : [value];
|
|
@@ -8,3 +15,15 @@ export const toOption = (value) => value === null ? [] : [value];
|
|
|
8
15
|
* property/index lookups) and FunctionalScript (which uses `null` for absence).
|
|
9
16
|
*/
|
|
10
17
|
export const fromUndefined = (value) => value === undefined ? null : value;
|
|
18
|
+
/**
|
|
19
|
+
* Extracts the value from a `Nullable`, asserting that it is not `null`.
|
|
20
|
+
*/
|
|
21
|
+
export const unwrap = (value) => {
|
|
22
|
+
assert(value !== null);
|
|
23
|
+
return value;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Lifts a function that signals failure with `null` into one that asserts
|
|
27
|
+
* success instead, unwrapping the result.
|
|
28
|
+
*/
|
|
29
|
+
export const mapUnwrap = (f) => fn(f).map(unwrap).result;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
1
|
import { type Result } from './module.f.ts';
|
|
2
|
-
declare const
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
export default _default;
|
|
2
|
+
export declare const tryCatch: <T>(f: () => T) => Result<T, unknown>;
|
|
3
|
+
export declare const asyncTryCatch: <T>(f: () => Promise<T>) => Promise<Result<T, unknown>>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ok, error } from "./module.f.js";
|
|
2
|
-
const tryCatch = f => {
|
|
2
|
+
export const tryCatch = f => {
|
|
3
3
|
// Side effect: `try catch` is not allowed in FunctionalScript.
|
|
4
4
|
try {
|
|
5
5
|
return ok(f());
|
|
@@ -8,6 +8,12 @@ const tryCatch = f => {
|
|
|
8
8
|
return error(e);
|
|
9
9
|
}
|
|
10
10
|
};
|
|
11
|
-
export
|
|
12
|
-
|
|
11
|
+
export const asyncTryCatch = async (f) => {
|
|
12
|
+
// Side effect: `try catch` is not allowed in FunctionalScript.
|
|
13
|
+
try {
|
|
14
|
+
return ok(await f());
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
return error(e);
|
|
18
|
+
}
|
|
13
19
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "functionalscript",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"**/*.js",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
},
|
|
44
44
|
"homepage": "https://github.com/functionalscript/functionalscript#readme",
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@playwright/test": "1.61.
|
|
47
|
-
"@types/node": "26.
|
|
46
|
+
"@playwright/test": "1.61.1",
|
|
47
|
+
"@types/node": "26.1.0",
|
|
48
48
|
"typescript": "6.0.3"
|
|
49
49
|
}
|
|
50
50
|
}
|
package/issues/demo/fs/app.js
DELETED
package/issues/demo/fs/math.f.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
const arrayOfTests = [
|
|
2
|
-
() => {
|
|
3
|
-
if (2 + 2 !== 4) throw "It's the end of the world as we know it!"
|
|
4
|
-
},
|
|
5
|
-
() => {
|
|
6
|
-
if (2n + 2n !== 4n) throw "It's the end of the world as we know it!"
|
|
7
|
-
}
|
|
8
|
-
]
|
|
9
|
-
|
|
10
|
-
export const proof = {
|
|
11
|
-
arrayOfTests,
|
|
12
|
-
generatingTests: () => arrayOfTests,
|
|
13
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|