functionalscript 0.32.3 → 0.33.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/fs/bnf/data/proof.f.d.ts +3 -0
- package/fs/bnf/data/proof.f.js +7 -0
- package/fs/cas/mcp/module.f.d.ts +4 -4
- package/fs/cas/mcp/module.f.js +21 -17
- package/fs/cas/mcp/proof.f.d.ts +1 -0
- package/fs/cas/mcp/proof.f.js +62 -42
- package/fs/cas/module.f.d.ts +13 -21
- package/fs/cas/module.f.js +100 -54
- package/fs/cas/proof.f.js +15 -24
- package/fs/ci/config/module.f.d.ts +6 -6
- package/fs/ci/config/module.f.js +6 -6
- package/fs/ci/proof.f.js +8 -6
- package/fs/cli/proof.f.js +2 -12
- package/fs/djs/parser/module.f.d.ts +0 -5
- package/fs/djs/proof.f.js +5 -6
- package/fs/djs/serializer/module.f.d.ts +1 -3
- package/fs/djs/tokenizer-new/module.f.js +2 -1
- package/fs/djs/tokenizer-new/proof.f.d.ts +1 -0
- package/fs/djs/tokenizer-new/proof.f.js +101 -67
- package/fs/djs/transpiler/proof.f.js +10 -10
- package/fs/effects/node/module.f.d.ts +8 -2
- package/fs/effects/node/module.f.js +3 -0
- package/fs/effects/node/module.js +21 -1
- package/fs/effects/node/proof.f.d.ts +15 -0
- package/fs/effects/node/proof.f.js +137 -26
- package/fs/effects/node/virtual/module.f.d.ts +18 -2
- package/fs/effects/node/virtual/module.f.js +185 -10
- package/fs/effects/node/virtual/proof.f.d.ts +14 -0
- package/fs/effects/node/virtual/proof.f.js +98 -5
- package/fs/emergent_testing/proof.f.js +3 -11
- package/fs/fjs/module.f.js +3 -3
- package/fs/fjs/proof.f.js +2 -11
- package/fs/js/tokenizer/module.f.d.ts +5 -0
- package/fs/js/tokenizer/module.f.js +13 -0
- package/fs/json/serializer/module.f.js +0 -1
- package/fs/text/sgr/proof.f.js +2 -11
- package/fs/types/bigint/module.f.d.ts +8 -15
- package/fs/types/bigint/module.f.js +9 -22
- package/fs/types/bigint/proof.f.d.ts +0 -2
- package/fs/types/bigint/proof.f.js +6 -16
- package/package.json +2 -2
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { assertEq } from "../../../asserts/module.f.js";
|
|
2
|
-
import { awaitIfPromise, fetch, rm, writeFile, readFile, readdir, import_ } from "../module.f.js";
|
|
3
|
-
import { vec8 } from "../../../types/bit_vec/module.f.js";
|
|
2
|
+
import { awaitIfPromise, fetch, rm, writeFile, readFile, readdir, import_, rename, readBytes } from "../module.f.js";
|
|
3
|
+
import { maxLengthBytes, vec, vec8 } from "../../../types/bit_vec/module.f.js";
|
|
4
4
|
import { emptyState, virtual } from "./module.f.js";
|
|
5
5
|
export const proof = {
|
|
6
6
|
rm: {
|
|
7
7
|
success: () => {
|
|
8
|
-
const root = { 'a.txt': vec8(0x42n) };
|
|
8
|
+
const root = { 'a.txt': [vec8(0x42n)] };
|
|
9
9
|
const [, result] = virtual({ ...emptyState, root })(rm('a.txt'));
|
|
10
10
|
assertEq(result[0], 'ok');
|
|
11
11
|
},
|
|
@@ -27,7 +27,7 @@ export const proof = {
|
|
|
27
27
|
assertEq(result[0], 'error');
|
|
28
28
|
},
|
|
29
29
|
readdirRecursive: () => {
|
|
30
|
-
const file = vec8(0x42n);
|
|
30
|
+
const file = [vec8(0x42n)];
|
|
31
31
|
const sub = { 'file.txt': file };
|
|
32
32
|
const outer = { 'sub': sub };
|
|
33
33
|
const root = { 'mydir': outer };
|
|
@@ -65,7 +65,7 @@ export const proof = {
|
|
|
65
65
|
},
|
|
66
66
|
importNonModule: () => {
|
|
67
67
|
// import_ on a Vec (not a JsModule) covers typeof entry !== 'function' branch
|
|
68
|
-
const root = { 'module.f.ts': vec8(0x42n) };
|
|
68
|
+
const root = { 'module.f.ts': [vec8(0x42n)] };
|
|
69
69
|
const [, result] = virtual({ ...emptyState, root })(import_('module.f.ts'));
|
|
70
70
|
assertEq(result[0], 'error');
|
|
71
71
|
},
|
|
@@ -76,4 +76,97 @@ export const proof = {
|
|
|
76
76
|
virtual({ ...emptyState, root })(readFile('a.f.ts'));
|
|
77
77
|
},
|
|
78
78
|
},
|
|
79
|
+
renameSamePath: () => {
|
|
80
|
+
// rename('a', 'a') should succeed as a no-op, not reject
|
|
81
|
+
const root = { 'a': [vec8(0x42n)] };
|
|
82
|
+
const [, result] = virtual({ ...emptyState, root })(rename('a', 'a'));
|
|
83
|
+
assertEq(result[0], 'ok');
|
|
84
|
+
},
|
|
85
|
+
renameIntoOwnSubtree: () => {
|
|
86
|
+
// rename('a', 'a/b') should fail (dst inside src's subtree)
|
|
87
|
+
const root = { 'a': { 'b': [vec8(0x42n)] } };
|
|
88
|
+
const [, result] = virtual({ ...emptyState, root })(rename('a', 'a/b'));
|
|
89
|
+
assertEq(result[0], 'error');
|
|
90
|
+
},
|
|
91
|
+
renameOntoOwnAncestor: () => {
|
|
92
|
+
// rename('a/b', 'a') should fail (src inside dst's subtree)
|
|
93
|
+
const root = { 'a': { 'b': [vec8(0x42n)] } };
|
|
94
|
+
const [, result] = virtual({ ...emptyState, root })(rename('a/b', 'a'));
|
|
95
|
+
assertEq(result[0], 'error');
|
|
96
|
+
},
|
|
97
|
+
renameNonEmptyDirOverEmptyDir: () => {
|
|
98
|
+
// rename a directory onto an empty directory should succeed
|
|
99
|
+
const root = { 'src': { 'file': [vec8(0x42n)] }, 'dst': {} };
|
|
100
|
+
const [, result] = virtual({ ...emptyState, root })(rename('src', 'dst'));
|
|
101
|
+
assertEq(result[0], 'ok');
|
|
102
|
+
},
|
|
103
|
+
renameEmptyDirOverNonEmptyDir: () => {
|
|
104
|
+
// rename an empty directory onto a non-empty directory should fail
|
|
105
|
+
const root = { 'src': {}, 'dst': { 'file': [vec8(0x42n)] } };
|
|
106
|
+
const [, result] = virtual({ ...emptyState, root })(rename('src', 'dst'));
|
|
107
|
+
assertEq(result[0], 'error');
|
|
108
|
+
},
|
|
109
|
+
renameFileOntoDirectory: () => {
|
|
110
|
+
// rename a file to a path that is already an existing directory should fail
|
|
111
|
+
const root = { 'myfile': [vec8(0x42n)], 'mydir': {} };
|
|
112
|
+
const [, result] = virtual({ ...emptyState, root })(rename('myfile', 'mydir'));
|
|
113
|
+
assertEq(result[0], 'error');
|
|
114
|
+
},
|
|
115
|
+
readFileTooLarge: () => {
|
|
116
|
+
// a file stored as two max-size chunks exceeds the limit; readFile must return an error
|
|
117
|
+
const chunk0 = vec(maxLengthBytes * 8n)(0n);
|
|
118
|
+
const chunk1 = vec(1n)(1n);
|
|
119
|
+
const root = { 'big': [chunk0, chunk1] };
|
|
120
|
+
const [, result] = virtual({ ...emptyState, root })(readFile('big'));
|
|
121
|
+
assertEq(result[0], 'error');
|
|
122
|
+
},
|
|
123
|
+
readBytesNegativeSize: () => {
|
|
124
|
+
// readBytes with negative size should fail
|
|
125
|
+
const root = { 'file': [vec8(0x42n)] };
|
|
126
|
+
const [, result] = virtual({ ...emptyState, root })(readBytes('file', 0, -1));
|
|
127
|
+
assertEq(result[0], 'error');
|
|
128
|
+
},
|
|
129
|
+
readBytesZeroSize: () => {
|
|
130
|
+
// readBytes with zero size should succeed and return empty vec
|
|
131
|
+
const root = { 'file': [vec8(0x42n)] };
|
|
132
|
+
const [, result] = virtual({ ...emptyState, root })(readBytes('file', 0, 0));
|
|
133
|
+
assertEq(result[0], 'ok');
|
|
134
|
+
},
|
|
135
|
+
readBytesNegativeOffset: () => {
|
|
136
|
+
// readBytes with negative offset should fail
|
|
137
|
+
const root = { 'file': [vec8(0x42n)] };
|
|
138
|
+
const [, result] = virtual({ ...emptyState, root })(readBytes('file', -1, 1));
|
|
139
|
+
assertEq(result[0], 'error');
|
|
140
|
+
},
|
|
141
|
+
readBytesFractionalSize: () => {
|
|
142
|
+
// readBytes with fractional size should fail rather than throw RangeError
|
|
143
|
+
const root = { 'file': [vec8(0x42n)] };
|
|
144
|
+
const [, result] = virtual({ ...emptyState, root })(readBytes('file', 0, 1.5));
|
|
145
|
+
assertEq(result[0], 'error');
|
|
146
|
+
},
|
|
147
|
+
readBytesFractionalOffset: () => {
|
|
148
|
+
// readBytes with fractional offset should fail rather than throw RangeError
|
|
149
|
+
const root = { 'file': [vec8(0x42n)] };
|
|
150
|
+
const [, result] = virtual({ ...emptyState, root })(readBytes('file', 0.5, 1));
|
|
151
|
+
assertEq(result[0], 'error');
|
|
152
|
+
},
|
|
153
|
+
readBytesAcrossChunkBoundary: () => {
|
|
154
|
+
// Two 128 KiB chunks; read 2 bytes spanning the boundary (last byte of chunk 0, first of chunk 1).
|
|
155
|
+
const chunkSize = Number(maxLengthBytes);
|
|
156
|
+
const chunk0 = vec(maxLengthBytes * 8n)(0xaan);
|
|
157
|
+
const chunk1 = vec(maxLengthBytes * 8n)(0xbbn);
|
|
158
|
+
const root = { 'big': [chunk0, chunk1] };
|
|
159
|
+
const [, result] = virtual({ ...emptyState, root })(readBytes('big', chunkSize - 1, 2));
|
|
160
|
+
assertEq(result[0], 'ok');
|
|
161
|
+
},
|
|
162
|
+
largeFileReadBytes: () => {
|
|
163
|
+
// A file stored as two 128 KiB chunks is larger than maxLengthBytes.
|
|
164
|
+
// readBytes within the second chunk (offset = 128 KiB, size = 1) should succeed.
|
|
165
|
+
const chunkSize = Number(maxLengthBytes);
|
|
166
|
+
const chunk0 = vec(maxLengthBytes * 8n)(0n);
|
|
167
|
+
const chunk1 = vec(maxLengthBytes * 8n)(0xffn);
|
|
168
|
+
const root = { 'large': [chunk0, chunk1] };
|
|
169
|
+
const [, result] = virtual({ ...emptyState, root })(readBytes('large', chunkSize, 1));
|
|
170
|
+
assertEq(result[0], 'ok');
|
|
171
|
+
},
|
|
79
172
|
};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { pure } from "../effects/module.f.js";
|
|
2
1
|
import { log } from "../effects/node/module.f.js";
|
|
3
|
-
import { emptyState } from "../effects/node/virtual/module.f.js";
|
|
2
|
+
import { defaultNodeProgramOptions, emptyState } from "../effects/node/virtual/module.f.js";
|
|
4
3
|
import { virtual } from "../effects/node/virtual/module.f.js";
|
|
5
|
-
import { assert, assertEq
|
|
4
|
+
import { assert, assertEq } from "../asserts/module.f.js";
|
|
6
5
|
import { testAll, defaultReporter, fmtPath, fmtTerm, fmtImport, ghEscape, isInteger, isIdentifier, registerModule, parseTestSet, defaultTest, } from "./module.f.js";
|
|
7
6
|
import { run as mockRun } from "../effects/mock/module.f.js";
|
|
8
7
|
import { shouldLoad } from "../dev/module.f.js";
|
|
@@ -13,16 +12,9 @@ const makeReporter = () => ({
|
|
|
13
12
|
summary: (pass, fail, time) => writeEvent(['summary', pass, fail, time]),
|
|
14
13
|
test: defaultTest,
|
|
15
14
|
});
|
|
16
|
-
const noopTestContext = { test: todo };
|
|
17
15
|
const options = (initCwd, github = false) => ({
|
|
18
|
-
|
|
16
|
+
...defaultNodeProgramOptions,
|
|
19
17
|
env: { INIT_CWD: initCwd, ...(github ? { GITHUB_ACTIONS: 'true' } : {}) },
|
|
20
|
-
home: '.',
|
|
21
|
-
std: { stdout: { isTTY: false }, stderr: { isTTY: false } },
|
|
22
|
-
testContext: noopTestContext,
|
|
23
|
-
bunTestContext: noopTestContext,
|
|
24
|
-
playwrightTestContext: noopTestContext,
|
|
25
|
-
engine: 'node',
|
|
26
18
|
});
|
|
27
19
|
const ok0 = () => ({ result: ['ok', undefined], duration: 0 });
|
|
28
20
|
const fail0 = () => ({ result: ['error', 'oops'], duration: 0 });
|
package/fs/fjs/module.f.js
CHANGED
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { compile } from "../djs/module.f.js";
|
|
7
7
|
import { main as testMain } from "../emergent_testing/module.f.js";
|
|
8
|
-
import { commands as casCommands } from "../cas/module.f.js";
|
|
8
|
+
import { commands as casCommands, fileCas } from "../cas/module.f.js";
|
|
9
9
|
import { main as ciMain } from "../ci/module.f.js";
|
|
10
10
|
import { import_ } from "../effects/node/module.f.js";
|
|
11
11
|
import { dispatch } from "../cli/module.f.js";
|
|
12
12
|
import { casMcpServer } from "../cas/mcp/module.f.js";
|
|
13
|
-
import {
|
|
13
|
+
import { toPath } from "../cas/module.f.js";
|
|
14
14
|
import { sha256 } from "../crypto/sha2/module.f.js";
|
|
15
15
|
import { join } from "../path/module.f.js";
|
|
16
16
|
import { pure } from "../effects/module.f.js";
|
|
@@ -34,7 +34,7 @@ const commands = [
|
|
|
34
34
|
names: ['mcp', 'm'],
|
|
35
35
|
description: 'Run an MCP server over stdio exposing the CAS as tools',
|
|
36
36
|
handler: ({ home }) => {
|
|
37
|
-
const c =
|
|
37
|
+
const c = fileCas(sha256)(home);
|
|
38
38
|
return casMcpServer(c, home, hash => join(home, toPath(hash))).step(() => pure(0));
|
|
39
39
|
},
|
|
40
40
|
},
|
package/fs/fjs/proof.f.js
CHANGED
|
@@ -1,17 +1,8 @@
|
|
|
1
1
|
import { assert, assertEq } from "../asserts/module.f.js";
|
|
2
2
|
import { pure } from "../effects/module.f.js";
|
|
3
|
-
import { emptyState, virtual } from "../effects/node/virtual/module.f.js";
|
|
3
|
+
import { defaultNodeProgramOptions, emptyState, virtual } from "../effects/node/virtual/module.f.js";
|
|
4
4
|
import { main } from "./module.f.js";
|
|
5
|
-
const makeOptions = (args) => ({
|
|
6
|
-
args,
|
|
7
|
-
env: {},
|
|
8
|
-
home: '.',
|
|
9
|
-
std: { stdout: { isTTY: false }, stderr: { isTTY: false } },
|
|
10
|
-
testContext: { test: async () => { } },
|
|
11
|
-
bunTestContext: { test: async () => { } },
|
|
12
|
-
playwrightTestContext: { test: async () => { } },
|
|
13
|
-
engine: 'node',
|
|
14
|
-
});
|
|
5
|
+
const makeOptions = (args) => ({ ...defaultNodeProgramOptions, args });
|
|
15
6
|
const run = (root) => (args) => virtual({ ...emptyState, root })(main(makeOptions(args)));
|
|
16
7
|
const appMain = ({ args }) => pure(args.length);
|
|
17
8
|
export const proof = {
|
|
@@ -95,4 +95,9 @@ export type JsTokenWithMetadata = {
|
|
|
95
95
|
type ErrorMessage = '" are missing' | 'unescaped character' | 'invalid hex value' | 'unexpected character' | 'invalid number' | 'invalid token' | '*\/ expected' | 'unterminated string literal' | 'eof';
|
|
96
96
|
export declare const isKeywordToken: (token: JsToken) => boolean;
|
|
97
97
|
export declare const tokenize: (input: List<number>) => (path: string) => List<JsTokenWithMetadata>;
|
|
98
|
+
export declare const proof: {
|
|
99
|
+
throw: {
|
|
100
|
+
unionConflict: () => void;
|
|
101
|
+
};
|
|
102
|
+
};
|
|
98
103
|
export {};
|
|
@@ -27,6 +27,7 @@ leftSquareBracket, reverseSolidus, rightSquareBracket, lowLine,
|
|
|
27
27
|
latinSmallLetterRange, latinSmallLetterA, latinSmallLetterB, latinSmallLetterE, latinSmallLetterF, latinSmallLetterN, latinSmallLetterR, latinSmallLetterT, latinSmallLetterU,
|
|
28
28
|
//
|
|
29
29
|
leftCurlyBracket, rightCurlyBracket, dollarSign } from "../../text/ascii/module.f.js";
|
|
30
|
+
import { todo } from "../../asserts/module.f.js";
|
|
30
31
|
const { fromCharCode } = String;
|
|
31
32
|
const rangeOneNine = range('19');
|
|
32
33
|
const rangeSetNewLine = [
|
|
@@ -519,3 +520,15 @@ export const tokenize = input => path => {
|
|
|
519
520
|
const scan = scanTokenize({ state: { kind: 'initial' }, metadata: { path, line: 1, column: 1 } });
|
|
520
521
|
return flat(scan(flat([input /*satisfies List<CharCodeOrEof>*/, [null]])));
|
|
521
522
|
};
|
|
523
|
+
export const proof = {
|
|
524
|
+
throw: {
|
|
525
|
+
// union throws when two distinct non-default handlers are merged for the same range;
|
|
526
|
+
// this path is unreachable through the public API (no overlapping ranges in practice).
|
|
527
|
+
unionConflict: () => {
|
|
528
|
+
const def = (_) => todo;
|
|
529
|
+
const a = (_) => todo;
|
|
530
|
+
const b = (_) => todo;
|
|
531
|
+
union(def)(a)(b);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
};
|
package/fs/text/sgr/proof.f.js
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
import { fgRed, reset, createConsoleText, backspace, csiWrite } from "./module.f.js";
|
|
2
|
-
import { virtual, emptyState } from "../../effects/node/virtual/module.f.js";
|
|
3
|
-
const makeOptions = (isTTY) => ({
|
|
4
|
-
args: [],
|
|
5
|
-
env: {},
|
|
6
|
-
home: '.',
|
|
7
|
-
std: { stdout: { isTTY }, stderr: { isTTY } },
|
|
8
|
-
testContext: { test: async () => { } },
|
|
9
|
-
bunTestContext: { test: async () => { } },
|
|
10
|
-
playwrightTestContext: { test: async () => { } },
|
|
11
|
-
engine: 'node',
|
|
12
|
-
});
|
|
2
|
+
import { virtual, emptyState, defaultNodeProgramOptions } from "../../effects/node/virtual/module.f.js";
|
|
3
|
+
const makeOptions = (isTTY) => ({ ...defaultNodeProgramOptions, std: { stdout: { isTTY }, stderr: { isTTY } } });
|
|
13
4
|
export const proof = [
|
|
14
5
|
() => {
|
|
15
6
|
if (fgRed !== '\x1b[31m') {
|
|
@@ -156,24 +156,17 @@ export declare const xor: Reduce;
|
|
|
156
156
|
export declare const divUp: (b: bigint) => Unary;
|
|
157
157
|
export declare const roundUp: (b: bigint) => Unary;
|
|
158
158
|
/**
|
|
159
|
-
*
|
|
159
|
+
* Converts a bit count to a byte count, rounding up — divides by `8`.
|
|
160
160
|
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
|
|
164
|
-
export declare const divUpE2: (e: bigint) => Unary;
|
|
165
|
-
/**
|
|
166
|
-
* Rounds a bigint value up to the nearest multiple of 2^e (shift-based, power-of-two only).
|
|
167
|
-
*
|
|
168
|
-
* @param e - The exponent (multiple = 2^e).
|
|
169
|
-
* @returns A function that rounds a value up to the nearest multiple of the given power of two.
|
|
170
|
-
*/
|
|
171
|
-
export declare const roundUpE2: (e: bigint) => Unary;
|
|
172
|
-
/**
|
|
173
|
-
* Converts a bit count to a byte count, rounding up — divides by `8` (`2^3` bits per byte).
|
|
161
|
+
* Domain: non-negative inputs (bit/byte counts). On negative inputs `divUp`
|
|
162
|
+
* truncates toward zero rather than flooring toward −∞, so the rounding
|
|
163
|
+
* direction is only meaningful for `v >= 0n`.
|
|
174
164
|
*/
|
|
175
165
|
export declare const divUp8: Unary;
|
|
176
166
|
/**
|
|
177
|
-
* Rounds a bit count up to the nearest whole byte — the nearest multiple of `8
|
|
167
|
+
* Rounds a bit count up to the nearest whole byte — the nearest multiple of `8`.
|
|
168
|
+
*
|
|
169
|
+
* Domain: non-negative inputs (bit/byte counts). See `divUp8` for the
|
|
170
|
+
* truncate-vs-floor caveat on negative values.
|
|
178
171
|
*/
|
|
179
172
|
export declare const roundUp8: Unary;
|
|
@@ -234,30 +234,17 @@ export const roundUp = (b) => {
|
|
|
234
234
|
return v => d(v) * b;
|
|
235
235
|
};
|
|
236
236
|
/**
|
|
237
|
-
*
|
|
237
|
+
* Converts a bit count to a byte count, rounding up — divides by `8`.
|
|
238
238
|
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
239
|
+
* Domain: non-negative inputs (bit/byte counts). On negative inputs `divUp`
|
|
240
|
+
* truncates toward zero rather than flooring toward −∞, so the rounding
|
|
241
|
+
* direction is only meaningful for `v >= 0n`.
|
|
241
242
|
*/
|
|
242
|
-
export const
|
|
243
|
-
const m = mask(e);
|
|
244
|
-
return v => (v + m) >> e;
|
|
245
|
-
};
|
|
243
|
+
export const divUp8 = divUp(8n);
|
|
246
244
|
/**
|
|
247
|
-
* Rounds a
|
|
245
|
+
* Rounds a bit count up to the nearest whole byte — the nearest multiple of `8`.
|
|
248
246
|
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*/
|
|
252
|
-
export const roundUpE2 = (e) => {
|
|
253
|
-
const d = divUpE2(e);
|
|
254
|
-
return v => d(v) << e;
|
|
255
|
-
};
|
|
256
|
-
/**
|
|
257
|
-
* Converts a bit count to a byte count, rounding up — divides by `8` (`2^3` bits per byte).
|
|
258
|
-
*/
|
|
259
|
-
export const divUp8 = divUpE2(3n);
|
|
260
|
-
/**
|
|
261
|
-
* Rounds a bit count up to the nearest whole byte — the nearest multiple of `8` (`2^3` bits per byte).
|
|
247
|
+
* Domain: non-negative inputs (bit/byte counts). See `divUp8` for the
|
|
248
|
+
* truncate-vs-floor caveat on negative values.
|
|
262
249
|
*/
|
|
263
|
-
export const roundUp8 =
|
|
250
|
+
export const roundUp8 = roundUp(8n);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { sum, abs, serialize, log2, bitLength, mask, combination, factorial, xor, multiple, product, divUp, roundUp,
|
|
1
|
+
import { sum, abs, serialize, log2, bitLength, mask, combination, factorial, xor, multiple, product, divUp, roundUp, divUp8, roundUp8 } from "./module.f.js";
|
|
2
2
|
import { assertEq } from "../../asserts/module.f.js";
|
|
3
3
|
import { min } from "../function/compare/module.f.js";
|
|
4
4
|
const oldLog2 = (v) => {
|
|
@@ -463,32 +463,22 @@ export const proof = {
|
|
|
463
463
|
assertEq(roundUp(8n)(15n), 16n);
|
|
464
464
|
assertEq(roundUp(8n)(3n), 8n);
|
|
465
465
|
},
|
|
466
|
-
divUpE2: () => {
|
|
467
|
-
assertEq(divUpE2(3n)(8n), 1n);
|
|
468
|
-
assertEq(divUpE2(3n)(15n), 2n);
|
|
469
|
-
assertEq(divUpE2(3n)(0n), 0n);
|
|
470
|
-
assertEq(divUpE2(3n)(8n), 1n);
|
|
471
|
-
assertEq(divUpE2(3n)(9n), 2n);
|
|
472
|
-
},
|
|
473
|
-
roundUpE2: () => {
|
|
474
|
-
assertEq(roundUpE2(3n)(8n), 8n);
|
|
475
|
-
assertEq(roundUpE2(3n)(15n), 16n);
|
|
476
|
-
assertEq(roundUpE2(3n)(3n), 8n);
|
|
477
|
-
assertEq(roundUpE2(3n)(0n), 0n);
|
|
478
|
-
assertEq(roundUpE2(3n)(8n), 8n);
|
|
479
|
-
assertEq(roundUpE2(3n)(9n), 16n);
|
|
480
|
-
},
|
|
481
466
|
divUp8: () => {
|
|
482
467
|
assertEq(divUp8(0n), 0n);
|
|
483
468
|
assertEq(divUp8(1n), 1n);
|
|
484
469
|
assertEq(divUp8(8n), 1n);
|
|
470
|
+
assertEq(divUp8(8n), 1n);
|
|
485
471
|
assertEq(divUp8(9n), 2n);
|
|
472
|
+
assertEq(divUp8(15n), 2n);
|
|
486
473
|
},
|
|
487
474
|
roundUp8: () => {
|
|
488
475
|
assertEq(roundUp8(0n), 0n);
|
|
489
476
|
assertEq(roundUp8(1n), 8n);
|
|
477
|
+
assertEq(roundUp8(3n), 8n);
|
|
478
|
+
assertEq(roundUp8(8n), 8n);
|
|
490
479
|
assertEq(roundUp8(8n), 8n);
|
|
491
480
|
assertEq(roundUp8(9n), 16n);
|
|
481
|
+
assertEq(roundUp8(15n), 16n);
|
|
492
482
|
},
|
|
493
483
|
xor: () => {
|
|
494
484
|
assertEq(xor(5n)(3n), 6n);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "functionalscript",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"**/*.js",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"homepage": "https://github.com/functionalscript/functionalscript#readme",
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@playwright/test": "1.61.0",
|
|
47
|
-
"@types/node": "
|
|
47
|
+
"@types/node": "26.0.0",
|
|
48
48
|
"typescript": "6.0.3"
|
|
49
49
|
}
|
|
50
50
|
}
|