open-index/open-npm huggingface dataset:
npm package: @ricsam/quickjs-crypto
Description: Web Crypto API implementation for QuickJS runtime
Author: Richard Samuelsson
Latest version: 0.2.17

# @ricsam/quickjs-crypto

Web Crypto API implementation for QuickJS runtime.

> **Note**: This is a low-level package. For most use cases, use [`@ricsam/quickjs-runtime`](../runtime) with `createRuntime()` instead.

## Installation

```bash
bun add @ricsam/quickjs-crypto
```

## Setup

```typescript
import { setupCrypto } from "@ricsam/quickjs-crypto";

const handle = setupCrypto(context);
```

## Injected Globals

- `crypto.getRandomValues(array)` - Fill a TypedArray with random bytes
- `crypto.randomUUID()` - Generate a random UUID v4
- `crypto.subtle` - SubtleCrypto interface for cryptographic operations

## Usage in QuickJS

```javascript
// Generate random bytes
const bytes = new Uint8Array(16);
crypto.getRandomValues(bytes);

// Generate UUID
const uuid = crypto.randomUUID();
console.log(uuid); // "550e8400-e29b-41d4-a716-446655440000"

// Hash data with SHA-256
const data = new TextEncoder().encode("Hello, World!");
const hash = await crypto.subtle.digest("SHA-256", data);

// Generate encryption key
const key = await crypto.subtle.generateKey(
  { name: "AES-GCM", length: 256 },
  true,
  ["encrypt", "decrypt"]
);

// Encrypt data
const iv = crypto.getRandomValues(new Uint8Array(12));
const encrypted = await crypto.subtle.encrypt(
  { name: "AES-GCM", iv },
  key,
  data
);

// Decrypt data
const decrypted = await crypto.subtle.decrypt(
  { name: "AES-GCM", iv },
  key,
  encrypted
);
```

## SubtleCrypto Methods

| Method | Description |
|--------|-------------|
| `digest` | Generate hash (SHA-256, SHA-384, SHA-512) |
| `generateKey` | Generate symmetric or asymmetric keys |
| `sign` / `verify` | Sign and verify data (HMAC, ECDSA) |
| `encrypt` / `decrypt` | Encrypt and decrypt data (AES-GCM, AES-CBC) |
| `importKey` / `exportKey` | Import/export keys (raw, jwk, pkcs8, spki) |
| `deriveBits` / `deriveKey` | Derive keys (PBKDF2, ECDH) |
| `wrapKey` / `unwrapKey` | Wrap/unwrap keys for secure transport |

## Supported Algorithms

- **Encryption**: AES-GCM, AES-CBC
- **Signing**: HMAC, ECDSA
- **Hashing**: SHA-256, SHA-384, SHA-512
- **Key Derivation**: PBKDF2, ECDH
- **Asymmetric**: ECDSA (P-256, P-384, P-521), RSA-OAEP

> **Note**: Cryptographic operations are delegated to the host's native `crypto.subtle` implementation, ensuring secure and performant cryptography.

**See also:** [MDN Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API)
npm package: @ricsam/quickjs-encoding
Description: Base64 encoding APIs (atob, btoa) for QuickJS runtime
Author: Richard Samuelsson
Latest version: 0.2.17

# @ricsam/quickjs-encoding

Base64 encoding APIs (atob, btoa) for QuickJS runtime.

> **Note**: This is a low-level package. For most use cases, use [`@ricsam/quickjs-runtime`](../runtime) with `createRuntime()` instead.

## Installation

```bash
bun add @ricsam/quickjs-encoding
```

## Setup

```typescript
import { setupEncoding } from "@ricsam/quickjs-encoding";

const handle = setupEncoding(context);
```

## Injected Globals

- `atob(encodedData)` - Decode a Base64-encoded string
- `btoa(stringToEncode)` - Encode a string to Base64

## Usage in QuickJS

```javascript
// Encode string to Base64
const encoded = btoa("Hello, World!");
console.log(encoded); // "SGVsbG8sIFdvcmxkIQ=="

// Decode Base64 to string
const decoded = atob("SGVsbG8sIFdvcmxkIQ==");
console.log(decoded); // "Hello, World!"

// Common use case: encoding JSON for transport
const data = { user: "john", token: "abc123" };
const base64Data = btoa(JSON.stringify(data));

// Decode it back
const originalData = JSON.parse(atob(base64Data));
```

## Error Handling

```javascript
// btoa throws for characters outside Latin1 range (0-255)
try {
  btoa("Hello 世界"); // Throws DOMException
} catch (e) {
  console.error("Cannot encode non-Latin1 characters");
}

// atob throws for invalid Base64
try {
  atob("not valid base64!!!");
} catch (e) {
  console.error("Invalid Base64 string");
}
```
npm package: @ricsam/quickjs-fetch
Description: Fetch API implementation for QuickJS runtime
Author: Richard Samuelsson
Latest version: 0.2.20

# @ricsam/quickjs-fetch

Fetch API and HTTP server handler for QuickJS runtime.

> **Note**: This is a low-level package. For most use cases, use [`@ricsam/quickjs-runtime`](../runtime) with `createRuntime()` instead.

## Installation

```bash
bun add @ricsam/quickjs-fetch
```

## Setup

```typescript
import { setupFetch } from "@ricsam/quickjs-fetch";

const handle = setupFetch(context, {
  onFetch: async (request) => {
    // Handle outbound fetch() calls from QuickJS
    console.log(`Fetching: ${request.url}`);
    return fetch(request);
  },
});
```

## Injected Globals

- `fetch`, `Request`, `Response`, `Headers`
- `FormData`, `AbortController`, `AbortSignal`
- `serve` (HTTP server handler)

## Usage in QuickJS

```javascript
// Outbound fetch
const response = await fetch("https://api.example.com/data");
const data = await response.json();

// Request/Response
const request = new Request("https://example.com", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "test" }),
});

const response = new Response(JSON.stringify({ ok: true }), {
  status: 200,
  headers: { "Content-Type": "application/json" },
});

// Static methods
Response.json({ message: "hello" });
Response.redirect("https://example.com", 302);

// AbortController
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);
await fetch(url, { signal: controller.signal });

// FormData
const formData = new FormData();
formData.append("name", "John");
formData.append("file", new File(["content"], "file.txt"));
```

## HTTP Server

Register a server handler in QuickJS and dispatch requests from the host:

```typescript
// In QuickJS
context.evalCode(`
  serve({
    fetch(request, server) {
      const url = new URL(request.url);

      if (url.pathname === "/ws") {
        if (server.upgrade(request, { data: { userId: "123" } })) {
          return new Response(null, { status: 101 });
        }
      }

      return Response.json({ path: url.pathname });
    },
    websocket: {
      open(ws) {
        console.log("Connected:", ws.data.userId);
      },
      message(ws, message) {
        ws.send("Echo: " + message);
      },
      close(ws, code, reason) {
        console.log("Closed:", code, reason);
      }
    }
  });
`);

// From host - dispatch HTTP request
const response = await handle.dispatchRequest(
  new Request("http://localhost/api/users")
);

// Check for WebSocket upgrade
const upgrade = handle.getUpgradeRequest();
if (upgrade?.requested) {
  // connectionId is generated by QuickJS in server.upgrade()
  // User data stays within QuickJS (no marshalling of complex objects)
  const { connectionId } = upgrade;
  handle.dispatchWebSocketOpen(connectionId);

  // Listen for outgoing messages
  handle.onWebSocketCommand((command) => {
    if (command.type === "message") {
      // Send to actual WebSocket client
    }
  });

  // Forward incoming messages
  handle.dispatchWebSocketMessage(connectionId, "Hello from client");
}
```
npm package: @ricsam/quickjs-fs
Description: File system API implementation for QuickJS runtime
Author: Richard Samuelsson
Latest version: 0.2.19

# @ricsam/quickjs-fs

File System Access API (OPFS-compatible) for QuickJS runtime.

> **Note**: This is a low-level package. For most use cases, use [`@ricsam/quickjs-runtime`](../runtime) with `createRuntime()` instead.

## Installation

```bash
bun add @ricsam/quickjs-fs
```

## Setup

```typescript
import { setupFs, createNodeDirectoryHandle } from "@ricsam/quickjs-fs";

const handle = setupFs(context, {
  getDirectory: async (path) => {
    // Validate path access
    if (!path.startsWith("/allowed")) {
      throw new Error("Access denied");
    }
    return createNodeDirectoryHandle(`./sandbox${path}`);
  },
});
```

## Injected Globals

- `getDirectory(path)` - Entry point for file system access
- `FileSystemDirectoryHandle`, `FileSystemFileHandle`
- `FileSystemWritableFileStream`

## Usage in QuickJS

```javascript
// Get directory handle
const root = await getDirectory("/data");

// Read a file
const fileHandle = await root.getFileHandle("config.json");
const file = await fileHandle.getFile();
const text = await file.text();
const config = JSON.parse(text);

// Write a file
const outputHandle = await root.getFileHandle("output.txt", { create: true });
const writable = await outputHandle.createWritable();
await writable.write("Hello, World!");
await writable.close();

// Directory operations
const subDir = await root.getDirectoryHandle("subdir", { create: true });
await root.removeEntry("old-file.txt");
await root.removeEntry("old-dir", { recursive: true });

// Iterate directory
for await (const [name, handle] of root.entries()) {
  console.log(name, handle.kind); // "file" or "directory"
}
```

## Host Adapters

### Node.js/Bun adapter

```typescript
import { createNodeDirectoryHandle } from "@ricsam/quickjs-fs";

const dirHandle = createNodeDirectoryHandle("/path/to/directory");
```

### In-memory adapter (for testing)

```typescript
import { createMemoryDirectoryHandle } from "@ricsam/quickjs-fs";

const memFs = createMemoryDirectoryHandle({
  "config.json": JSON.stringify({ debug: true }),
  "data/users.json": JSON.stringify([]),
});
```
npm package: @ricsam/quickjs-path
Description: POSIX path utilities (join, resolve, dirname, basename, etc.) for QuickJS runtime
Author: Richard Samuelsson
Latest version: 0.2.17

# @ricsam/quickjs-path

POSIX path utilities (join, resolve, dirname, basename, etc.) for QuickJS runtime.

> **Note**: This is a low-level package. For most use cases, use [`@ricsam/quickjs-runtime`](../runtime) with `createRuntime()` instead.

## Installation

```bash
bun add @ricsam/quickjs-path
```

## Setup

```typescript
import { setupPath } from "@ricsam/quickjs-path";

const handle = setupPath(context, {
  cwd: "/home/user/project", // Current working directory for resolve()
});
```

## Injected Globals

- `path.join(...paths)` - Join path segments
- `path.resolve(...paths)` - Resolve to absolute path
- `path.dirname(path)` - Get directory name
- `path.basename(path, ext?)` - Get base name
- `path.extname(path)` - Get extension
- `path.normalize(path)` - Normalize path
- `path.isAbsolute(path)` - Check if absolute
- `path.relative(from, to)` - Get relative path
- `path.parse(path)` - Parse into components
- `path.format(pathObject)` - Format from components
- `path.sep` - Path separator (`/`)
- `path.delimiter` - Path delimiter (`:`)

## Usage in QuickJS

```javascript
// Join paths
path.join("/foo", "bar", "baz"); // "/foo/bar/baz"
path.join("/foo", "../bar");     // "/bar"

// Resolve to absolute path
path.resolve("foo", "bar");       // "/home/user/project/foo/bar"
path.resolve("/foo", "bar");      // "/foo/bar"

// Directory and base names
path.dirname("/foo/bar/baz.txt"); // "/foo/bar"
path.basename("/foo/bar/baz.txt"); // "baz.txt"
path.basename("/foo/bar/baz.txt", ".txt"); // "baz"

// Extension
path.extname("index.html"); // ".html"
path.extname("index.");     // "."
path.extname("index");      // ""

// Normalize
path.normalize("/foo/bar//baz/./qux/../"); // "/foo/bar/baz"

// Check absolute
path.isAbsolute("/foo");  // true
path.isAbsolute("foo");   // false

// Relative path
path.relative("/foo/bar", "/foo/baz"); // "../baz"

// Parse and format
const parsed = path.parse("/foo/bar/baz.txt");
// { root: "/", dir: "/foo/bar", base: "baz.txt", ext: ".txt", name: "baz" }

path.format({ dir: "/foo/bar", base: "baz.txt" }); // "/foo/bar/baz.txt"
```
npm package: @ricsam/quickjs-test-environment
Description: Test environment for QuickJS with Bun/Jest/Vitest-compatible primitives
Author: Richard Samuelsson
Latest version: 0.2.18

# @ricsam/quickjs-test-environment

Test primitives for running tests in sandboxed QuickJS. Provides a Bun/Jest/Vitest-compatible API with event-based result streaming.

> **Note**: This is a low-level package. For most use cases, use [`@ricsam/quickjs-runtime`](../runtime) with `createRuntime({ testEnvironment: true })` instead.

## Installation

```bash
bun add @ricsam/quickjs-test-environment
```

## Setup

```typescript
import { setupTestEnvironment } from "@ricsam/quickjs-test-environment";

const handle = setupTestEnvironment(context, {
  onEvent: (event) => {
    if (event.type === "testEnd") {
      const icon = event.test.status === "pass" ? "✓" : "✗";
      console.log(`${icon} ${event.test.fullName}`);
      if (event.test.error) {
        console.log(`  Error: ${event.test.error.message}`);
      }
    } else if (event.type === "runEnd") {
      console.log(`\n${event.results.passed}/${event.results.total} tests passed`);
    }
  },
});
```

## Injected Globals

- `describe`, `it`, `test` (with `.skip`, `.only`, `.todo` modifiers)
- `beforeAll`, `afterAll`, `beforeEach`, `afterEach`
- `expect` with matchers (`toBe`, `toEqual`, `toThrow`, etc.) and modifiers (`.not`, `.resolves`, `.rejects`)

## Usage in QuickJS

```javascript
describe("Math operations", () => {
  beforeEach(() => {
    // setup before each test
  });

  it("should add numbers", () => {
    expect(1 + 1).toBe(2);
  });

  it("should multiply numbers", async () => {
    await Promise.resolve();
    expect(2 * 3).toEqual(6);
  });

  describe("edge cases", () => {
    it.skip("should handle infinity", () => {
      expect(1 / 0).toBe(Infinity);
    });
  });
});
```

## Running Tests from Host

```typescript
// Load untrusted test code
context.evalCode(userProvidedTestCode);

// Check test count
console.log(`Found ${handle.getTestCount()} tests`);

// Run all registered tests
const results = await handle.run();
console.log(`${results.passed}/${results.total} passed`);

// Reset for re-running (optional)
handle.reset();

handle.dispose();
```

## TestEvent Types

| Event Type | Description |
|------------|-------------|
| `runStart` | Emitted when test run begins (includes `testCount`, `suiteCount`) |
| `suiteStart` | Emitted when a describe block begins |
| `suiteEnd` | Emitted when a describe block completes |
| `testStart` | Emitted before each test runs |
| `testEnd` | Emitted when a test completes (includes `status`: pass/fail/skip/todo) |
| `runEnd` | Emitted after all tests complete (includes full `results`) |
npm package: @ricsam/quickjs-test-utils
Description: Testing utilities for QuickJS runtime
Author: Richard Samuelsson
Latest version: 1.0.26

# @ricsam/quickjs-test-utils

Testing utilities including type checking for QuickJS user code.

## Installation

```bash
bun add @ricsam/quickjs-test-utils
```

## Type Checking QuickJS Code

Validate TypeScript/JavaScript code that will run inside QuickJS before execution using `ts-morph`:

```typescript
import { typecheckQuickJSCode } from "@ricsam/quickjs-test-utils";

const result = typecheckQuickJSCode(`
  serve({
    fetch(request, server) {
      const url = new URL(request.url);

      if (url.pathname === "/ws") {
        server.upgrade(request, { data: { userId: 123 } });
        return new Response(null, { status: 101 });
      }

      return Response.json({ message: "Hello!" });
    },
    websocket: {
      message(ws, message) {
        ws.send("Echo: " + message);
      }
    }
  });
`, { include: ["core", "fetch"] });

if (!result.success) {
  console.error("Type errors found:");
  for (const error of result.errors) {
    console.error(`  Line ${error.line}: ${error.message}`);
  }
}
```

## Options

| Option | Description |
|--------|-------------|
| `include` | Which package types to include: `"core"`, `"fetch"`, `"fs"` (default: all) |
| `compilerOptions` | Additional TypeScript compiler options |

## Using with Tests

```typescript
import { describe, expect, test } from "bun:test";
import { typecheckQuickJSCode } from "@ricsam/quickjs-test-utils";

describe("QuickJS code validation", () => {
  test("server code is type-safe", () => {
    const result = typecheckQuickJSCode(userProvidedCode, {
      include: ["fetch"]
    });
    expect(result.success).toBe(true);
  });
});
```

## Type Definition Strings

The type definitions are also exported as strings for custom use cases:

```typescript
import {
  CORE_TYPES,   // ReadableStream, Blob, File, URL, etc.
  FETCH_TYPES,  // fetch, Request, Response, serve, etc.
  FS_TYPES,     // getDirectory, FileSystemHandle, etc.
  CRYPTO_TYPES, // crypto.subtle, CryptoKey, etc.
  TYPE_DEFINITIONS  // All types as { core, fetch, fs, crypto, ... }
} from "@ricsam/quickjs-test-utils";

// Use with your own ts-morph project
project.createSourceFile("quickjs-globals.d.ts", FETCH_TYPES);
```

## Type Definition Files

Each package also exports `.d.ts` files for use with `tsconfig.json`:

```json
{
  "compilerOptions": {
    "lib": ["ESNext", "DOM"]
  },
  "include": ["quickjs-code/**/*.ts"],
  "references": [
    { "path": "./node_modules/@ricsam/quickjs-core/src/quickjs.d.ts" },
    { "path": "./node_modules/@ricsam/quickjs-fetch/src/quickjs.d.ts" },
    { "path": "./node_modules/@ricsam/quickjs-fs/src/quickjs.d.ts" },
    { "path": "./node_modules/@ricsam/quickjs-crypto/src/quickjs.d.ts" }
  ]
}
```
npm package: @ricsam/quickjs-timers
Description: Timer APIs (setTimeout, setInterval, clearTimeout, clearInterval) for QuickJS runtime
Author: Richard Samuelsson
Latest version: 0.2.17

# @ricsam/quickjs-timers

Timer APIs (setTimeout, setInterval, clearTimeout, clearInterval) for QuickJS runtime.

> **Note**: This is a low-level package. For most use cases, use [`@ricsam/quickjs-runtime`](../runtime) with `createRuntime()` instead.

## Installation

```bash
bun add @ricsam/quickjs-timers
```

## Setup

```typescript
import { setupTimers } from "@ricsam/quickjs-timers";

const handle = setupTimers(context);

// Clear all pending timers
handle.clearAll();

// Cleanup
handle.dispose();
```

## Injected Globals

- `setTimeout(callback, delay, ...args)` - Execute callback after delay
- `clearTimeout(id)` - Cancel a timeout
- `setInterval(callback, delay, ...args)` - Execute callback repeatedly
- `clearInterval(id)` - Cancel an interval

## Usage in QuickJS

```javascript
// setTimeout
const timeoutId = setTimeout(() => {
  console.log("Executed after 1 second");
}, 1000);

// clearTimeout
clearTimeout(timeoutId);

// setInterval
let count = 0;
const intervalId = setInterval(() => {
  count++;
  console.log(`Tick ${count}`);
  if (count >= 5) {
    clearInterval(intervalId);
  }
}, 100);

// With arguments
setTimeout((a, b) => {
  console.log(a + b); // 3
}, 100, 1, 2);
```

## Host Integration

Timers integrate with QuickJS's job queue. The host must call `runtime.executePendingJobs()` to process timer callbacks:

```typescript
// After setting up timers and evaluating code
while (runtime.hasPendingJob()) {
  const result = runtime.executePendingJobs();
  if (result.error) {
    console.error("Timer error:", context.dump(result.error));
    result.error.dispose();
  }
}
```