functionalscript 0.23.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 (55) hide show
  1. package/fs/cas/module.f.d.ts +2 -2
  2. package/fs/cas/module.f.js +2 -2
  3. package/fs/cas/proof.f.js +3 -3
  4. package/fs/ci/module.f.d.ts +2 -2
  5. package/fs/ci/module.f.js +2 -2
  6. package/fs/ci/proof.f.js +1 -1
  7. package/fs/dev/module.f.d.ts +2 -9
  8. package/fs/dev/module.f.js +10 -9
  9. package/fs/dev/proof.f.d.ts +0 -1
  10. package/fs/dev/proof.f.js +0 -21
  11. package/fs/dev/version/module.f.d.ts +2 -2
  12. package/fs/dev/version/module.f.js +2 -2
  13. package/fs/dev/version/proof.f.js +2 -2
  14. package/fs/djs/module.f.d.ts +2 -2
  15. package/fs/djs/module.f.js +2 -2
  16. package/fs/djs/parser/module.f.d.ts +0 -2
  17. package/fs/djs/proof.f.js +1 -1
  18. package/fs/djs/transpiler/module.f.d.ts +2 -2
  19. package/fs/djs/transpiler/module.f.js +2 -2
  20. package/fs/djs/transpiler/proof.f.js +1 -1
  21. package/fs/{types/effects → effects}/module.f.d.ts +1 -1
  22. package/fs/{types/effects → effects}/module.f.js +1 -1
  23. package/fs/{io → effects/node}/module.d.ts +5 -12
  24. package/fs/{types/effects → effects}/node/module.f.d.ts +3 -3
  25. package/fs/{types/effects → effects}/node/module.f.js +1 -1
  26. package/fs/{io → effects/node}/module.js +96 -12
  27. package/fs/{types/effects → effects}/node/proof.f.js +1 -1
  28. package/fs/{types/effects → effects}/node/virtual/module.f.d.ts +1 -1
  29. package/fs/{types/effects → effects}/node/virtual/module.f.js +5 -5
  30. package/fs/emergent_testing/all.test.d.ts +1 -1
  31. package/fs/emergent_testing/all.test.js +3 -2
  32. package/fs/emergent_testing/module.f.d.ts +2 -2
  33. package/fs/emergent_testing/module.f.js +2 -2
  34. package/fs/emergent_testing/proof.f.js +4 -4
  35. package/fs/emergent_testing/scenarios/all.d.ts +1 -1
  36. package/fs/emergent_testing/scenarios/all.js +1 -1
  37. package/fs/fjs/module.f.d.ts +1 -1
  38. package/fs/fjs/module.f.js +1 -1
  39. package/fs/fjs/module.js +2 -2
  40. package/fs/text/sgr/module.f.d.ts +2 -17
  41. package/fs/text/sgr/module.f.js +4 -19
  42. package/fs/website/module.f.d.ts +2 -2
  43. package/fs/website/module.f.js +2 -2
  44. package/package.json +1 -1
  45. package/fs/emergent_testing/module.d.ts +0 -1
  46. package/fs/emergent_testing/module.js +0 -4
  47. package/fs/io/module.f.d.ts +0 -134
  48. package/fs/io/module.f.js +0 -113
  49. /package/fs/{types/effects → effects}/mock/module.f.d.ts +0 -0
  50. /package/fs/{types/effects → effects}/mock/module.f.js +0 -0
  51. /package/fs/{types/effects → effects}/module.d.ts +0 -0
  52. /package/fs/{types/effects → effects}/module.js +0 -0
  53. /package/fs/{types/effects → effects}/node/proof.f.d.ts +0 -0
  54. /package/fs/{types/effects → effects}/proof.f.d.ts +0 -0
  55. /package/fs/{types/effects → effects}/proof.f.js +0 -0
@@ -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 };
package/fs/cas/proof.f.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { cas, main } from "./module.f.js";
2
2
  import { sha256 } from "../crypto/sha2/module.f.js";
3
3
  import { empty, length, vec8 } 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";
6
- import { emptyState, virtual } from "../types/effects/node/virtual/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";
7
7
  export const proof = {
8
8
  mainAdd: () => {
9
9
  const content = vec8(0x2an);
@@ -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)));
@@ -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
15
  import { relativize, toPosix } 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
- };
17
16
  /**
18
17
  * Returns `true` if the file should be loaded for proof discovery.
19
18
  *
@@ -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`;
@@ -1,7 +1,7 @@
1
1
  import { utf8, utf8ToString } from "../../text/module.f.js";
2
2
  import { isVec } from "../../types/bit_vec/module.f.js";
3
- import { all, writeFile } from "../../types/effects/node/module.f.js";
4
- import { emptyState, virtual } from "../../types/effects/node/virtual/module.f.js";
3
+ import { all, writeFile } from "../../effects/node/module.f.js";
4
+ import { emptyState, virtual } from "../../effects/node/virtual/module.f.js";
5
5
  import { updateVersion } from "./module.f.js";
6
6
  const version = '0.3.0';
7
7
  const x = {
@@ -4,8 +4,8 @@
4
4
  * @module
5
5
  */
6
6
  import type { Primitive as JsonPrimitive } from '../json/module.f.ts';
7
- import { type Effect } from '../types/effects/module.f.ts';
8
- import { type WriteFile, type ReadFile, type Write } from '../types/effects/node/module.f.ts';
7
+ import { type Effect } from '../effects/module.f.ts';
8
+ import { type WriteFile, type ReadFile, type Write } from '../effects/node/module.f.ts';
9
9
  export type Object = {
10
10
  readonly [k in string]: Unknown;
11
11
  };
@@ -1,8 +1,8 @@
1
1
  import { transpile } from "./transpiler/module.f.js";
2
2
  import { stringify, stringifyAsTree } from "./serializer/module.f.js";
3
3
  import { sort } from "../types/object/module.f.js";
4
- import { pure } from "../types/effects/module.f.js";
5
- import { writeFile, error, } from "../types/effects/node/module.f.js";
4
+ import { pure } from "../effects/module.f.js";
5
+ import { writeFile, error, } from "../effects/node/module.f.js";
6
6
  import { utf8 } from "../text/module.f.js";
7
7
  export const compile = args => {
8
8
  if (args.length < 2) {
@@ -7,11 +7,9 @@ import { type Result } from '../../types/result/module.f.ts';
7
7
  import { type List } from '../../types/list/module.f.ts';
8
8
  import type { DjsTokenWithMetadata } from '../tokenizer/module.f.ts';
9
9
  import { type OrderedMap } from '../../types/ordered_map/module.f.ts';
10
- import type { Fs } from '../../io/module.f.ts';
11
10
  import type { AstModule } from '../ast/module.f.ts';
12
11
  import type { TokenMetadata } from '../../js/tokenizer/module.f.ts';
13
12
  export type ParseContext = {
14
- readonly fs: Fs;
15
13
  readonly complete: OrderedMap<Result<AstModule, string>>;
16
14
  readonly stack: List<string>;
17
15
  };
package/fs/djs/proof.f.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { compile } from "./module.f.js";
2
- import { virtual, emptyState } from "../types/effects/node/virtual/module.f.js";
2
+ import { virtual, emptyState } from "../effects/node/virtual/module.f.js";
3
3
  import { isVec } from "../types/bit_vec/module.f.js";
4
4
  import { utf8, utf8ToString } from "../text/module.f.js";
5
5
  const readOutput = (root, path) => {
@@ -8,8 +8,8 @@ import { type Result } from '../../types/result/module.f.ts';
8
8
  import { type List } from '../../types/list/module.f.ts';
9
9
  import { type OrderedMap } from '../../types/ordered_map/module.f.ts';
10
10
  import { type ParseError } from '../parser/module.f.ts';
11
- import { type Effect } from '../../types/effects/module.f.ts';
12
- import { type ReadFile } from '../../types/effects/node/module.f.ts';
11
+ import { type Effect } from '../../effects/module.f.ts';
12
+ import { type ReadFile } from '../../effects/node/module.f.ts';
13
13
  /**
14
14
  * State threaded through the recursive transpilation of a DJS module graph.
15
15
  *
@@ -12,8 +12,8 @@ import { stringToList } from "../../text/utf16/module.f.js";
12
12
  import { concat as pathConcat } from "../../path/module.f.js";
13
13
  import { parseFromTokens } from "../parser/module.f.js";
14
14
  import { run } from "../ast/module.f.js";
15
- import { foldStep, pure } from "../../types/effects/module.f.js";
16
- import { readFile } from "../../types/effects/node/module.f.js";
15
+ import { foldStep, pure } from "../../effects/module.f.js";
16
+ import { readFile } from "../../effects/node/module.f.js";
17
17
  import { utf8ToString } from "../../text/module.f.js";
18
18
  const mapDjs = context => path => {
19
19
  const res = at(path)(context.complete);
@@ -1,7 +1,7 @@
1
1
  import { sort } from "../../types/object/module.f.js";
2
2
  import { transpile } from "./module.f.js";
3
3
  import { stringifyAsTree } from "../serializer/module.f.js";
4
- import { virtual, emptyState } from "../../types/effects/node/virtual/module.f.js";
4
+ import { virtual, emptyState } from "../../effects/node/virtual/module.f.js";
5
5
  import { utf8 } from "../../text/module.f.js";
6
6
  const run = (root) => (path) => {
7
7
  const [_, result] = virtual({ ...emptyState, root })(transpile(path));
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @module
5
5
  */
6
- import { type List } from '../list/module.f.ts';
6
+ import { type List } from '../types/list/module.f.ts';
7
7
  export type Operation = readonly [string, (..._: readonly never[]) => unknown];
8
8
  export type Effect<O extends Operation, T> = {
9
9
  value: Value<O, T>;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @module
5
5
  */
6
- import { fold } from "../list/module.f.js";
6
+ import { fold } from "../types/list/module.f.js";
7
7
  export const pure = (v) => ({
8
8
  value: [v],
9
9
  step: f => f(v)
@@ -1,10 +1,4 @@
1
- import { type Io } from './module.f.ts';
2
- import type { Module, NodeProgram } from '../types/effects/node/module.f.ts';
3
- import { type Result } from '../types/result/module.f.ts';
4
- export declare const asyncImport: (v: string) => Promise<Module>;
5
- export declare const tryCatch: <T>(f: () => T) => Result<T, unknown>;
6
- export declare const io: Io;
7
- export type NodeRun = (p: NodeProgram) => Promise<never>;
1
+ import { type NodeProgram } from './module.f.ts';
8
2
  /**
9
3
  * Runs a `NodeProgram` against the real Node `io` and process arguments,
10
4
  * resolving to its exit code **without** terminating the process.
@@ -12,7 +6,7 @@ export type NodeRun = (p: NodeProgram) => Promise<never>;
12
6
  * Use this when the caller must stay alive afterwards — e.g. when proofs are
13
7
  * registered under an external test runner (Node `--test`, Bun, Playwright)
14
8
  * that owns the process lifecycle. For a standalone CLI entry point that should
15
- * exit with the program's code, use the default {@link run} export instead.
9
+ * exit with the program's code, use {@link run} instead.
16
10
  */
17
11
  export declare const runEffect: (p: NodeProgram) => Promise<number>;
18
12
  /**
@@ -20,8 +14,7 @@ export declare const runEffect: (p: NodeProgram) => Promise<number>;
20
14
  * `process.exit` with its exit code. The `Promise<never>` return type reflects
21
15
  * that control never returns to the caller — the process terminates.
22
16
  *
23
- * This is the default export so a `bin` script can simply
24
- * `import run from '.../io/module.js'; run(main)`.
17
+ * A `bin` script can simply
18
+ * `import { run } from '.../fs/effects/node/module.js'; await run(main)`.
25
19
  */
26
- declare const run: NodeRun;
27
- export default run;
20
+ export declare const run: (p: NodeProgram) => Promise<never>;
@@ -1,6 +1,6 @@
1
- import type { Vec } from '../../bit_vec/module.f.ts';
2
- import type { Nominal } from '../../nominal/module.f.ts';
3
- import type { Result } from '../../result/module.f.ts';
1
+ import type { Vec } from '../../types/bit_vec/module.f.ts';
2
+ import type { Nominal } from '../../types/nominal/module.f.ts';
3
+ import type { Result } from '../../types/result/module.f.ts';
4
4
  import { type Effect, type Func, type Operation, type ToAsyncOperationMap } from '../module.f.ts';
5
5
  export type IoResult<T> = Result<T, unknown>;
6
6
  export type All = ['all', <T>(...effects: Effect<never, T>[]) => readonly T[]];
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * @module
9
9
  */
10
- import { utf8 } from "../../../text/module.f.js";
10
+ import { utf8 } from "../../text/module.f.js";
11
11
  import { begin, do_, pure } from "../module.f.js";
12
12
  const doAll = do_('all');
13
13
  /**
@@ -10,12 +10,97 @@ import http from 'node:http';
10
10
  import childProcess from 'node:child_process';
11
11
  import fs from 'node:fs';
12
12
  import process from 'node:process';
13
- import { concat } from "../path/module.f.js";
14
13
  import { once } from 'node:events';
15
- import { runProgram } from "./module.f.js";
16
- import { error, ok } from "../types/result/module.f.js";
17
- import { fromVec } from "../types/uint8array/module.f.js";
18
14
  import * as testContext from 'node:test';
15
+ import { concat } from "../../path/module.f.js";
16
+ import { normalize } from "../../path/module.f.js";
17
+ import {} from "../module.f.js";
18
+ import { asyncRun } from "../module.js";
19
+ import {} from "./module.f.js";
20
+ import { asBase, asNominal } from "../../types/nominal/module.f.js";
21
+ import { error, ok } from "../../types/result/module.f.js";
22
+ import { fromVec, listToVec, toVec } from "../../types/uint8array/module.f.js";
23
+ const tc = async (f) => {
24
+ try {
25
+ return ok(await f());
26
+ }
27
+ catch (e) {
28
+ return error(e);
29
+ }
30
+ };
31
+ const collect = async (v) => {
32
+ let result = [];
33
+ for await (const a of v) {
34
+ result = [...result, a];
35
+ }
36
+ return result;
37
+ };
38
+ const fromIo = ({ fs: { promises: { mkdir, readFile, readdir, writeFile, rm, access } }, fetch, http: { createServer }, childProcess, asyncImport, now: ioNow, sandbox, write, await: awaitPromise, }) => {
39
+ const result = asyncRun({
40
+ all: async (...effects) => await Promise.all(effects.map(result)),
41
+ fetch: async (url) => tc(async () => {
42
+ const response = await fetch(url);
43
+ if (!response.ok) {
44
+ throw new Error(`Fetch error: ${response.status} ${response.statusText}`);
45
+ }
46
+ return toVec(new Uint8Array(await response.arrayBuffer()));
47
+ }),
48
+ mkdir: (...p) => tc(async () => { await mkdir(...p); }),
49
+ readFile: path => tc(async () => toVec(await readFile(path))),
50
+ readdir: (path, r) => tc(async () => (await readdir(path, { ...r, withFileTypes: true }))
51
+ .map(v => ({
52
+ name: v.name,
53
+ parentPath: normalize(v.parentPath),
54
+ isFile: v.isFile()
55
+ }))),
56
+ writeFile: (path, data) => tc(() => writeFile(path, fromVec(data))),
57
+ rm: path => tc(() => rm(path)),
58
+ access: path => tc(() => access(path)),
59
+ import: path => tc(() => asyncImport(path)),
60
+ exec: (command, stdin) => new Promise(resolve => {
61
+ const child = childProcess.exec(command, (e, stdout, stderr) => resolve(e !== null ? ['error', e] : ok({ stdout, stderr })));
62
+ child.stdin?.end(stdin);
63
+ }),
64
+ createServer: async (requestListener) => {
65
+ const erl = requestListener;
66
+ const nodeRl = async (req, res) => {
67
+ const reqBody = await collect(req);
68
+ const { method, url, headers } = req;
69
+ const { status, headers: outHeaders, body: outBody } = await result(erl({
70
+ method,
71
+ url,
72
+ headers,
73
+ body: listToVec(reqBody)
74
+ }));
75
+ res
76
+ .writeHead(status, outHeaders)
77
+ .end(fromVec(outBody));
78
+ };
79
+ const server = asNominal(createServer(nodeRl));
80
+ return server;
81
+ },
82
+ listen: async (server, port) => {
83
+ const s = asBase(server);
84
+ s.listen(port);
85
+ },
86
+ forever: () => new Promise(() => { }),
87
+ now: async () => ioNow(),
88
+ sandbox,
89
+ await: awaitPromise,
90
+ write,
91
+ test: async (ctx, name, expectFailure, test) => ctx.test(name, { expectFailure }, async (t) => result(test(t))),
92
+ });
93
+ return result;
94
+ };
95
+ const runProgram = (io) => {
96
+ const { process: { env, stdout, stderr }, testContext, bunTestContext, playwrightTestContext, engine } = io;
97
+ const std = { stdout, stderr };
98
+ const f = fromIo(io);
99
+ return args => {
100
+ const options = { args, env, std, testContext, bunTestContext, playwrightTestContext, engine };
101
+ return program => f(program(options));
102
+ };
103
+ };
19
104
  const isPlaywright = 'PLAYWRIGHT_TEST' in (process?.env ?? {});
20
105
  const pwTest = isPlaywright
21
106
  ? (await import('@playwright/test')).test
@@ -66,8 +151,8 @@ const writeAll = async (stream, data) => {
66
151
  await once(stream, 'drain');
67
152
  }
68
153
  };
69
- export const asyncImport = (v) => import(__rewriteRelativeImportExtension(v));
70
- export const tryCatch = f => {
154
+ const asyncImport = (v) => import(__rewriteRelativeImportExtension(v));
155
+ const tryCatch = f => {
71
156
  try {
72
157
  return ok(f());
73
158
  }
@@ -76,7 +161,7 @@ export const tryCatch = f => {
76
161
  }
77
162
  };
78
163
  const awaitPromise = async (p) => [p instanceof Promise ? await p : p];
79
- export const io = {
164
+ const io = {
80
165
  console,
81
166
  fs,
82
167
  process,
@@ -132,7 +217,7 @@ export const io = {
132
217
  * Use this when the caller must stay alive afterwards — e.g. when proofs are
133
218
  * registered under an external test runner (Node `--test`, Bun, Playwright)
134
219
  * that owns the process lifecycle. For a standalone CLI entry point that should
135
- * exit with the program's code, use the default {@link run} export instead.
220
+ * exit with the program's code, use {@link run} instead.
136
221
  */
137
222
  export const runEffect = runProgram(io)(io.process.argv.slice(2));
138
223
  /**
@@ -140,8 +225,7 @@ export const runEffect = runProgram(io)(io.process.argv.slice(2));
140
225
  * `process.exit` with its exit code. The `Promise<never>` return type reflects
141
226
  * that control never returns to the caller — the process terminates.
142
227
  *
143
- * This is the default export so a `bin` script can simply
144
- * `import run from '.../io/module.js'; run(main)`.
228
+ * A `bin` script can simply
229
+ * `import { run } from '.../fs/effects/node/module.js'; await run(main)`.
145
230
  */
146
- const run = async (p) => process.exit(await runEffect(p));
147
- export default run;
231
+ export const run = async (p) => process.exit(await runEffect(p));
@@ -1,4 +1,4 @@
1
- import { empty, isVec, uint, vec8 } from "../../bit_vec/module.f.js";
1
+ import { empty, isVec, uint, vec8 } from "../../types/bit_vec/module.f.js";
2
2
  import { pure } from "../module.f.js";
3
3
  import { fetch, mkdir, now, readdir, readFile, rm, sandbox, writeFile } from "./module.f.js";
4
4
  import { emptyState, virtual } from "./virtual/module.f.js";
@@ -1,4 +1,4 @@
1
- import { type Vec } from '../../../bit_vec/module.f.ts';
1
+ import { type Vec } from '../../../types/bit_vec/module.f.ts';
2
2
  import { type RunInstance } from '../../mock/module.f.ts';
3
3
  import type { Module, NodeOp } from '../module.f.ts';
4
4
  /**
@@ -3,11 +3,11 @@
3
3
  *
4
4
  * @module
5
5
  */
6
- import { assert, todo } from "../../../../asserts/module.f.js";
7
- import { parse } from "../../../../path/module.f.js";
8
- import { utf8ToString } from "../../../../text/module.f.js";
9
- import { isVec } from "../../../bit_vec/module.f.js";
10
- import { error, ok } from "../../../result/module.f.js";
6
+ import { todo } from "../../../asserts/module.f.js";
7
+ import { parse } from "../../../path/module.f.js";
8
+ import { utf8ToString } from "../../../text/module.f.js";
9
+ import { isVec } from "../../../types/bit_vec/module.f.js";
10
+ import { error, ok } from "../../../types/result/module.f.js";
11
11
  import { run } from "../../mock/module.f.js";
12
12
  export const emptyState = {
13
13
  stdout: '',
@@ -1 +1 @@
1
- import './module.ts';
1
+ export {};
@@ -1,3 +1,4 @@
1
- import "./module.js";
1
+ import { runEffect } from "../effects/node/module.js";
2
+ import { register } from "./module.f.js";
2
3
  // we need `await` for Playwright.
3
- // await run()
4
+ await runEffect(register);
@@ -1,5 +1,5 @@
1
- import { type All, type Await, type NodeProgram, type NodeProgramOptions, type Program, type Sandbox, type SandboxResult, type Test, type TestContext, type Write } from '../types/effects/node/module.f.ts';
2
- import { type Effect, type Operation } from '../types/effects/module.f.ts';
1
+ import { type All, type Await, type NodeProgram, type NodeProgramOptions, type Program, type Sandbox, type SandboxResult, type Test, type TestContext, type Write } from '../effects/node/module.f.ts';
2
+ import { type Effect, type Operation } from '../effects/module.f.ts';
3
3
  import { type LoadModuleOperations, type ModuleMap } from '../dev/module.f.ts';
4
4
  /** A zero-argument test function whose return value may contain sub-tests. */
5
5
  export type TestFn = () => unknown;
@@ -11,8 +11,8 @@
11
11
  * @module
12
12
  */
13
13
  import { reset, fgGreen, fgRed, bold, csiWrite } from "../text/sgr/module.f.js";
14
- import { all, awaitIfPromise, sandbox, test } from "../types/effects/node/module.f.js";
15
- import { pure } from "../types/effects/module.f.js";
14
+ import { all, awaitIfPromise, sandbox, test } from "../effects/node/module.f.js";
15
+ import { pure } from "../effects/module.f.js";
16
16
  import { loadModuleMap, shouldLoad } from "../dev/module.f.js";
17
17
  import { invert } from "../types/result/module.f.js";
18
18
  const addPass = (delta) => (ts) => ({ ...ts, time: ts.time + delta, pass: ts.pass + 1 });
@@ -1,9 +1,9 @@
1
- import { pure } from "../types/effects/module.f.js";
2
- import { emptyState } from "../types/effects/node/virtual/module.f.js";
3
- import { virtual } from "../types/effects/node/virtual/module.f.js";
1
+ import { pure } from "../effects/module.f.js";
2
+ import { emptyState } from "../effects/node/virtual/module.f.js";
3
+ import { virtual } from "../effects/node/virtual/module.f.js";
4
4
  import { assert, assertEq, todo } from "../asserts/module.f.js";
5
5
  import { testAll, defaultReporter, fmtPath, fmtTerm, fmtImport, ghEscape, isInteger, isIdentifier, registerModule, defaultTest, } from "./module.f.js";
6
- import { run as mockRun } from "../types/effects/mock/module.f.js";
6
+ import { run as mockRun } from "../effects/mock/module.f.js";
7
7
  import { shouldLoad } from "../dev/module.f.js";
8
8
  const makeReporter = () => {
9
9
  const events = [];
@@ -1 +1 @@
1
- import '../module.ts';
1
+ import '../all.test.ts';
@@ -1 +1 @@
1
- import "../module.js";
1
+ import "../all.test.js";
@@ -1,2 +1,2 @@
1
- import { type NodeProgram } from '../types/effects/node/module.f.ts';
1
+ import { type NodeProgram } from '../effects/node/module.f.ts';
2
2
  export declare const main: NodeProgram;
@@ -6,7 +6,7 @@
6
6
  import { compile } from "../djs/module.f.js";
7
7
  import { main as testMain } from "../emergent_testing/module.f.js";
8
8
  import { main as casMain } from "../cas/module.f.js";
9
- import { import_, errorExit } from "../types/effects/node/module.f.js";
9
+ import { import_, errorExit } from "../effects/node/module.f.js";
10
10
  export const main = options => {
11
11
  const [command, ...rest] = options.args;
12
12
  switch (command) {
package/fs/fjs/module.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
2
  import { main } from "./module.f.js";
3
- import run from "../io/module.js";
4
- run(main);
3
+ import { run } from "../effects/node/module.js";
4
+ await run(main);
@@ -4,9 +4,8 @@
4
4
  *
5
5
  * @module
6
6
  */
7
- import type { Io, Writable } from "../../io/module.f.ts";
8
- import { type Write, type WriteConsoles, type NodeProgramOptions } from '../../types/effects/node/module.f.ts';
9
- import { type Effect } from '../../types/effects/module.f.ts';
7
+ import { type Write, type WriteConsoles, type NodeProgramOptions } from '../../effects/node/module.f.ts';
8
+ import { type Effect } from '../../effects/module.f.ts';
10
9
  export declare const backspace: string;
11
10
  type End = 'm';
12
11
  type Csi = (code: number | string) => string;
@@ -45,20 +44,6 @@ export type WriteText = (text: string) => WriteText;
45
44
  */
46
45
  export declare const createConsoleText: (stdout: Stdout) => WriteText;
47
46
  export type CsiConsole = (s: string) => void;
48
- /**
49
- * Creates a TTY-aware console function. Appends `\n` to each string before writing.
50
- *
51
- * For TTY destinations, ANSI SGR sequences are preserved.
52
- * For non-TTY destinations, ANSI SGR sequences are stripped.
53
- *
54
- * @param io - Runtime IO bindings.
55
- * @returns A function that targets a writable stream.
56
- */
57
- export declare const console: ({ fs: { writeSync } }: Io) => (w: Writable) => CsiConsole;
58
- /** Writes to process stdout using a TTY-aware CSI console. */
59
- export declare const stdio: (io: Io) => CsiConsole;
60
- /** Writes to process stderr using a TTY-aware CSI console. */
61
- export declare const stderr: (io: Io) => CsiConsole;
62
47
  /**
63
48
  * Effect-based TTY-aware write. Strips ANSI SGR sequences when the target
64
49
  * stream is not a TTY, then encodes to UTF-8 and emits a `Write` effect.
@@ -4,8 +4,10 @@
4
4
  *
5
5
  * @module
6
6
  */
7
- import { write } from "../../types/effects/node/module.f.js";
8
- import {} from "../../types/effects/module.f.js";
7
+ // C0 control codes
8
+ // https://en.wikipedia.org/wiki/ANSI_escape_code#C0_control_codes
9
+ import { write } from "../../effects/node/module.f.js";
10
+ import {} from "../../effects/module.f.js";
9
11
  import { utf8 } from "../module.f.js";
10
12
  export const backspace = '\x08';
11
13
  const begin = '\x1b[';
@@ -50,23 +52,6 @@ export const createConsoleText = (stdout) => {
50
52
  return f('');
51
53
  };
52
54
  const str = (isTTY) => (s) => isTTY ? s : s.replace(/\x1b\[[0-9;]*m/g, '');
53
- /**
54
- * Creates a TTY-aware console function. Appends `\n` to each string before writing.
55
- *
56
- * For TTY destinations, ANSI SGR sequences are preserved.
57
- * For non-TTY destinations, ANSI SGR sequences are stripped.
58
- *
59
- * @param io - Runtime IO bindings.
60
- * @returns A function that targets a writable stream.
61
- */
62
- export const console = ({ fs: { writeSync } }) => (w) => {
63
- const toStr = str(w.isTTY);
64
- return (s) => writeSync(w.fd, toStr(s) + '\n');
65
- };
66
- /** Writes to process stdout using a TTY-aware CSI console. */
67
- export const stdio = (io) => console(io)(io.process.stdout);
68
- /** Writes to process stderr using a TTY-aware CSI console. */
69
- export const stderr = (io) => console(io)(io.process.stderr);
70
55
  /**
71
56
  * Effect-based TTY-aware write. Strips ANSI SGR sequences when the target
72
57
  * stream is not a TTY, then encodes to UTF-8 and emits a `Write` effect.
@@ -1,4 +1,4 @@
1
- import { type WriteFile } from '../types/effects/node/module.f.ts';
2
- import { type Effect } from '../types/effects/module.f.ts';
1
+ import { type WriteFile } from '../effects/node/module.f.ts';
2
+ import { type Effect } from '../effects/module.f.ts';
3
3
  declare const _default: () => Effect<WriteFile, number>;
4
4
  export default _default;
@@ -4,8 +4,8 @@
4
4
  * @module
5
5
  */
6
6
  import { htmlUtf8 } from "../html/module.f.js";
7
- import { writeFile } from "../types/effects/node/module.f.js";
8
- import { pure } from "../types/effects/module.f.js";
7
+ import { writeFile } from "../effects/node/module.f.js";
8
+ import { pure } from "../effects/module.f.js";
9
9
  const html = htmlUtf8()(['a',
10
10
  { href: 'https://github.com/functionalscript/functionalscript' },
11
11
  'GitHub Repository'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "**/*.js",
@@ -1 +0,0 @@
1
- export {};
@@ -1,4 +0,0 @@
1
- import { runEffect } from "../io/module.js";
2
- import { register } from "./module.f.js";
3
- // we need `await` for Playwright.
4
- await runEffect(register);
@@ -1,134 +0,0 @@
1
- import { type Effect } from '../types/effects/module.f.ts';
2
- import { type Headers, type Module, type NodeOp, type Env, type SandboxResult, type NodeProgram, type WriteConsoles, type TestContext, type Engine } from '../types/effects/node/module.f.ts';
3
- import type { Vec } from '../types/bit_vec/module.f.ts';
4
- import { type Result } from '../types/result/module.f.ts';
5
- /**
6
- * Represents a directory entry (file or directory) in the filesystem
7
- * @see https://nodejs.org/api/fs.html#class-fsdirent
8
- */
9
- export type Dirent = {
10
- readonly name: string;
11
- readonly parentPath: string;
12
- readonly isDirectory: () => boolean;
13
- readonly isFile: () => boolean;
14
- };
15
- export type RmOptions = {
16
- readonly force?: boolean;
17
- readonly recursive?: boolean;
18
- };
19
- export type MakeDirectoryOptions = {
20
- readonly recursive?: boolean;
21
- };
22
- export type ReadDir = ((path: string, options: {
23
- withFileTypes: true;
24
- }) => Promise<Dirent[]>) & ((path: string, options: {
25
- recursive?: true;
26
- }) => Promise<readonly string[]>);
27
- /**
28
- * File system operations interface
29
- * @see https://nodejs.org/api/fs.html
30
- */
31
- export type Fs = {
32
- readonly writeSync: (fd: number, s: string) => void;
33
- readonly writeFileSync: (file: string, data: Uint8Array) => void;
34
- readonly readFileSync: (path: string) => Uint8Array | null;
35
- readonly promises: {
36
- readonly readFile: (path: string) => Promise<Uint8Array>;
37
- readonly writeFile: (path: string, data: Uint8Array) => Promise<void>;
38
- readonly readdir: ReadDir;
39
- readonly rm: (path: string, options?: RmOptions) => Promise<void>;
40
- readonly mkdir: (path: string, options?: MakeDirectoryOptions) => Promise<string | undefined>;
41
- readonly copyFile: (src: string, dest: string) => Promise<void>;
42
- readonly access: (path: string) => Promise<void>;
43
- };
44
- };
45
- /**
46
- * Console operations interface
47
- * @see https://nodejs.org/api/console.html
48
- */
49
- export type Console = {
50
- readonly log: (...d: unknown[]) => void;
51
- readonly error: (...d: unknown[]) => void;
52
- };
53
- /**
54
- * High-resolution time measurement interface
55
- * @see https://nodejs.org/api/perf_hooks.html#performance-now
56
- */
57
- export type Performance = {
58
- readonly now: () => number;
59
- };
60
- export type Writable = {
61
- readonly fd: number;
62
- readonly isTTY: boolean;
63
- };
64
- /**
65
- * Node.js Process interface
66
- * @see https://nodejs.org/api/process.html
67
- */
68
- export type Process = {
69
- readonly argv: string[];
70
- readonly env: Env;
71
- readonly exit: (code: number) => never;
72
- readonly cwd: () => string;
73
- readonly stdout: Writable;
74
- readonly stderr: Writable;
75
- };
76
- export type TryCatch = <T>(f: () => T) => Result<T, unknown>;
77
- export type Sandbox = <T>(f: () => T) => Promise<SandboxResult<T>>;
78
- export type Server = {
79
- readonly listen: (port: number) => void;
80
- };
81
- export type Readable = AsyncIterable<Uint8Array>;
82
- export type IncomingMessage = Readable & {
83
- readonly method: string;
84
- readonly url: string;
85
- readonly headers: Headers;
86
- };
87
- export type ServerResponse = {
88
- readonly writeHead: (status: number, headers: Record<string, string>) => ServerResponse;
89
- readonly end: (body: Uint8Array) => void;
90
- };
91
- export type RequestListener = (req: IncomingMessage, res: ServerResponse) => Promise<void>;
92
- export type Http = {
93
- readonly createServer: (_: RequestListener) => Server;
94
- };
95
- export type ChildProcess = {
96
- readonly exec: (command: string, callback: (error: unknown, stdout: string, stderr: string) => void) => {
97
- readonly stdin: null | {
98
- readonly end: (data?: string) => void;
99
- };
100
- };
101
- };
102
- /**
103
- * Core IO operations interface providing access to system resources
104
- */
105
- export type Io = {
106
- readonly console: Console;
107
- readonly fs: Fs;
108
- readonly process: Process;
109
- readonly asyncImport: (s: string) => Promise<Module>;
110
- readonly performance: Performance;
111
- readonly fetch: (url: string) => Promise<Response>;
112
- readonly tryCatch: TryCatch;
113
- readonly asyncTryCatch: <T>(f: () => Promise<T>) => Promise<Result<T, unknown>>;
114
- readonly http: Http;
115
- readonly childProcess: ChildProcess;
116
- readonly now: () => number;
117
- readonly sandbox: Sandbox;
118
- readonly write: (stream: WriteConsoles, data: Vec) => Promise<void>;
119
- readonly testContext: TestContext;
120
- readonly bunTestContext: TestContext;
121
- readonly playwrightTestContext: TestContext;
122
- readonly engine: Engine;
123
- readonly await: (p: unknown) => Promise<readonly [unknown]>;
124
- };
125
- export type App = (io: Io) => Promise<number>;
126
- export type Run = (f: App) => Promise<never>;
127
- /**
128
- * Runs a function and exits the process with the returned code
129
- * Handles errors by exiting with code 1
130
- */
131
- export declare const run: (io: Io) => Run;
132
- export type EffectToPromise = <T>(effect: Effect<NodeOp, T>) => Promise<T>;
133
- export declare const fromIo: ({ fs: { promises: { mkdir, readFile, readdir, writeFile, rm, access } }, fetch, http: { createServer }, childProcess, asyncImport, now: ioNow, sandbox, write, await: awaitPromise, }: Io) => EffectToPromise;
134
- export declare const runProgram: (io: Io) => (args: readonly string[]) => (program: NodeProgram) => Promise<number>;
package/fs/io/module.f.js DELETED
@@ -1,113 +0,0 @@
1
- /**
2
- * Legacy `Io` interface and adapter (`fromIo`) bridging the old IO API to the
3
- * effect runner.
4
- *
5
- * @deprecated Use `fs/types/effects/node` (see issue
6
- * [i139](../../issues/README.md)).
7
- *
8
- * @module
9
- */
10
- import { normalize } from "../path/module.f.js";
11
- import {} from "../types/effects/module.f.js";
12
- import { asyncRun } from "../types/effects/module.js";
13
- import {} from "../types/effects/node/module.f.js";
14
- import { asBase, asNominal } from "../types/nominal/module.f.js";
15
- import { error, ok } from "../types/result/module.f.js";
16
- import { fromVec, listToVec, toVec } from "../types/uint8array/module.f.js";
17
- /**
18
- * Runs a function and exits the process with the returned code
19
- * Handles errors by exiting with code 1
20
- */
21
- export const run = (io) => {
22
- const exitCode = ([x, b]) => {
23
- if (x === 'error') {
24
- io.console.error(b);
25
- return 1;
26
- }
27
- else {
28
- return b;
29
- }
30
- };
31
- return async (f) => io.process.exit(exitCode(await io.asyncTryCatch(() => f(io))));
32
- };
33
- const tc = async (f) => {
34
- try {
35
- return ok(await f());
36
- }
37
- catch (e) {
38
- return error(e);
39
- }
40
- };
41
- const collect = async (v) => {
42
- let result = [];
43
- for await (const a of v) {
44
- result = [...result, a];
45
- }
46
- return result;
47
- };
48
- export const fromIo = ({ fs: { promises: { mkdir, readFile, readdir, writeFile, rm, access } }, fetch, http: { createServer }, childProcess, asyncImport, now: ioNow, sandbox, write, await: awaitPromise, }) => {
49
- const result = asyncRun({
50
- all: async (...effects) => await Promise.all(effects.map(result)),
51
- fetch: async (url) => tc(async () => {
52
- const response = await fetch(url);
53
- if (!response.ok) {
54
- throw new Error(`Fetch error: ${response.status} ${response.statusText}`);
55
- }
56
- return toVec(new Uint8Array(await response.arrayBuffer()));
57
- }),
58
- mkdir: (...p) => tc(async () => { await mkdir(...p); }),
59
- readFile: path => tc(async () => toVec(await readFile(path))),
60
- readdir: (path, r) => tc(async () => (await readdir(path, { ...r, withFileTypes: true }))
61
- .map(v => ({
62
- name: v.name,
63
- parentPath: normalize(v.parentPath),
64
- isFile: v.isFile()
65
- }))),
66
- writeFile: (path, data) => tc(() => writeFile(path, fromVec(data))),
67
- rm: path => tc(() => rm(path)),
68
- access: path => tc(() => access(path)),
69
- import: path => tc(() => asyncImport(path)),
70
- exec: (command, stdin) => new Promise(resolve => {
71
- const child = childProcess.exec(command, (e, stdout, stderr) => resolve(e !== null ? ['error', e] : ok({ stdout, stderr })));
72
- child.stdin?.end(stdin);
73
- }),
74
- createServer: async (requestListener) => {
75
- const erl = requestListener;
76
- const nodeRl = async (req, res) => {
77
- const reqBody = await collect(req);
78
- const { method, url, headers } = req;
79
- const { status, headers: outHeaders, body: outBody } = await result(erl({
80
- method,
81
- url,
82
- headers,
83
- body: listToVec(reqBody)
84
- }));
85
- res
86
- .writeHead(status, outHeaders)
87
- .end(fromVec(outBody));
88
- };
89
- const server = asNominal(createServer(nodeRl));
90
- return server;
91
- },
92
- listen: async (server, port) => {
93
- const s = asBase(server);
94
- s.listen(port);
95
- },
96
- forever: () => new Promise(() => { }),
97
- now: async () => ioNow(),
98
- sandbox,
99
- await: awaitPromise,
100
- write,
101
- test: async (ctx, name, expectFailure, test) => ctx.test(name, { expectFailure }, async (t) => result(test(t))),
102
- });
103
- return result;
104
- };
105
- export const runProgram = (io) => {
106
- const { process: { env, stdout, stderr }, testContext, bunTestContext, playwrightTestContext, engine } = io;
107
- const std = { stdout, stderr };
108
- const f = fromIo(io);
109
- return args => {
110
- const options = { args, env, std, testContext, bunTestContext, playwrightTestContext, engine };
111
- return program => f(program(options));
112
- };
113
- };
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes