npm package: @ricsam/quickjs-core
Description: Core utilities and class builder for QuickJS runtime bindings
Author: Richard Samuelsson
Latest version: 0.2.17

# @ricsam/quickjs-core

Core utilities and Web Streams API for QuickJS runtime bindings.

> **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-core
```

## Setup

```typescript
import { setupCore } from "@ricsam/quickjs-core";

const handle = setupCore(context);
```

## Injected Globals

- `ReadableStream`, `WritableStream`, `TransformStream`
- `ReadableStreamDefaultReader`, `WritableStreamDefaultWriter`
- `Blob`, `File`

## Usage in QuickJS

```javascript
// Streams
const stream = new ReadableStream({
  start(controller) {
    controller.enqueue("chunk1");
    controller.enqueue("chunk2");
    controller.close();
  }
});

const reader = stream.getReader();
const { value, done } = await reader.read();

// Blob
const blob = new Blob(["hello", " ", "world"], { type: "text/plain" });
const text = await blob.text(); // "hello world"

// File
const file = new File(["content"], "file.txt", { type: "text/plain" });
console.log(file.name); // "file.txt"
```

## Core Utilities

```typescript
import {
  // Marshalling
  marshal,       // JS value -> QuickJS handle
  unmarshal,     // QuickJS handle -> JS value

  // Handle utilities
  isHandle,      // Check if value is a QuickJS handle
  getHandleType, // Get handle type as string

  // Scope management
  withScope,      // Automatic handle cleanup
  withScopeAsync, // Async version

  // Class/function builders
  defineClass,
  defineFunction,
  defineAsyncFunction,
  defineAsyncIteratorFunction, // For async generators
  cleanupAsyncIterators,       // Cleanup on context disposal

  // State management
  createStateMap,
  getState,
  setState,
} from "@ricsam/quickjs-core";
```

### Marshalling Example

```typescript
// Marshal JS values to QuickJS
const handle = marshal(context, {
  name: "test",
  values: [1, 2, 3],
  callback: (x) => x * 2,
});

// Unmarshal QuickJS values to JS
const value = unmarshal(context, handle);
```

### Custom Class Definition

```typescript
const PointClass = defineClass(context, stateMap, {
  name: "Point",
  construct: ([x, y]) => ({ x: Number(x), y: Number(y) }),
  properties: {
    x: {
      get() { return this.x; },
      set(v) { this.x = Number(v); },
    },
    y: {
      get() { return this.y; },
      set(v) { this.y = Number(v); },
    },
  },
  methods: {
    distance() {
      return Math.sqrt(this.x ** 2 + this.y ** 2);
    },
  },
});

context.setProp(context.global, "Point", PointClass);
```

### Async Iterator Function

Define functions that return async iterables (for streaming data):

```typescript
import { defineAsyncIteratorFunction, cleanupAsyncIterators } from "@ricsam/quickjs-core";

const streamFn = defineAsyncIteratorFunction(context, "streamNumbers", async function* (count) {
  for (let i = 0; i < Number(count); i++) {
    await new Promise(r => setTimeout(r, 100));
    yield i;
  }
});

context.setProp(context.global, "streamNumbers", streamFn);
streamFn.dispose();

// In QuickJS:
// for await (const n of streamNumbers(5)) {
//   console.log(n); // 0, 1, 2, 3, 4
// }

// Clean up before context disposal
cleanupAsyncIterators(context);
```