
# Pachete populare

Conformitatea cu specificația nu garantează că bibliotecile reale funcționează. Motoarele JS care trec 99 % din test262 încă se defectează frecvent cu cod de producție, deoarece bibliotecile depind de o mulțime de „detalii obscure ale specificației” — capcane Proxy în anumite ordini, forma `Function.prototype.toString`, comportamentul expresiilor regulate pentru intrări dificile, modul exact în care ordonarea `Object.keys` interacționează cu numele de proprietăți calculate.

Phasis verifică **204 biblioteci utilizate pe scară largă** octet cu octet față de Node.js (V8). Acestea se află în `tests/Popular/` din depozit, iar CI le rulează ori de câte ori se modifică sursa motorului sau suita.

## Acoperire pe categorii

| Categorie | Biblioteci |
|---|---|
| **Analizoare / 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 |
| **Șabloane / 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 |
| **Utilitare / funcționale** | 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 |
| **Acces la obiecte** | 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 |
| **Validare / scheme** | 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 |
| **Dată / oră** | dayjs 1.11.20, date-fns 4.1.0, timeago.js 4.0.2, luxon 3.7.3, moment 2.30.2 |
| **Matematică / numere** | 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 |
| **Hashing / criptografie** | 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 |
| **Căutare / diferențe** | 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 / formate de date** | 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 |
| **Șiruri / lingvistică** | 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 |
| **Comprimare / codare / arhivare** | pako 2.1.0, lz-string 1.5.0, base64-js 1.5.1, JSZip 3.10.1 |
| **Culoare** | 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 |
| **Clonare / egalitate** | rfdc 1.4.1, klona 2.0.6, fast-copy 3.0.2 |
| **Formatare / afișare** | ms 2.1.3, bytes 3.1.2 |
| **ID-uri / UUID-uri** | uuid 10.0.0, hexoid 2.0.0, ulid 3.0.1, cuid2 2.2.2, short-unique-id 5.4.3 |
| **Detectarea tipurilor / 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 / configurare** | semver 7.6.3, compare-versions 6.1.1, semver-compare 1.0.0 |
| **Cache-uri / performanță** | lru-cache 11.0.2, marky 1.3.0, array-flatten 3.0.0, arr-diff 4.0.0 |
| **Asincron / evenimente** | 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 |
| **Stare reactivă** | 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 / stilizare** | postcss 8.5.7, stylis 4.3.6, css-tree 3.0.4 |
| **Build / AST / compilatoare** | 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 (compilator), typescript 6.0.3 |
| **MQTT / protocol** | mqtt-packet 9.0.4 |
| **GraphQL** | graphql-js 16.11.0 |
| **Evidențierea sintaxei** | highlight.js 11.11.1 |
| **Testare / aserțiuni** | chai 6.2.1 |

Total: **204 biblioteci** reproduc toate exact rezultatul Node. Toate sunt fixate la cea mai recentă versiune upstream la momentul ultimei actualizări.

## Cum funcționează

Fiecare scenariu este un director `tests/Popular/<lib>/` cu trei fișiere:

```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` este un test cu furnizor de date PHPUnit care:

1. Încarcă `lodash.js` + `runner.js` într-un `new Phasis\Engine()` nou.
2. Capturează rezultatul `console.log` într-un buffer.
3. Verifică dacă bufferul capturat este identic byte cu byte cu `oracle.txt`.

Regenerează un oracol cu:

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

(Se folosește când actualizați biblioteca inclusă — rulează din nou runnerul în Node real și suprascrie `oracle.txt`.)

## Verificare CI

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

Rulează la push-uri și cereri pull către `main` care modifică `src/`, `tests/Popular/`, `phpunit.xml.dist`, fișierele Composer sau workflow-ul în sine, precum și la declanșare manuală. Doi pași:

1. **Partea Phasis** — rulează suita de teste PHPUnit `popular`, care execută fiecare bibliotecă prin Phasis și compară cu oracolul salvat în depozit. Eșuează dacă diferă măcar un byte.
2. **Reverificare Node** — rulează `node tests/Popular/gen-oracle.js …` pentru fiecare bibliotecă și verifică dacă oracolul regenerat corespunde celui din depozit. Detectează abaterile de tipul „biblioteca inclusă a fost actualizată fără actualizarea oracolului”.

Ambele trebuie să treacă înainte de îmbinarea PR-ului. O îmbunătățire test262 care strică lodash nu este acceptabilă; nici una pentru lodash care strică test262.

## De ce aceste biblioteci

- **acorn** — analizarea sintactică este cea mai fragilă componentă a oricărui motor JS. Acoperă fiecare caz-limită sintactic pe care îl adaugă JS modern. Dacă Phasis poate analiza cod modern arbitrar cu acorn, runtime-ul este solid.
- **mustache.js** — șabloanele sunt unul dintre cazurile de utilizare încorporate pe care Phasis le vizează în mod explicit (primul exemplu concret din README este „motoare de șabloane”). Mustache testează iterația, rezolvarea domeniului de vizibilitate și transformările de șiruri în ordinea folosită de șabloanele reale.
- **lodash** — cea mai folosită bibliotecă de utilitare JS din lume. Cele peste 300 funcții ale sale ating tranzitiv fiecare metodă din biblioteca standard. Dacă lodash funcționează, funcționează și JS pentru transformarea generică a datelor.
- **marked** — redare Markdown. Este practic și testează expresii regulate (multe) plus manipularea șirurilor cu stare între linii. Scoate la iveală abaterile motorului de expresii regulate dintre PCRE2 (fallback-ul Phasis) și Irregexp din V8.
- **dayjs** — operațiile aritmetice cu date și ore sunt o sursă clasică de erori de tip off-by-one pe care niciun caz test262 nu le detectează. dayjs acoperă variantele constructorului, operațiile aritmetice la granițele lunilor echivalente în DST și extinderea tokenurilor de formatare, pe aproximativ aceleași căi de cod folosite de fiecare bibliotecă Date JS.
- **bignumber.js** — aritmetica de precizie arbitrară fără TypedArrays testează analizarea numerelor din șiruri, buclele de înmulțire și împărțire pentru numere întregi mari și alegerea modului de rotunjire — toate în JS pur, astfel încât motorul suportă întregul cost. Evidențiază orice defecțiune subtilă la conversia Number ↔ String.
- **json5** — analizarea JSON cu sintaxă permisivă se bazează în mare măsură pe expresii regulate cu clase de caractere și pe tokenizare cu stare. Este un test bun pentru corectitudinea expresiilor regulate și cazurile-limită ale iterării prin șiruri.
- **fuse.js** — un UMD transpilat de Babel care testează `_classCallCheck` (modelul `this instanceof Ctor` folosit de fiecare clasă transpilată înainte de ES6), plus algoritmul complet de potrivire aproximativă bitap. Este o formă comună tuturor bibliotecilor transpile de Babel, așa că orice lucru care strică Fuse strică jumătate din ecosistemul npm.
- **handlebars** — șabloane complete cu compilare urmată de randare. Testează calea de runtime fără `eval` printr-un singur punct de intrare `compile()` foarte mare, parcurgerea AST, distribuirea helperelor printr-un tabel de căutare dinamic și verificarea de marcă `SafeString` care folosește `instanceof` între realm-uri. Un contrapunct la parcurgătorul de șabloane mai simplu al lui mustache.js.
- **zod** — validarea schemelor la runtime. Ierarhii de clase complexe (`ZodString`, `ZodObject`, `ZodArray`, `ZodUnion`, …), cu înlănțuirea metodelor care returnează subclase rafinate, formatarea structurată a erorilor în care forma tabloului `.issues` din partea JS trebuie să corespundă byte cu byte cu Node și modele cu discriminatori și etichete literale. Testează codul de validare cu multe clase OO care stă la baza jumătății aplicațiilor moderne TypeScript.
- **typescript** — compilatorul *real* TypeScript care rulează pe motorul încorporat. Un compilator de 9 MB minificat care reanalizează sintactic orice cod TS, parcurge AST-ul și emite JS — cea mai grea încărcătură pură JS imaginabilă. Dacă Phasis poate transpila generice, async/await, enum-uri și ierarhii de clase cu un rezultat identic byte cu byte cu `tsc`, semantica limbajului este solidă.
- **prettier** — formator JS cu opinii proprii. Formatarea JS *cu* JS atinge fiecare colț al specificației prin același flux de control folosit pentru formatarea codului — o sarcină de lucru deosebit de solicitantă.
- **svelte/compiler** — compilatorul autonom al Svelte. Analizează sursa `.svelte`, parcurge AST-ul și emite JS atât pentru țintele client, cât și pentru SSR.
- **terser / @babel/parser / postcss** — minificator JS, analizor JS, postprocesor CSS. Zeci de mii de linii de cod minificat care reanalizează sintactic intrări arbitrare — zona în care apar forme rare de AST.
- **ajv** — validator de scheme JSON care compilează JIT fiecare schemă într-o funcție de validare personalizată prin `new Function(...)`. Testează calea constructorului Function pe care se bazează majoritatea bibliotecilor pentru scheme și șabloane.
- **mobx** — stare reactivă bazată pe proxy-uri. Fiecare citire a unui observabil trece printr-o capcană Proxy `get` care înregistrează o dependență; fiecare scriere declanșează reacții. Un test de stres pentru infrastructura Proxy, Map-uri / tablouri / obiecte imbricate observabile și planificatorul autorun.
- **cheerio / htmlparser2** — jQuery pe server, construit peste un analizor rapid HTML. Analizarea motorului de selectori, parcurgerea în stil DOM, manipularea atributelor și serializarea HTML într-un singur pachet.
- **graphql-js / jsonata** — implementarea de referință GraphQL și un limbaj de interogare JSON. Ambele folosesc intens scheme, validare și evaluatoare recursive — cod tipic pentru „stratul de date în browser”.
- **JSZip** — generator asincron de arhive ZIP. Direcționează lucrările prin planificare bazată pe `setImmediate` și produce rezultate binare reale, testând atât suprafața timerelor, cât și căile cu utilizare intensă a `Uint8Array`.
- **moment / luxon** — operații aritmetice cu date și ore. moment este un UMD mutabil, reglat manual; luxon este rescrierea modernă, imutabilă. Împreună acoperă toate aspectele formatării, analizării sintactice și calculelor cu luni și ani echivalente în fusuri orare.
- **mqtt-packet** — codec MQTT 3.1.1 / 5.0 pur JS. Împachetare și decodare la nivel de byte, plus clase de caractere din expresii regulate pentru caractere în afara alfabetului base64, care testează cazurile-limită ale gramaticii Annex-B.
- **xstate / valtio / nanostores / jotai / redux-saga** — gama modernă de gestionare a stării. Mașini de stare, stare proxy, depozite de atomi, atomi derivați, rutine de efecte bazate pe generatoare — fiecare bibliotecă testează o formă diferită de reactivitate.
- **escodegen / acorn-walk / estraverse / magic-string** — instrumente AST. Generarea codului, parcurgere și editare nedistructivă a sursei — elementele de bază ale oricărui transformator JS pe JS (instrumente de build, codemod-uri, linters).
- **papaparse / lunr / yaml / sax / css-tree** — analizoare și tokenizatoare pur JS. CSV, index de căutare integrală, YAML 1.2, XML în stil SAX cu flux continuu și AST CSS. Gramatici diferite, toate teste bune pentru scanarea la nivel de caracter și comportamentul expresiilor regulate.

## Adăugarea altora

Adăugați un director nou sub `tests/Popular/<name>/` cu structura de trei fișiere, apoi:

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

Suita PHPUnit îl detectează automat la următoarea rulare, iar CI îl include deoarece modificarea atinge `tests/Popular/`.

Candidați promițători de adăugat: `chevrotain` (combinator de analizare, testează closures + expresii regulate), `nanoid` (limita dintre criptografie și aleatoriu), `date-fns` (aspecte legate de fusurile orare dincolo de dayjs).
