
# Pacotes populares

A conformidade com a especificação não garante que bibliotecas reais funcionem. Mecanismos JS que passam em 99 % do test262 ainda falham com frequência em código de produção porque as bibliotecas dependem de uma longa lista de "casos extremos da especificação" — traps de Proxy em ordens específicas, formato de `Function.prototype.toString`, comportamento de regex com entradas difíceis e a interação exata entre a ordenação de `Object.keys` e nomes de propriedades computados.

O Phasis verifica **204 bibliotecas amplamente utilizadas**, comparando-as byte a byte com Node.js (V8). Elas ficam em `tests/Popular/` no repositório, e o CI as executa sempre que o código-fonte do mecanismo ou o conjunto de testes muda.

## Cobertura por categoria

| Categoria | Bibliotecas |
|---|---|
| **Analisadores / AST** | acorn 8.16.0, chevrotain 11.0.3, parse5 7.2.1, parsimmon 1.18.1, jsep 1.4.0, postcss-value-parser 4.2.0, acorn-walk 8.3.4, estraverse 5.3.0, escodegen 2.1.0, css-tree 3.0.4, sax 1.4.1, nearley 2.20.1 |
| **Templates / Markdown / HTML** | mustache 4.2.0, handlebars 4.7.9, marked 18.0.3, markdown-it 14.1.0 (+ markdown-it-emoji), markdown-table 3.0.4, showdown 2.1.0, cheerio 1.1.2, htmlparser2 11.0.0 |
| **Utilitários / Funcional** | lodash 4.18.1, ramda 0.31.3, remeda 2.17.4, es-toolkit 1.27.0, immutable 5.1.3, immer 10.1.1, redux 5.0.1, deepmerge 4.3.1, dot-object 2.1.5, lodash.merge 4.6.2, lodash.clonedeep 4.5.0, extend 3.0.2, extend-shallow 3.0.2, mixin-deep 2.0.1, merge-options 3.0.4 |
| **Acesso a objetos** | dequal 2.0.3, clsx 2.1.1, classnames 2.5.1, get-value 4.0.1, set-value 4.1.0, object.omit 3.0.0, object.pick 1.3.0, is-plain-obj 4.1.0, kind-of 6.0.3 |
| **Validação / Esquema** | zod 4.4.3, yup 1.4.0, valibot 1.1.0, superstruct 2.0.2, validator 13.12.0, email-validator 2.0.4, ajv 8.17.1, @sinclair/typebox 0.34.42, runtypes 6.7.0, typanion 3.14.0, ow 2.0.0 |
| **Data / hora** | dayjs 1.11.20, date-fns 4.1.0, timeago.js 4.0.2, luxon 3.7.3, moment 2.30.2 |
| **Matemática / números** | bignumber.js 11.1.1, decimal.js 10.6.0, numeral 2.0.6, jsbi 4.3.0, big.js 6.2.2, fraction.js 4.3.7, complex.js 2.4.2, simple-statistics 7.8.8 |
| **Hash / criptografia** | blueimp-md5 2.19.0, crypto-js 4.2.0, fnv-plus 1.3.1, murmurhash3js 3.0.1, hash-sum 2.0.0, jwt-decode 4.0.0, @noble/hashes 2.2.0, tweetnacl 1.0.3, aes-js 3.1.2, bcryptjs 3.0.2, xxhashjs 0.2.2, object-hash 3.0.0 |
| **Pesquisa / diff** | fuse.js 7.3.0, minisearch 7.1.1, diff 8.0.2, diff-match-patch 1.0.5, fast-deep-equal 3.1.3, fast-equals 5.2.2, fastest-levenshtein 1.0.16, lunr 2.3.9 |
| **JSON / formatos de dados** | json5 2.2.3, js-yaml 4.1.0, yaml 2.6.1, toml 3.0.0, smol-toml 1.3.1, fast-json-patch 3.1.1, jmespath 0.16.0, jsonata 2.0.6, jsonpath-plus 10.3.0, mingo 6.7.0, sift 17.1.3, fast-json-stable-stringify 2.1.0, safe-stable-stringify 2.5.0, json-stringify-safe 5.0.1, canonicalize 2.1.0, papaparse 5.5.4 |
| **Strings / linguística** | he 1.2.0, slugify 1.6.9, camelcase 8.0.0, entities 6.0.1, pluralize 8.0.0, inflection 3.0.2, wcwidth 1.0.1, emoji-regex 10.4.0, unraw 3.0.0, jsesc 3.1.0, lower-case 2.0.2, upper-case 2.0.2, dot-case 3.0.4, pascal-case 3.1.2, snake-case 3.0.4, title-case 3.0.3, xregexp 5.1.1, escape-string-regexp 5.0.0, ansi-regex 6.1.0, strip-ansi 7.1.2, string-width 8.1.0 |
| **URL / web** | url-parse 1.5.10, qs 6.13.1, query-string 9.1.1, tldts 6.1.69, punycode 2.3.1, linkifyjs 4.3.1, ipaddr.js 2.2.0, uri-js 4.4.1, url-template 3.1.1, bowser 2.11.0 |
| **Compactação / codificação / arquivos** | pako 2.1.0, lz-string 1.5.0, base64-js 1.5.1, JSZip 3.10.1 |
| **Cor** | color-string 2.1.1, d3-color 3.1.0, chroma-js 3.1.2, color-name 2.0.0, tinycolor2 1.6.0, color 5.0.3 |
| **Cópia / igualdade** | rfdc 1.4.1, klona 2.0.6, fast-copy 3.0.2 |
| **Formato / exibição** | ms 2.1.3, bytes 3.1.2 |
| **IDs / UUIDs** | uuid 10.0.0, hexoid 2.0.0, ulid 3.0.1, cuid2 2.2.2, short-unique-id 5.4.3 |
| **Detecção de tipos / glob** | type-detect 4.1.0, picomatch 4.0.2, minimatch 10.1.1, wildcard-match 5.1.4, glob-to-regexp 0.4.1, to-regex 4.0.4, array-uniq 3.0.0, array-unique 0.3.2 |
| **Semver / configuração** | semver 7.6.3, compare-versions 6.1.1, semver-compare 1.0.0 |
| **Caches / desempenho** | lru-cache 11.0.2, marky 1.3.0, array-flatten 3.0.0, arr-diff 4.0.0 |
| **Assíncrono / eventos** | eventemitter3 5.0.1, eventemitter2 6.4.10, mitt 3.0.1, p-limit 7.1.1, p-queue 9.0.2, p-defer 5.0.0, p-retry 7.1.0, throttle-debounce 5.0.2, async 3.2.6 |
| **Estado reativo** | mobx 6.13.7, xstate 5.23.0, valtio 2.1.5, nanostores 1.0.1, jotai 2.16.1, redux-saga 1.3.0, redux 5.0.1 |
| **CSS / estilos** | postcss 8.5.7, stylis 4.3.6, css-tree 3.0.4 |
| **Build / AST / compiladores** | magic-string 0.30.20, escodegen 2.1.0, acorn-walk 8.3.4, estraverse 5.3.0, @babel/parser 7.28.5, terser 5.46.0, prettier 3.3.3, svelte 5.55.7 (compiler), typescript 6.0.3 |
| **MQTT / protocolo** | mqtt-packet 9.0.4 |
| **GraphQL** | graphql-js 16.11.0 |
| **Realce de sintaxe** | highlight.js 11.11.1 |
| **Testes / asserções** | chai 6.2.1 |

Total: **204 bibliotecas** reproduzem exatamente a saída do Node. Todas estão fixadas na versão upstream mais recente disponível na última atualização.

## Como funciona

Cada cenário é um diretório `tests/Popular/<lib>/` com três arquivos:

```text
tests/Popular/lodash/
├── lodash.js     ← vendored upstream library (untouched, UMD bundle)
├── runner.js     ← Phasis-side script that exercises the library
└── oracle.txt    ← Node.js output of running runner.js (committed)
```

`tests/Popular/PopularPackagesTest.php` é um teste PHPUnit com provedor de dados que:

1. Carrega `lodash.js` + `runner.js` em um `new Phasis\Engine()` novo.
2. Captura a saída de `console.log` em um buffer.
3. Verifica se o buffer capturado é idêntico byte a byte ao `oracle.txt`.

Gere novamente um oráculo com:

```bash
node tests/Popular/gen-oracle.js tests/Popular/<lib>
```

(Usado ao atualizar a biblioteca incorporada — executa novamente o runner no Node real e substitui `oracle.txt`.)

## Controle do CI

Workflow: [`.github/workflows/popular.yml`](https://github.com/inline0/phasis/blob/main/.github/workflows/popular.yml).

Executa em pushes e pull requests para `main` que alterem `src/`, `tests/Popular/`, `phpunit.xml.dist`, os arquivos Composer ou o próprio workflow, além de execuções manuais. Duas etapas:

1. **Lado Phasis** — executa a suíte de testes PHPUnit `popular`, que executa cada biblioteca por meio de Phasis e compara os resultados com o oráculo versionado. Falha se um único byte for diferente.
2. **Nova verificação no Node** — executa `node tests/Popular/gen-oracle.js …` com cada biblioteca e confirma que o oráculo recém-gerado corresponde ao que está no repositório. Detecta alterações causadas por "atualização da biblioteca incorporada sem atualizar o oráculo".

Ambas precisam passar antes da integração do PR. Uma melhoria em test262 que prejudique o lodash não é aceitável; uma melhoria no lodash que prejudique test262 também não.

## Por que estas bibliotecas

- **acorn** — a análise sintática é a parte mais frágil de qualquer mecanismo JS. Ela exercita todos os casos extremos de sintaxe que o JS moderno acrescenta. Se Phasis consegue analisar código moderno arbitrário com acorn, o runtime é sólido.
- **mustache.js** — a criação de templates é um dos casos de uso de incorporação que o Phasis visa explicitamente (o primeiro exemplo concreto do README são "mecanismos de templates"). Mustache exercita iteração, resolução de escopo e transformações de strings na ordem usada por templates reais.
- **lodash** — a biblioteca utilitária JS mais usada no mundo. Suas mais de 300 funções acessam indiretamente todos os métodos da biblioteca padrão. Se o lodash funciona, a transformação genérica de dados JS funciona.
- **marked** — renderização de Markdown. É prático e exercita regex (muito) e manipulação de strings com estado entre linhas. Revela diferenças entre o mecanismo de regex do PCRE2 (fallback do Phasis) e o Irregexp do V8.
- **dayjs** — a aritmética de datas e horários é uma fonte clássica de erros de um dia que nenhum caso de test262 detecta. dayjs cobre variantes de construtores, operações aritméticas que atravessam limites de meses equivalentes ao horário de verão e expansão de tokens de formatação nos mesmos caminhos de código usados por praticamente todas as bibliotecas de Date do JS.
- **bignumber.js** — a aritmética de precisão arbitrária sem TypedArrays exercita a análise de números baseada em strings, laços de multiplicação e divisão de inteiros grandes e seleção do modo de arredondamento — tudo em JS puro, portanto o mecanismo arca com todo o custo. Revela qualquer falha sutil na conversão entre Number e String.
- **json5** — a análise sintática de JSON flexível depende bastante de regexes de classes de caracteres e tokenização com estado. É um bom teste de alerta para a correção de regexes e os limites da iteração por strings.
- **fuse.js** — um UMD transpilado pelo Babel que exercita `_classCallCheck` (o padrão `this instanceof Ctor` usado por todas as classes transpiladas antes do ES6), além do algoritmo bitap completo de busca aproximada. Tem o formato compartilhado por todo tipo de biblioteca transpilada pelo Babel; assim, qualquer problema que afete o Fuse afeta metade do ecossistema npm.
- **handlebars** — criação completa de templates com compilação seguida de renderização. Exercita o caminho de runtime sem `eval` por meio de uma única entrada `compile()` enorme, travessia da AST, despacho de helpers por uma tabela de busca dinâmica e verificação de marca de `SafeString` que usa `instanceof` entre realms. É um contraponto ao percurso mais simples de templates do mustache.js.
- **zod** — validação de esquemas em runtime. Hierarquias extensas de classes (`ZodString`, `ZodObject`, `ZodArray`, `ZodUnion`, …) com encadeamento de métodos que retorna subclasses refinadas; formatação estruturada de erros em que o formato do array `.issues` do lado do JS precisa corresponder byte a byte ao Node; e padrões de discriminadores e tags literais. Testa o tipo de código de validação fortemente orientado a objetos que envolve metade dos aplicativos modernos TypeScript.
- **typescript** — o compilador TypeScript *real* em execução no mecanismo incorporado. São 9 MB de compilador minificado que reanalisa TS arbitrário, percorre a AST e emite JS — a carga útil JS pura mais pesada que se pode imaginar. Se Phasis consegue transpilar generics, async/await, enums e hierarquias de classes com resultado byte a byte idêntico ao de `tsc`, a semântica da linguagem é sólida.
- **prettier** — formatador de JS opinativo. Formatar JS *com* JS exercita todos os casos extremos da especificação do mecanismo pelo mesmo fluxo de controle que formata seu código — uma carga de trabalho excepcionalmente exigente.
- **svelte/compiler** — compilador independente do Svelte. Analisa código-fonte `.svelte`, percorre a AST e emite JS para destinos client e SSR.
- **terser / @babel/parser / postcss** — minificador JS, analisador JS, pós-processador CSS. Dezenas de milhares de linhas de código minificado que reanalisam entradas arbitrárias — a superfície em que surgem estruturas de AST raras.
- **ajv** — validador de esquemas JSON que compila cada esquema JIT em uma função validadora personalizada por meio de `new Function(...)`. Exercita o caminho do construtor Function, usado pela maioria das bibliotecas de esquemas e templates.
- **mobx** — estado reativo baseado em proxy. Cada leitura de um observável passa por uma armadilha Proxy `get` que registra uma dependência; cada gravação dispara reações. Um teste de estresse para a infraestrutura Proxy, Maps observáveis / arrays / objetos aninhados e o agendador autorun.
- **cheerio / htmlparser2** — jQuery do lado do servidor sobre um analisador rápido HTML. Análise pelo mecanismo de seletores, travessia no estilo DOM, manipulação de atributos e serialização HTML em um só pacote.
- **graphql-js / jsonata** — implementação de referência GraphQL e uma linguagem de consulta JSON. Ambas fazem uso intenso de esquemas, validação e avaliadores recursivos — código típico de «camada de dados no navegador».
- **JSZip** — criador assíncrono de arquivos ZIP. Encaminha o trabalho por meio do agendamento orientado a `setImmediate` e produz saída binária real, exercitando tanto a superfície de temporizadores quanto caminhos com uso intenso de `Uint8Array`.
- **moment / luxon** — operações aritméticas com datas e horários. moment é um UMD mutável e ajustado manualmente; luxon é a reescrita imutável moderna. Juntas, cobrem toda a superfície de formatação, análise e cálculos de meses/anos equivalentes entre fusos horários.
- **mqtt-packet** — codec MQTT JS / 5.0 puro de 3.1.1. Empacotamento e decodificação em nível de byte, além de classes de caracteres de regex para caracteres fora do alfabeto base64, que exercitam casos extremos da gramática do Annex-B.
- **xstate / valtio / nanostores / jotai / redux-saga** — a variedade moderna de gerenciamento de estado. Máquinas de estado, estado proxy, armazenamentos de átomos, átomos derivados e executores de efeitos baseados em geradores — cada biblioteca aborda um formato diferente de reatividade.
- **escodegen / acorn-walk / estraverse / magic-string** — ferramentas de AST. Geração e travessia de código, além de edição não destrutiva do código-fonte — os componentes básicos de qualquer transformador de JS em JS (ferramentas de build, codemods, linters).
- **papaparse / lunr / yaml / sax / css-tree** — analisadores e tokenizadores puros. CSV, índice de pesquisa de texto completo, YAML 1.2, análise em fluxo no estilo SAX XML e AST de CSS. Gramáticas diferentes, todas boas sentinelas para a varredura em nível de caractere e o comportamento de regex.

## Adicionando mais

Adicione um novo diretório em `tests/Popular/<name>/` com a estrutura de três arquivos e, em seguida:

```bash
node tests/Popular/gen-oracle.js tests/Popular/<name>   # one-time, generates oracle.txt
git add tests/Popular/<name>
```

A suíte PHPUnit o detecta automaticamente na próxima execução, e o CI o inclui porque a alteração afeta `tests/Popular/`.

Bons candidatos para adicionar: `chevrotain` (combinador de analisadores, exercita closures + regex), `nanoid` (limite de criptografia/aleatoriedade), `date-fns` (suporte a fusos horários além do dayjs).
