Skip to content

Add an async iterator API for progressive barcode detection #111

Description

@jimmywarting

Problem

BarcodeDetector.detect() returns a Promise<DetectedBarcode[]> that resolves only after the entire image has been analyzed.

For large images (for example, scanned A4 documents containing dozens of QR codes), this means applications cannot process any detected barcodes until detection has completely finished.

This introduces unnecessary latency for use cases where consumers could start processing results immediately as they are found.

Proposal

Introduce an asynchronous iterator-based API that yields detected barcodes progressively.

For example:

for await (const barcode of barcodeDetector.detec(image)) {
  console.log(barcode.rawValue);
}

or

const stream = barcodeDetector.detectStream(image);

for await (const barcode of stream) {
  // Process each barcode immediately
}

Benefits

  • Lower perceived latency.
  • Applications can start processing or displaying results immediately.
  • Better support for large images containing many barcodes.
  • Makes cancellation more practical by allowing consumers to stop iteration once sufficient results have been found.
  • Fits naturally with modern JavaScript async iteration patterns.

Use case

Consider an A4 document containing 100 QR codes.

With the current API:

  1. Analyze the entire image.
  2. Detect all 100 codes.
  3. Resolve the promise.
  4. Begin processing.

With an async iterator:

  1. Begin analyzing the image.
  2. Yield the first detected QR code.
  3. Continue scanning while the application processes earlier results.
  4. Continue until scanning completes or the consumer cancels iteration.

Notes

This proposal would be an addition rather than a replacement for detect(). The existing API would remain appropriate for cases where all results are needed at once, while an async iterator would better support streaming and low-latency workflows.

One possible API shape could be:

interface BarcodeDetector {
  detect(source: ImageBitmapSource): Promise<DetectedBarcode[]>;

  detectStream(
    source: ImageBitmapSource,
    options?: DetectOptions
  ): AsyncIterable<DetectedBarcode>;
}

This would align with the growing use of AsyncIterable in the web platform for APIs capable of producing results incrementally.

A AbortSignal would be benefitial here as well... barcodeDetector.detectStream(image, { signal: AbortSignal.timeout(1000) })

Also many usecases involve scanning a live video feed continuously (#99, #108) until we say that we are done.
It would be helpful if this also connected well together with the async-iterator-helpers

So it would be sweet if detectStream could continuously parse a hole video instead of a single video frame.
(some form of memory cache would be needed so that same barcode isn't yield:ed multiple times)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions