functionalscript 0.22.0 → 0.24.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.
Files changed (82) hide show
  1. package/fs/asn.1/module.f.js +2 -1
  2. package/fs/cas/module.f.d.ts +2 -2
  3. package/fs/cas/module.f.js +2 -2
  4. package/fs/cas/proof.f.d.ts +9 -0
  5. package/fs/cas/proof.f.js +98 -4
  6. package/fs/ci/config/module.f.d.ts +2 -2
  7. package/fs/ci/config/module.f.js +2 -2
  8. package/fs/ci/module.f.d.ts +2 -2
  9. package/fs/ci/module.f.js +2 -2
  10. package/fs/ci/proof.f.js +1 -1
  11. package/fs/crypto/pow/module.f.d.ts +37 -0
  12. package/fs/crypto/pow/module.f.js +72 -0
  13. package/fs/crypto/pow/proof.f.d.ts +33 -0
  14. package/fs/crypto/pow/proof.f.js +161 -0
  15. package/fs/dev/module.f.d.ts +2 -9
  16. package/fs/dev/module.f.js +12 -11
  17. package/fs/dev/proof.f.d.ts +0 -1
  18. package/fs/dev/proof.f.js +0 -21
  19. package/fs/dev/version/module.f.d.ts +2 -2
  20. package/fs/dev/version/module.f.js +2 -2
  21. package/fs/dev/version/proof.f.js +2 -2
  22. package/fs/djs/module.f.d.ts +2 -2
  23. package/fs/djs/module.f.js +2 -2
  24. package/fs/djs/parser/module.f.d.ts +0 -2
  25. package/fs/djs/proof.f.js +1 -1
  26. package/fs/djs/transpiler/module.f.d.ts +2 -2
  27. package/fs/djs/transpiler/module.f.js +2 -2
  28. package/fs/djs/transpiler/proof.f.js +1 -1
  29. package/fs/{types/effects → effects}/module.f.d.ts +1 -1
  30. package/fs/{types/effects → effects}/module.f.js +1 -1
  31. package/fs/effects/node/module.d.ts +20 -0
  32. package/fs/{types/effects → effects}/node/module.f.d.ts +3 -3
  33. package/fs/{types/effects → effects}/node/module.f.js +1 -1
  34. package/fs/effects/node/module.js +231 -0
  35. package/fs/{types/effects → effects}/node/proof.f.js +1 -1
  36. package/fs/{types/effects → effects}/node/virtual/module.f.d.ts +1 -1
  37. package/fs/{types/effects → effects}/node/virtual/module.f.js +5 -5
  38. package/fs/emergent_testing/all.test.js +3 -2
  39. package/fs/emergent_testing/example.f.d.ts +13 -0
  40. package/fs/emergent_testing/example.f.js +31 -0
  41. package/fs/emergent_testing/module.f.d.ts +2 -2
  42. package/fs/emergent_testing/module.f.js +2 -2
  43. package/fs/emergent_testing/proof.f.js +4 -4
  44. package/fs/emergent_testing/scenarios/all.d.ts +1 -1
  45. package/fs/emergent_testing/scenarios/all.js +1 -3
  46. package/fs/fjs/module.f.d.ts +1 -1
  47. package/fs/fjs/module.f.js +1 -1
  48. package/fs/fjs/module.js +2 -2
  49. package/fs/path/module.f.d.ts +4 -0
  50. package/fs/path/module.f.js +5 -1
  51. package/fs/path/proof.f.d.ts +1 -0
  52. package/fs/path/proof.f.js +28 -2
  53. package/fs/text/sgr/module.f.d.ts +2 -17
  54. package/fs/text/sgr/module.f.js +4 -19
  55. package/fs/types/bigint/module.f.d.ts +0 -15
  56. package/fs/types/bigint/module.f.js +0 -15
  57. package/fs/types/bigint/proof.f.js +2 -1
  58. package/fs/types/bit_vec/module.f.js +2 -2
  59. package/fs/types/function/compare/module.f.d.ts +12 -0
  60. package/fs/types/function/compare/module.f.js +12 -0
  61. package/fs/types/function/compare/proof.f.js +31 -1
  62. package/fs/types/function/operator/module.f.d.ts +0 -2
  63. package/fs/types/function/operator/module.f.js +0 -2
  64. package/fs/types/function/operator/proof.f.d.ts +0 -2
  65. package/fs/types/function/operator/proof.f.js +2 -18
  66. package/fs/types/number/module.f.js +4 -4
  67. package/fs/website/module.f.d.ts +2 -2
  68. package/fs/website/module.f.js +2 -2
  69. package/package.json +1 -1
  70. package/fs/emergent_testing/module.d.ts +0 -1
  71. package/fs/emergent_testing/module.js +0 -4
  72. package/fs/io/module.d.ts +0 -9
  73. package/fs/io/module.f.d.ts +0 -134
  74. package/fs/io/module.f.js +0 -113
  75. package/fs/io/module.js +0 -132
  76. /package/fs/{types/effects → effects}/mock/module.f.d.ts +0 -0
  77. /package/fs/{types/effects → effects}/mock/module.f.js +0 -0
  78. /package/fs/{types/effects → effects}/module.d.ts +0 -0
  79. /package/fs/{types/effects → effects}/module.js +0 -0
  80. /package/fs/{types/effects → effects}/node/proof.f.d.ts +0 -0
  81. /package/fs/{types/effects → effects}/proof.f.d.ts +0 -0
  82. /package/fs/{types/effects → effects}/proof.f.js +0 -0
@@ -4,9 +4,10 @@
4
4
  *
5
5
  * @module
6
6
  */
7
- import { bitLength, max } from "../types/bigint/module.f.js";
7
+ import { bitLength } from "../types/bigint/module.f.js";
8
8
  import { empty, isVec, length, msb, uint, unpack, vec, vec8 } from "../types/bit_vec/module.f.js";
9
9
  import { identity } from "../types/function/module.f.js";
10
+ import { max } from "../types/function/compare/module.f.js";
10
11
  import { encode as b128encode, decode as b128decode } from "../base128/module.f.js";
11
12
  const { popFront: pop, listToVec } = msb;
12
13
  const pop8 = pop(8n);
@@ -5,8 +5,8 @@
5
5
  */
6
6
  import { type Sha2 } from '../crypto/sha2/module.f.ts';
7
7
  import type { Vec } from '../types/bit_vec/module.f.ts';
8
- import { type Effect, type Operation } from '../types/effects/module.f.ts';
9
- import { type Fs, type NodeOp } from '../types/effects/node/module.f.ts';
8
+ import { type Effect, type Operation } from '../effects/module.f.ts';
9
+ import { type Fs, type NodeOp } from '../effects/node/module.f.ts';
10
10
  export type KvStore<O extends Operation> = {
11
11
  /** Reads a value by key; returns `undefined` when the key does not exist. */
12
12
  readonly read: (key: Vec) => Effect<O, Vec | undefined>;
@@ -6,8 +6,8 @@
6
6
  import { computeSync, sha256 } from "../crypto/sha2/module.f.js";
7
7
  import { parse } from "../path/module.f.js";
8
8
  import { cBase32ToVec, vecToCBase32 } from "../cbase32/module.f.js";
9
- import { begin, forEachStep, pure } from "../types/effects/module.f.js";
10
- import { errorExit, log, mkdir, readdir, readFile, writeFile } from "../types/effects/node/module.f.js";
9
+ import { begin, forEachStep, pure } from "../effects/module.f.js";
10
+ import { errorExit, log, mkdir, readdir, readFile, writeFile } from "../effects/node/module.f.js";
11
11
  import { toOption } from "../types/nullable/module.f.js";
12
12
  import { unwrap } from "../types/result/module.f.js";
13
13
  const o = { withFileTypes: true };
@@ -1,4 +1,13 @@
1
1
  export declare const proof: {
2
+ mainAdd: () => void;
3
+ mainAddWrongArgs: () => void;
4
+ mainGetFound: () => void;
5
+ mainGetNotFound: () => void;
6
+ mainGetWrongArgs: () => void;
7
+ mainGetInvalidHash: () => void;
8
+ mainList: () => void;
9
+ mainNoCmd: () => void;
10
+ mainUnknownCmd: () => void;
2
11
  casWrite: () => void;
3
12
  casReadPassthrough: () => void;
4
13
  };
package/fs/cas/proof.f.js CHANGED
@@ -1,9 +1,103 @@
1
- import { cas } from "./module.f.js";
1
+ import { cas, main } from "./module.f.js";
2
2
  import { sha256 } from "../crypto/sha2/module.f.js";
3
- import { empty, length } from "../types/bit_vec/module.f.js";
4
- import { pure } from "../types/effects/module.f.js";
5
- import { run } from "../types/effects/mock/module.f.js";
3
+ import { empty, length, vec8 } from "../types/bit_vec/module.f.js";
4
+ import { pure } from "../effects/module.f.js";
5
+ import { run } from "../effects/mock/module.f.js";
6
+ import { emptyState, virtual } from "../effects/node/virtual/module.f.js";
6
7
  export const proof = {
8
+ mainAdd: () => {
9
+ const content = vec8(0x2an);
10
+ const state = { ...emptyState, root: { myfile: content } };
11
+ const [finalState, exitCode] = virtual(state)(main(['add', 'myfile']));
12
+ if (exitCode !== 0) {
13
+ throw ['expected exit 0', exitCode];
14
+ }
15
+ if (finalState.stdout.length === 0) {
16
+ throw 'expected hash in stdout';
17
+ }
18
+ },
19
+ mainAddWrongArgs: () => {
20
+ const [finalState, exitCode] = virtual(emptyState)(main(['add']));
21
+ if (exitCode !== 1) {
22
+ throw ['expected exit 1', exitCode];
23
+ }
24
+ if (finalState.stderr.length === 0) {
25
+ throw 'expected error in stderr';
26
+ }
27
+ },
28
+ mainGetFound: () => {
29
+ const content = vec8(0x2an);
30
+ const state = { ...emptyState, root: { myfile: content } };
31
+ const [state1, exitCode1] = virtual(state)(main(['add', 'myfile']));
32
+ if (exitCode1 !== 0) {
33
+ throw ['expected add exit 0', exitCode1];
34
+ }
35
+ const hashStr = state1.stdout.trim();
36
+ const [, exitCode2] = virtual(state1)(main(['get', hashStr, 'output']));
37
+ if (exitCode2 !== 0) {
38
+ throw ['expected get exit 0', exitCode2];
39
+ }
40
+ },
41
+ mainGetNotFound: () => {
42
+ // valid cBase32 hash that has not been stored
43
+ const content = vec8(0x2an);
44
+ const state = { ...emptyState, root: { myfile: content } };
45
+ const [state1] = virtual(state)(main(['add', 'myfile']));
46
+ const hashStr = state1.stdout.trim();
47
+ // use an empty store so the hash is not found
48
+ const [finalState, exitCode] = virtual(emptyState)(main(['get', hashStr, 'output']));
49
+ if (exitCode !== 1) {
50
+ throw ['expected exit 1', exitCode];
51
+ }
52
+ if (finalState.stderr.length === 0) {
53
+ throw 'expected error in stderr';
54
+ }
55
+ },
56
+ mainGetWrongArgs: () => {
57
+ const [finalState, exitCode] = virtual(emptyState)(main(['get']));
58
+ if (exitCode !== 1) {
59
+ throw ['expected exit 1', exitCode];
60
+ }
61
+ if (finalState.stderr.length === 0) {
62
+ throw 'expected error in stderr';
63
+ }
64
+ },
65
+ mainGetInvalidHash: () => {
66
+ const [finalState, exitCode] = virtual(emptyState)(main(['get', 'not-a-valid-hash', 'output']));
67
+ if (exitCode !== 1) {
68
+ throw ['expected exit 1', exitCode];
69
+ }
70
+ if (finalState.stderr.length === 0) {
71
+ throw 'expected error in stderr';
72
+ }
73
+ },
74
+ mainList: () => {
75
+ const content = vec8(0x2an);
76
+ const state = { ...emptyState, root: { myfile: content } };
77
+ const [state1] = virtual(state)(main(['add', 'myfile']));
78
+ const [, exitCode] = virtual(state1)(main(['list']));
79
+ if (exitCode !== 0) {
80
+ throw ['expected exit 0', exitCode];
81
+ }
82
+ },
83
+ mainNoCmd: () => {
84
+ const [finalState, exitCode] = virtual(emptyState)(main([]));
85
+ if (exitCode !== 1) {
86
+ throw ['expected exit 1', exitCode];
87
+ }
88
+ if (finalState.stderr.length === 0) {
89
+ throw 'expected error in stderr';
90
+ }
91
+ },
92
+ mainUnknownCmd: () => {
93
+ const [finalState, exitCode] = virtual(emptyState)(main(['bogus']));
94
+ if (exitCode !== 1) {
95
+ throw ['expected exit 1', exitCode];
96
+ }
97
+ if (finalState.stderr.length === 0) {
98
+ throw 'expected error in stderr';
99
+ }
100
+ },
7
101
  casWrite: () => {
8
102
  const store = {
9
103
  read: (_key) => pure(undefined),
@@ -20,7 +20,7 @@ export declare const images: {
20
20
  };
21
21
  };
22
22
  export declare const bun = "1.3.14";
23
- export declare const deno = "2.8.1";
23
+ export declare const deno = "2.8.2";
24
24
  export declare const playwright = "1.60.0";
25
25
  export declare const node: {
26
26
  readonly default: "26.3.0";
@@ -28,7 +28,7 @@ export declare const node: {
28
28
  };
29
29
  export declare const wasmtime = "45.0.0";
30
30
  export declare const wasmer = "7.1.0";
31
- export declare const tsgo = "7.0.0-dev.20260601.1";
31
+ export declare const tsgo = "7.0.0-dev.20260604.1";
32
32
  export declare const actions: {
33
33
  readonly 'actions/checkout': "v6";
34
34
  readonly 'actions/setup-node': "v6";
@@ -23,7 +23,7 @@ export const images = {
23
23
  // https://bun.sh/
24
24
  export const bun = '1.3.14';
25
25
  // https://deno.com/
26
- export const deno = '2.8.1';
26
+ export const deno = '2.8.2';
27
27
  // https://www.npmjs.com/package/playwright
28
28
  export const playwright = '1.60.0';
29
29
  // https://nodejs.org/en/download
@@ -36,7 +36,7 @@ export const wasmtime = '45.0.0';
36
36
  // https://github.com/wasmerio/wasmer/releases
37
37
  export const wasmer = '7.1.0';
38
38
  // https://www.npmjs.com/package/@typescript/native-preview?activeTab=versions
39
- export const tsgo = '7.0.0-dev.20260601.1';
39
+ export const tsgo = '7.0.0-dev.20260604.1';
40
40
  // GitHub Action versions used by CI step builders. The key is the action
41
41
  // `owner/name`; call sites compose the full ref as
42
42
  // `` `${name}@${actions[name]}` ``.
@@ -1,5 +1,5 @@
1
- import { type Effect } from '../types/effects/module.f.ts';
2
- import { type NodeOp } from '../types/effects/node/module.f.ts';
1
+ import { type Effect } from '../effects/module.f.ts';
2
+ import { type NodeOp } from '../effects/node/module.f.ts';
3
3
  import { type MetaStep, type Os } from './common/module.f.ts';
4
4
  export type Setup = {
5
5
  readonly rust: boolean;
package/fs/ci/module.f.js CHANGED
@@ -4,8 +4,8 @@
4
4
  * @module
5
5
  */
6
6
  import { utf8 } from "../text/module.f.js";
7
- import { begin, pure } from "../types/effects/module.f.js";
8
- import { writeFile } from "../types/effects/node/module.f.js";
7
+ import { begin, pure } from "../effects/module.f.js";
8
+ import { writeFile } from "../effects/node/module.f.js";
9
9
  import { images } from "./config/module.f.js";
10
10
  import { architecture, findTgz, os, test, toSteps } from "./common/module.f.js";
11
11
  import { rustSteps } from "./rust/module.f.js";
package/fs/ci/proof.f.js CHANGED
@@ -3,7 +3,7 @@ import { utf8ToString } from "../text/module.f.js";
3
3
  import { isVec } from "../types/bit_vec/module.f.js";
4
4
  import { test, parseGitHubAction } from "./common/module.f.js";
5
5
  import { assert } from "../asserts/module.f.js";
6
- import { emptyState, virtual } from "../types/effects/node/virtual/module.f.js";
6
+ import { emptyState, virtual } from "../effects/node/virtual/module.f.js";
7
7
  import { parse as jsonParse } from "../json/module.f.js";
8
8
  import { unwrap } from "../types/result/module.f.js";
9
9
  const hasRun = (cmd) => (gha) => Object.values(gha.jobs).some(job => job.steps.some(step => step.run?.includes(cmd)));
@@ -0,0 +1,37 @@
1
+ import { type Vec } from '../../types/bit_vec/module.f.ts';
2
+ import type { Nullable } from '../../types/nullable/module.f.ts';
3
+ import { type Sha2 } from '../sha2/module.f.ts';
4
+ /** Genesis-block compact target (`0x1d00ffff`). */
5
+ export declare const genesisNBits = 486604799n;
6
+ /** Genesis-block uint256 target decoded from {@link genesisNBits}. */
7
+ export declare const genesisTarget = 26959535291011309493156476344723991336010898738574164086137773096960n;
8
+ /**
9
+ * Decodes compact **nBits** (32-bit block-header "bits") to a uint256 target:
10
+ *
11
+ * - `exponent = nBits >> 24`
12
+ * - `mantissa = nBits & 0xffffff`
13
+ * - `target = mantissa × 2^(8 × (exponent − 3))`
14
+ *
15
+ * Returns `null` for malformed encodings per Bitcoin `SetCompact` rules (negative
16
+ * sign bit, overflow, target wider than 256 bits).
17
+ *
18
+ * @param nBits - Compact target encoding.
19
+ * @returns Decoded target, or `null` when **nBits** is invalid.
20
+ */
21
+ export declare const targetFromNBits: (nBits: bigint) => Nullable<bigint>;
22
+ export type Pow = {
23
+ /** Hash `data` with the configured `Sha2`; digest as big-endian uint256. */
24
+ readonly hashInt: (data: Vec) => bigint;
25
+ /** Whether `hashInt(data) <= targetFromNBits(nBits)`; `false` when **nBits** is invalid. */
26
+ readonly meets: (nBits: bigint) => (data: Vec) => boolean;
27
+ };
28
+ /**
29
+ * Builds PoW helpers for a hash function (typical consumer: {@link sha256}).
30
+ *
31
+ * @param hash - SHA-2 configuration whose digest is compared as uint256.
32
+ */
33
+ export declare const pow: (hash: Sha2) => Pow;
34
+ /** SHA-256 proof-of-work (`pow(sha256)`). */
35
+ export declare const sha256Pow: Pow;
36
+ /** Bitcoin block-header PoW; same as {@link sha256Pow}. */
37
+ export declare const bitcoinPow: Pow;
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Bitcoin-style proof-of-work: compact **nBits** target decoding and
3
+ * hash-vs-target verification using an injected SHA-2 hash.
4
+ *
5
+ * @module
6
+ */
7
+ import { mask } from "../../types/bigint/module.f.js";
8
+ import { uint } from "../../types/bit_vec/module.f.js";
9
+ import { computeSync, sha256 } from "../sha2/module.f.js";
10
+ const nBitsMantissa = mask(24n);
11
+ const mantissaSign = 0x00800000n;
12
+ const mantissaBody = 0x007fffffn;
13
+ const exponentShift = 24n;
14
+ const uint256Mask = mask(256n);
15
+ /** Genesis-block compact target (`0x1d00ffff`). */
16
+ export const genesisNBits = 0x1d00ffffn;
17
+ /** Genesis-block uint256 target decoded from {@link genesisNBits}. */
18
+ export const genesisTarget = 0x00000000ffff0000000000000000000000000000000000000000000000000000n;
19
+ const decodeShift = (exponent) => 8n * (exponent - 3n);
20
+ const compactTarget = (exponent) => (mantissa) => {
21
+ const shift = decodeShift(exponent);
22
+ return shift >= 0n ? mantissa << shift : mantissa >> -shift;
23
+ };
24
+ const negativeNBits = (mantissa) => mantissa !== 0n && (mantissa & mantissaSign) !== 0n;
25
+ const overflowNBits = (exponent) => (mantissa) => (target) => target !== 0n &&
26
+ (exponent > 34n || (mantissa !== 0n && (mantissa & mantissaBody) === 0n));
27
+ /**
28
+ * Decodes compact **nBits** (32-bit block-header "bits") to a uint256 target:
29
+ *
30
+ * - `exponent = nBits >> 24`
31
+ * - `mantissa = nBits & 0xffffff`
32
+ * - `target = mantissa × 2^(8 × (exponent − 3))`
33
+ *
34
+ * Returns `null` for malformed encodings per Bitcoin `SetCompact` rules (negative
35
+ * sign bit, overflow, target wider than 256 bits).
36
+ *
37
+ * @param nBits - Compact target encoding.
38
+ * @returns Decoded target, or `null` when **nBits** is invalid.
39
+ */
40
+ export const targetFromNBits = (nBits) => {
41
+ const exponent = nBits >> exponentShift;
42
+ const mantissa = nBits & nBitsMantissa;
43
+ if (negativeNBits(mantissa)) {
44
+ return null;
45
+ }
46
+ const target = compactTarget(exponent)(mantissa);
47
+ if (overflowNBits(exponent)(mantissa)(target)) {
48
+ return null;
49
+ }
50
+ if (target > uint256Mask) {
51
+ return null;
52
+ }
53
+ return target;
54
+ };
55
+ /**
56
+ * Builds PoW helpers for a hash function (typical consumer: {@link sha256}).
57
+ *
58
+ * @param hash - SHA-2 configuration whose digest is compared as uint256.
59
+ */
60
+ export const pow = (hash) => {
61
+ const c = computeSync(hash);
62
+ const hashInt = (data) => uint(c([data]));
63
+ const meets = (nBits) => (data) => {
64
+ const target = targetFromNBits(nBits);
65
+ return target !== null && hashInt(data) <= target;
66
+ };
67
+ return { hashInt, meets };
68
+ };
69
+ /** SHA-256 proof-of-work (`pow(sha256)`). */
70
+ export const sha256Pow = pow(sha256);
71
+ /** Bitcoin block-header PoW; same as {@link sha256Pow}. */
72
+ export const bitcoinPow = sha256Pow;
@@ -0,0 +1,33 @@
1
+ export declare const proof: {
2
+ targetFromNBits: {
3
+ genesis: () => void;
4
+ block0HashWithinGenesisTarget: () => void;
5
+ exponent3: () => void;
6
+ exponent2: () => void;
7
+ hardTargetOne: () => void;
8
+ zero: () => void;
9
+ negative: () => void;
10
+ negativeHighMantissa: () => void;
11
+ overflowExponent: () => void;
12
+ exceeds256: () => void;
13
+ };
14
+ meets: {
15
+ easy: () => void;
16
+ hard: () => void;
17
+ genesisFailsSample: () => void;
18
+ zeroTargetRejectsSample: () => void;
19
+ invalidNBits: () => void;
20
+ hashLeqTarget: () => void;
21
+ };
22
+ hashInt: {
23
+ sha256Sample: () => void;
24
+ sha256Empty: () => void;
25
+ sha224: () => void;
26
+ stable: () => void;
27
+ };
28
+ pow: {
29
+ sha256Pow: () => void;
30
+ bitcoinPow: () => void;
31
+ independentInstances: () => void;
32
+ };
33
+ };
@@ -0,0 +1,161 @@
1
+ import { utf8 } from "../../text/module.f.js";
2
+ import { empty, uint } from "../../types/bit_vec/module.f.js";
3
+ import { computeSync, sha224, sha256 } from "../sha2/module.f.js";
4
+ import { bitcoinPow, genesisNBits, genesisTarget, pow, sha256Pow, targetFromNBits } from "./module.f.js";
5
+ const p256 = sha256Pow;
6
+ const p224 = pow(sha224);
7
+ const sample = utf8('functionalscript pow proof');
8
+ const emptyData = empty;
9
+ /** Target large enough for {@link sample} under SHA-256 (`0x207fffff`). */
10
+ const easyNBits = 0x207fffffn;
11
+ /** Compact encoding for target `1` (`0x03000001`). */
12
+ const hardNBits = 0x03000001n;
13
+ /** SHA-256 of the empty message (NIST / Bitcoin block merkle uses this primitive). */
14
+ const sha256EmptyHash = 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855n;
15
+ /** Bitcoin block #0 header hash as big-endian uint256. */
16
+ const block0Hash = 0x000000000019d6689c085ae165831e934ff763ae46a2a6cffb388491c27dc990n;
17
+ const expectNull = (nBits) => {
18
+ if (targetFromNBits(nBits) !== null) {
19
+ throw nBits;
20
+ }
21
+ };
22
+ export const proof = {
23
+ targetFromNBits: {
24
+ genesis: () => {
25
+ if (targetFromNBits(genesisNBits) !== genesisTarget) {
26
+ throw 'genesis target';
27
+ }
28
+ },
29
+ block0HashWithinGenesisTarget: () => {
30
+ if (block0Hash > genesisTarget) {
31
+ throw 'block0 hash exceeds genesis target';
32
+ }
33
+ },
34
+ exponent3: () => {
35
+ if (targetFromNBits(0x030000ffn) !== 0xffn) {
36
+ throw 'exponent 3';
37
+ }
38
+ },
39
+ exponent2: () => {
40
+ if (targetFromNBits(0x02008000n) !== 0x80n) {
41
+ throw 'exponent 2';
42
+ }
43
+ },
44
+ hardTargetOne: () => {
45
+ if (targetFromNBits(hardNBits) !== 1n) {
46
+ throw 'hard target';
47
+ }
48
+ },
49
+ zero: () => {
50
+ if (targetFromNBits(0n) !== 0n) {
51
+ throw 'zero nBits';
52
+ }
53
+ },
54
+ negative: () => {
55
+ expectNull(0x01800001n);
56
+ },
57
+ negativeHighMantissa: () => {
58
+ expectNull(0x22ffffffn);
59
+ },
60
+ overflowExponent: () => {
61
+ expectNull(0x23000001n);
62
+ },
63
+ exceeds256: () => {
64
+ expectNull(0x227fffffn);
65
+ },
66
+ },
67
+ meets: {
68
+ easy: () => {
69
+ if (!p256.meets(easyNBits)(sample)) {
70
+ throw 'easy nBits should pass';
71
+ }
72
+ },
73
+ hard: () => {
74
+ if (p256.meets(hardNBits)(sample)) {
75
+ throw 'target 1 should fail';
76
+ }
77
+ },
78
+ genesisFailsSample: () => {
79
+ if (p256.meets(genesisNBits)(sample)) {
80
+ throw 'genesis target too hard for sample';
81
+ }
82
+ },
83
+ zeroTargetRejectsSample: () => {
84
+ if (p256.meets(0n)(sample)) {
85
+ throw 'non-zero hash vs zero target';
86
+ }
87
+ },
88
+ invalidNBits: () => {
89
+ if (p256.meets(0x01800001n)(sample)) {
90
+ throw 'invalid nBits should not pass';
91
+ }
92
+ },
93
+ hashLeqTarget: () => {
94
+ const h = p256.hashInt(sample);
95
+ const target = targetFromNBits(easyNBits);
96
+ if (target === null) {
97
+ throw 'easy nBits decode';
98
+ }
99
+ if (h > target) {
100
+ throw 'hash above easy target';
101
+ }
102
+ if (!(h <= target)) {
103
+ throw 'hash <= target';
104
+ }
105
+ },
106
+ },
107
+ hashInt: {
108
+ sha256Sample: () => {
109
+ const digest = computeSync(sha256)([sample]);
110
+ if (p256.hashInt(sample) !== uint(digest)) {
111
+ throw 'sha256 sample';
112
+ }
113
+ },
114
+ sha256Empty: () => {
115
+ if (p256.hashInt(emptyData) !== sha256EmptyHash) {
116
+ throw 'sha256 empty constant';
117
+ }
118
+ const digest = computeSync(sha256)([emptyData]);
119
+ if (p256.hashInt(emptyData) !== uint(digest)) {
120
+ throw 'sha256 empty';
121
+ }
122
+ },
123
+ sha224: () => {
124
+ const digest = computeSync(sha224)([sample]);
125
+ if (p224.hashInt(sample) !== uint(digest)) {
126
+ throw 'sha224';
127
+ }
128
+ },
129
+ stable: () => {
130
+ if (p256.hashInt(sample) !== p256.hashInt(sample)) {
131
+ throw 'stable';
132
+ }
133
+ },
134
+ },
135
+ pow: {
136
+ sha256Pow: () => {
137
+ const built = pow(sha256);
138
+ if (sha256Pow.hashInt(sample) !== built.hashInt(sample)) {
139
+ throw 'hashInt';
140
+ }
141
+ if (sha256Pow.meets(easyNBits)(sample) !== built.meets(easyNBits)(sample)) {
142
+ throw 'meets';
143
+ }
144
+ },
145
+ bitcoinPow: () => {
146
+ if (bitcoinPow.hashInt(sample) !== sha256Pow.hashInt(sample)) {
147
+ throw 'bitcoinPow';
148
+ }
149
+ },
150
+ independentInstances: () => {
151
+ const a = pow(sha256);
152
+ const b = pow(sha256);
153
+ if (a.hashInt(sample) !== b.hashInt(sample)) {
154
+ throw 'hashInt';
155
+ }
156
+ if (a.meets(easyNBits)(sample) !== b.meets(easyNBits)(sample)) {
157
+ throw 'meets';
158
+ }
159
+ },
160
+ },
161
+ };
@@ -1,11 +1,5 @@
1
- /**
2
- * Development utilities for indexing modules and loading FunctionalScript files.
3
- *
4
- * @module
5
- */
6
- import type { Io } from '../io/module.f.ts';
7
- import { type Access, type All, type Env, type Import, type NodeProgram, type Readdir } from '../types/effects/node/module.f.ts';
8
- import { type Effect } from '../types/effects/module.f.ts';
1
+ import { type Access, type All, type Env, type Import, type NodeProgram, type Readdir } from '../effects/node/module.f.ts';
2
+ import { type Effect } from '../effects/module.f.ts';
9
3
  export type Module = {
10
4
  readonly proof?: unknown;
11
5
  readonly [k: string]: unknown;
@@ -13,7 +7,6 @@ export type Module = {
13
7
  export type ModuleMap = {
14
8
  readonly [k in string]: Module;
15
9
  };
16
- export declare const env: (io: Io) => (v: string) => string | undefined;
17
10
  /**
18
11
  * Returns `true` if the file should be loaded for proof discovery.
19
12
  *
@@ -1,19 +1,18 @@
1
+ /**
2
+ * Development utilities for indexing modules and loading FunctionalScript files.
3
+ *
4
+ * @module
5
+ */
1
6
  import { updateVersion } from "./version/module.f.js";
2
- import { access, all, both, import_, readdir, readFile, writeFile } from "../types/effects/node/module.f.js";
7
+ import { all, both, import_, readdir, readFile, writeFile } from "../effects/node/module.f.js";
3
8
  import { cmp as strCmp } from "../types/string/module.f.js";
4
9
  import { utf8, utf8ToString } from "../text/module.f.js";
5
10
  import { unwrap } from "../types/result/module.f.js";
6
- import { begin, pure } from "../types/effects/module.f.js";
11
+ import { begin, pure } from "../effects/module.f.js";
7
12
  import { parse as jsonParse } from "../json/module.f.js";
8
13
  import { record, unknown as rttiUnknown } from "../types/rtti/module.f.js";
9
14
  import { parse as rttiParse } from "../types/rtti/parse/module.f.js";
10
- import { relativize } from "../path/module.f.js";
11
- export const env = ({ process: { env } }) => a => {
12
- const r = Object.getOwnPropertyDescriptor(env, a);
13
- return r === undefined ? undefined :
14
- typeof r.get === 'function' ? r.get() :
15
- r.value;
16
- };
15
+ import { relativize, toPosix } from "../path/module.f.js";
17
16
  /**
18
17
  * Returns `true` if the file should be loaded for proof discovery.
19
18
  *
@@ -74,7 +73,7 @@ const { fromEntries } = Object;
74
73
  */
75
74
  export const loadModuleMap = (env) => {
76
75
  const initCwd = env['INIT_CWD'];
77
- const s = initCwd === undefined ? '.' : `${initCwd.replaceAll('\\', '/')}`;
76
+ const s = initCwd === undefined ? '.' : toPosix(initCwd);
78
77
  const prefix = s === '.' ? '' : s;
79
78
  // TODO: there are multiple `all` effects here,
80
79
  // we should consider optimize them by ALIQ technique or something similar.
@@ -92,7 +91,9 @@ const parseDenoJson = rttiParse(record(rttiUnknown));
92
91
  const index2 = updateVersion
93
92
  .step(() => readFile(denoJson))
94
93
  .step(v => pure(unwrap(parseDenoJson(jsonParse(utf8ToString(unwrap(v)))))));
95
- const allFiles2aa = allFiles('.', v => v.endsWith('/module.f.ts') || v.endsWith('/module.ts'))
94
+ const allFiles2aa = allFiles('.', v => v.endsWith('/module.f.ts') ||
95
+ v.endsWith('/module.ts') ||
96
+ v.endsWith('/all.test.ts'))
96
97
  .step(files => {
97
98
  const exportsA = files.map(v => [v, `./${v.substring(2)}`]);
98
99
  return pure(Object.fromEntries(exportsA));
@@ -9,5 +9,4 @@ export declare const proof: {
9
9
  properties: () => void;
10
10
  getOwnPropertyDescriptor: () => void;
11
11
  throw: () => void;
12
- env: () => void;
13
12
  };
package/fs/dev/proof.f.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import { todo } from "../asserts/module.f.js";
2
- import { env } from "./module.f.js";
3
2
  export const proof = {
4
3
  shouldPass: () => ({
5
4
  then: () => undefined
@@ -57,24 +56,4 @@ export const proof = {
57
56
  throw: () => {
58
57
  todo();
59
58
  },
60
- env: () => {
61
- const mockIo = { process: { env: { MY_VAR: 'hello' } } };
62
- // missing key → undefined
63
- const r1 = env(mockIo)('MISSING');
64
- if (r1 !== undefined) {
65
- throw r1;
66
- }
67
- // regular value property → returns value
68
- const r2 = env(mockIo)('MY_VAR');
69
- if (r2 !== 'hello') {
70
- throw r2;
71
- }
72
- // getter property → calls get()
73
- const envWithGetter = Object.defineProperty({}, 'GETTER_VAR', { get: () => 'from-getter', enumerable: true, configurable: true });
74
- const mockIo2 = { process: { env: envWithGetter } };
75
- const r3 = env(mockIo2)('GETTER_VAR');
76
- if (r3 !== 'from-getter') {
77
- throw r3;
78
- }
79
- }
80
59
  };
@@ -1,3 +1,3 @@
1
- import { type Effect } from '../../types/effects/module.f.ts';
2
- import { type All, type ReadFile, type WriteFile } from '../../types/effects/node/module.f.ts';
1
+ import { type Effect } from '../../effects/module.f.ts';
2
+ import { type All, type ReadFile, type WriteFile } from '../../effects/node/module.f.ts';
3
3
  export declare const updateVersion: Effect<ReadFile | WriteFile | All, number>;
@@ -4,8 +4,8 @@
4
4
  * @module
5
5
  */
6
6
  import { utf8, utf8ToString } from "../../text/module.f.js";
7
- import { begin, pure } from "../../types/effects/module.f.js";
8
- import { all, readFile, writeFile } from "../../types/effects/node/module.f.js";
7
+ import { begin, pure } from "../../effects/module.f.js";
8
+ import { all, readFile, writeFile } from "../../effects/node/module.f.js";
9
9
  import { unwrap } from "../../types/result/module.f.js";
10
10
  const { stringify, parse } = JSON;
11
11
  const jsonFile = (jsonFile) => `${jsonFile}.json`;