# Annotation.js

To run tests, in the tests folder run, for example, `npm run test labelmap.test.js`

## Keeping the event loop responsive

`Annotation.combine` and `Annotation.combineStream` are synchronous: converting
dense RLE masks to polygons blocks the event loop for as long as it runs, which
can starve timers and in-flight I/O.

`Annotation.combineStreamAsync` is an opt-in async iterable producing the same
files, in the same order, with the same bytes. For YOLO-family formats the mask
decode, contour scan/trace, and polygon simplification hand control back to the
event loop on an elapsed-time budget (10ms by default); other formats are
adapted from their synchronous generators unchanged.

```js
const stream = Annotation.combineStreamAsync(
    annotations, "yolov8", labelmap, dataset, version, workspaceUrl,
    { sliceMs: 10 } // optional scheduler options
);

for await (const file of stream) {
    for await (const chunk of file.contents) {
        // chunk is a Buffer
    }
}
```

## To publish/upload package on npm:

The publish process is automated with a GitHub action:

1. Update version in package.json
1. Create a GitHub release: a GitHub action will publish the package

## To publish a prerelease (for testing before a real release):

Prereleases are published under the `next` dist-tag so they don't affect `npm install @roboflow/annotation` (which keeps resolving to `latest`).

1. Bump version with a prerelease suffix, e.g. `1.0.233-rc.0`.

```bash
npm version prerelease --preid=rc
```

1. Create a GitHub release and check **"Set as a pre-release"**. The GitHub action publishes it with `--tag next`.

Install the prerelease with:

```bash
npm install @roboflow/annotation@next            # latest prerelease
npm install @roboflow/annotation@1.0.233-beta.0  # pinned
```

When the real release goes out (version without suffix, release not marked as pre-release), it publishes to `latest` as usual.

The publish workflow will fail if the version in `package.json` has a prerelease suffix but the GitHub release is not marked as pre-release, to prevent accidentally pushing a draft to `latest`.
