
# Populárne balíky

Zhoda so špecifikáciou nezaručuje, že budú fungovať aj reálne knižnice. JS enginy, ktoré zvládnu 99 % test262, v produkčnom kóde pravidelne zlyhávajú, pretože knižnice sa spoliehajú na množstvo okrajových prípadov špecifikácie — poradie zachytenia Proxy pascí, tvar `Function.prototype.toString`, správanie regulárnych výrazov pri zložitých vstupoch či presný spôsob, akým poradie `Object.keys` interaguje s vypočítanými názvami vlastností.

Phasis overuje **204 široko používaných knižníc** bajt po bajte oproti Node.js (V8). Nachádzajú sa v repozitári pod `tests/Popular/` a CI ich spúšťa pri každej zmene zdrojového kódu enginu alebo testovacej sady.

## Pokrytie podľa kategórií

| Kategória | Knižnice |
|---|---|
| **Parsery / 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 |
| **Šablóny / 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 |
| **Pomocné / funkcionálne** | 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 |
| **Prístup k objektom** | 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 |
| **Validácia / schémy** | 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 |
| **Dátum / čas** | dayjs 1.11.20, date-fns 4.1.0, timeago.js 4.0.2, luxon 3.7.3, moment 2.30.2 |
| **Matematika / čísla** | 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 |
| **Hašovanie / kryptografia** | 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 |
| **Vyhľadávanie / rozdiely** | 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 / dátové formáty** | 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 |
| **Reťazce / lingvistika** | 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 |
| **Kompresia / kódovanie / archívy** | pako 2.1.0, lz-string 1.5.0, base64-js 1.5.1, JSZip 3.10.1 |
| **Farby** | 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 |
| **Klonovanie / rovnosť** | rfdc 1.4.1, klona 2.0.6, fast-copy 3.0.2 |
| **Formátovanie / zobrazenie** | ms 2.1.3, bytes 3.1.2 |
| **ID / UUID** | uuid 10.0.0, hexoid 2.0.0, ulid 3.0.1, cuid2 2.2.2, short-unique-id 5.4.3 |
| **Detekcia typov / 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 / konfigurácia** | semver 7.6.3, compare-versions 6.1.1, semver-compare 1.0.0 |
| **Vyrovnávacie pamäte / výkon** | lru-cache 11.0.2, marky 1.3.0, array-flatten 3.0.0, arr-diff 4.0.0 |
| **Asynchrónnosť / udalosti** | 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 |
| **Reaktívny stav** | 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 / štýlovanie** | postcss 8.5.7, stylis 4.3.6, css-tree 3.0.4 |
| **Zostavovanie / AST / kompilátory** | 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 (kompilátor), typescript 6.0.3 |
| **MQTT / protokol** | mqtt-packet 9.0.4 |
| **GraphQL** | graphql-js 16.11.0 |
| **Zvýrazňovanie syntaxe** | highlight.js 11.11.1 |
| **Testovanie / overovanie** | chai 6.2.1 |

Spolu: **204 knižníc** presne reprodukuje výstup Node. Všetky sú pripnuté na najnovšiu verziu z upstreamu v čase poslednej aktualizácie.

## Ako to funguje

Každý scenár je adresár `tests/Popular/<lib>/` s tromi súbormi:

```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` je test s poskytovateľom dát typu PHPUnit, ktorý:

1. Načíta `lodash.js` + `runner.js` do nového `new Phasis\Engine()`.
2. Zachytí výstup `console.log` do vyrovnávacej pamäte.
3. Overí, že zachytená vyrovnávacia pamäť sa bajt po bajte zhoduje s `oracle.txt`.

Znovu vygenerujte referenčný výstup pomocou:

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

(Používa sa pri aktualizácii vendorizovanej knižnice — znovu spustí runner v skutočnom Node a prepíše `oracle.txt`.)

## Brána CI

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

Spúšťa sa pri odoslaní zmien a požiadavkách na zlúčenie do `main`, ktoré menia `src/`, `tests/Popular/`, `phpunit.xml.dist`, súbory Composer alebo samotný pracovný postup, aj pri manuálnom spustení. Má dva kroky:

1. **Strana Phasis** — spustí testovaciu sadu PHPUnit `popular`, ktorá vykoná každú knižnicu cez Phasis a porovná ju s uloženým referenčným výstupom. Zlyhá, ak sa líši čo i len jeden bajt.
2. **Opätovné overenie v Node** — spustí `node tests/Popular/gen-oracle.js …` pre každú knižnicu a overí, že novo vygenerovaný referenčný výstup sa zhoduje s uloženým. Odhalí rozdiel spôsobený „aktualizáciou vendorizovanej knižnice bez aktualizácie referenčného výstupu“.

Oba kroky musia prejsť, aby sa PR zlúčil. Víťazstvo test262, ktoré pokazí lodash, nie je prijateľné; rovnako ani víťazstvo lodash, ktoré pokazí test262.

## Prečo práve tieto knižnice

- **acorn** — parsovanie je najkrehkejšou oblasťou každého enginu JS. Overuje všetky syntaktické okrajové prípady, ktoré prináša moderné JS. Ak Phasis dokáže pomocou acorn parsovať ľubovoľný moderný kód, runtime je spoľahlivý.
- **mustache.js** — šablóny sú jedným z prípadov použitia pri vkladaní, na ktoré sa Phasis výslovne zameriava (prvým konkrétnym príkladom v README sú „šablónovacie enginy“). Mustache overuje iteráciu, rozlíšenie rozsahov platnosti a transformácie reťazcov v poradí, aké používajú skutočné šablóny.
- **lodash** — najpoužívanejšia pomocná knižnica JS na svete. Jej viac než 300 funkcií sa nepriamo dotýka každej metódy štandardnej knižnice. Ak funguje lodash, fungujú aj všeobecné nástroje JS na transformáciu dát.
- **marked** — vykresľovanie markdownu. Je praktická a preveruje regulárne výrazy (vo veľkej miere) aj manipuláciu s reťazcami so stavom naprieč riadkami. Odhaľuje rozdiely v správaní regex enginu medzi PCRE2 (záložný mechanizmus Phasis) a Irregexp v V8.
- **dayjs** — aritmetika s dátumom a časom je klasickým zdrojom chýb o jeden deň, ktoré neodhalí žiadny prípad test262. dayjs pokrýva varianty konštruktora, aritmetiku cez hranice mesiacov ekvivalentné vzhľadom na DST a rozširovanie formátovacích tokenov v približne rovnakých častiach kódu, ktoré používa každá knižnica dátumov JS.
- **bignumber.js** — aritmetika s ľubovoľnou presnosťou bez TypedArrays preveruje parsovanie čísel z reťazcov, násobenie a delenie veľkých celých čísel v cykloch aj výber režimu zaokrúhľovania — všetko v čistom JS, takže celé náklady nesie engine. Odhalí aj jemné chyby pri konverzii Number ↔ String.
- **json5** — uvoľnené parsovanie JSON sa vo veľkej miere spolieha na regulárne výrazy s triedami znakov a tokenizáciu so stavom. Je dobrým indikátorom správnosti regexov aj okrajových prípadov iterácie cez reťazec.
- **fuse.js** — UMD preložené pomocou Babelu preveruje `_classCallCheck` (vzor `this instanceof Ctor`, ktorý používa každá trieda preložená pred ES6) aj úplný algoritmus približného vyhľadávania bitap. Ide o typický tvar každej knižnice preloženej pomocou Babelu, takže všetko, čo pokazí Fuse, pokazí polovicu ekosystému npm.
- **handlebars** — plnohodnotné šablóny s kompiláciou pred vykreslením. Preveruje runtime cestu bez `eval` cez jediný rozsiahly vstupný bod `compile()`, prechádzanie AST, volanie pomocných funkcií cez dynamickú vyhľadávaciu tabuľku a overovanie značiek `SafeString`, ktoré používa `instanceof` naprieč realmami. Je protipólom jednoduchšieho prechádzania šablón v mustache.js.
- **zod** — validácia schém za behu. Rozsiahle hierarchie tried (`ZodString`, `ZodObject`, `ZodArray`, `ZodUnion`, …) s reťazením metód, ktoré vracia odvodené podtriedy; formátovanie štruktúrovaných chýb, pri ktorom sa tvar poľa JS `.issues` musí bajt po bajte zhodovať s Node, a vzory rozlišovačov a literálových značiek. Testuje objektovo orientovaný validačný kód, ktorý zastrešuje polovicu moderných aplikácií TypeScript.
- **typescript** — *skutočný* kompilátor TypeScript spustený vo vloženom engine. Minifikovaný kompilátor s veľkosťou 9 MB znovu parsuje ľubovoľné TS, prechádza AST a vytvára JS — najnáročnejší čisto JS balík, aký si možno predstaviť. Ak Phasis dokáže preložiť generiká, async/await, enumy a hierarchie tried s bajtovou zhodou s `tsc`, sémantika jazyka je spoľahlivá.
- **prettier** — názorový formátovač JS. Formátovanie JS *pomocou* JS aktivuje každý okrajový prípad špecifikácie enginu cez rovnaký riadiaci tok, ktorý formátuje váš kód — ide o mimoriadne náročné pracovné zaťaženie.
- **svelte/compiler** — samostatný kompilátor Svelte. Parsuje zdrojový kód `.svelte`, prechádza AST a vytvára JS pre klienta aj ciele SSR.
- **terser / @babel/parser / postcss** — minifikátor JS, parser JS, postprocesor CSS. Desiatky tisíc riadkov minifikovaného kódu znovu parsujú ľubovoľný vstup — práve tu sa objavujú zriedkavé tvary AST.
- **ajv** — validátor schém JSON, ktorý pomocou `new Function(...)` kompiluje každú schému JIT do vlastnej validačnej funkcie. Preveruje cestu konštruktora Function, na ktorú sa spolieha väčšina knižníc na prácu so schémami a šablónami.
- **mobx** — reaktívny stav založený na proxy. Každé čítanie pozorovateľnej hodnoty prechádza cez Proxy pascu `get`, ktorá zaregistruje závislosť; každý zápis spustí reakcie. Záťažový test infraštruktúry Proxy, pozorovateľných máp, polí a vnorených objektov aj plánovača autorun.
- **cheerio / htmlparser2** — jQuery na strane servera postavené na rýchlom parseri HTML. V jednom balíku spája parsovanie enginu selektorov, prechádzanie v štýle DOM, úpravu atribútov a serializáciu HTML.
- **graphql-js / jsonata** — referenčná implementácia GraphQL a dopytovací jazyk JSON. Obe sa intenzívne opierajú o schémy, validáciu a rekurzívne evaluátory — typický kód „dátovej vrstvy v prehliadači“.
- **JSZip** — asynchrónny nástroj na tvorbu archívov ZIP. Prácu plánuje pomocou `setImmediate` a vytvára skutočný binárny výstup, čím preveruje časovače aj cesty náročné na `Uint8Array`.
- **moment / luxon** — aritmetika s dátumom a časom. moment je meniteľný, ručne optimalizovaný UMD; luxon je jeho moderná nemenná verzia. Spolu pokrývajú celú škálu formátovania, parsovania a výpočtov s mesiacmi a rokmi ekvivalentnými vzhľadom na časové pásmo.
- **mqtt-packet** — čisto JS kodek MQTT 3.1.1 / 5.0. Balenie a dekódovanie na úrovni bajtov aj triedy znakov regexov pre abecedu mimo Base64 preverujú okrajové prípady gramatiky Annex B.
- **xstate / valtio / nanostores / jotai / redux-saga** — súčasný prierez knižnicami na správu stavu. Stavové automaty, stav proxy, úložiská atómov, odvodené atómy a spúšťače efektov založené na generátoroch — každá knižnica preveruje inú podobu reaktivity.
- **escodegen / acorn-walk / estraverse / magic-string** — nástroje pre AST. Generovanie kódu, prechádzanie a nedestruktívne úpravy zdrojového kódu — základné stavebné prvky každého transformátora JS nad JS (nástroje na zostavovanie, codemody, lintery).
- **papaparse / lunr / yaml / sax / css-tree** — čisté parsery a tokenizéry. CSV, fulltextový vyhľadávací index, YAML 1.2, streamovacie parsovanie v štýle SAX XML a AST CSS. Rôzne gramatiky, no všetky dobre preverujú skenovanie na úrovni znakov a správanie regexov.

## Pridávanie ďalších

Vytvorte nový adresár pod `tests/Popular/<name>/` s tromi súbormi a potom:

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

Testovacia sada PHPUnit ho pri ďalšom spustení automaticky objaví a CI ho zahrnie, pretože zmena sa týka `tests/Popular/`.

Dobré kandidáty na pridanie: `chevrotain` (parserový kombinátor, preveruje uzávery a regexy), `nanoid` (hranica kryptografie a náhodnosti), `date-fns` (práca s časovými pásmami nad rámec dayjs).
