functionalscript 0.30.0 → 0.31.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 (181) hide show
  1. package/fs/asn.1/module.f.js +18 -22
  2. package/fs/asn.1/proof.f.d.ts +5 -0
  3. package/fs/asn.1/proof.f.js +38 -2
  4. package/fs/base64/module.f.d.ts +9 -0
  5. package/fs/base64/module.f.js +60 -0
  6. package/fs/base64/proof.f.d.ts +11 -0
  7. package/fs/base64/proof.f.js +117 -0
  8. package/fs/base_n/module.f.d.ts +44 -0
  9. package/fs/base_n/module.f.js +54 -0
  10. package/fs/base_n/proof.f.d.ts +10 -0
  11. package/fs/base_n/proof.f.js +86 -0
  12. package/fs/bnf/data/module.f.d.ts +4 -9
  13. package/fs/bnf/data/module.f.js +4 -3
  14. package/fs/bnf/module.f.d.ts +3 -4
  15. package/fs/bnf/module.f.js +3 -2
  16. package/fs/bnf/proof.f.d.ts +9 -0
  17. package/fs/bnf/proof.f.js +98 -1
  18. package/fs/cas/mcp/module.f.d.ts +40 -0
  19. package/fs/cas/mcp/module.f.js +223 -0
  20. package/fs/cas/mcp/proof.f.d.ts +30 -0
  21. package/fs/cas/mcp/proof.f.js +310 -0
  22. package/fs/cas/module.f.d.ts +9 -3
  23. package/fs/cas/module.f.js +104 -69
  24. package/fs/cas/proof.f.d.ts +2 -0
  25. package/fs/cas/proof.f.js +30 -1
  26. package/fs/cbase32/module.f.d.ts +1 -1
  27. package/fs/cbase32/module.f.js +19 -40
  28. package/fs/cbase32/proof.f.d.ts +1 -0
  29. package/fs/cbase32/proof.f.js +15 -0
  30. package/fs/ci/config/module.f.d.ts +6 -6
  31. package/fs/ci/config/module.f.js +6 -6
  32. package/fs/ci/deno/module.f.js +2 -2
  33. package/fs/ci/module.f.d.ts +5 -0
  34. package/fs/ci/module.f.js +2 -3
  35. package/fs/ci/proof.f.d.ts +1 -0
  36. package/fs/ci/proof.f.js +9 -3
  37. package/fs/cli/module.f.d.ts +3 -1
  38. package/fs/cli/module.f.js +22 -12
  39. package/fs/cli/proof.f.d.ts +5 -0
  40. package/fs/cli/proof.f.js +76 -0
  41. package/fs/crypto/hmac/proof.f.d.ts +1 -0
  42. package/fs/crypto/hmac/proof.f.js +8 -0
  43. package/fs/crypto/secp/proof.f.d.ts +1 -0
  44. package/fs/crypto/secp/proof.f.js +10 -0
  45. package/fs/crypto/sign/module.f.js +1 -4
  46. package/fs/dev/module.f.d.ts +5 -3
  47. package/fs/dev/module.f.js +13 -2
  48. package/fs/dev/package_json/proof.f.d.ts +1 -0
  49. package/fs/dev/package_json/proof.f.js +5 -0
  50. package/fs/dev/proof.f.d.ts +1 -0
  51. package/fs/dev/proof.f.js +12 -1
  52. package/fs/djs/ast/module.f.d.ts +1 -1
  53. package/fs/djs/ast/proof.f.d.ts +5 -0
  54. package/fs/djs/ast/proof.f.js +17 -0
  55. package/fs/djs/module.f.d.ts +1 -1
  56. package/fs/djs/module.f.js +2 -3
  57. package/fs/djs/serializer/module.f.js +24 -11
  58. package/fs/djs/transpiler/module.f.js +3 -4
  59. package/fs/effects/memory/module.f.d.ts +37 -0
  60. package/fs/effects/memory/module.f.js +24 -0
  61. package/fs/effects/memory/proof.f.d.ts +6 -0
  62. package/fs/effects/memory/proof.f.js +64 -0
  63. package/fs/effects/mock/module.f.d.ts +7 -2
  64. package/fs/effects/mock/module.f.js +12 -8
  65. package/fs/effects/module.d.ts +1 -1
  66. package/fs/effects/module.f.d.ts +41 -0
  67. package/fs/effects/module.f.js +25 -0
  68. package/fs/effects/module.js +6 -7
  69. package/fs/effects/node/memory/module.d.ts +20 -0
  70. package/fs/effects/node/memory/module.js +44 -0
  71. package/fs/effects/node/memory/proof.d.ts +10 -0
  72. package/fs/effects/node/memory/proof.js +35 -0
  73. package/fs/effects/node/module.d.ts +1 -1
  74. package/fs/effects/node/module.f.d.ts +54 -8
  75. package/fs/effects/node/module.f.js +55 -4
  76. package/fs/effects/node/module.js +166 -135
  77. package/fs/effects/node/proof.f.d.ts +10 -0
  78. package/fs/effects/node/proof.f.js +88 -21
  79. package/fs/effects/node/virtual/module.f.d.ts +6 -0
  80. package/fs/effects/node/virtual/module.f.js +48 -16
  81. package/fs/effects/node/virtual/proof.f.d.ts +17 -0
  82. package/fs/effects/node/virtual/proof.f.js +79 -0
  83. package/fs/effects/proof.f.d.ts +5 -0
  84. package/fs/effects/proof.f.js +54 -34
  85. package/fs/emergent_testing/module.f.d.ts +6 -1
  86. package/fs/emergent_testing/module.f.js +8 -3
  87. package/fs/emergent_testing/proof.f.d.ts +11 -0
  88. package/fs/emergent_testing/proof.f.js +52 -16
  89. package/fs/fjs/module.f.js +2 -2
  90. package/fs/fjs/proof.f.d.ts +8 -0
  91. package/fs/fjs/proof.f.js +39 -0
  92. package/fs/fsc/module.f.d.ts +5 -0
  93. package/fs/fsc/module.f.js +17 -27
  94. package/fs/fsc/proof.f.d.ts +8 -0
  95. package/fs/fsc/proof.f.js +48 -2
  96. package/fs/fsm/module.f.d.ts +2 -3
  97. package/fs/fsm/module.f.js +1 -1
  98. package/fs/html/module.f.d.ts +2 -3
  99. package/fs/html/module.f.js +7 -6
  100. package/fs/html/proof.f.d.ts +1 -0
  101. package/fs/html/proof.f.js +7 -0
  102. package/fs/js/tokenizer/module.f.js +1 -1
  103. package/fs/js/tokenizer/proof.f.js +7 -0
  104. package/fs/json/module.f.d.ts +9 -2
  105. package/fs/json/module.f.js +9 -7
  106. package/fs/json/parser/module.f.js +4 -6
  107. package/fs/json/parser/proof.f.js +19 -10
  108. package/fs/json/proof.f.d.ts +2 -1
  109. package/fs/json/proof.f.js +33 -6
  110. package/fs/json/rpc/module.f.d.ts +5 -0
  111. package/fs/json/rpc/module.f.js +16 -11
  112. package/fs/json/schema/module.f.d.ts +15 -14
  113. package/fs/json/schema/proof.f.d.ts +3 -0
  114. package/fs/json/schema/proof.f.js +16 -1
  115. package/fs/mcp/module.f.d.ts +103 -5
  116. package/fs/mcp/module.f.js +139 -2
  117. package/fs/mcp/proof.f.d.ts +34 -0
  118. package/fs/mcp/proof.f.js +207 -0
  119. package/fs/mcp/stdio/module.f.d.ts +39 -0
  120. package/fs/mcp/stdio/module.f.js +54 -0
  121. package/fs/mcp/stdio/proof.f.d.ts +10 -0
  122. package/fs/mcp/stdio/proof.f.js +92 -0
  123. package/fs/mime/module.f.d.ts +39 -0
  124. package/fs/mime/module.f.js +78 -0
  125. package/fs/mime/proof.f.d.ts +15 -0
  126. package/fs/mime/proof.f.js +30 -0
  127. package/fs/path/module.f.d.ts +8 -0
  128. package/fs/path/module.f.js +10 -3
  129. package/fs/path/proof.f.d.ts +1 -0
  130. package/fs/path/proof.f.js +40 -2
  131. package/fs/text/sgr/proof.f.js +30 -2
  132. package/fs/text/utf8/module.f.d.ts +7 -0
  133. package/fs/text/utf8/module.f.js +85 -31
  134. package/fs/text/utf8/proof.f.d.ts +1 -0
  135. package/fs/text/utf8/proof.f.js +60 -1
  136. package/fs/types/bigfloat/module.f.d.ts +3 -0
  137. package/fs/types/bigfloat/module.f.js +30 -31
  138. package/fs/types/bigint/module.f.d.ts +24 -2
  139. package/fs/types/bigint/module.f.js +30 -2
  140. package/fs/types/bigint/proof.f.d.ts +7 -0
  141. package/fs/types/bigint/proof.f.js +47 -16
  142. package/fs/types/bit_vec/module.f.d.ts +18 -0
  143. package/fs/types/bit_vec/module.f.js +18 -0
  144. package/fs/types/bit_vec/proof.f.d.ts +1 -0
  145. package/fs/types/bit_vec/proof.f.js +13 -1
  146. package/fs/types/function/operator/proof.f.d.ts +2 -0
  147. package/fs/types/function/operator/proof.f.js +20 -2
  148. package/fs/types/list/module.f.js +1 -4
  149. package/fs/types/list/proof.f.d.ts +1 -1
  150. package/fs/types/list/proof.f.js +14 -6
  151. package/fs/types/map/proof.f.d.ts +1 -0
  152. package/fs/types/map/proof.f.js +10 -1
  153. package/fs/types/nibble_set/module.f.d.ts +13 -0
  154. package/fs/types/nibble_set/module.f.js +16 -0
  155. package/fs/types/object/module.f.d.ts +12 -8
  156. package/fs/types/object/module.f.js +9 -2
  157. package/fs/types/object/proof.f.d.ts +14 -0
  158. package/fs/types/object/proof.f.js +4 -0
  159. package/fs/types/ordered_map/proof.f.d.ts +1 -0
  160. package/fs/types/ordered_map/proof.f.js +39 -79
  161. package/fs/types/phantom/module.f.d.ts +22 -0
  162. package/fs/types/phantom/module.f.js +11 -0
  163. package/fs/types/prime_field/proof.f.d.ts +7 -0
  164. package/fs/types/prime_field/proof.f.js +63 -122
  165. package/fs/types/rtti/common/module.f.d.ts +4 -4
  166. package/fs/types/rtti/common/module.f.js +1 -1
  167. package/fs/types/rtti/module.f.d.ts +2 -3
  168. package/fs/types/rtti/parse/module.f.js +0 -1
  169. package/fs/types/rtti/ts/module.f.d.ts +26 -32
  170. package/fs/types/rtti/ts/module.f.js +2 -2
  171. package/fs/types/rtti/ts/proof.f.js +3 -3
  172. package/fs/types/rtti/validate/module.f.js +0 -1
  173. package/fs/types/sorted_list/module.f.d.ts +6 -0
  174. package/fs/types/sorted_list/module.f.js +11 -0
  175. package/fs/types/sorted_set/module.f.js +2 -8
  176. package/fs/types/ts/module.f.d.ts +1 -1
  177. package/fs/types/ts/module.f.js +3 -1
  178. package/fs/types/ts/proof.f.js +3 -2
  179. package/fs/website/proof.f.d.ts +1 -0
  180. package/fs/website/proof.f.js +8 -1
  181. package/package.json +3 -3
@@ -56,10 +56,7 @@ export const toArray = (list) => {
56
56
  };
57
57
  const apply = (f) => (input) => () => {
58
58
  const n = next(input);
59
- if (n === null) {
60
- return null;
61
- }
62
- return f(n);
59
+ return n === null ? null : f(n);
63
60
  };
64
61
  const flatStep = ({ first, tail }) => concat(first)(flat(tail));
65
62
  export const flat = apply(flatStep);
@@ -1,6 +1,6 @@
1
1
  export declare const proof: {
2
2
  stringifyTest: () => void;
3
- cycle: () => void;
3
+ cycle: (() => void)[];
4
4
  countdown: () => void;
5
5
  flat: () => void;
6
6
  concat: () => void;
@@ -9,12 +9,20 @@ const stringifyTest = () => {
9
9
  throw s;
10
10
  }
11
11
  };
12
- const cycleTest = () => {
13
- const x = str(toArray(take(10)(cycle([1, 2, 3]))));
14
- if (x !== '[1,2,3,1,2,3,1,2,3,1]') {
15
- throw x;
16
- }
17
- };
12
+ const cycleTest = [
13
+ () => {
14
+ const x = str(toArray(take(10)(cycle([1, 2, 3]))));
15
+ if (x !== '[1,2,3,1,2,3,1,2,3,1]') {
16
+ throw x;
17
+ }
18
+ },
19
+ () => {
20
+ const x = str(toArray(cycle([])));
21
+ if (x !== '[]') {
22
+ throw x;
23
+ }
24
+ },
25
+ ];
18
26
  const countdownTest = () => {
19
27
  const result = str(countdown(10));
20
28
  if (result !== '[9,8,7,6,5,4,3,2,1,0]') {
@@ -1,4 +1,5 @@
1
1
  export declare const proof: {
2
2
  set: () => void;
3
3
  delete: () => void;
4
+ deleteOneOfMany: () => void;
4
5
  };
@@ -1,4 +1,5 @@
1
1
  import { mapSet, mapDelete } from "./module.f.js";
2
+ import { assertEq } from "../../asserts/module.f.js";
2
3
  export const proof = {
3
4
  set: () => {
4
5
  const map = mapSet(new Map(), 'a', 'b');
@@ -17,5 +18,13 @@ export const proof = {
17
18
  if (map.size !== 0) {
18
19
  throw 'error';
19
20
  }
20
- }
21
+ },
22
+ deleteOneOfMany: () => {
23
+ const m0 = mapSet(new Map(), 'a', 1);
24
+ const m1 = mapSet(m0, 'b', 2);
25
+ const result = mapDelete(m1, 'a');
26
+ assertEq(result.get('b'), 2);
27
+ assertEq(result.get('a'), undefined);
28
+ assertEq(result.size, 1);
29
+ },
21
30
  };
@@ -1,9 +1,22 @@
1
1
  /**
2
2
  * Nibble-set operations for compact 4-bit membership tracking.
3
3
  *
4
+ * A set of nibbles (values `0..15`) stored as a 16-bit mask in a plain
5
+ * `number`. It implements the same bitmask-as-set algebra as
6
+ * {@link ../byte_set/module.f.ts | `byte_set`}, which tracks all 256 byte
7
+ * values in a `bigint`.
8
+ *
9
+ * **Prefer `byte_set`.** Its 256-value universe covers the common cases and
10
+ * it is the set type used across the codebase. Use `nibble_set` only when
11
+ * the set has to be serialized into JSON: a `NibbleSet` is a `number`, which
12
+ * round-trips through `JSON.stringify`/`JSON.parse` as-is, while a
13
+ * `ByteSet` is a `bigint`, which `JSON.stringify` cannot serialize.
14
+ *
4
15
  * @module
5
16
  */
17
+ /** A set of nibbles as a 16-bit mask. JSON-serializable. */
6
18
  export type NibbleSet = number;
19
+ /** A 4-bit value, `0..15`. */
7
20
  export type Nibble = number;
8
21
  export declare const empty = 0;
9
22
  export declare const universe = 65535;
@@ -1,3 +1,19 @@
1
+ /**
2
+ * Nibble-set operations for compact 4-bit membership tracking.
3
+ *
4
+ * A set of nibbles (values `0..15`) stored as a 16-bit mask in a plain
5
+ * `number`. It implements the same bitmask-as-set algebra as
6
+ * {@link ../byte_set/module.f.ts | `byte_set`}, which tracks all 256 byte
7
+ * values in a `bigint`.
8
+ *
9
+ * **Prefer `byte_set`.** Its 256-value universe covers the common cases and
10
+ * it is the set type used across the codebase. Use `nibble_set` only when
11
+ * the set has to be serialized into JSON: a `NibbleSet` is a `number`, which
12
+ * round-trips through `JSON.stringify`/`JSON.parse` as-is, while a
13
+ * `ByteSet` is a `bigint`, which `JSON.stringify` cannot serialize.
14
+ *
15
+ * @module
16
+ */
1
17
  export const empty = 0;
2
18
  export const universe = 0xFFFF;
3
19
  const one = n => 1 << n;
@@ -1,10 +1,9 @@
1
1
  import { type List } from '../list/module.f.ts';
2
+ import { type Nullable } from '../nullable/module.f.ts';
2
3
  import { type OrderedMap } from '../ordered_map/module.f.ts';
3
- export type Map<T> = {
4
- readonly [k in string]: T;
5
- };
4
+ export type Map<T> = StringMap<string, T>;
6
5
  export type Entry<T> = readonly [string, T];
7
- export declare const at: (name: string) => <T>(object: Map<T>) => T | null;
6
+ export declare const at: (name: string) => <T>(object: Map<T>) => Nullable<Exclude<T, undefined>>;
8
7
  export declare const sort: <T>(e: List<Entry<T>>) => List<Entry<T>>;
9
8
  export declare const fromEntries: <T>(e: List<Entry<T>>) => Map<T>;
10
9
  export declare const fromMap: <T>(m: OrderedMap<T>) => Map<T>;
@@ -15,7 +14,7 @@ export declare const fromMap: <T>(m: OrderedMap<T>) => Map<T>;
15
14
  * https://stackoverflow.com/questions/57571664/typescript-type-for-an-object-with-only-one-key-no-union-type-allowed-as-a-key
16
15
  */
17
16
  export type OneKey<K extends string, V> = {
18
- [P in K]: (ReadonlyRecord<P, V> & Partial<ReadonlyRecord<Exclude<K, P>, never>>) extends infer O ? {
17
+ [P in K]: (StringMap<P, V> & Partial<StringMap<Exclude<K, P>, never>>) extends infer O ? {
19
18
  [Q in keyof O]: O[Q];
20
19
  } : never;
21
20
  }[K];
@@ -25,8 +24,13 @@ export type OneKey<K extends string, V> = {
25
24
  export type NotUnion<T, U = T> = T extends unknown ? [
26
25
  U
27
26
  ] extends [T] ? T : never : never;
28
- export type SingleProperty<T extends ReadonlyRecord<string, never>> = keyof T extends NotUnion<keyof T> ? T : never;
27
+ export type SingleProperty<T extends StringMap<string, never>> = keyof T extends NotUnion<keyof T> ? T : never;
29
28
  export declare const isObject: (value: unknown) => value is { readonly [k in string]: unknown; };
30
- export type ReadonlyRecord<S extends string, T> = {
31
- readonly [K in S]: T;
29
+ /** Returns only the defined (non-undefined) values of a partial record. */
30
+ export declare const definedValues: <T>(map: StringMap<string, Exclude<T, undefined>>) => readonly Exclude<T, undefined>[];
31
+ export type StringMap<K extends string, T> = string extends K ? {
32
+ readonly [k in string]?: T;
33
+ } : {
34
+ readonly [k in K]: T;
32
35
  };
36
+ export declare const definedEntries: <T>(cmd: StringMap<string, Exclude<T, undefined>>) => readonly (readonly [string, Exclude<T, undefined>])[];
@@ -7,11 +7,18 @@
7
7
  */
8
8
  import { isArray } from "../array/module.f.js";
9
9
  import { iterable } from "../list/module.f.js";
10
- import { fromUndefined, map } from "../nullable/module.f.js";
10
+ import { fromUndefined } from "../nullable/module.f.js";
11
11
  import { entries as mapEntries, fromEntries as mapFromEntries } from "../ordered_map/module.f.js";
12
12
  const { getOwnPropertyDescriptor, fromEntries: objectFromEntries } = Object;
13
- export const at = name => object => map((d) => d.value)(fromUndefined(getOwnPropertyDescriptor(object, name)));
13
+ export const at = name => object => {
14
+ const d = getOwnPropertyDescriptor(object, name);
15
+ return d === undefined ? null : fromUndefined(d.value);
16
+ };
14
17
  export const sort = e => mapEntries(mapFromEntries(e));
15
18
  export const fromEntries = e => objectFromEntries(iterable(e));
16
19
  export const fromMap = m => fromEntries(mapEntries(m));
17
20
  export const isObject = (value) => typeof value === 'object' && !isArray(value) && value !== null;
21
+ const { values, entries } = Object;
22
+ /** Returns only the defined (non-undefined) values of a partial record. */
23
+ export const definedValues = (map) => values(map).filter(v => v !== undefined);
24
+ export const definedEntries = (cmd) => entries(cmd).flatMap(([a, b]) => b === undefined ? [] : [[a, b]]);
@@ -1,4 +1,18 @@
1
+ import type { StringMap } from './module.f.ts';
2
+ type E<A, B> = A extends B ? B extends A ? true : false : false;
3
+ type _InfiniteIsOptional = E<StringMap<string, bigint>, {
4
+ readonly [k in string]?: bigint;
5
+ }>;
6
+ type _FiniteIsRequired = E<StringMap<'a' | 'b', bigint>, {
7
+ readonly a: bigint;
8
+ readonly b: bigint;
9
+ }>;
1
10
  export declare const proof: {
11
+ stringMap: {
12
+ infiniteIsOptional: _InfiniteIsOptional;
13
+ finiteIsRequired: _FiniteIsRequired;
14
+ };
2
15
  ctor: () => void;
3
16
  property: () => void;
4
17
  };
18
+ export {};
@@ -1,5 +1,9 @@
1
1
  import { at } from "./module.f.js";
2
2
  export const proof = {
3
+ stringMap: {
4
+ infiniteIsOptional: true,
5
+ finiteIsRequired: true,
6
+ },
3
7
  ctor: () => {
4
8
  const a = {};
5
9
  const value = at('constructor')(a);
@@ -1,4 +1,5 @@
1
1
  export declare const proof: {
2
2
  main: (() => void)[];
3
+ fromEntries: () => void;
3
4
  stress: () => void;
4
5
  };
@@ -1,101 +1,61 @@
1
- import { at, setReplace, setReduce, empty, entries, remove } from "./module.f.js";
1
+ import { at, setReplace, setReduce, empty, entries, remove, fromEntries } from "./module.f.js";
2
2
  import { toArray } from "../list/module.f.js";
3
+ import { assertEq } from "../../asserts/module.f.js";
3
4
  export const proof = {
4
5
  main: [
5
6
  () => {
6
7
  let m = setReplace('a')(1)(null);
7
- if (at('a')(m) !== 1) {
8
- throw 'error';
9
- }
10
- if (at('b')(m) !== null) {
11
- throw 'error';
12
- }
8
+ assertEq(at('a')(m), 1);
9
+ assertEq(at('b')(m), null);
13
10
  m = setReplace('b')(2)(m);
14
- if (at('a')(m) !== 1) {
15
- throw 'error';
16
- }
17
- if (at('b')(m) !== 2) {
18
- throw 'error';
19
- }
20
- if (at('c')(m) !== null) {
21
- throw 'error';
22
- }
11
+ assertEq(at('a')(m), 1);
12
+ assertEq(at('b')(m), 2);
13
+ assertEq(at('c')(m), null);
23
14
  m = setReplace('z')(3)(m);
24
- if (at('a')(m) !== 1) {
25
- throw 'error';
26
- }
27
- if (at('b')(m) !== 2) {
28
- throw 'error';
29
- }
30
- if (at('z')(m) !== 3) {
31
- throw 'error';
32
- }
33
- if (at('')(m) !== null) {
34
- throw 'error';
35
- }
15
+ assertEq(at('a')(m), 1);
16
+ assertEq(at('b')(m), 2);
17
+ assertEq(at('z')(m), 3);
18
+ assertEq(at('')(m), null);
36
19
  m = setReplace('')(4)(m);
37
- if (at('a')(m) !== 1) {
38
- throw 'error';
39
- }
40
- if (at('b')(m) !== 2) {
41
- throw 'error';
42
- }
43
- if (at('z')(m) !== 3) {
44
- throw 'error';
45
- }
46
- if (at('')(m) !== 4) {
47
- throw 'error';
48
- }
49
- if (at('Hello world!')(m) !== null) {
50
- throw 'error';
51
- }
20
+ assertEq(at('a')(m), 1);
21
+ assertEq(at('b')(m), 2);
22
+ assertEq(at('z')(m), 3);
23
+ assertEq(at('')(m), 4);
24
+ assertEq(at('Hello world!')(m), null);
52
25
  m = setReplace('Hello world!')(42)(m);
53
- if (at('a')(m) !== 1) {
54
- throw 'error';
55
- }
56
- if (at('b')(m) !== 2) {
57
- throw 'error';
58
- }
59
- if (at('z')(m) !== 3) {
60
- throw 'error';
61
- }
62
- if (at('')(m) !== 4) {
63
- throw 'error';
64
- }
65
- if (at('Hello world!')(m) !== 42) {
66
- throw 'error';
67
- }
68
- if (at('x')(m) !== null) {
69
- throw 'error';
70
- }
26
+ assertEq(at('a')(m), 1);
27
+ assertEq(at('b')(m), 2);
28
+ assertEq(at('z')(m), 3);
29
+ assertEq(at('')(m), 4);
30
+ assertEq(at('Hello world!')(m), 42);
31
+ assertEq(at('x')(m), null);
71
32
  // console.log(Array.from(m.entries()))
72
33
  m = remove('Hello world!')(m);
73
- if (at('Hello world!')(m) !== null) {
74
- throw m;
75
- }
34
+ assertEq(at('Hello world!')(m), null);
76
35
  m = setReduce((a) => (b) => a + b)('a')(43)(m);
77
- if (at('a')(m) !== 44) {
78
- throw 'error';
79
- }
36
+ assertEq(at('a')(m), 44);
80
37
  },
81
38
  () => {
82
39
  let m = setReplace('x')(12)(null);
83
40
  m = setReplace('y')(44)(m);
84
- if (at('x')(m) !== 12) {
85
- throw 'error';
86
- }
87
- if (at('y')(m) !== 44) {
88
- throw 'error';
89
- }
90
- if (at('a')(m) !== null) {
91
- throw 'error';
92
- }
41
+ assertEq(at('x')(m), 12);
42
+ assertEq(at('y')(m), 44);
43
+ assertEq(at('a')(m), null);
93
44
  const e = toArray(entries(m));
94
- if (e.length !== 2) {
95
- throw 'error';
96
- }
45
+ assertEq(e.length, 2);
97
46
  },
98
47
  ],
48
+ fromEntries: () => {
49
+ const list = [['a', 1], ['b', 2], ['c', 3]];
50
+ const m = fromEntries(list);
51
+ assertEq(at('a')(m), 1);
52
+ assertEq(at('b')(m), 2);
53
+ assertEq(at('c')(m), 3);
54
+ assertEq(at('d')(m), null);
55
+ // duplicate key: last one wins
56
+ const m2 = fromEntries([['x', 10], ['x', 20]]);
57
+ assertEq(at('x')(m2), 20);
58
+ },
99
59
  stress: () => {
100
60
  let m = empty;
101
61
  for (let i = 0; i < 100_000; ++i) {
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Phantom type — attaches a compile-time type annotation `T` to `S` with zero
3
+ * runtime representation, analogous to Rust's `PhantomData<T>`.
4
+ *
5
+ * The phantom field uses a unique symbol key so it is excluded from string index
6
+ * signatures (`{ readonly [K in string]: ... }`), making `Phantom<S, T>` valid
7
+ * for any `S` regardless of its index signature constraints.
8
+ *
9
+ * @module
10
+ */
11
+ declare const phantomKey: unique symbol;
12
+ export type { phantomKey };
13
+ /**
14
+ * Intersects `S` with a phantom field carrying type `T`.
15
+ *
16
+ * The field is optional (`?`) so it never needs to be present at runtime.
17
+ * Use `phantomKey` to read the phantom type back out via a conditional type:
18
+ * `S extends Phantom<unknown, infer T> ? T : never`.
19
+ */
20
+ export type Phantom<S, T> = S & {
21
+ readonly [phantomKey]?: T;
22
+ };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Phantom type — attaches a compile-time type annotation `T` to `S` with zero
3
+ * runtime representation, analogous to Rust's `PhantomData<T>`.
4
+ *
5
+ * The phantom field uses a unique symbol key so it is excluded from string index
6
+ * signatures (`{ readonly [K in string]: ... }`), making `Phantom<S, T>` valid
7
+ * for any `S` regardless of its index signature constraints.
8
+ *
9
+ * @module
10
+ */
11
+ export {};
@@ -1,4 +1,8 @@
1
1
  export declare const proof: {
2
+ throw: {
3
+ reciprocal_zero: () => bigint;
4
+ sqrt_bad_prime: () => (a: bigint) => bigint | null;
5
+ };
2
6
  prime_field_test: () => {
3
7
  neg: () => void;
4
8
  sub: () => void;
@@ -11,5 +15,8 @@ export declare const proof: {
11
15
  reduce: () => void;
12
16
  quadRes: () => void;
13
17
  modSqrt: () => void;
18
+ div: () => void;
19
+ pow3: () => void;
20
+ abs: () => void;
14
21
  };
15
22
  };
@@ -1,121 +1,69 @@
1
1
  import { modSqrt, prime_field, sqrt } from "./module.f.js";
2
+ import { assert, assertEq } from "../../asserts/module.f.js";
2
3
  export const proof = {
4
+ throw: {
5
+ reciprocal_zero: () => prime_field(7n).reciprocal(0n),
6
+ sqrt_bad_prime: () => sqrt(prime_field(5n)),
7
+ },
3
8
  prime_field_test: () => {
4
9
  const p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn;
5
10
  const f = prime_field(p);
6
11
  const sqrt_f = sqrt(f);
7
12
  return {
8
13
  neg: () => {
9
- if (f.neg(0n) !== 0n) {
10
- throw '-0';
11
- }
12
- if (f.neg(1n) !== p - 1n) {
13
- throw '-1';
14
- }
14
+ assertEq(f.neg(0n), 0n);
15
+ assertEq(f.neg(1n), p - 1n);
15
16
  },
16
17
  sub: () => {
17
- if (f.sub(10n)(4n) !== 6n) {
18
- throw '10 - 4';
19
- }
20
- if (f.sub(11n)(14n) !== p - 3n) {
21
- throw '11 - 14';
22
- }
18
+ assertEq(f.sub(10n)(4n), 6n);
19
+ assertEq(f.sub(11n)(14n), p - 3n);
23
20
  },
24
21
  add: () => {
25
- if (f.add(13n)(24n) !== 37n) {
26
- throw '13 + 24';
27
- }
28
- if (f.add(77n)(f.neg(12n)) !== 65n) {
29
- throw '77 + (-12)';
30
- }
22
+ assertEq(f.add(13n)(24n), 37n);
23
+ assertEq(f.add(77n)(f.neg(12n)), 65n);
31
24
  },
32
25
  mul: () => {
33
- if (f.mul(100n)(0n) !== 0n) {
34
- throw '100 * 0';
35
- }
36
- if (f.mul(101n)(205n) !== 20705n) {
37
- throw '101 * 205';
38
- }
39
- if (f.mul(304n)(f.neg(1n)) !== f.neg(304n)) {
40
- throw '304 * -1';
41
- }
42
- if (f.mul(f.neg(507n))(609n) !== f.neg(308763n)) {
43
- throw '-507 * 609';
44
- }
45
- if (f.mul(f.neg(713n))(f.neg(825n)) !== 588225n) {
46
- throw '-713 * -825';
47
- }
26
+ assertEq(f.mul(100n)(0n), 0n);
27
+ assertEq(f.mul(101n)(205n), 20705n);
28
+ assertEq(f.mul(304n)(f.neg(1n)), f.neg(304n));
29
+ assertEq(f.mul(f.neg(507n))(609n), f.neg(308763n));
30
+ assertEq(f.mul(f.neg(713n))(f.neg(825n)), 588225n);
48
31
  },
49
32
  reciprocal: () => {
50
33
  let i = 1n;
51
34
  while (i < 10000n) {
52
- const x = f.reciprocal(i);
53
- if (f.mul(x)(i) !== 1n) {
54
- throw i;
55
- }
35
+ assertEq(f.mul(f.reciprocal(i))(i), 1n);
56
36
  ++i;
57
37
  }
58
38
  },
59
39
  pow: () => {
60
40
  const test = a => {
61
- if (f.pow(0n)(a) !== 1n) {
62
- throw '**0';
63
- }
64
- if (f.pow(1n)(a) !== a) {
65
- throw '**1';
66
- }
41
+ assertEq(f.pow(0n)(a), 1n);
42
+ assertEq(f.pow(1n)(a), a);
67
43
  // https://en.wikipedia.org/wiki/Fermat%27s_little_theorem
68
44
  // a^(p-1) % p = 1
69
- if (f.abs(f.pow(f.middle)(a)) !== 1n) {
70
- throw '**middle';
71
- }
72
- if (f.pow(f.sub(f.max)(1n))(a) !== f.reciprocal(a)) {
73
- throw '**(max-1)';
74
- }
75
- if (f.pow(f.max)(a) !== 1n) {
76
- throw '**max';
77
- }
45
+ assertEq(f.abs(f.pow(f.middle)(a)), 1n);
46
+ assertEq(f.pow(f.sub(f.max)(1n))(a), f.reciprocal(a));
47
+ assertEq(f.pow(f.max)(a), 1n);
78
48
  };
79
49
  // 0
80
- if (f.pow(0n)(0n) !== 1n) {
81
- throw '0**0';
82
- }
83
- if (f.pow(f.max)(0n) !== 0n) {
84
- throw '0**max';
85
- }
50
+ assertEq(f.pow(0n)(0n), 1n);
51
+ assertEq(f.pow(f.max)(0n), 0n);
86
52
  // 1
87
53
  test(1n);
88
54
  // 2
89
55
  test(2n);
90
- if (f.pow(2n)(2n) !== 4n) {
91
- throw '2**2';
92
- }
93
- if (f.pow(3n)(2n) !== 8n) {
94
- throw '2**3';
95
- }
96
- if (f.pow(128n)(2n) !== 1n << 128n) {
97
- throw '2**128';
98
- }
56
+ assertEq(f.pow(2n)(2n), 4n);
57
+ assertEq(f.pow(3n)(2n), 8n);
58
+ assertEq(f.pow(128n)(2n), 1n << 128n);
99
59
  // 3
100
60
  test(3n);
101
- if (f.pow(2n)(3n) !== 9n) {
102
- throw '3**2';
103
- }
104
- if (f.pow(3n)(3n) !== 27n) {
105
- throw '3**3';
106
- }
107
- if (f.pow(100n)(3n) !== 3n ** 100n) {
108
- throw '3**100';
109
- }
110
- if (f.pow(110n)(3n) !== 3n ** 110n) {
111
- throw '3**110';
112
- }
113
- if (f.pow(120n)(3n) !== 3n ** 120n) {
114
- throw '3**120';
115
- }
116
- if (f.pow(121n)(3n) !== 3n ** 121n) {
117
- throw '3**121';
118
- }
61
+ assertEq(f.pow(2n)(3n), 9n);
62
+ assertEq(f.pow(3n)(3n), 27n);
63
+ assertEq(f.pow(100n)(3n), 3n ** 100n);
64
+ assertEq(f.pow(110n)(3n), 3n ** 110n);
65
+ assertEq(f.pow(120n)(3n), 3n ** 120n);
66
+ assertEq(f.pow(121n)(3n), 3n ** 121n);
119
67
  //
120
68
  test(f.middle);
121
69
  test(f.max - 1n);
@@ -123,18 +71,13 @@ export const proof = {
123
71
  },
124
72
  sqrtExample: () => {
125
73
  const field = prime_field(7n);
126
- const root = sqrt(field)(4n);
127
- if (root !== 2n) {
128
- throw root;
129
- }
74
+ assertEq(sqrt(field)(4n), 2n);
130
75
  },
131
76
  sqrt: () => {
132
77
  const test = a => {
133
78
  const a2 = f.mul(a)(a);
134
79
  const s = sqrt_f(a2);
135
- if (s !== null && f.abs(s) !== f.abs(a)) {
136
- throw 'sqrt';
137
- }
80
+ assert(s === null || f.abs(s) === f.abs(a), 'sqrt');
138
81
  };
139
82
  let i = 1n;
140
83
  while (i < 1000n) {
@@ -145,42 +88,40 @@ export const proof = {
145
88
  test(f.max);
146
89
  },
147
90
  reduce: () => {
148
- if (f.reduce(13n) !== 13n) {
149
- throw f.reduce(13n);
150
- }
151
- if (f.reduce(-1n) !== p - 1n) {
152
- throw [f.reduce(-1n), p - 1n];
153
- }
91
+ assertEq(f.reduce(13n), 13n);
92
+ assertEq(f.reduce(-1n), p - 1n);
154
93
  },
155
94
  quadRes: () => {
156
- if (!f.quadRes(0n)) {
157
- throw 0n;
158
- }
159
- if (!f.quadRes(1n)) {
160
- throw 1n;
161
- }
162
- if (!f.quadRes(p)) {
163
- throw p;
164
- }
165
- if (f.quadRes(3n)) {
166
- throw 3n;
167
- }
95
+ assert(f.quadRes(0n), 0n);
96
+ assert(f.quadRes(1n), 1n);
97
+ assert(f.quadRes(p), p);
98
+ assert(!f.quadRes(3n), 3n);
168
99
  const f2 = prime_field(2n);
169
- if (!f2.quadRes(0n)) {
170
- throw '0 mod 2';
171
- }
172
- if (!f2.quadRes(1n)) {
173
- throw '1 mod 2';
174
- }
100
+ assert(f2.quadRes(0n), '0 mod 2');
101
+ assert(f2.quadRes(1n), '1 mod 2');
175
102
  },
176
103
  modSqrt: () => {
177
104
  const root = modSqrt(f);
178
- if (root(4n) !== 2n) {
179
- throw root(4n);
180
- }
181
- if (f.pow2(root(2n)) !== 2n) {
182
- throw root(2n);
183
- }
105
+ assertEq(root(4n), 2n);
106
+ assertEq(f.pow2(root(2n)), 2n);
107
+ },
108
+ div: () => {
109
+ assertEq(f.div(6n)(2n), 3n);
110
+ assertEq(f.div(0n)(5n), 0n);
111
+ assertEq(f.div(1n)(1n), 1n);
112
+ },
113
+ pow3: () => {
114
+ assertEq(f.pow3(0n), 0n);
115
+ assertEq(f.pow3(1n), 1n);
116
+ assertEq(f.pow3(2n), 8n);
117
+ assertEq(f.pow3(3n), 27n);
118
+ assertEq(f.pow3(10n), 1000n);
119
+ },
120
+ abs: () => {
121
+ assertEq(f.abs(0n), 0n);
122
+ assertEq(f.abs(1n), 1n);
123
+ assertEq(f.abs(f.neg(1n)), 1n);
124
+ assertEq(f.abs(f.middle), f.middle);
184
125
  },
185
126
  };
186
127
  }