npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@adatechnology/product-vision-provider

v0.1.0

Published

Identifica produto a partir de uma foto: leitor de codigo de barras e embedding CLIP, ambos locais e gratuitos, encadeaveis

Readme

@adatechnology/product-vision-provider

Identifica produto a partir de uma foto. Dois engines, ambos locais e gratuitos: leitor de código de barras em WebAssembly e embedding CLIP em ONNX. Nenhum serviço a subir, nenhuma chave a pagar.

Satisfaz a ProductVisionPort do @adatechnology/catalog-module sem importá-lo — o provider não conhece quem o consome.

Instalação

bun add @adatechnology/product-vision-provider
bun add @undecaf/zbar-wasm          # só se usar o leitor de código de barras
bun add @huggingface/transformers   # só se usar o embedding

As duas são peerDependencies opcionais: a raiz do pacote não carrega engine nenhum, e quem só quer ler código de barras não baixa runtime de ONNX junto.

Uso

import { createVisionChain } from '@adatechnology/product-vision-provider'
import { createBarcodeReader } from '@adatechnology/product-vision-provider/barcode'
import { createClipEmbedder } from '@adatechnology/product-vision-provider/clip-local'

const vision = createVisionChain([createBarcodeReader(), createClipEmbedder()])

createCatalogModule({ db, config, providers: { vision } })

A cadeia funde, não escolhe

É a diferença em relação ao createTranscriberChain do audio-transcription-provider. Lá os engines são alternativas para a mesma pergunta e o primeiro que responde ganha. Aqui eles respondem perguntas diferentes — um lê o código de barras, o outro produz o vetor — e a leitura é a soma das duas.

Parar no primeiro que devolvesse barcode economizaria a inferência do CLIP e quebraria o caminho que mais importa: código lido cujo GTIN ninguém cadastrou. O consumidor cai para a busca vetorial exatamente ali, e cairia num vetor que nunca foi gerado.

Um engine vivo basta — leitura parcial é útil. Falha é quando nenhum responde; engolir isso devolveria "nada encontrado" ao cliente enquanto a causa é infraestrutura fora do ar. Passe onEngineFailure para enxergar a degradação: sem ele, o engine de vetor cair é invisível.

Decisões que não são configuráveis

QR Code fica de fora dos formatos aceitos. Gôndola tem QR de promoção colado ao lado do preço, e o cliente fotografa a prateleira inteira — decodificar esse QR viraria "código do produto" com a confiança de um GTIN.

Símbolo sem dígito não passa por código de barras. CODE-128 carrega texto livre; entregar LOTE-ABC-2026 a uma busca por chave exata gastaria a consulta e responderia "não encontrado" em vez de deixar a cascata seguir para o vetor.

Vetor de dimensão inesperada é erro, não aviso. A coluna do consumidor tem tamanho fixo: deixar passar adiaria a falha para o INSERT, no meio de uma conversa, e um vetor de outro modelo responde produto errado com toda a confiança.

O modelo carrega uma vez, não por foto. Instanciar o pipeline a cada imagem releria os pesos do disco a cada mensagem — a diferença entre dezenas de milissegundos e vários segundos por chamada.

Runtime sem decodificador de imagem

O zbar recebe pixels, não um JPEG. O engine usa createImageBitmap + OffscreenCanvas quando o runtime os tem; fora deles, injete o seu decoder:

createBarcodeReader({}, { decodeImage: async (input, maxPixels) => /* sharp, jimp… */ })

Desempate por modelo de visão

Ainda não incluído. A ProductVisionPort prevê rank, e a cascata do catalog-module funciona sem ele — sem rank, os candidatos voltam para a pessoa escolher na conversa. É o único degrau com custo real de infraestrutura (RAM e latência de CPU), e entra quando a métrica de acerto do vetorial mostrar que vale a máquina.

Licença

MIT — Ada Technology.