functionalscript 0.46.0 → 0.47.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/fjs/basen/cbase32/module.f.mjs +18 -10
- package/fjs/basen/cbase32/proof.f.d.mts +3 -0
- package/fjs/basen/cbase32/proof.f.mjs +24 -2
- package/fjs/basen/proof.f.mjs +8 -16
- package/fjs/bnf/ll1/proof.f.d.mts +2 -0
- package/fjs/bnf/ll1/proof.f.mjs +33 -18
- package/fjs/bnf/module.f.d.mts +2 -2
- package/fjs/bnf/module.f.mjs +2 -2
- package/fjs/cas/proof.f.mjs +4 -26
- package/fjs/ci/common/module.f.mjs +6 -0
- package/fjs/ci/config/module.f.d.mts +7 -7
- package/fjs/ci/config/module.f.mjs +7 -7
- package/fjs/cli/module.f.mjs +14 -10
- package/fjs/crypto/vdf/module.f.d.mts +0 -1
- package/fjs/crypto/vdf/module.f.mjs +3 -14
- package/fjs/dev/module.f.mjs +10 -20
- package/fjs/djs/parser/module.f.d.mts +101 -53
- package/fjs/djs/parser/module.f.mjs +732 -525
- package/fjs/djs/parser/proof.f.d.mts +6 -0
- package/fjs/djs/parser/proof.f.mjs +315 -11
- package/fjs/djs/parser/types.d.ts +29 -2
- package/fjs/djs/tokenizer/module.f.mjs +122 -105
- package/fjs/djs/tokenizer/proof.f.mjs +17 -0
- package/fjs/djs/transpiler/module.f.mjs +4 -5
- package/fjs/djs/transpiler/proof.f.d.mts +2 -0
- package/fjs/djs/transpiler/proof.f.mjs +25 -0
- package/fjs/edag/amnesia/module.f.d.mts +20 -0
- package/fjs/edag/amnesia/module.f.mjs +303 -0
- package/fjs/edag/amnesia/proof.f.d.mts +79 -0
- package/fjs/edag/amnesia/proof.f.mjs +573 -0
- package/fjs/edag/amnesia/types.d.ts +15 -0
- package/fjs/edag/module.f.d.mts +410 -0
- package/fjs/edag/module.f.mjs +559 -0
- package/fjs/edag/proof.f.d.mts +116 -0
- package/fjs/edag/proof.f.mjs +686 -0
- package/fjs/edag/types.d.ts +55 -0
- package/fjs/effects/node/memory/module.d.mts +37 -3
- package/fjs/effects/node/memory/module.mjs +38 -4
- package/fjs/effects/node/memory/proof.d.mts +5 -2
- package/fjs/effects/node/memory/proof.mjs +36 -6
- package/fjs/effects/node/module.d.mts +9 -1
- package/fjs/effects/node/module.f.d.mts +39 -0
- package/fjs/effects/node/module.f.mjs +46 -0
- package/fjs/effects/node/module.mjs +234 -32
- package/fjs/effects/node/types.d.ts +28 -2
- package/fjs/effects/node/virtual/module.f.d.mts +19 -10
- package/fjs/effects/node/virtual/module.f.mjs +246 -32
- package/fjs/effects/node/virtual/proof.f.d.mts +17 -2
- package/fjs/effects/node/virtual/proof.f.mjs +232 -8
- package/fjs/effects/node/virtual/types.d.ts +57 -1
- package/fjs/emergent_testing/browser/proof.d.mts +55 -0
- package/fjs/emergent_testing/browser/proof.mjs +352 -0
- package/fjs/emergent_testing/browser/species.proof.d.mts +4 -0
- package/fjs/emergent_testing/browser/species.proof.mjs +45 -0
- package/fjs/emergent_testing/browser.d.mts +79 -0
- package/fjs/emergent_testing/browser.mjs +432 -0
- package/fjs/emergent_testing/proof.f.d.mts +1 -1
- package/fjs/emergent_testing/proof.f.mjs +2 -2
- package/fjs/js/string_escape/module.f.d.mts +47 -0
- package/fjs/js/string_escape/module.f.mjs +95 -0
- package/fjs/js/string_escape/proof.f.d.mts +8 -0
- package/fjs/js/string_escape/proof.f.mjs +68 -0
- package/fjs/js/tokenizer/module.f.mjs +14 -12
- package/fjs/mcp/cas/module.f.d.mts +1 -7
- package/fjs/mcp/cas/module.f.mjs +24 -15
- package/fjs/mcp/evo/module.f.mjs +9 -24
- package/fjs/mcp/module.f.d.mts +3 -1
- package/fjs/mcp/module.f.mjs +4 -2
- package/fjs/media/json/rtti/module.f.d.mts +2 -2
- package/fjs/media/json/rtti/module.f.mjs +1 -1
- package/fjs/media/json/schema/module.f.d.mts +15 -5
- package/fjs/media/json/schema/module.f.mjs +42 -15
- package/fjs/media/json/schema/proof.f.d.mts +10 -1
- package/fjs/media/json/schema/proof.f.mjs +88 -16
- package/fjs/media/json/serializer/module.f.mjs +14 -26
- package/fjs/media/json/types.d.ts +1 -1
- package/fjs/media/lock/module.f.d.mts +8 -3
- package/fjs/media/lock/module.f.mjs +9 -3
- package/fjs/media/lock/proof.f.d.mts +1 -1
- package/fjs/media/lock/proof.f.mjs +2 -2
- package/fjs/media/lock/types.d.ts +1 -3
- package/fjs/media/module.f.d.mts +20 -13
- package/fjs/media/module.f.mjs +29 -16
- package/fjs/media/note/module.f.d.mts +14 -7
- package/fjs/media/note/module.f.mjs +14 -7
- package/fjs/media/note/proof.f.mjs +1 -1
- package/fjs/media/proof.f.mjs +5 -5
- package/fjs/media/revision/module.f.d.mts +8 -2
- package/fjs/media/revision/module.f.mjs +9 -3
- package/fjs/media/revision/proof.f.mjs +1 -1
- package/fjs/media/revision/types.d.ts +1 -1
- package/fjs/media/type/module.f.d.mts +20 -0
- package/fjs/media/type/module.f.mjs +74 -0
- package/fjs/media/type/proof.f.d.mts +5 -0
- package/fjs/media/type/proof.f.mjs +24 -1
- package/fjs/module.f.mjs +6 -0
- package/fjs/path/module.f.d.mts +60 -3
- package/fjs/path/module.f.mjs +138 -14
- package/fjs/path/proof.f.d.mts +3 -0
- package/fjs/path/proof.f.mjs +298 -2
- package/fjs/protocol/json_rpc/module.f.d.mts +65 -28
- package/fjs/protocol/json_rpc/module.f.mjs +49 -13
- package/fjs/protocol/json_rpc/proof.f.d.mts +4 -0
- package/fjs/protocol/json_rpc/proof.f.mjs +29 -0
- package/fjs/protocol/json_rpc/types.d.ts +12 -2
- package/fjs/protocol/mcp/module.f.d.mts +89 -54
- package/fjs/protocol/mcp/module.f.mjs +110 -56
- package/fjs/protocol/mcp/proof.f.d.mts +13 -0
- package/fjs/protocol/mcp/proof.f.mjs +107 -7
- package/fjs/protocol/mcp/stdio/module.f.mjs +3 -4
- package/fjs/protocol/mcp/stdio/proof.f.mjs +2 -2
- package/fjs/protocol/mcp/types.d.ts +14 -2
- package/fjs/text/utf8/module.f.mjs +27 -1
- package/fjs/text/utf8/proof.f.mjs +37 -0
- package/fjs/types/array/module.f.mjs +18 -11
- package/fjs/types/array/proof.f.mjs +27 -1
- package/fjs/types/bigfloat/module.f.d.mts +48 -9
- package/fjs/types/bigfloat/module.f.mjs +147 -59
- package/fjs/types/bigfloat/proof.f.d.mts +2 -0
- package/fjs/types/bigfloat/proof.f.mjs +136 -4
- package/fjs/types/bigfloat/types.d.ts +17 -0
- package/fjs/types/function/module.f.d.mts +11 -2
- package/fjs/types/function/module.f.mjs +20 -2
- package/fjs/types/function/proof.f.mjs +5 -1
- package/fjs/types/phantom/types.d.ts +21 -0
- package/fjs/types/result/module.f.d.mts +4 -4
- package/fjs/types/result/module.f.mjs +2 -2
- package/fjs/types/result/proof.f.d.mts +6 -2
- package/fjs/types/result/proof.f.mjs +17 -1
- package/fjs/types/rtti/common/module.f.d.mts +78 -5
- package/fjs/types/rtti/common/module.f.mjs +168 -3
- package/fjs/types/rtti/common/proof.f.d.mts +14 -0
- package/fjs/types/rtti/common/proof.f.mjs +61 -2
- package/fjs/types/rtti/common/types.d.ts +23 -1
- package/fjs/types/rtti/data/module.f.d.mts +57 -1
- package/fjs/types/rtti/data/module.f.mjs +241 -47
- package/fjs/types/rtti/data/proof.f.d.mts +10 -0
- package/fjs/types/rtti/data/proof.f.mjs +272 -39
- package/fjs/types/rtti/data/types.d.ts +14 -7
- package/fjs/types/rtti/host.proof.d.mts +33 -0
- package/fjs/types/rtti/host.proof.mjs +170 -0
- package/fjs/types/rtti/module.f.d.mts +51 -6
- package/fjs/types/rtti/module.f.mjs +50 -3
- package/fjs/types/rtti/parse/module.f.d.mts +31 -24
- package/fjs/types/rtti/parse/module.f.mjs +197 -59
- package/fjs/types/rtti/parse/proof.f.d.mts +37 -2
- package/fjs/types/rtti/parse/proof.f.mjs +171 -47
- package/fjs/types/rtti/proof.f.d.mts +6 -0
- package/fjs/types/rtti/proof.f.mjs +42 -1
- package/fjs/types/rtti/ts/module.f.d.mts +9 -3
- package/fjs/types/rtti/ts/module.f.mjs +68 -15
- package/fjs/types/rtti/ts/proof.f.d.mts +42 -2
- package/fjs/types/rtti/ts/proof.f.mjs +139 -6
- package/fjs/types/rtti/ts/types.d.ts +164 -16
- package/fjs/types/rtti/types.d.ts +31 -3
- package/fjs/types/rtti/validate/module.f.d.mts +120 -0
- package/fjs/types/rtti/validate/module.f.mjs +351 -0
- package/fjs/types/rtti/validate/proof.f.d.mts +154 -0
- package/fjs/types/rtti/validate/proof.f.mjs +781 -0
- package/fjs/types/ts/types.d.ts +4 -0
- package/fjs/web/module.f.d.mts +115 -0
- package/fjs/web/module.f.mjs +581 -0
- package/fjs/web/proof.f.d.mts +39 -0
- package/fjs/web/proof.f.mjs +413 -0
- package/fjs/web/types.d.ts +39 -0
- package/fjs/website/browser-prepare.d.mts +5 -0
- package/fjs/website/browser-prepare.mjs +115 -0
- package/fjs/website/browser-source.d.mts +37 -0
- package/fjs/website/browser-source.mjs +202 -0
- package/fjs/website/browser-source.proof.d.mts +31 -0
- package/fjs/website/browser-source.proof.mjs +162 -0
- package/fjs/website/browser.d.mts +5 -0
- package/fjs/website/browser.mjs +8 -0
- package/fjs/website/module.f.d.mts +3 -3
- package/fjs/website/module.f.mjs +62 -9
- package/fjs/website/proof.f.d.mts +4 -0
- package/fjs/website/proof.f.mjs +18 -3
- package/package.json +2 -3
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @import { Nullable } from '../../types/nullable/types.ts'
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { msb, lsb, length, vec, empty } from '../../types/bit_vec/module.f.mjs'
|
|
10
|
+
import { msb, lsb, length, maxLength, vec, empty } from '../../types/bit_vec/module.f.mjs'
|
|
11
11
|
import { baseN } from '../module.f.mjs'
|
|
12
12
|
|
|
13
13
|
// 0123456789abcdef
|
|
@@ -47,15 +47,23 @@ export const vecToCBase32 = v => {
|
|
|
47
47
|
|
|
48
48
|
/** @type {(s: string) => Nullable<Vec>} */
|
|
49
49
|
export const cBase32ToVec = s => {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
50
|
+
// Locate the sentinel from the end one character at a time. This preserves
|
|
51
|
+
// accepted non-canonical spellings with trailing zero characters without
|
|
52
|
+
// ever materialising their padded body as one oversized vector.
|
|
53
|
+
for (let i = s.length - 1; i >= 0; i--) {
|
|
54
|
+
let tail = cBase32ToVec5x(s[i])
|
|
55
|
+
if (tail === null) { return null }
|
|
56
|
+
while (tail !== empty) {
|
|
57
|
+
const [last, rest] = popBack1(tail)
|
|
58
|
+
tail = rest
|
|
59
|
+
if (last === 1n) {
|
|
60
|
+
const head = cBase32ToVec5x(s.slice(0, i))
|
|
61
|
+
if (head === null || length(head) + length(rest) > maxLength) {
|
|
62
|
+
return null
|
|
63
|
+
}
|
|
64
|
+
return concat(head)(rest)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
59
67
|
}
|
|
60
68
|
return null
|
|
61
69
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @import { Vec } from '../../types/bit_vec/types.ts'
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { empty, vec } from '../../types/bit_vec/module.f.mjs'
|
|
5
|
+
import { empty, maxLength, vec } from '../../types/bit_vec/module.f.mjs'
|
|
6
6
|
import { cBase32ToVec, cBase32ToVec5x, vec5xToCBase32, vecToCBase32 } from './module.f.mjs'
|
|
7
7
|
import { assertEq } from '../../asserts/module.f.mjs'
|
|
8
8
|
|
|
@@ -75,5 +75,27 @@ export const proof = {
|
|
|
75
75
|
assertEq(cBase32ToVec("0"), null, 'single zero symbol must be null')
|
|
76
76
|
assertEq(cBase32ToVec("00"), null, 'all-zero symbols must be null')
|
|
77
77
|
assertEq(cBase32ToVec("o"), null, 'o (maps to 0) must be null')
|
|
78
|
-
|
|
78
|
+
assertEq(cBase32ToVec('u'), null, 'invalid trailing symbol must be null')
|
|
79
|
+
assertEq(cBase32ToVec('u8'), null, 'invalid symbol before sentinel must be null')
|
|
80
|
+
assertEq(cBase32ToVec('8u'), null, 'invalid symbol after sentinel must be null')
|
|
81
|
+
},
|
|
82
|
+
trailingZeroSymbols: () => {
|
|
83
|
+
assertEq(cBase32ToVec('g0'), empty)
|
|
84
|
+
assertEq(cBase32ToVec('80'), vec(1n)(0n))
|
|
85
|
+
},
|
|
86
|
+
decodeAtMaxLengthSucceeds: () => {
|
|
87
|
+
const value = vec(maxLength)(0n)
|
|
88
|
+
// Construct the boundary encoding directly. Encoding a `maxLength`
|
|
89
|
+
// vector exceeds Bun's own BigInt size limit while adding the stop
|
|
90
|
+
// bit, independently of this decoder regression.
|
|
91
|
+
const encoded = '0'.repeat(209_715) + '8'
|
|
92
|
+
assertEq(cBase32ToVec(encoded), value)
|
|
93
|
+
},
|
|
94
|
+
decodeOverflow: () => {
|
|
95
|
+
// Reject both an independently oversized head and a valid head whose
|
|
96
|
+
// retained tail would push the combined result over `maxLength`.
|
|
97
|
+
assertEq(cBase32ToVec('0'.repeat(209_717) + 'g'), null)
|
|
98
|
+
assertEq(cBase32ToVec('0'.repeat(209_715) + '4'), null)
|
|
99
|
+
assertEq(cBase32ToVec('0'.repeat(209_715) + '1'), null)
|
|
100
|
+
},
|
|
79
101
|
}
|
package/fjs/basen/proof.f.mjs
CHANGED
|
@@ -4,15 +4,10 @@ import { baseN } from './module.f.mjs'
|
|
|
4
4
|
|
|
5
5
|
const hex = baseN(4n, '0123456789abcdef')
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
case 'l': { return '1' }
|
|
12
|
-
case 'o': { return '0' }
|
|
13
|
-
default: { return lower }
|
|
14
|
-
}
|
|
15
|
-
})
|
|
7
|
+
// A synthetic normalizer keeps this proof focused on `baseN`'s mechanism
|
|
8
|
+
// rather than duplicating the rules owned by a concrete codec.
|
|
9
|
+
const normalizedHex = baseN(4n, '0123456789abcdef', c =>
|
|
10
|
+
c === 'x' ? 'a' : c === 'y' ? 'z' : c.toLowerCase())
|
|
16
11
|
|
|
17
12
|
// Sample input for the `big` proof below: 262 144 `f` characters decode into a
|
|
18
13
|
// 1 Mibit (`maxLength`) vector.
|
|
@@ -48,16 +43,13 @@ export const proof = {
|
|
|
48
43
|
},
|
|
49
44
|
normalizeHit: () => {
|
|
50
45
|
// 'A' lowercases to 'a' — same vector as the lowercase input.
|
|
51
|
-
const a =
|
|
52
|
-
const b =
|
|
46
|
+
const a = normalizedHex.stringToVec('A')
|
|
47
|
+
const b = normalizedHex.stringToVec('a')
|
|
53
48
|
assertEq(a, b, [a, b])
|
|
54
|
-
|
|
55
|
-
assertEq(cb32.stringToVec('I'), cb32.stringToVec('1'), 'I→1')
|
|
56
|
-
assertEq(cb32.stringToVec('l'), cb32.stringToVec('1'), 'l→1')
|
|
57
|
-
assertEq(cb32.stringToVec('o'), cb32.stringToVec('0'), 'o→0')
|
|
49
|
+
assertEq(normalizedHex.stringToVec('x'), a, 'x→a')
|
|
58
50
|
},
|
|
59
51
|
normalizeMiss: () => {
|
|
60
|
-
assertEq(
|
|
52
|
+
assertEq(normalizedHex.stringToVec('y'), null, 'normalizing to an unknown char should return null')
|
|
61
53
|
},
|
|
62
54
|
// Decodes a 1 Mibit hex string. With the O(n log n) `listToVec` builder this
|
|
63
55
|
// runs in well under a second (was ~13 s node / ~43 s bun under the old
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* @import { RuleSet } from '../data/types.ts'
|
|
4
4
|
* @import { CodePointMeta } from '../descent/types.ts'
|
|
5
5
|
* @import { Rule as FRule } from '../types.ts'
|
|
6
|
+
* @import { Match } from './types.ts'
|
|
6
7
|
* @import { MatchResult } from './types.ts'
|
|
7
8
|
*/
|
|
8
9
|
export declare const proof: {
|
|
@@ -28,4 +29,5 @@ export declare const proof: {
|
|
|
28
29
|
leftRecursiveVariant: () => void;
|
|
29
30
|
};
|
|
30
31
|
cyclicNullability: () => void;
|
|
32
|
+
ssn: () => void;
|
|
31
33
|
};
|
package/fjs/bnf/ll1/proof.f.mjs
CHANGED
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
* @import { RuleSet } from '../data/types.ts'
|
|
4
4
|
* @import { CodePointMeta } from '../descent/types.ts'
|
|
5
5
|
* @import { Rule as FRule } from '../types.ts'
|
|
6
|
+
* @import { Match } from './types.ts'
|
|
6
7
|
* @import { MatchResult } from './types.ts'
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
10
|
import { stringToCodePointList } from '../../text/utf16/module.f.mjs'
|
|
10
11
|
import { map, toArray } from '../../types/list/module.f.mjs'
|
|
11
|
-
import { commaJoin0Plus, eof, option, range, repeat0Plus, set } from '../module.f.mjs'
|
|
12
|
+
import { commaJoin0Plus, eof, option, range, repeat, repeat0Plus, set } from '../module.f.mjs'
|
|
12
13
|
import { toData } from '../data/module.f.mjs'
|
|
13
14
|
import { descentParser } from '../descent/module.f.mjs'
|
|
14
15
|
import { dispatchMap, parser, parserRuleSet } from './module.f.mjs'
|
|
@@ -18,6 +19,15 @@ import { deterministic, showAst } from '../testlib.f.mjs'
|
|
|
18
19
|
/** @type {(cp: CodePoint) => CodePointMeta<unknown>} */
|
|
19
20
|
const mapCodePoint = cp => [cp, undefined]
|
|
20
21
|
|
|
22
|
+
/** @type {(mr: MatchResult) => boolean} */
|
|
23
|
+
const isMatchSuccess = ([, success, remainder]) => success && remainder?.length === 0
|
|
24
|
+
|
|
25
|
+
/** @type {(m: Match) => (s: string, success: boolean) => void} */
|
|
26
|
+
const expectMatch = m => (s, success) => {
|
|
27
|
+
const mr = m('', toArray(stringToCodePointList(s)))
|
|
28
|
+
assertEq(isMatchSuccess(mr), success, mr)
|
|
29
|
+
}
|
|
30
|
+
|
|
21
31
|
/**
|
|
22
32
|
* One grammar matched by both backends, which must build the same AST for it:
|
|
23
33
|
* the shape is pinned once and asserted against each backend, so neither can
|
|
@@ -241,13 +251,7 @@ export const proof = {
|
|
|
241
251
|
},
|
|
242
252
|
() => {
|
|
243
253
|
const m = parser(option('a'))
|
|
244
|
-
|
|
245
|
-
const isSuccess = (/** @type {MatchResult} */mr) => mr[1] && mr[2]?.length === 0
|
|
246
|
-
/** @type {(s: string, success: boolean) => void} */
|
|
247
|
-
const expect = (s, success) => {
|
|
248
|
-
const mr = m('', toArray(stringToCodePointList(s)))
|
|
249
|
-
assertEq(isSuccess(mr), success, mr)
|
|
250
|
-
}
|
|
254
|
+
const expect = expectMatch(m)
|
|
251
255
|
|
|
252
256
|
expect('a', true)
|
|
253
257
|
expect('', true)
|
|
@@ -268,12 +272,10 @@ export const proof = {
|
|
|
268
272
|
|
|
269
273
|
const m = parser(value)
|
|
270
274
|
|
|
271
|
-
/** @type {(mr: MatchResult) => boolean} */
|
|
272
|
-
const isSuccess = mr => mr[1] && mr[2]?.length === 0
|
|
273
275
|
/** @type {(s: string, success: boolean) => void} */
|
|
274
276
|
const expect = (s, success) => {
|
|
275
277
|
const mr = m('value', toArray(stringToCodePointList(s)))
|
|
276
|
-
assertEq(
|
|
278
|
+
assertEq(isMatchSuccess(mr), success, mr)
|
|
277
279
|
}
|
|
278
280
|
|
|
279
281
|
expect('', false)
|
|
@@ -305,7 +307,7 @@ export const proof = {
|
|
|
305
307
|
/** @type {(s: string) => void} */
|
|
306
308
|
const expectNoMatch = s => {
|
|
307
309
|
const mr = ml(entry, toArray(stringToCodePointList(s)))
|
|
308
|
-
assertEq(mr
|
|
310
|
+
assertEq(isMatchSuccess(mr), false, s)
|
|
309
311
|
}
|
|
310
312
|
|
|
311
313
|
expectSameAst(' true ')
|
|
@@ -570,12 +572,7 @@ export const proof = {
|
|
|
570
572
|
const ws = option(' ')
|
|
571
573
|
const value = () => ({ array: ['[', value, ']'], leaf: 'a' })
|
|
572
574
|
const m = parser([ws, value, ws]) // must not throw 'can not merge'
|
|
573
|
-
|
|
574
|
-
/** @type {(s: string, success: boolean) => void} */
|
|
575
|
-
const expect = (s, success) => {
|
|
576
|
-
const mr = m('', toArray(stringToCodePointList(s)))
|
|
577
|
-
assertEq(mr[1] && mr[2]?.length === 0, success, mr)
|
|
578
|
-
}
|
|
575
|
+
const expect = expectMatch(m)
|
|
579
576
|
|
|
580
577
|
expect('a', true)
|
|
581
578
|
expect(' a ', true)
|
|
@@ -584,4 +581,22 @@ export const proof = {
|
|
|
584
581
|
expect(' [[a]] ', true)
|
|
585
582
|
expect('b', false)
|
|
586
583
|
},
|
|
584
|
+
// A Social Security Number, `ddd-dd-dddd`.
|
|
585
|
+
ssn: () => {
|
|
586
|
+
const ws = repeat0Plus(' ')
|
|
587
|
+
const d = range('09')
|
|
588
|
+
const ssn = /** @type {const} */([
|
|
589
|
+
ws, repeat(3)(d), ws, '-', ws, repeat(2)(d), ws, '-', ws, repeat(4)(d), ws])
|
|
590
|
+
|
|
591
|
+
const m = parser(ssn) // must not throw 'can not merge'
|
|
592
|
+
const expect = expectMatch(m)
|
|
593
|
+
|
|
594
|
+
expect('123-45-6789', true)
|
|
595
|
+
expect(' 123 - 45 - 6789 ', true)
|
|
596
|
+
expect('22', false) // too short
|
|
597
|
+
expect('123456789', false) // no dashes
|
|
598
|
+
expect('123-3456-78', false) // wrong grouping
|
|
599
|
+
expect('123-345-6789', false) // wrong grouping
|
|
600
|
+
expect('12a-34-5678', false) // a letter where a digit is required
|
|
601
|
+
}
|
|
587
602
|
}
|
package/fjs/bnf/module.f.d.mts
CHANGED
|
@@ -106,9 +106,9 @@ export declare const none: None;
|
|
|
106
106
|
/**
|
|
107
107
|
* Creates an option value from a required branch.
|
|
108
108
|
*/
|
|
109
|
-
export declare const option: <S extends Rule>(
|
|
109
|
+
export declare const option: <const S extends Rule>(
|
|
110
110
|
/**
|
|
111
|
-
* @template {Rule} S
|
|
111
|
+
* @template {Rule} const S
|
|
112
112
|
* @param {S} some
|
|
113
113
|
* @returns {Option<S>}
|
|
114
114
|
*/
|
package/fjs/bnf/module.f.mjs
CHANGED
|
@@ -236,7 +236,7 @@ export const none = []
|
|
|
236
236
|
*/
|
|
237
237
|
export const option =
|
|
238
238
|
/**
|
|
239
|
-
* @template {Rule} S
|
|
239
|
+
* @template {Rule} const S
|
|
240
240
|
* @param {S} some
|
|
241
241
|
* @returns {Option<S>}
|
|
242
242
|
*/
|
|
@@ -261,7 +261,7 @@ export const repeat0Plus =
|
|
|
261
261
|
* @returns {Repeat0Plus<T>}
|
|
262
262
|
*/
|
|
263
263
|
some => {
|
|
264
|
-
const r = () => option(
|
|
264
|
+
const r = () => option([some, r])
|
|
265
265
|
return r
|
|
266
266
|
}
|
|
267
267
|
|
package/fjs/cas/proof.f.mjs
CHANGED
|
@@ -215,20 +215,9 @@ export const proof = {
|
|
|
215
215
|
const hash = writeResult[1]
|
|
216
216
|
assertEq(length(hash), 256n, ['expected 256-bit hash', length(hash)])
|
|
217
217
|
assertEq(msb.cmp(hash)(computeSync(sha256)([content])), 0, 'write hash mismatch')
|
|
218
|
-
|
|
219
|
-
const drain = acc =>
|
|
220
|
-
stream =>
|
|
221
|
-
ioStep(
|
|
222
|
-
stream,
|
|
223
|
-
(node) => {
|
|
224
|
-
if (node === undefined) { return pureOk(acc) }
|
|
225
|
-
const { first, tail } = node
|
|
226
|
-
return drain([...acc, first])(tail)
|
|
227
|
-
},
|
|
228
|
-
)
|
|
229
|
-
const [, readResult] = virtual(state1)(drain([])(c.read(hash)))
|
|
218
|
+
const [, readResult] = virtual(state1)(collectRead(c.read(hash)))
|
|
230
219
|
assert(readResult[0] === 'ok', ['expected read ok', readResult])
|
|
231
|
-
assertEq(msb.cmp(
|
|
220
|
+
assertEq(msb.cmp(readResult[1])(content), 0, 'read content mismatch')
|
|
232
221
|
},
|
|
233
222
|
casReadMissingShard: () => {
|
|
234
223
|
// A missing shard fails the stream; it is never the `ok(undefined)` that
|
|
@@ -252,21 +241,10 @@ export const proof = {
|
|
|
252
241
|
assert(writeResult[0] === 'ok', ['expected write ok', writeResult])
|
|
253
242
|
const hash = writeResult[1]
|
|
254
243
|
assertEq(msb.cmp(hash)(computeSync(sha256)(chunks)), 0, 'multi-chunk write hash mismatch')
|
|
255
|
-
|
|
256
|
-
const drain = acc =>
|
|
257
|
-
stream =>
|
|
258
|
-
ioStep(
|
|
259
|
-
stream,
|
|
260
|
-
(node) => {
|
|
261
|
-
if (node === undefined) { return pureOk(acc) }
|
|
262
|
-
const { first, tail } = node
|
|
263
|
-
return drain([...acc, first])(tail)
|
|
264
|
-
},
|
|
265
|
-
)
|
|
266
|
-
const [, readResult] = virtual(state1)(drain([])(c.read(hash)))
|
|
244
|
+
const [, readResult] = virtual(state1)(collectRead(c.read(hash)))
|
|
267
245
|
assert(readResult[0] === 'ok', ['expected read ok', readResult])
|
|
268
246
|
const expected = msb.concat(msb.concat(chunks[0])(chunks[1]))(chunks[2])
|
|
269
|
-
assertEq(msb.cmp(
|
|
247
|
+
assertEq(msb.cmp(readResult[1])(expected), 0, 'multi-chunk read content mismatch')
|
|
270
248
|
},
|
|
271
249
|
casWriteDedup: () => {
|
|
272
250
|
// Same content ⇒ same hash; the second upload's replace-`rename` publishes over the
|
|
@@ -18,6 +18,12 @@ export const os = /** @type {const} */ (['ubuntu', 'macos', 'windows'])
|
|
|
18
18
|
|
|
19
19
|
export const architecture = /** @type {const} */ (['intel', 'arm'])
|
|
20
20
|
|
|
21
|
+
// These three are **closed**, which is the bare form's meaning and the right
|
|
22
|
+
// one here: `parseGitHubAction` reads back a workflow this repo generates, so
|
|
23
|
+
// a key the schema does not name is generator drift rather than a field a
|
|
24
|
+
// third party added. Reading a hand-written workflow — which carries `name`,
|
|
25
|
+
// `if`, `env` and much else — would need `open`.
|
|
26
|
+
|
|
21
27
|
export const stepSchema = /** @type {const} */ ({
|
|
22
28
|
run: option(string),
|
|
23
29
|
uses: option(string),
|
|
@@ -18,20 +18,20 @@ export declare const images: {
|
|
|
18
18
|
readonly arm: 'windows-11-arm';
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
|
-
export declare const functionalscript = /** @type {const} */ "0.
|
|
22
|
-
export declare const bun = "1.
|
|
21
|
+
export declare const functionalscript = /** @type {const} */ "0.46.1";
|
|
22
|
+
export declare const bun = "1.4.0";
|
|
23
23
|
export declare const deno = "2.9.5";
|
|
24
24
|
export declare const node: {
|
|
25
25
|
readonly default: '26.7.0';
|
|
26
26
|
readonly node22: '22.23.2';
|
|
27
|
-
readonly node24: '24.
|
|
27
|
+
readonly node24: '24.19.0';
|
|
28
28
|
};
|
|
29
29
|
export declare const nixpkgs: {
|
|
30
30
|
readonly ref: 'nixos-26.05';
|
|
31
|
-
readonly commit: '
|
|
31
|
+
readonly commit: 'f4f698677b11021a8f84f452e23ae9ef2427bec3';
|
|
32
32
|
};
|
|
33
|
-
export declare const wasmtime = "
|
|
34
|
-
export declare const wasmer = "7.
|
|
33
|
+
export declare const wasmtime = "48.0.1";
|
|
34
|
+
export declare const wasmer = "7.3.0";
|
|
35
35
|
export declare const actions: {
|
|
36
36
|
readonly 'actions/checkout': 'v7.0.1';
|
|
37
37
|
readonly 'actions/setup-node': 'v7.0.0';
|
|
@@ -41,5 +41,5 @@ export declare const actions: {
|
|
|
41
41
|
readonly 'bytecodealliance/actions/wasmtime/setup': 'v1.1.3';
|
|
42
42
|
readonly 'wasmerio/setup-wasmer': 'v3.1';
|
|
43
43
|
readonly 'cachix/install-nix-action': 'v31.11.1';
|
|
44
|
-
readonly 'dtolnay/rust-toolchain': '1.
|
|
44
|
+
readonly 'dtolnay/rust-toolchain': '1.98.0';
|
|
45
45
|
};
|
|
@@ -25,10 +25,10 @@ export const images = /** @type {const} */({
|
|
|
25
25
|
// published FunctionalScript release; do not tie it to package.json's current
|
|
26
26
|
// in-repo version.
|
|
27
27
|
// https://www.npmjs.com/package/functionalscript
|
|
28
|
-
export const functionalscript = /** @type {const} */ '0.
|
|
28
|
+
export const functionalscript = /** @type {const} */ '0.46.1'
|
|
29
29
|
|
|
30
30
|
// https://bun.sh/
|
|
31
|
-
export const bun = '1.
|
|
31
|
+
export const bun = '1.4.0'
|
|
32
32
|
|
|
33
33
|
// https://deno.com/
|
|
34
34
|
export const deno = '2.9.5'
|
|
@@ -43,7 +43,7 @@ export const deno = '2.9.5'
|
|
|
43
43
|
export const node = /** @type {const} */({
|
|
44
44
|
default: '26.7.0',
|
|
45
45
|
node22: '22.23.2',
|
|
46
|
-
node24: '24.
|
|
46
|
+
node24: '24.19.0',
|
|
47
47
|
})
|
|
48
48
|
|
|
49
49
|
// Official Nixpkgs snapshot used by the generated CI flakes. `ref` is the
|
|
@@ -53,14 +53,14 @@ export const node = /** @type {const} */({
|
|
|
53
53
|
// https://channels.nixos.org/nixos-26.05/git-revision
|
|
54
54
|
export const nixpkgs = /** @type {const} */({
|
|
55
55
|
ref: 'nixos-26.05',
|
|
56
|
-
commit: '
|
|
56
|
+
commit: 'f4f698677b11021a8f84f452e23ae9ef2427bec3',
|
|
57
57
|
})
|
|
58
58
|
|
|
59
59
|
// https://github.com/bytecodealliance/wasmtime/releases
|
|
60
|
-
export const wasmtime = '
|
|
60
|
+
export const wasmtime = '48.0.1'
|
|
61
61
|
|
|
62
62
|
// https://github.com/wasmerio/wasmer/releases
|
|
63
|
-
export const wasmer = '7.
|
|
63
|
+
export const wasmer = '7.3.0'
|
|
64
64
|
|
|
65
65
|
// GitHub Action versions used by CI step builders. The key is the action
|
|
66
66
|
// `owner/name`; call sites compose the full ref as
|
|
@@ -85,5 +85,5 @@ export const actions = /** @type {const} */({
|
|
|
85
85
|
// Enables the `nix-command` and `flakes` experimental features by default.
|
|
86
86
|
'cachix/install-nix-action': 'v31.11.1',
|
|
87
87
|
// https://rust-lang.org/ - value is Rust version, not action version
|
|
88
|
-
'dtolnay/rust-toolchain': '1.
|
|
88
|
+
'dtolnay/rust-toolchain': '1.98.0',
|
|
89
89
|
})
|
package/fjs/cli/module.f.mjs
CHANGED
|
@@ -14,19 +14,23 @@ import { at, fromEntries } from '../types/object/module.f.mjs'
|
|
|
14
14
|
|
|
15
15
|
const helpMeta = { names: ['help', 'h', '?'], description: 'Print this help message' }
|
|
16
16
|
|
|
17
|
-
/** @type {<O extends NodeOp>(commands: Commands<O>) =>
|
|
18
|
-
|
|
19
|
-
const [cmd, ...rest] = options.args
|
|
17
|
+
/** @type {<O extends NodeOp>(commands: Commands<O>) => string} */
|
|
18
|
+
const renderHelp = commands => {
|
|
20
19
|
const rows = [...commands, helpMeta]
|
|
21
|
-
const nameCol = rows.map(({names}) => names.join(', '))
|
|
22
|
-
const width = Math.max(...nameCol.map(({length}) => length))
|
|
23
|
-
|
|
20
|
+
const nameCol = rows.map(({ names }) => names.join(', '))
|
|
21
|
+
const width = Math.max(...nameCol.map(({ length }) => length))
|
|
22
|
+
return [
|
|
24
23
|
'Available commands:',
|
|
25
|
-
...rows.map(({description}, i) => ` ${nameCol[i].padEnd(width)} ${description}`)
|
|
24
|
+
...rows.map(({ description }, i) => ` ${nameCol[i].padEnd(width)} ${description}`)
|
|
26
25
|
].join('\n')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** @type {<O extends NodeOp>(commands: Commands<O>) => Program<O | Write>} */
|
|
29
|
+
export const dispatch = commands => options => {
|
|
30
|
+
const [cmd, ...rest] = options.args
|
|
27
31
|
const map = fromEntries(commands.flatMap(c => c.names.map(n => /** @type {const} */ ([n, c]))))
|
|
28
32
|
if (cmd === undefined) {
|
|
29
|
-
return errorExit(`Error: command is required.\n${
|
|
33
|
+
return errorExit(`Error: command is required.\n${renderHelp(commands)}`)
|
|
30
34
|
}
|
|
31
35
|
if (helpMeta.names.includes(cmd)) {
|
|
32
36
|
const [target] = rest
|
|
@@ -36,11 +40,11 @@ export const dispatch = commands => options => {
|
|
|
36
40
|
return dispatch(targetCmd.handler)({ ...options, args: ['help'] })
|
|
37
41
|
}
|
|
38
42
|
}
|
|
39
|
-
return exitStep(log(
|
|
43
|
+
return exitStep(log(renderHelp(commands)))
|
|
40
44
|
}
|
|
41
45
|
const found = at(cmd)(map)
|
|
42
46
|
if (found === null) {
|
|
43
|
-
return errorExit(`Error: unknown command "${cmd}".\n${
|
|
47
|
+
return errorExit(`Error: unknown command "${cmd}".\n${renderHelp(commands)}`)
|
|
44
48
|
}
|
|
45
49
|
const { handler } = found
|
|
46
50
|
return (typeof handler === 'function' ? handler : dispatch(handler))({ ...options, args: rest })
|
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
*
|
|
19
19
|
* @import { PrimeField } from '../../types/prime_field/types.ts'
|
|
20
20
|
* @import { Nullable } from '../../types/nullable/types.ts'
|
|
21
|
-
* @import { Unary } from '../../types/bigint/types.ts'
|
|
22
21
|
* @import { Sloth } from './types.ts'
|
|
23
22
|
*/
|
|
24
23
|
import type { Sloth } from './types.ts';
|
|
@@ -18,27 +18,16 @@
|
|
|
18
18
|
*
|
|
19
19
|
* @import { PrimeField } from '../../types/prime_field/types.ts'
|
|
20
20
|
* @import { Nullable } from '../../types/nullable/types.ts'
|
|
21
|
-
* @import { Unary } from '../../types/bigint/types.ts'
|
|
22
21
|
* @import { Sloth } from './types.ts'
|
|
23
22
|
*/
|
|
24
23
|
|
|
24
|
+
import { iterate } from '../../types/function/module.f.mjs'
|
|
25
25
|
import { modSqrt, prime_field } from '../../types/prime_field/module.f.mjs'
|
|
26
26
|
|
|
27
27
|
/** Sloth VDF modulus (3072-bit safe prime, same as reference implementations). */
|
|
28
28
|
export const p =
|
|
29
29
|
0xf2346eae06a23388_2814ff16f6a076d3_b8f2161c5c92171c_0b7b84eed4e9475b_cce0c13bde34512a_fdf90f41ab9b86dc_f834f85e04b27fad_ee712eed23a1d4e5_8cd1b09d9bfb1069_6d614f119179a40c_49dc8762edc29e81_15263913237e1471_8cbcd4dc6b35bace_13f8cdb1b5156c50_c47b4aaee0820c87_4e2864cb854367c3n
|
|
30
30
|
|
|
31
|
-
/** @type {(steps: bigint) => (f: Unary) => (value: bigint) => bigint} */
|
|
32
|
-
const repeatSeq = steps => f => value => {
|
|
33
|
-
let v = value
|
|
34
|
-
let i = 0n
|
|
35
|
-
while (i < steps) {
|
|
36
|
-
v = f(v)
|
|
37
|
-
i = i + 1n
|
|
38
|
-
}
|
|
39
|
-
return v
|
|
40
|
-
}
|
|
41
|
-
|
|
42
31
|
/**
|
|
43
32
|
* Builds Sloth VDF operations over `modulus`.
|
|
44
33
|
*
|
|
@@ -52,11 +41,11 @@ export const sloth_vdf = modulus => {
|
|
|
52
41
|
|
|
53
42
|
/** @type {(steps: bigint) => (value: bigint) => bigint} */
|
|
54
43
|
const squareLoop = steps => value =>
|
|
55
|
-
|
|
44
|
+
iterate(steps)(reduce(value))(pow2)
|
|
56
45
|
|
|
57
46
|
/** @type {(steps: bigint) => (value: bigint) => bigint} */
|
|
58
47
|
const modSqrtLoop = steps => value =>
|
|
59
|
-
|
|
48
|
+
iterate(steps)(reduce(value))(root)
|
|
60
49
|
|
|
61
50
|
/** @type {(steps: bigint) => (x: bigint) => Nullable<bigint>} */
|
|
62
51
|
const evalSteps = steps => x =>
|
package/fjs/dev/module.f.mjs
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import { allOk, import_, readdir } from '../effects/node/module.f.mjs'
|
|
13
13
|
import { cmp as strCmp } from '../types/string/module.f.mjs'
|
|
14
|
+
import { fromEntries } from '../types/object/module.f.mjs'
|
|
14
15
|
import { unwrap } from '../types/result/module.f.mjs'
|
|
15
16
|
import { mapStep, pureOk, step } from '../effects/module.f.mjs'
|
|
16
17
|
import { join, relativize, toPosix } from '../path/module.f.mjs'
|
|
@@ -55,24 +56,14 @@ const allFiles = (s, predicate) => {
|
|
|
55
56
|
const load = p => {
|
|
56
57
|
const listed = step(
|
|
57
58
|
readdir(p, {}),
|
|
58
|
-
d => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (name === 'node_modules') { continue }
|
|
67
|
-
result = [...result, load(file)]
|
|
68
|
-
continue
|
|
69
|
-
}
|
|
70
|
-
if (predicate(file)) {
|
|
71
|
-
result = [...result, pureOk([file])]
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return allOk(...result)
|
|
75
|
-
})
|
|
59
|
+
d => allOk(...d.flatMap(i => {
|
|
60
|
+
const { name } = i
|
|
61
|
+
if (name.startsWith('.')) { return [] }
|
|
62
|
+
const file = join(p, name)
|
|
63
|
+
return i.isFile
|
|
64
|
+
? (predicate(file) ? [pureOk([file])] : [])
|
|
65
|
+
: (name === 'node_modules' ? [] : [load(file)])
|
|
66
|
+
})))
|
|
76
67
|
return mapStep(listed, v => v.flat())
|
|
77
68
|
}
|
|
78
69
|
return load(s)
|
|
@@ -82,8 +73,6 @@ const allFiles = (s, predicate) => {
|
|
|
82
73
|
const loadFile = f =>
|
|
83
74
|
mapStep(import_(f), m => [/** @type {const} */ ([f, m])])
|
|
84
75
|
|
|
85
|
-
const { fromEntries } = Object
|
|
86
|
-
|
|
87
76
|
/**
|
|
88
77
|
* Discovers all source files under `INIT_CWD` (or `.` if unset) that match
|
|
89
78
|
* `predicate`, imports them, and returns a map from relative path to module
|
|
@@ -142,6 +131,7 @@ export const proof = {
|
|
|
142
131
|
// still skipped.
|
|
143
132
|
/** @type {Dir} */
|
|
144
133
|
const root = {
|
|
134
|
+
'.hidden.f.ts': [],
|
|
145
135
|
'a.f.ts': [],
|
|
146
136
|
'b.f.mjs': [],
|
|
147
137
|
'c.f.mts': [],
|