Pre-AlphaMetaScript is in early design phase. The compiler is not yet available.Join Discord for updates
MetaScript

Standard Library

The @metascript/core package provides cross-platform utilities that work on all backends.

Installation

npm install @metascript/core

Modules

fs (File System)

Cross-platform file system operations.

import { fs } from "@metascript/core"

// Read file
const content = await fs.readFile("config.json", "utf-8")

// Write file
await fs.writeFile("output.txt", "Hello, World!")

// Check existence
if (await fs.exists("file.txt")) {
  // ...
}

// Read directory
const entries = await fs.readdir("src/")
for (const entry of entries) {
  console.log(entry.name, entry.isFile())
}

// Walk directory recursively
for await (const entry of fs.walk("src/")) {
  console.log(entry.path)
}

// Create directory
await fs.mkdir("dist/", { recursive: true })

// Remove file/directory
await fs.remove("temp/")

// Copy
await fs.copy("src/", "backup/")

// Move/rename
await fs.move("old.txt", "new.txt")

// File stats
const stats = await fs.stat("file.txt")
console.log(stats.size, stats.mtime)

path

Path manipulation utilities.

import { path } from "@metascript/core"

// Join paths
const full = path.join("src", "components", "Button.ms")
// => "src/components/Button.ms"

// Resolve absolute path
const abs = path.resolve("./src/main.ms")
// => "/Users/me/project/src/main.ms"

// Get parts
path.basename("/src/file.ms")   // "file.ms"
path.dirname("/src/file.ms")    // "/src"
path.extname("/src/file.ms")    // ".ms"

// Parse path
const parsed = path.parse("/src/file.ms")
// { root: "/", dir: "/src", base: "file.ms", ext: ".ms", name: "file" }

// Normalize
path.normalize("/src/../lib/./utils")
// => "/lib/utils"

// Relative path
path.relative("/src/components", "/src/utils")
// => "../utils"

http

HTTP client for making requests.

import { http } from "@metascript/core"

// GET request
const response = await http.get("https://api.example.com/users")
const users = await response.json()

// POST request
const created = await http.post("https://api.example.com/users", {
  body: JSON.stringify({ name: "Alice" }),
  headers: {
    "Content-Type": "application/json",
  },
})

// With options
const response = await http.request("https://api.example.com/data", {
  method: "PUT",
  body: data,
  headers: { Authorization: `Bearer ${token}` },
  timeout: 5000,
})

// Streaming response
const stream = await http.get("https://example.com/large-file", {
  stream: true,
})
for await (const chunk of stream.body) {
  process.stdout.write(chunk)
}

env

Environment variable access.

import { env } from "@metascript/core"

// Get variable
const port = env.get("PORT", "3000")

// Required variable (throws if missing)
const secret = env.require("API_SECRET")

// Check existence
if (env.has("DEBUG")) {
  // ...
}

// All variables
const all = env.all()

// Set variable (for current process)
env.set("MY_VAR", "value")

process

Process utilities.

import { process } from "@metascript/core"

// Command line arguments
const args = process.argv

// Current working directory
const cwd = process.cwd()

// Exit
process.exit(0)

// Environment info
console.log(process.platform) // "darwin" | "linux" | "win32"
console.log(process.arch)     // "x64" | "arm64"

// Standard streams
process.stdout.write("Hello")
process.stderr.write("Error")
const input = await process.stdin.read()

// Signals
process.on("SIGINT", () => {
  console.log("Interrupted")
  process.exit(0)
})

crypto

Cryptographic utilities.

import { crypto } from "@metascript/core"

// Hash
const hash = crypto.hash("sha256", "hello")
// => "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"

// HMAC
const hmac = crypto.hmac("sha256", "secret", "message")

// Random bytes
const bytes = crypto.randomBytes(32)

// Random UUID
const id = crypto.randomUUID()
// => "550e8400-e29b-41d4-a716-446655440000"

// Encrypt/Decrypt
const encrypted = crypto.encrypt("aes-256-gcm", key, plaintext)
const decrypted = crypto.decrypt("aes-256-gcm", key, encrypted)

json

JSON utilities with type safety.

import { json } from "@metascript/core"

// Parse with type
const user = json.parse<User>(text)
// Returns Result<User, ParseError>

// Parse with validation
@derive(Serialize, Deserialize)
class User {
  name: string
  email: string
}

const result = json.parse(text, User)
if (result.ok) {
  console.log(result.value.name)
} else {
  console.error(result.error)
}

// Stringify with options
const text = json.stringify(data, {
  indent: 2,
  sortKeys: true,
})

time

Time and date utilities.

import { time } from "@metascript/core"

// Current time
const now = time.now()

// Timestamps
const unix = time.unix()      // seconds
const millis = time.millis()  // milliseconds

// Sleep
await time.sleep(1000)  // 1 second

// Measure duration
const start = time.now()
await doWork()
const elapsed = time.since(start)
console.log(`Took ${elapsed}ms`)

// Formatting
const formatted = time.format(now, "YYYY-MM-DD HH:mm:ss")

// Parsing
const date = time.parse("2024-01-15", "YYYY-MM-DD")

Result and Option

Functional error handling.

import { Result, Option, Ok, Err, Some, None } from "@metascript/core"

// Result type
function divide(a: number, b: number): Result<number, string> {
  if (b === 0) {
    return Err("Division by zero")
  }
  return Ok(a / b)
}

const result = divide(10, 2)
if (result.ok) {
  console.log(result.value)
} else {
  console.error(result.error)
}

// Chaining
const doubled = divide(10, 2)
  .map(x => x * 2)
  .mapErr(e => `Error: ${e}`)

// Option type
function find(arr: number[], pred: (n: number) => boolean): Option<number> {
  for (const item of arr) {
    if (pred(item)) return Some(item)
  }
  return None
}

const found = find([1, 2, 3], x => x > 2)
if (found.some) {
  console.log(found.value)
}

// Unwrap with default
const value = found.unwrapOr(0)

collections

Advanced data structures.

import { Vec, HashMap, HashSet, Queue, Stack } from "@metascript/core"

// Vec (resizable array)
const vec = new Vec<number>()
vec.push(1, 2, 3)
vec.pop()
console.log(vec.get(0))

// HashMap with custom hash
const map = new HashMap<User, number>()
map.set(user, 42)
console.log(map.get(user))

// HashSet
const set = new HashSet<string>()
set.add("a")
set.add("b")
console.log(set.has("a"))

// Queue (FIFO)
const queue = new Queue<string>()
queue.enqueue("first")
queue.enqueue("second")
console.log(queue.dequeue()) // "first"

// Stack (LIFO)
const stack = new Stack<string>()
stack.push("first")
stack.push("second")
console.log(stack.pop()) // "second"

testing

Test utilities.

import { test, expect, describe, beforeEach, mock } from "@metascript/core"

describe("Calculator", () => {
  let calc: Calculator

  beforeEach(() => {
    calc = new Calculator()
  })

  test("adds numbers", () => {
    expect(calc.add(1, 2)).toBe(3)
  })

  test("handles async", async () => {
    const result = await calc.fetchAndAdd(1)
    expect(result).toBeGreaterThan(0)
  })
})

// Mocking
const mockFetch = mock.fn(() => Promise.resolve({ data: [] }))
mock.module("./api", { fetch: mockFetch })

// Assertions
expect(value).toBe(expected)
expect(value).toEqual(expected)
expect(value).toBeTruthy()
expect(value).toBeFalsy()
expect(fn).toThrow(Error)
expect(array).toContain(item)
expect(object).toHaveProperty("key")

Next Steps