functionalscript 0.12.6 → 0.12.8

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/io/module.f.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type Effect } from '../types/effects/module.f.ts';
2
- import type { ExecResult, Headers, IoResult, NodeOp } from '../types/effects/node/module.f.ts';
2
+ import type { ExecParam, ExecResult, Headers, IoResult, NodeOp } from '../types/effects/node/module.f.ts';
3
3
  import { type Result } from '../types/result/module.f.ts';
4
4
  /**
5
5
  * Represents a directory entry (file or directory) in the filesystem
@@ -97,7 +97,7 @@ export type Http = {
97
97
  readonly createServer: (_: RequestListener) => Server;
98
98
  };
99
99
  export type ChildProcess = {
100
- readonly exec: (command: string) => Promise<IoResult<ExecResult>>;
100
+ readonly exec: (param: ExecParam) => Promise<IoResult<ExecResult>>;
101
101
  };
102
102
  /**
103
103
  * Core IO operations interface providing access to system resources
package/io/module.js CHANGED
@@ -8,12 +8,14 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
8
8
  };
9
9
  import http from 'node:http';
10
10
  import { exec } from 'node:child_process';
11
- import { fromIo, run } from "./module.f.js";
12
11
  import fs from 'node:fs';
13
12
  import process from 'node:process';
13
+ import { promisify } from 'node:util';
14
+ import { fromIo, run } from "./module.f.js";
14
15
  import { concat } from "../path/module.f.js";
15
16
  import { error, ok } from "../types/result/module.f.js";
16
17
  const prefix = 'file:///';
18
+ const execAsync = promisify(exec);
17
19
  export const io = {
18
20
  console,
19
21
  fs,
@@ -43,7 +45,13 @@ export const io = {
43
45
  },
44
46
  http,
45
47
  childProcess: {
46
- exec: command => new Promise(resolve => exec(command, (e, stdout, stderr) => resolve(e !== null ? error(e) : ok({ stdout, stderr })))),
48
+ exec: ([command, stdin]) => {
49
+ const promise = execAsync(command);
50
+ if (stdin !== undefined && promise.child.stdin !== null) {
51
+ promise.child.stdin.end(stdin);
52
+ }
53
+ return promise.then(({ stdout, stderr }) => ok({ stdout, stderr }), (e) => error(e));
54
+ },
47
55
  },
48
56
  };
49
57
  export const legacyRun = run(io);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.12.6",
3
+ "version": "0.12.8",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "**/*.js",
@@ -188,6 +188,16 @@ export declare const msb: BitOrder;
188
188
  * @returns The resulting vector based on the provided bit order.
189
189
  */
190
190
  export declare const u8ListToVec: ({ unpackConcat }: BitOrder) => (list: List<number>) => Vec;
191
+ /**
192
+ * Chunks a bit vector into fixed-size pieces of `n` bits using the provided bit order.
193
+ * The last chunk may be smaller than `n` bits if the vector length is not a multiple of `n`.
194
+ *
195
+ * @param bitOrder The bit order for the conversion.
196
+ * @param n The chunk size in bits.
197
+ * @param v The vector to be chunked.
198
+ * @returns A thunk that produces a list of bit vectors, each representing one chunk.
199
+ */
200
+ export declare const chunkList: ({ unpackSplit }: BitOrder) => (n: bigint) => (v: Vec) => Thunk<Vec>;
191
201
  /**
192
202
  * Converts a bit vector to a list of unsigned 8-bit integers based on the provided bit order.
193
203
  *
@@ -195,7 +205,7 @@ export declare const u8ListToVec: ({ unpackConcat }: BitOrder) => (list: List<nu
195
205
  * @param v The vector to be converted.
196
206
  * @returns A thunk that produces a list of unsigned 8-bit integers.
197
207
  */
198
- export declare const u8List: ({ unpackSplit }: BitOrder) => (v: Vec) => Thunk<number>;
208
+ export declare const u8List: (bo: BitOrder) => (v: Vec) => Thunk<number>;
199
209
  /**
200
210
  * Concatenates a list of vectors using the provided bit order.
201
211
  */
@@ -21,9 +21,9 @@
21
21
  *
22
22
  * @module
23
23
  */
24
- import { bitLength, mask, max, min, xor } from "../bigint/module.f.js";
24
+ import { bitLength, divUp, mask, max, min, xor } from "../bigint/module.f.js";
25
25
  import { flip } from "../function/module.f.js";
26
- import { fold, iterable } from "../list/module.f.js";
26
+ import { fold, iterable, map } from "../list/module.f.js";
27
27
  import { asBase, asNominal } from "../nominal/module.f.js";
28
28
  import { repeat as mRepeat } from "../monoid/module.f.js";
29
29
  import { cmp } from "../function/compare/module.f.js";
@@ -230,37 +230,54 @@ export const u8ListToVec = ({ unpackConcat }) => (list) => {
230
230
  return pack(result.reduce((p, c) => unpackConcat(c)(p), unpackEmpty));
231
231
  };
232
232
  /**
233
- * Converts a bit vector to a list of unsigned 8-bit integers based on the provided bit order.
233
+ * Chunks a bit vector into fixed-size pieces of `n` bits using the provided bit order.
234
+ * The last chunk may be smaller than `n` bits if the vector length is not a multiple of `n`.
234
235
  *
235
236
  * @param bitOrder The bit order for the conversion.
236
- * @param v The vector to be converted.
237
- * @returns A thunk that produces a list of unsigned 8-bit integers.
237
+ * @param n The chunk size in bits.
238
+ * @param v The vector to be chunked.
239
+ * @returns A thunk that produces a list of bit vectors, each representing one chunk.
238
240
  */
239
- export const u8List = ({ unpackSplit }) => (v) => {
240
- if (v === empty) {
241
- return () => null;
242
- }
243
- const f = (stack) => () => {
244
- while (true) {
245
- const [first, rest] = stack;
246
- const { length, uint } = first;
247
- if (length <= 8n) {
248
- // the last unpack split is required to align data.
249
- const v = length < 8n ? unpackSplit(8n)(first)[0] : uint;
250
- return { first: Number(v), tail: rest !== undefined ? f(rest) : null };
251
- }
252
- // `length` is bigger than `8n` so `newLen` is `8n` or bigger.
253
- const aLength = ((length + 7n) >> 4n) << 3n;
254
- const bLength = length - aLength;
255
- const [a, b] = unpackSplit(aLength)(first);
256
- stack = [
257
- { length: aLength, uint: a & mask(aLength) },
258
- [{ length: bLength, uint: b & mask(bLength) }, rest],
259
- ];
241
+ export const chunkList = ({ unpackSplit }) => (n) => {
242
+ const divUpN2 = divUp(n << 1n);
243
+ return v => {
244
+ if (v === empty) {
245
+ return () => null;
260
246
  }
247
+ const f = (stack) => () => {
248
+ while (true) {
249
+ const [first, rest] = stack;
250
+ const { length } = first;
251
+ if (length <= n) {
252
+ return { first: pack(first), tail: rest !== undefined ? f(rest) : null };
253
+ }
254
+ const aLength = divUpN2(length) * n;
255
+ const bLength = length - aLength;
256
+ const [a, b] = unpackSplit(aLength)(first);
257
+ stack = [
258
+ { length: aLength, uint: a & mask(aLength) },
259
+ [{ length: bLength, uint: b & mask(bLength) }, rest],
260
+ ];
261
+ }
262
+ };
263
+ return f([unpack(v), undefined]);
261
264
  };
262
- return f([unpack(v), undefined]);
263
265
  };
266
+ const vecToU8 = ({ unpackSplit }) => {
267
+ const unpackSplit8 = unpackSplit(8n);
268
+ return chunk => {
269
+ const u = unpack(chunk);
270
+ return Number(u.length < 8n ? unpackSplit8(u)[0] : u.uint);
271
+ };
272
+ };
273
+ /**
274
+ * Converts a bit vector to a list of unsigned 8-bit integers based on the provided bit order.
275
+ *
276
+ * @param bitOrder The bit order for the conversion.
277
+ * @param v The vector to be converted.
278
+ * @returns A thunk that produces a list of unsigned 8-bit integers.
279
+ */
280
+ export const u8List = (bo) => (v) => map(vecToU8(bo))(chunkList(bo)(8n)(v));
264
281
  /**
265
282
  * Concatenates a list of vectors using the provided bit order.
266
283
  */
@@ -41,5 +41,12 @@ declare const _default: {
41
41
  msbCmp: () => void;
42
42
  u8ListToVec: () => () => void;
43
43
  u8ListUnaligned: () => void;
44
+ chunkList: {
45
+ empty: () => void;
46
+ lsb_aligned: () => void;
47
+ msb_aligned: () => void;
48
+ lsb_unaligned: () => void;
49
+ msb_unaligned: () => void;
50
+ };
44
51
  };
45
52
  export default _default;
@@ -1,6 +1,6 @@
1
1
  import { mask } from "../bigint/module.f.js";
2
2
  import { asBase, asNominal } from "../nominal/module.f.js";
3
- import { length, empty, uint, vec, lsb, msb, repeat, vec8, u8ListToVec, u8List } from "./module.f.js";
3
+ import { length, empty, uint, vec, lsb, msb, repeat, vec8, u8ListToVec, u8List, chunkList } from "./module.f.js";
4
4
  import { repeat as listRepeat, toArray } from "../list/module.f.js";
5
5
  const unsafeVec = (a) => asNominal(a);
6
6
  // 0x8 = 0b1000 = 0 + 8
@@ -482,5 +482,73 @@ export default {
482
482
  if (a1 !== 0x80) {
483
483
  throw `a1: ${a1.toString(16)}`;
484
484
  }
485
- }
485
+ },
486
+ chunkList: {
487
+ empty: () => {
488
+ const chunks = toArray(chunkList(lsb)(4n)(empty));
489
+ if (chunks.length !== 0) {
490
+ throw chunks.length;
491
+ }
492
+ },
493
+ // 8-bit vector 0xF5 = 0b1111_0101, aligned to 4-bit chunks
494
+ lsb_aligned: () => {
495
+ const chunks = toArray(chunkList(lsb)(4n)(vec(8n)(0xf5n)));
496
+ // LSB: low nibble first — bits 0-3 = 0101 = 5, bits 4-7 = 1111 = 15
497
+ if (chunks.length !== 2) {
498
+ throw chunks.length;
499
+ }
500
+ if (length(chunks[0]) !== 4n || uint(chunks[0]) !== 5n) {
501
+ throw chunks[0];
502
+ }
503
+ if (length(chunks[1]) !== 4n || uint(chunks[1]) !== 0xfn) {
504
+ throw chunks[1];
505
+ }
506
+ },
507
+ msb_aligned: () => {
508
+ const chunks = toArray(chunkList(msb)(4n)(vec(8n)(0xf5n)));
509
+ // MSB: high nibble first — bits 0-3 = 1111 = 15, bits 4-7 = 0101 = 5
510
+ if (chunks.length !== 2) {
511
+ throw chunks.length;
512
+ }
513
+ if (length(chunks[0]) !== 4n || uint(chunks[0]) !== 0xfn) {
514
+ throw chunks[0];
515
+ }
516
+ if (length(chunks[1]) !== 4n || uint(chunks[1]) !== 5n) {
517
+ throw chunks[1];
518
+ }
519
+ },
520
+ // 10-bit vector 0x1B5 = 0b01_1011_0101, unaligned to 4-bit chunks (last chunk is 2 bits)
521
+ lsb_unaligned: () => {
522
+ const chunks = toArray(chunkList(lsb)(4n)(vec(10n)(0x1b5n)));
523
+ // LSB: bits 0-3 = 0101 = 5, bits 4-7 = 1011 = 11, bits 8-9 = 01 = 1
524
+ if (chunks.length !== 3) {
525
+ throw chunks.length;
526
+ }
527
+ if (length(chunks[0]) !== 4n || uint(chunks[0]) !== 5n) {
528
+ throw chunks[0];
529
+ }
530
+ if (length(chunks[1]) !== 4n || uint(chunks[1]) !== 0xbn) {
531
+ throw chunks[1];
532
+ }
533
+ if (length(chunks[2]) !== 2n || uint(chunks[2]) !== 1n) {
534
+ throw chunks[2];
535
+ }
536
+ },
537
+ msb_unaligned: () => {
538
+ const chunks = toArray(chunkList(msb)(4n)(vec(10n)(0x1b5n)));
539
+ // MSB: bits 0-3 = 0110 = 6, bits 4-7 = 1101 = 13, bits 8-9 = 01 = 1
540
+ if (chunks.length !== 3) {
541
+ throw chunks.length;
542
+ }
543
+ if (length(chunks[0]) !== 4n || uint(chunks[0]) !== 6n) {
544
+ throw chunks[0];
545
+ }
546
+ if (length(chunks[1]) !== 4n || uint(chunks[1]) !== 0xdn) {
547
+ throw chunks[1];
548
+ }
549
+ if (length(chunks[2]) !== 2n || uint(chunks[2]) !== 1n) {
550
+ throw chunks[2];
551
+ }
552
+ },
553
+ },
486
554
  };
@@ -47,8 +47,9 @@ export type ExecResult = {
47
47
  readonly stdout: string;
48
48
  readonly stderr: string;
49
49
  };
50
- export type Exec = readonly ['exec', (_: string) => IoResult<ExecResult>];
51
- export declare const exec: Func<Exec>;
50
+ export type ExecParam = readonly [string, string?];
51
+ export type Exec = readonly ['exec', (_: ExecParam) => IoResult<ExecResult>];
52
+ export declare const exec: RestFunc<Exec>;
52
53
  export type Fs = Mkdir | ReadFile | Readdir | WriteFile | Rm | Exec;
53
54
  export type Error = ['error', (_: string) => void];
54
55
  export declare const error: Func<Error>;
@@ -15,7 +15,7 @@ export const readFile = do_('readFile');
15
15
  export const readdir = doRest('readdir');
16
16
  export const writeFile = doRest('writeFile');
17
17
  export const rm = do_('rm');
18
- export const exec = do_('exec');
18
+ export const exec = doRest('exec');
19
19
  export const error = do_('error');
20
20
  export const log = do_('log');
21
21
  export const createServer = do_('createServer');