functionalscript 0.17.0 → 0.18.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 (59) hide show
  1. package/fs/ci/common/module.f.d.ts +4 -5
  2. package/fs/ci/common/module.f.js +4 -4
  3. package/fs/ci/config/module.f.d.ts +4 -4
  4. package/fs/ci/config/module.f.js +4 -4
  5. package/fs/ci/test.f.js +2 -4
  6. package/fs/dev/module.f.d.ts +3 -3
  7. package/fs/dev/module.f.js +12 -9
  8. package/fs/dev/tf/module.d.ts +1 -0
  9. package/fs/dev/tf/module.f.d.ts +70 -6
  10. package/fs/dev/tf/module.f.js +135 -87
  11. package/fs/dev/tf/module.js +66 -17
  12. package/fs/dev/tf/test.f.d.ts +21 -20
  13. package/fs/dev/tf/test.f.js +249 -31
  14. package/fs/djs/module.f.d.ts +2 -2
  15. package/fs/djs/module.f.js +8 -5
  16. package/fs/djs/test.f.js +5 -6
  17. package/fs/djs/tokenizer-new/test.f.js +126 -78
  18. package/fs/djs/transpiler/module.f.js +2 -2
  19. package/fs/djs/transpiler/test.f.js +11 -12
  20. package/fs/fjs/module.f.d.ts +2 -7
  21. package/fs/fjs/module.f.js +16 -22
  22. package/fs/fjs/module.js +2 -2
  23. package/fs/io/module.d.ts +3 -3
  24. package/fs/io/module.f.d.ts +5 -2
  25. package/fs/io/module.f.js +14 -3
  26. package/fs/io/module.js +38 -17
  27. package/fs/path/module.f.d.ts +6 -0
  28. package/fs/path/module.f.js +6 -0
  29. package/fs/path/test.f.d.ts +3 -5
  30. package/fs/path/test.f.js +67 -49
  31. package/fs/text/sgr/module.f.d.ts +9 -1
  32. package/fs/text/sgr/module.f.js +16 -5
  33. package/fs/types/effects/node/module.f.d.ts +17 -17
  34. package/fs/types/effects/node/module.f.js +20 -2
  35. package/fs/types/effects/node/test.f.js +8 -5
  36. package/fs/types/effects/node/virtual/module.f.d.ts +11 -2
  37. package/fs/types/effects/node/virtual/module.f.js +30 -17
  38. package/fs/types/function/compare/module.f.d.ts +12 -0
  39. package/fs/types/function/compare/module.f.js +33 -0
  40. package/fs/types/function/operator/test.f.d.ts +10 -0
  41. package/fs/types/function/operator/test.f.js +81 -0
  42. package/fs/types/range_map/module.f.js +3 -18
  43. package/fs/types/result/module.f.d.ts +4 -0
  44. package/fs/types/result/module.f.js +4 -0
  45. package/fs/types/result/test.f.d.ts +2 -4
  46. package/fs/types/result/test.f.js +24 -16
  47. package/fs/types/rtti/common/module.f.d.ts +10 -1
  48. package/fs/types/rtti/common/module.f.js +7 -2
  49. package/fs/types/rtti/parse/module.f.js +35 -46
  50. package/fs/types/rtti/validate/module.f.js +9 -12
  51. package/fs/types/sorted_list/module.f.d.ts +1 -2
  52. package/fs/types/sorted_list/module.f.js +8 -21
  53. package/fs/types/sorted_set/module.f.d.ts +1 -3
  54. package/fs/types/ts/test.f.d.ts +18 -0
  55. package/fs/types/ts/test.f.js +111 -0
  56. package/fs/types/uint8array/module.f.js +7 -1
  57. package/fs/types/uint8array/test.f.d.ts +1 -0
  58. package/fs/types/uint8array/test.f.js +5 -1
  59. package/package.json +1 -1
@@ -0,0 +1,81 @@
1
+ import { join, concat, logicalNot, strictEqual, addition, min, max, increment, foldToScan, reduceToScan, } from "./module.f.js";
2
+ export const joinTest = () => {
3
+ const result = join(', ')('world')('hello');
4
+ if (result !== 'hello, world') {
5
+ throw result;
6
+ }
7
+ };
8
+ export const concatTest = () => {
9
+ const result = concat('world')('hello');
10
+ if (result !== 'helloworld') {
11
+ throw result;
12
+ }
13
+ };
14
+ export const logicalNotTest = () => {
15
+ if (logicalNot(true) !== false) {
16
+ throw 'expected false';
17
+ }
18
+ if (logicalNot(false) !== true) {
19
+ throw 'expected true';
20
+ }
21
+ };
22
+ export const strictEqualTest = () => {
23
+ if (!strictEqual(1)(1)) {
24
+ throw 'expected true';
25
+ }
26
+ if (strictEqual(1)(2)) {
27
+ throw 'expected false';
28
+ }
29
+ };
30
+ export const additionTest = () => {
31
+ const result = addition(3)(4);
32
+ if (result !== 7) {
33
+ throw result;
34
+ }
35
+ };
36
+ export const minTest = () => {
37
+ if (min(3)(5) !== 3) {
38
+ throw 'min(3)(5)';
39
+ }
40
+ if (min(7)(2) !== 2) {
41
+ throw 'min(7)(2)';
42
+ }
43
+ };
44
+ export const maxTest = () => {
45
+ if (max(3)(5) !== 5) {
46
+ throw 'max(3)(5)';
47
+ }
48
+ if (max(7)(2) !== 7) {
49
+ throw 'max(7)(2)';
50
+ }
51
+ };
52
+ export const incrementTest = () => {
53
+ if (increment(4) !== 5) {
54
+ throw 'increment(4)';
55
+ }
56
+ if (increment(0) !== 1) {
57
+ throw 'increment(0)';
58
+ }
59
+ };
60
+ export const foldToScanTest = () => {
61
+ const scan = foldToScan(addition)(0);
62
+ const [v1, scan2] = scan(3);
63
+ if (v1 !== 3) {
64
+ throw v1;
65
+ }
66
+ const [v2] = scan2(4);
67
+ if (v2 !== 7) {
68
+ throw v2;
69
+ }
70
+ };
71
+ export const reduceToScanTest = () => {
72
+ const scan = reduceToScan(addition);
73
+ const [v0, scan2] = scan(10);
74
+ if (v0 !== 10) {
75
+ throw v0;
76
+ }
77
+ const [v1] = scan2(5);
78
+ if (v1 !== 15) {
79
+ throw v1;
80
+ }
81
+ };
@@ -37,6 +37,7 @@
37
37
  import { genericMerge } from "../sorted_list/module.f.js";
38
38
  import { next } from "../list/module.f.js";
39
39
  import { cmp } from "../number/module.f.js";
40
+ import { bsearch } from "../function/compare/module.f.js";
40
41
  const reduceOp = ({ union, equal }) => state => ([aItem, aMax]) => ([bItem, bMax]) => {
41
42
  const sign = cmp(aMax)(bMax);
42
43
  const min = sign === 1 ? bMax : aMax;
@@ -59,24 +60,8 @@ const tailReduce = equal => state => tail => {
59
60
  };
60
61
  export const merge = op => genericMerge({ reduceOp: reduceOp(op), tailReduce: tailReduce(op.equal) })(null);
61
62
  export const get = def => value => rm => {
62
- const len = rm.length;
63
- let b = 0;
64
- let e = len - 1;
65
- while (true) {
66
- if (b >= len) {
67
- return def;
68
- }
69
- if (e - b < 0) {
70
- return rm[b][0];
71
- }
72
- const mid = b + (e - b >> 1);
73
- if (value <= rm[mid][1]) {
74
- e = mid - 1;
75
- }
76
- else {
77
- b = mid + 1;
78
- }
79
- }
63
+ const pos = bsearch(rm.length)(mid => value <= rm[mid][1] ? -1 : 1);
64
+ return pos < rm.length ? rm[pos][0] : def;
80
65
  };
81
66
  export const fromRange = def => ([a, b]) => v => [[def, a - 1], [v, b]];
82
67
  /**
@@ -51,3 +51,7 @@ export declare const error: <E>(e: E) => Error<E>;
51
51
  * @returns The value if the result is successful. Otherwise, throws the error.
52
52
  */
53
53
  export declare const unwrap: <T, E>([kind, v]: Result<T, E>) => T;
54
+ /**
55
+ * Swaps the `ok` and `error` cases of a result.
56
+ */
57
+ export declare const invert: <T, E>([k, v]: Result<T, E>) => Result<E, T>;
@@ -44,3 +44,7 @@ export const unwrap = ([kind, v]) => {
44
44
  }
45
45
  return v;
46
46
  };
47
+ /**
48
+ * Swaps the `ok` and `error` cases of a result.
49
+ */
50
+ export const invert = ([k, v]) => k === 'ok' ? error(v) : ok(v);
@@ -1,4 +1,2 @@
1
- declare const _default: {
2
- example: () => void;
3
- };
4
- export default _default;
1
+ export declare const example: () => void;
2
+ export declare const invertTest: () => void;
@@ -1,18 +1,26 @@
1
- import { error, ok, unwrap } from "./module.f.js";
2
- export default {
3
- example: () => {
4
- const success = ok(42);
5
- const failure = error('Something went wrong');
6
- if (unwrap(success) !== 42) {
7
- throw 'error';
8
- }
9
- const [kind, v] = failure;
10
- if (kind !== 'error') {
11
- throw 'error';
12
- }
13
- // `v` is inferred as `string` here
14
- if (v !== 'Something went wrong') {
15
- throw 'error';
16
- }
1
+ import { error, ok, unwrap, invert } from "./module.f.js";
2
+ export const example = () => {
3
+ const success = ok(42);
4
+ const failure = error('Something went wrong');
5
+ if (unwrap(success) !== 42) {
6
+ throw 'error';
7
+ }
8
+ const [kind, v] = failure;
9
+ if (kind !== 'error') {
10
+ throw 'error';
11
+ }
12
+ // `v` is inferred as `string` here
13
+ if (v !== 'Something went wrong') {
14
+ throw 'error';
15
+ }
16
+ };
17
+ export const invertTest = () => {
18
+ const [k0, v0] = invert(ok(42));
19
+ if (k0 !== 'error' || v0 !== 42) {
20
+ throw [k0, v0];
21
+ }
22
+ const [k1, v1] = invert(error('oops'));
23
+ if (k1 !== 'ok' || v1 !== 'oops') {
24
+ throw [k1, v1];
17
25
  }
18
26
  };
@@ -23,9 +23,10 @@
23
23
  * @module
24
24
  */
25
25
  import type { Primitive, Unknown } from '../../../djs/module.f.ts';
26
- import { type Info0, type Primitive0, type Struct, type Tuple, type Type } from '../module.f.ts';
26
+ import { type Info0, type Primitive0, type Struct, type Tag1, type Tuple, type Type } from '../module.f.ts';
27
27
  import { type Error, type Result as CommonResult } from '../../result/module.f.ts';
28
28
  import type { Ts } from '../ts/module.f.ts';
29
+ import { type ReadonlyRecord } from '../../object/module.f.ts';
29
30
  /** A path to a sub-value within the validated structure. Each step is an object key or stringified array index. */
30
31
  export type Path = readonly string[];
31
32
  /** Detailed validation failure: the offending `path` plus a short `message`. */
@@ -65,6 +66,14 @@ export type Visitor<R> = {
65
66
  readonly primitive0: (tag: Primitive0) => R;
66
67
  readonly unknown: () => R;
67
68
  };
69
+ /** Type guard narrowing `Unknown` to a specific container type `C`. */
70
+ export type IsContainer<C extends Unknown> = (value: Unknown) => value is C;
71
+ /** Maps a `Tag1` to its runtime container type. */
72
+ export type Container<K extends Tag1> = K extends 'array' ? ReadonlyArray<Unknown> : ReadonlyRecord<string, Unknown>;
73
+ /** `IsContainer` guard for arrays, shared by `validate` and `parse`. */
74
+ export declare const isArray: IsContainer<ReadonlyArray<Unknown>>;
75
+ /** `IsContainer` guard for records/structs, shared by `validate` and `parse`. */
76
+ export declare const isObject: IsContainer<ReadonlyRecord<string, Unknown>>;
68
77
  /**
69
78
  * Visits a schema `Type` by dispatching to the matching handler in `v`.
70
79
  *
@@ -1,6 +1,7 @@
1
1
  import {} from "../module.f.js";
2
2
  import { error, ok } from "../../result/module.f.js";
3
- import { isArray } from "../../array/module.f.js";
3
+ import { isArray as commonIsArray } from "../../array/module.f.js";
4
+ import { isObject as commonIsObject } from "../../object/module.f.js";
4
5
  /** Builds an error result with empty path and the given message. */
5
6
  export const verror = (message) => error({ path: [], message });
6
7
  /** Prepends `key` to the error's path, used to build the path bottom-up. */
@@ -18,8 +19,12 @@ export const constPrimitiveValidate = (rtti) => value => Object.is(rtti, value)
18
19
  ? ok(value)
19
20
  : verror('unexpected value');
20
21
  const visitConst = (v) => (c) => typeof c === 'object' && c !== null
21
- ? (isArray(c) ? v.tuple(c) : v.struct(c))
22
+ ? (commonIsArray(c) ? v.tuple(c) : v.struct(c))
22
23
  : v.constPrimitive(c);
24
+ /** `IsContainer` guard for arrays, shared by `validate` and `parse`. */
25
+ export const isArray = value => commonIsArray(value);
26
+ /** `IsContainer` guard for records/structs, shared by `validate` and `parse`. */
27
+ export const isObject = value => commonIsObject(value);
23
28
  /**
24
29
  * Visits a schema `Type` by dispatching to the matching handler in `v`.
25
30
  *
@@ -1,71 +1,60 @@
1
1
  import {} from "../module.f.js";
2
2
  import { ok } from "../../result/module.f.js";
3
- import { isArray as commonIsArray } from "../../array/module.f.js";
4
- import { isObject as commonIsObject } from "../../object/module.f.js";
3
+ import {} from "../../object/module.f.js";
5
4
  import { find, map as listMap } from "../../list/module.f.js";
6
- import { constPrimitiveValidate, prependPath, primitive0Validate, verror, visit, } from "../common/module.f.js";
5
+ import { constPrimitiveValidate, isArray, isObject, prependPath, primitive0Validate, verror, visit, } from "../common/module.f.js";
7
6
  export {} from "../common/module.f.js";
8
- const indexedFirstError = (results) => {
9
- // TODO: findIndex breaks type inference,
10
- // we should replace it with something else.
11
- const i = results.findIndex(r => r[0] === 'error');
12
- return i < 0 ? null : [i, results[i]];
13
- };
7
+ const { entries } = Object;
14
8
  const keyedFirstError = (results) => {
15
9
  const e = results.find(([, r]) => r[0] === 'error');
16
10
  return e === undefined ? null : [e[0], e[1]];
17
11
  };
18
- const arrayParse = (item) => value => {
19
- if (!commonIsArray(value)) {
20
- return verror('unexpected value');
21
- }
22
- if (value.length === 0) {
23
- return ok([]);
24
- }
25
- // Note: we shouldn't instantiate `itemParse` until we know the array is non-empty.
26
- // Otherwise, we can get infinite recursion on empty arrays for recursive schemas.
27
- const itemParse = parse(item);
28
- const results = value.map(itemParse);
29
- const err = indexedFirstError(results);
30
- return (err === null
31
- ? ok(results.map(r => r[1]))
32
- : prependPath(String(err[0]), err[1]));
33
- };
34
- const recordParse = (item) => value => {
35
- if (!commonIsObject(value)) {
12
+ const arrayRebuild = entries => entries.map(([, v]) => v);
13
+ const recordRebuild = entries => Object.fromEntries(entries);
14
+ /** Drops the `'ok'` tag from each result, yielding the rebuild's `[key, value]` entries. */
15
+ const okEntries = (results) => results.map(([k, r]) => [k, r[1]]);
16
+ /**
17
+ * Builds a parser for `array` or `record` schemas. Mirrors `validate`'s
18
+ * `containerValidate`, but rebuilds a fresh container from each item's parsed
19
+ * result instead of returning the value unchanged. The inner item parser is
20
+ * instantiated lazily (only when the container is non-empty) so recursive
21
+ * schemas don't recurse forever on empty containers.
22
+ */
23
+ const containerParse = (isContainer, rebuild) => (item) => value => {
24
+ if (!isContainer(value)) {
36
25
  return verror('unexpected value');
37
26
  }
38
- const entries = Object.entries(value);
39
- if (entries.length === 0) {
40
- return ok({});
27
+ const e = entries(value);
28
+ if (e.length === 0) {
29
+ return ok(rebuild([]));
41
30
  }
42
31
  const itemParse = parse(item);
43
- const results = entries.map(([k, v]) => [k, itemParse(v)]);
32
+ const results = e.map(([k, v]) => [k, itemParse(v)]);
44
33
  const err = keyedFirstError(results);
45
34
  return (err === null
46
- ? ok(Object.fromEntries(results.map(([k, r]) => [k, r[1]])))
35
+ ? ok(rebuild(okEntries(results)))
47
36
  : prependPath(err[0], err[1]));
48
37
  };
49
- const tupleParse = (rtti) => value => {
50
- if (!commonIsArray(value)) {
51
- return verror('unexpected value');
52
- }
53
- const results = rtti.map((t, i) => parse(t)(value[i]));
54
- const err = indexedFirstError(results);
55
- return (err === null
56
- ? ok(results.map(r => r[1]))
57
- : prependPath(String(err[0]), err[1]));
58
- };
59
- const structParse = (rtti) => value => {
60
- if (!commonIsObject(value)) {
38
+ const arrayParse = containerParse(isArray, arrayRebuild);
39
+ const recordParse = containerParse(isObject, recordRebuild);
40
+ /**
41
+ * Builds a parser for `Tuple` or `Struct` const schemas. Mirrors `validate`'s
42
+ * `constContainerValidate`: it iterates the schema's entries (so extra tuple
43
+ * elements and undeclared struct keys are dropped) and rebuilds the result
44
+ * from each parsed item.
45
+ */
46
+ const constContainerParse = (isContainer, getItem, rebuild) => (rtti) => value => {
47
+ if (!isContainer(value)) {
61
48
  return verror('unexpected value');
62
49
  }
63
- const results = Object.entries(rtti).map(([k, t]) => [k, parse(t)(value[k])]);
50
+ const results = entries(rtti).map(([k, t]) => [k, parse(t)(getItem(value, k))]);
64
51
  const err = keyedFirstError(results);
65
52
  return (err === null
66
- ? ok(Object.fromEntries(results.map(([k, r]) => [k, r[1]])))
53
+ ? ok(rebuild(okEntries(results)))
67
54
  : prependPath(err[0], err[1]));
68
55
  };
56
+ const tupleParse = constContainerParse(isArray, (value, k) => value[Number(k)], arrayRebuild);
57
+ const structParse = constContainerParse(isObject, (value, k) => value[k], recordRebuild);
69
58
  const findFirst = find(verror('no match'))((k) => k[0] === 'ok');
70
59
  const orParse = (rtti) => value => findFirst(listMap(t => parse(t)(value))(rtti));
71
60
  /**
@@ -1,26 +1,26 @@
1
1
  import {} from "../module.f.js";
2
2
  import { ok } from "../../result/module.f.js";
3
- import { isArray as commonIsArray } from "../../array/module.f.js";
4
- import { isObject as commonIsObject } from "../../object/module.f.js";
5
- import { constPrimitiveValidate, prependPath, primitive0Validate, verror, visit, } from "../common/module.f.js";
3
+ import {} from "../../object/module.f.js";
4
+ import { constPrimitiveValidate, isArray, isObject, prependPath, primitive0Validate, verror, visit, } from "../common/module.f.js";
6
5
  export { constPrimitiveValidate, prependPath, primitive0Validate, verror, } from "../common/module.f.js";
6
+ const { entries } = Object;
7
7
  /**
8
8
  * Builds a validator for `array` or `record` schemas.
9
9
  * The inner item validator is instantiated lazily (only when the container is
10
10
  * non-empty) to avoid infinite recursion with recursive schemas.
11
11
  */
12
- const containerValidate = (isContainer, getEntries) => (item) => value => {
12
+ const containerValidate = (isContainer) => (item) => value => {
13
13
  if (!isContainer(value)) {
14
14
  return verror('unexpected value');
15
15
  }
16
- const entries = getEntries(value);
17
- if (entries.length === 0) {
16
+ const e = entries(value);
17
+ if (e.length === 0) {
18
18
  return ok(value);
19
19
  }
20
20
  // Note: we shouldn't instantiate `itemValidate` until we make sure `entries` is not empty.
21
21
  // Otherwise, we can get infinite recursion on empty arrays and objects
22
22
  const itemValidate = validate(item);
23
- for (const [k, v] of entries) {
23
+ for (const [k, v] of e) {
24
24
  const r = itemValidate(v);
25
25
  if (r[0] === 'error') {
26
26
  return prependPath(k, r);
@@ -28,11 +28,8 @@ const containerValidate = (isContainer, getEntries) => (item) => value => {
28
28
  }
29
29
  return ok(value);
30
30
  };
31
- const isArray = value => commonIsArray(value);
32
- const arrayEntries = (value) => value.map((v, i) => [String(i), v]);
33
- const arrayValidate = containerValidate(isArray, arrayEntries);
34
- const isObject = value => commonIsObject(value);
35
- const recordValidate = containerValidate(isObject, Object.entries);
31
+ const arrayValidate = containerValidate(isArray);
32
+ const recordValidate = containerValidate(isObject);
36
33
  /**
37
34
  * Builds a validator for `Tuple` or `Struct` const schemas.
38
35
  * Iterates over the schema's entries and validates each corresponding
@@ -3,12 +3,11 @@
3
3
  *
4
4
  * @module
5
5
  */
6
- import type { Sign } from '../function/compare/module.f.ts';
6
+ import { type Sign, type Cmp } from '../function/compare/module.f.ts';
7
7
  import { type List } from '../list/module.f.ts';
8
8
  import type { Nullable } from '../nullable/module.f.ts';
9
9
  export type SortedList<T> = List<T>;
10
10
  type SortedArray<T> = readonly T[];
11
- type Cmp<T> = (a: T) => (b: T) => Sign;
12
11
  export type ReduceOp<T, S> = (state: S) => (a: T) => (b: T) => readonly [Nullable<T>, Sign, S];
13
12
  export type TailReduce<T, S> = (state: S) => (tail: List<T>) => List<T>;
14
13
  type MergeReduce<T, S> = {
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Sorted immutable list helpers and merge operations.
3
+ *
4
+ * @module
5
+ */
6
+ import { bsearch } from "../function/compare/module.f.js";
1
7
  import { next } from "../list/module.f.js";
2
8
  import { identity } from "../function/module.f.js";
3
9
  export const genericMerge = ({ reduceOp, tailReduce }) => {
@@ -29,25 +35,6 @@ const cmpReduce = (cmp) => () => a => b => {
29
35
  const mergeTail = () => identity;
30
36
  export const find = (cmp) => (value) => (array) => {
31
37
  const cmpValue = cmp(value);
32
- let b = 0;
33
- let e = array.length - 1;
34
- while (true) {
35
- const d = e - b;
36
- if (d < 0)
37
- return null;
38
- const mid = b + (d >> 1);
39
- switch (cmpValue(array[mid])) {
40
- case -1: {
41
- e = mid - 1;
42
- break;
43
- }
44
- case 0: {
45
- return value;
46
- }
47
- case 1: {
48
- b = mid + 1;
49
- break;
50
- }
51
- }
52
- }
38
+ const pos = bsearch(array.length)(mid => cmpValue(array[mid]));
39
+ return pos < array.length && cmpValue(array[pos]) === 0 ? value : null;
53
40
  };
@@ -26,10 +26,8 @@
26
26
  * has(cmp)(2)(setA) // false
27
27
  * ```
28
28
  */
29
- import type { Sign } from '../function/compare/module.f.ts';
29
+ import type { Cmp } from '../function/compare/module.f.ts';
30
30
  export type SortedSet<T> = readonly T[];
31
- type Cmp<T> = (a: T) => (b: T) => Sign;
32
31
  export declare const union: <T>(cmp: Cmp<T>) => (a: SortedSet<T>) => (b: SortedSet<T>) => SortedSet<T>;
33
32
  export declare const intersect: <T>(cmp: Cmp<T>) => (a: SortedSet<T>) => (b: SortedSet<T>) => SortedSet<T>;
34
33
  export declare const has: <T>(cmp: Cmp<T>) => (value: T) => (set: SortedSet<T>) => boolean;
35
- export {};
@@ -0,0 +1,18 @@
1
+ export declare const primitiveNull: () => void;
2
+ export declare const primitiveBigint: () => void;
3
+ export declare const primitiveString: () => void;
4
+ export declare const primitiveNumberFinite: () => void;
5
+ export declare const primitiveNumberInfinite: () => void;
6
+ export declare const primitiveUndefined: () => void;
7
+ export declare const primitiveBoolean: () => void;
8
+ export declare const unionEmpty: () => void;
9
+ export declare const unionSingle: () => void;
10
+ export declare const unionMulti: () => void;
11
+ export declare const printerReadonlyTuple: () => void;
12
+ export declare const printerReadonlyStruct: () => void;
13
+ export declare const printerReadonlyArray: () => void;
14
+ export declare const printerReadonlyRecord: () => void;
15
+ export declare const printerMutableTuple: () => void;
16
+ export declare const printerMutableStruct: () => void;
17
+ export declare const printerMutableArray: () => void;
18
+ export declare const printerMutableRecord: () => void;
@@ -0,0 +1,111 @@
1
+ import { printer, primitive, union } from "./module.f.js";
2
+ const ro = printer();
3
+ const mut = printer(true);
4
+ export const primitiveNull = () => {
5
+ const r = primitive(null);
6
+ if (r !== 'null') {
7
+ throw r;
8
+ }
9
+ };
10
+ export const primitiveBigint = () => {
11
+ const r = primitive(42n);
12
+ if (r !== '42n') {
13
+ throw r;
14
+ }
15
+ };
16
+ export const primitiveString = () => {
17
+ const r = primitive('hello');
18
+ if (r !== '"hello"') {
19
+ throw r;
20
+ }
21
+ };
22
+ export const primitiveNumberFinite = () => {
23
+ const r = primitive(3.14);
24
+ if (r !== '3.14') {
25
+ throw r;
26
+ }
27
+ };
28
+ export const primitiveNumberInfinite = () => {
29
+ const r = primitive(Infinity);
30
+ if (r !== 'number') {
31
+ throw r;
32
+ }
33
+ };
34
+ export const primitiveUndefined = () => {
35
+ const r = primitive(undefined);
36
+ if (r !== 'undefined') {
37
+ throw r;
38
+ }
39
+ };
40
+ export const primitiveBoolean = () => {
41
+ const r = primitive(true);
42
+ if (r !== 'true') {
43
+ throw r;
44
+ }
45
+ };
46
+ export const unionEmpty = () => {
47
+ const r = union([]);
48
+ if (r !== 'never') {
49
+ throw r;
50
+ }
51
+ };
52
+ export const unionSingle = () => {
53
+ const r = union(['string']);
54
+ if (r !== 'string') {
55
+ throw r;
56
+ }
57
+ };
58
+ export const unionMulti = () => {
59
+ const r = union(['string', 'number']);
60
+ if (r !== 'string|number') {
61
+ throw r;
62
+ }
63
+ };
64
+ export const printerReadonlyTuple = () => {
65
+ const r = ro.tuple(['string', 'number']);
66
+ if (r !== 'readonly[string,number]') {
67
+ throw r;
68
+ }
69
+ };
70
+ export const printerReadonlyStruct = () => {
71
+ const r = ro.struct([['x', 'number'], ['y', 'string']]);
72
+ if (r !== '{readonly"x":number,readonly"y":string}') {
73
+ throw r;
74
+ }
75
+ };
76
+ export const printerReadonlyArray = () => {
77
+ const r = ro.array('string');
78
+ if (r !== 'readonly(string)[]') {
79
+ throw r;
80
+ }
81
+ };
82
+ export const printerReadonlyRecord = () => {
83
+ const r = ro.record('number');
84
+ if (r !== '{readonly[k:string]:number}') {
85
+ throw r;
86
+ }
87
+ };
88
+ export const printerMutableTuple = () => {
89
+ const r = mut.tuple(['string', 'number']);
90
+ if (r !== '[string,number]') {
91
+ throw r;
92
+ }
93
+ };
94
+ export const printerMutableStruct = () => {
95
+ const r = mut.struct([['x', 'number']]);
96
+ if (r !== '{"x":number}') {
97
+ throw r;
98
+ }
99
+ };
100
+ export const printerMutableArray = () => {
101
+ const r = mut.array('string');
102
+ if (r !== '(string)[]') {
103
+ throw r;
104
+ }
105
+ };
106
+ export const printerMutableRecord = () => {
107
+ const r = mut.record('number');
108
+ if (r !== '{[k:string]:number}') {
109
+ throw r;
110
+ }
111
+ };
@@ -1,5 +1,11 @@
1
1
  /**
2
- * Conversions between Uint8Array values and bit vectors.
2
+ * Conversions between `Uint8Array` values and bit vectors.
3
+ *
4
+ * @deprecated FunctionalScript represents byte data as `bigint`-based bit
5
+ * vectors (`Vec` from `fs/types/bit_vec`). Use `utf8`/`utf8ToString` from
6
+ * `fs/text` for string encoding, and the `bit_vec` module directly for raw
7
+ * byte manipulation. `Uint8Array` interop belongs at Node.js boundaries only
8
+ * (e.g. `fromVec`/`toVec` when reading or writing files).
3
9
  *
4
10
  * @module
5
11
  */
@@ -8,5 +8,6 @@ declare const _default: {
8
8
  decodeUtf8Ascii: () => void;
9
9
  decodeUtf8Multibyte: () => void;
10
10
  utf8RoundTrip: () => void;
11
+ listToVec: () => void;
11
12
  };
12
13
  export default _default;
@@ -1,5 +1,5 @@
1
1
  import { vec } from "../bit_vec/module.f.js";
2
- import { toVec, fromVec, decodeUtf8, encodeUtf8 } from "./module.f.js";
2
+ import { toVec, fromVec, listToVec, decodeUtf8, encodeUtf8 } from "./module.f.js";
3
3
  import { strictEqual } from "../function/operator/module.f.js";
4
4
  import { equal, fromArrayLike } from "../list/module.f.js";
5
5
  const assertEq = (a, b) => {
@@ -54,5 +54,9 @@ export default {
54
54
  const input = 'FunctionalScript 🐝';
55
55
  const output = decodeUtf8(encodeUtf8(input));
56
56
  assertEq(output, input);
57
+ },
58
+ listToVec: () => {
59
+ const result = listToVec([Uint8Array.from([1, 2]), Uint8Array.from([3])]);
60
+ assertArrayEq(fromVec(result), Uint8Array.from([1, 2, 3]));
57
61
  }
58
62
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.17.0",
3
+ "version": "0.18.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "**/*.js",