functionalscript 0.12.4 → 0.12.6

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/ci/module.f.js CHANGED
@@ -69,7 +69,7 @@ const node = (version) => (extra) => basicNode(version)([
69
69
  const findTgz = (v) => v === 'windows' ? '(Get-ChildItem *.tgz).FullName' : './*.tgz';
70
70
  const playwrightVersion = '1.58.2';
71
71
  const playwrightAndVersion = `playwright@${playwrightVersion}`;
72
- const rustToolchain = '1.93.1';
72
+ const rustToolchain = '1.94.1';
73
73
  const toSteps = (m) => {
74
74
  const filter = (st) => m.flatMap((mt) => mt.type === st ? [mt.step] : []);
75
75
  const aptGet = m.flatMap(v => v.type === 'apt-get' ? [v.package] : []).join(' ');
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 { Headers, NodeOp } from '../types/effects/node/module.f.ts';
2
+ import type { 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
@@ -96,6 +96,9 @@ export type RequestListener = (req: IncomingMessage, res: ServerResponse) => Pro
96
96
  export type Http = {
97
97
  readonly createServer: (_: RequestListener) => Server;
98
98
  };
99
+ export type ChildProcess = {
100
+ readonly exec: (command: string) => Promise<IoResult<ExecResult>>;
101
+ };
99
102
  /**
100
103
  * Core IO operations interface providing access to system resources
101
104
  */
@@ -109,6 +112,7 @@ export type Io = {
109
112
  readonly tryCatch: TryCatch;
110
113
  readonly asyncTryCatch: <T>(f: () => Promise<T>) => Promise<Result<T, unknown>>;
111
114
  readonly http: Http;
115
+ readonly childProcess: ChildProcess;
112
116
  };
113
117
  /**
114
118
  * The environment variables.
@@ -124,4 +128,4 @@ export type Run = (f: App) => Promise<never>;
124
128
  */
125
129
  export declare const run: (io: Io) => Run;
126
130
  export type EffectToPromise = <T>(effect: Effect<NodeOp, T>) => Promise<T>;
127
- export declare const fromIo: ({ console: { error, log }, fs: { promises: { mkdir, readFile, readdir, writeFile } }, fetch, http: { createServer }, }: Io) => EffectToPromise;
131
+ export declare const fromIo: ({ console: { error, log }, fs: { promises: { mkdir, readFile, readdir, writeFile, rm } }, fetch, http: { createServer }, childProcess: { exec }, }: Io) => EffectToPromise;
package/io/module.f.js CHANGED
@@ -35,7 +35,7 @@ const collect = async (v) => {
35
35
  }
36
36
  return result;
37
37
  };
38
- export const fromIo = ({ console: { error, log }, fs: { promises: { mkdir, readFile, readdir, writeFile } }, fetch, http: { createServer }, }) => {
38
+ export const fromIo = ({ console: { error, log }, fs: { promises: { mkdir, readFile, readdir, writeFile, rm } }, fetch, http: { createServer }, childProcess: { exec }, }) => {
39
39
  const result = asyncRun({
40
40
  all: async (effects) => await Promise.all(effects.map(result)),
41
41
  error: async (message) => error(message),
@@ -52,6 +52,8 @@ export const fromIo = ({ console: { error, log }, fs: { promises: { mkdir, readF
52
52
  readdir: ([path, r]) => tc(async () => (await readdir(path, { ...r, withFileTypes: true }))
53
53
  .map(v => ({ name: v.name, parentPath: normalize(v.parentPath), isFile: v.isFile() }))),
54
54
  writeFile: ([path, data]) => tc(() => writeFile(path, fromVec(data))),
55
+ rm: path => tc(() => rm(path)),
56
+ exec,
55
57
  createServer: async (requestListener) => {
56
58
  const erl = requestListener;
57
59
  const nodeRl = async (req, res) => {
package/io/module.js CHANGED
@@ -7,6 +7,7 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
7
7
  return path;
8
8
  };
9
9
  import http from 'node:http';
10
+ import { exec } from 'node:child_process';
10
11
  import { fromIo, run } from "./module.f.js";
11
12
  import fs from 'node:fs';
12
13
  import process from 'node:process';
@@ -41,6 +42,9 @@ export const io = {
41
42
  }
42
43
  },
43
44
  http,
45
+ childProcess: {
46
+ exec: command => new Promise(resolve => exec(command, (e, stdout, stderr) => resolve(e !== null ? error(e) : ok({ stdout, stderr })))),
47
+ },
44
48
  };
45
49
  export const legacyRun = run(io);
46
50
  export const ioRun = (io) => {
@@ -36,5 +36,8 @@ export const createVirtualIo = (files) => ({
36
36
  asyncTryCatch: async (f) => ['ok', await f()],
37
37
  http: {
38
38
  createServer: todo
39
- }
39
+ },
40
+ childProcess: {
41
+ exec: todo,
42
+ },
40
43
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.12.4",
3
+ "version": "0.12.6",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "**/*.js",
@@ -41,7 +41,15 @@ export declare const readdir: RestFunc<Readdir>;
41
41
  export type WriteFileParam = readonly [string, Vec];
42
42
  export type WriteFile = readonly ['writeFile', (_: WriteFileParam) => IoResult<void>];
43
43
  export declare const writeFile: RestFunc<WriteFile>;
44
- export type Fs = Mkdir | ReadFile | Readdir | WriteFile;
44
+ export type Rm = readonly ['rm', (_: string) => IoResult<void>];
45
+ export declare const rm: Func<Rm>;
46
+ export type ExecResult = {
47
+ readonly stdout: string;
48
+ readonly stderr: string;
49
+ };
50
+ export type Exec = readonly ['exec', (_: string) => IoResult<ExecResult>];
51
+ export declare const exec: Func<Exec>;
52
+ export type Fs = Mkdir | ReadFile | Readdir | WriteFile | Rm | Exec;
45
53
  export type Error = ['error', (_: string) => void];
46
54
  export declare const error: Func<Error>;
47
55
  export type Log = ['log', (_: string) => void];
@@ -14,6 +14,8 @@ export const mkdir = doRest('mkdir');
14
14
  export const readFile = do_('readFile');
15
15
  export const readdir = doRest('readdir');
16
16
  export const writeFile = doRest('writeFile');
17
+ export const rm = do_('rm');
18
+ export const exec = do_('exec');
17
19
  export const error = do_('error');
18
20
  export const log = do_('log');
19
21
  export const createServer = do_('createServer');
@@ -24,5 +24,11 @@ declare const _default: {
24
24
  nestedPath: () => void;
25
25
  directory: () => void;
26
26
  };
27
+ rm: {
28
+ one: () => void;
29
+ nested: () => void;
30
+ noSuchFile: () => void;
31
+ isDirectory: () => void;
32
+ };
27
33
  };
28
34
  export default _default;
@@ -1,6 +1,6 @@
1
1
  import { empty, isVec, uint, vec8 } from "../../bit_vec/module.f.js";
2
2
  import { pure } from "../module.f.js";
3
- import { fetch, mkdir, readdir, readFile, writeFile } from "./module.f.js";
3
+ import { fetch, mkdir, readdir, readFile, rm, writeFile } from "./module.f.js";
4
4
  import { emptyState, virtual } from "./virtual/module.f.js";
5
5
  export default {
6
6
  map: () => {
@@ -272,4 +272,58 @@ export default {
272
272
  }
273
273
  },
274
274
  },
275
+ rm: {
276
+ one: () => {
277
+ const [state, [t, result]] = virtual({
278
+ ...emptyState,
279
+ root: { hello: vec8(0x2an) },
280
+ })(rm('hello'));
281
+ if (t !== 'ok') {
282
+ throw result;
283
+ }
284
+ if (state.root.hello !== undefined) {
285
+ throw state.root;
286
+ }
287
+ },
288
+ nested: () => {
289
+ const [state, [t, result]] = virtual({
290
+ ...emptyState,
291
+ root: { tmp: { cache: vec8(0x15n) } },
292
+ })(rm('tmp/cache'));
293
+ if (t !== 'ok') {
294
+ throw result;
295
+ }
296
+ const tmp = state.root.tmp;
297
+ if (tmp === undefined || isVec(tmp)) {
298
+ throw state.root;
299
+ }
300
+ if (tmp.cache !== undefined) {
301
+ throw tmp;
302
+ }
303
+ },
304
+ noSuchFile: () => {
305
+ const [_, [t, result]] = virtual(emptyState)(rm('hello'));
306
+ if (t !== 'error') {
307
+ throw result;
308
+ }
309
+ if (result !== 'no such file') {
310
+ throw result;
311
+ }
312
+ },
313
+ isDirectory: () => {
314
+ const [state, [t, result]] = virtual({
315
+ ...emptyState,
316
+ root: { tmp: {} },
317
+ })(rm('tmp'));
318
+ if (t !== 'error') {
319
+ throw result;
320
+ }
321
+ if (result !== 'invalid path') {
322
+ throw result;
323
+ }
324
+ if (state.root.tmp === undefined) {
325
+ throw state.root;
326
+ }
327
+ },
328
+ },
275
329
  };
@@ -94,6 +94,21 @@ const readdir = (base, recursive) => readOperation((dir, path) => {
94
94
  };
95
95
  return ok(f(base, dir));
96
96
  });
97
+ const rm = operation((dir, path) => {
98
+ if (path.length !== 1) {
99
+ return [dir, error('invalid path')];
100
+ }
101
+ const [name] = path;
102
+ const entry = dir[name];
103
+ if (entry === undefined) {
104
+ return [dir, error('no such file')];
105
+ }
106
+ if (!isVec(entry)) {
107
+ return [dir, error('is a directory')];
108
+ }
109
+ const { [name]: _, ...rest } = dir;
110
+ return [rest, okVoid];
111
+ });
97
112
  const console = (name) => (state, payload) => [{ ...state, [name]: `${state[name]}${payload}\n` }, undefined];
98
113
  const map = {
99
114
  all: (state, a) => {
@@ -115,6 +130,8 @@ const map = {
115
130
  readFile,
116
131
  readdir: (state, [path, { recursive }]) => readdir(path, recursive === true)(state, path),
117
132
  writeFile: (state, [path, payload]) => writeFile(payload)(state, path),
133
+ rm: (state, path) => rm(state, path),
134
+ exec: todo,
118
135
  createServer: todo,
119
136
  listen: todo,
120
137
  forever: todo,