@metta-ts/node and @metta-ts/browser
The two platform entry points. Both re-export everything from @metta-ts/core and add platform-specific pieces.
@metta-ts/node
npm install @metta-ts/node # library
npm install -g @metta-ts/node # the metta-ts CLI on your PATHCLI
metta-ts path/to/program.metta
npx -p @metta-ts/node metta-ts path/to/program.metta # without a global installRuns a .metta file, resolving import! relative to the file's directory, and prints each !-query's results.
Host runtime flags are opt-in:
metta-ts --py program.metta # Python through pythonia
metta-ts --prolog program.metta # Prolog through a local swipl executableWith those flags, .py and .pl files imported through import! are handled by the matching host adapter. Without the flags, the CLI never loads Python, Prolog, or their optional dependencies.
API
function runFile(path: string, fuel?: number): QueryResult[];
function readImports(src: string, baseDir: string): Map<string, Atom[]>;
class ParallelFlatMatcher {
constructor(kb: FlatKB, workerCount?: number);
match(pattern: Atom): Promise<Array<Map<string, Atom>>>; // variable name -> atom, per match
close(): Promise<void>; // terminate the worker pool
}runFile runs a file from disk. readImports pre-reads the import! targets a program references, resolving names against baseDir. ParallelFlatMatcher scans a FlatKB across worker_threads over a SharedArrayBuffer; build it once, reuse the warm pool, and close() when done. It is for large, non-selective, small-result scans only (see scaling).
@metta-ts/browser
npm install @metta-ts/browserfunction run(src: string, files?: Map<string, string>, fuel?: number): QueryResult[];
function vfsImports(src: string, files: Map<string, string>): Map<string, Atom[]>;run evaluates a program in the browser, resolving import! against an in-memory virtual file system (files maps a module name to its MeTTa source). vfsImports builds that import map directly. The base interpreter is pure TypeScript, so it runs in any browser with no native addon and no required WASM, which is exactly what powers the playground.
For optional host runtimes, use @metta-ts/browser/host:
import { createBrowserRunner, createBrowserTextLoader } from "@metta-ts/browser/host";
import { createPyodideInterop } from "@metta-ts/py/pyodide";
import { createSwiWasmInterop } from "@metta-ts/prolog/swi-wasm";
const files = new Map([
["math.py", "def add(a, b):\n return a + b\n"],
["facts.pl", "edge(alice, bob).\n"],
]);
const loadText = createBrowserTextLoader({ files, baseUrl: import.meta.url });
const runner = createBrowserRunner({
files,
interops: [await createPyodideInterop({ loadText }), await createSwiWasmInterop({ loadText })],
});
await runner.run(`
!(import! &self "math.py")
!(py-call (math.add 40 2))
!(import! &self "facts.pl")
!(prolog-call (edge alice $x))
`);The Pyodide and SWI-WASM packages are only included in bundles that import their adapter subpaths.