
# Oblíbené balíčky

Shoda se specifikací nezaručuje, že budou fungovat skutečné knihovny. Enginy JS, které projdou 99 % testů test262, běžně selhávají na produkčním kódu, protože knihovny závisejí na dlouhém seznamu okrajových případů specifikace: pořadí volání Proxy trapů, tvar `Function.prototype.toString`, chování regexů u složitých vstupů a přesný způsob, jakým pořadí `Object.keys` ovlivňuje vypočítané názvy vlastností.

Phasis ověřuje shodu výstupu po bajtech u **204 široce používaných knihoven** s Node.js (V8). Jsou uloženy v repozitáři pod `tests/Popular/` a CI je spouští při každé změně zdrojového kódu enginu nebo sady testů.

## Pokrytí podle kategorií

| Kategorie | Knihovny |
|---|---|
| **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 |
| **Šablony / 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ální** | 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 |
| **Přístup k objektům** | 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 |
| **Validace / schéma** | 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 |
| **Datum / č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šování / kryptografie** | 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 |
| **Vyhledávání / rozdíly** | 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 / datové 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 |
| **Řetězce / 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 |
| **Komprese / kódování / archivy** | pako 2.1.0, lz-string 1.5.0, base64-js 1.5.1, JSZip 3.10.1 |
| **Barvy** | 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 |
| **Klonování / shoda** | rfdc 1.4.1, klona 2.0.6, fast-copy 3.0.2 |
| **Formát / zobrazení** | 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 |
| **Detekce typů / 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 / konfigurace** | semver 7.6.3, compare-versions 6.1.1, semver-compare 1.0.0 |
| **Mezipaměť / výkon** | lru-cache 11.0.2, marky 1.3.0, array-flatten 3.0.0, arr-diff 4.0.0 |
| **Asynchronní operace / události** | 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 |
| **Reaktivní 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 / stylování** | postcss 8.5.7, stylis 4.3.6, css-tree 3.0.4 |
| **Sestavení / 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ňování syntaxe** | highlight.js 11.11.1 |
| **Testování / ověřování** | chai 6.2.1 |

Celkem: **204 knihoven** přesně reprodukuje výstup Node. Všechny jsou připnuté na nejnovější vydání upstreamu k datu poslední aktualizace.

## Jak to funguje

Každý scénář je adresář `tests/Popular/<lib>/` se třemi soubory:

```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 poskytovatelem dat PHPUnit, který:

1. Načte `lodash.js` + `runner.js` do nové instance `new Phasis\Engine()`.
2. Zachytí výstup `console.log` do vyrovnávací paměti.
3. Ověří, že zachycená data jsou po bajtech shodná s `oracle.txt`.

Znovu vygenerujte referenční výstup příkazem:

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

(Používá se při aktualizaci přibalené knihovny — znovu spustí testovací běh ve skutečném Node a přepíše `oracle.txt`.)

## Kontrola CI

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

Spouští se při odeslání změn a při pull requestech do `main`, které mění `src/`, `tests/Popular/`, `phpunit.xml.dist`, soubory Composer nebo samotný workflow, a také ručně. Má dva kroky:

1. **Část Phasis** — spustí testovací sadu PHPUnit `popular`, která provede každou knihovnu přes Phasis a porovná výsledek s uloženým referenčním výstupem. Selže, pokud se liší jediný bajt.
2. **Opakované ověření v Node** — spustí `node tests/Popular/gen-oracle.js …` nad každou knihovnou a ověří, že nově vygenerovaný referenční výstup odpovídá uloženému. Odhalí rozdíly způsobené aktualizací přibalené knihovny bez aktualizace referenčního výstupu.

Před sloučením PR musí oba kroky projít. Výhra v testech test262, která rozbije lodash, není přijatelná; stejně tak není přijatelná výhra pro lodash, která rozbije test262.

## Proč právě tyto knihovny

- **acorn** — Parsování je v každém enginu JS nejzranitelnější oblast. Prověřuje všechny syntaktické okrajové případy, které přidává moderní JS. Pokud Phasis dokáže pomocí acornu parsovat libovolný moderní kód, běhové prostředí je spolehlivé.
- **mustache.js** — Šablony patří mezi případy použití při vkládání, na které se Phasis výslovně zaměřuje (prvním konkrétním příkladem v README jsou „šablonovací enginy“). Mustache prověřuje iteraci, rozlišení rozsahu platnosti a transformace řetězců v pořadí, které používají skutečné šablony.
- **lodash** — Nejpoužívanější pomocná knihovna JS na světě. Jejích více než 300 funkcí nepřímo využívá každou metodu standardní knihovny. Pokud funguje lodash, fungují i obecné transformace dat JS.
- **marked** — Vykreslování Markdownu. Jde o praktickou zátěž, která prověřuje regexy (ve velké míře) i práci s řetězci se stavem napříč řádky. Odhaluje rozdíly mezi regexovými enginy PCRE2 (náhradní řešení Phasis) a Irregexp v V8.
- **dayjs** — Aritmetika s datem a časem je klasickým zdrojem chyb o jeden den, které žádný případ test262 nezachytí. dayjs prověřuje různé varianty konstruktoru, aritmetiku přes hranice měsíců odpovídající přechodu na letní čas a rozšiřování formátovacích tokenů v přibližně stejných částech kódu jako každá knihovna Date pro JS.
- **bignumber.js** — Aritmetika s libovolnou přesností bez TypedArrays prověřuje parsování čísel z řetězců, cykly násobení a dělení velkých celých čísel a volbu režimu zaokrouhlování — vše v čistém JS, takže veškerou práci odvádí engine. Odhalí i drobné chyby při převodu mezi Number a String.
- **json5** — Parsování tolerantního JSON silně spoléhá na regexy s třídami znaků a tokenizaci se stavem. Dobře prověřuje správnost regexů i práci s iterací řetězců na okrajových případech.
- **fuse.js** — Knihovna UMD přeložená pomocí Babelu, která prověřuje `_classCallCheck` (vzor `this instanceof Ctor` používaný každou třídou přeloženou před ES6) a také celý algoritmus fuzzy vyhledávání bitap. Takový tvar sdílí každá knihovna přeložená pomocí Babelu, takže cokoli, co rozbije Fuse, zasáhne polovinu ekosystému npm.
- **handlebars** — Plnohodnotný šablonovací systém s kompilací před vykreslením. Prověřuje běhovou cestu bez `eval` přes jediný rozsáhlý vstupní soubor `compile()`, procházení AST, volání pomocných funkcí pomocí dynamické vyhledávací tabulky a kontrolu značky `SafeString`, která mezi realmami používá `instanceof`. Představuje protiklad k jednoduššímu procházení šablon v mustache.js.
- **zod** — Ověřování schémat za běhu. Rozsáhlé hierarchie tříd (`ZodString`, `ZodObject`, `ZodArray`, `ZodUnion`, …) s řetězením metod, které vrací zpřesněné podtřídy, strukturovaným formátováním chyb, kde tvar pole `.issues` na straně JS musí bajt po bajtu odpovídat Node, a vzory diskriminátorů a doslovných značek. Prověřuje objektově orientovaný validační kód, který obaluje polovinu moderních aplikací TypeScript.
- **typescript** — Skutečný kompilátor TypeScript běžící ve vloženém enginu. Minifikovaný kompilátor o velikosti 9 MB znovu parsuje libovolný TS, prochází AST a generuje JS — největší čistě JS zátěž, jakou si lze představit. Pokud Phasis dokáže přeložit generické typy, async/await, výčty a hierarchie tříd s výstupem shodným po bajtech s `tsc`, sémantika jazyka je správná.
- **prettier** — Názorově vyhraněný formátovač JS. Formátování JS s JS zasáhne každý okrajový případ specifikace v enginu stejným tokem řízení, který formátuje váš kód — jde o mimořádně náročnou zátěž.
- **svelte/compiler** — Samostatný kompilátor Svelte. Parsuje zdrojový kód `.svelte`, prochází AST a generuje JS pro klientské vykreslování i SSR.
- **terser / @babel/parser / postcss** — minifikátor JS, parser JS, postprocesor CSS. Desítky tisíc řádků minifikovaného kódu, který znovu parsuje libovolný vstup — prostředí, v němž se objevují vzácné tvary AST.
- **ajv** — JSON validátor schémat, který každé schéma kompiluje za běhu JIT do vlastní validační funkce pomocí `new Function(...)`. Prověřuje cestu přes konstruktor Function, na kterou spoléhá většina knihoven pro schémata a šablony.
- **mobx** — reaktivní stav založený na proxy. Každé čtení pozorovatelné hodnoty prochází přes Proxy past `get`, která zaregistruje závislost; každý zápis spustí reakce. Zátěžový test infrastruktury Proxy, pozorovatelných Map, polí a vnořených objektů i plánovače autorun.
- **cheerio / htmlparser2** — jQuery na straně serveru postavené na rychlém parseru HTML. V jednom balíčku nabízí parsování pomocí selektorového jádra, procházení ve stylu DOM, úpravy atributů a serializaci HTML.
- **graphql-js / jsonata** — referenční implementace GraphQL a dotazovací jazyk JSON. Oba intenzivně využívají schémata, validaci a rekurzivní vyhodnocovací mechanismy — typický kód pro „datovou vrstvu v prohlížeči“.
- **JSZip** — asynchronní nástroj pro vytváření archivů ZIP. Směruje práci přes plánování řízené `setImmediate` a vytváří skutečný binární výstup, čímž prověřuje jak časové funkce, tak náročné cesty využívající `Uint8Array`.
- **moment / luxon** — aritmetika s daty a časem. moment je proměnlivý UMD vyladěný ručně; luxon je jeho moderní neměnná přepisovaná verze. Společně pokrývají celé spektrum formátování, parsování a výpočtů měsíců a let odpovídajících časovým pásmům.
- **mqtt-packet** — čistě JS kodek MQTT 3.1.1 / 5.0. Balení a dekódování na úrovni bajtů i třídy znaků regulárních výrazů pro znaky mimo abecedu base64, které prověřují okraje gramatiky Annex B.
- **xstate / valtio / nanostores / jotai / redux-saga** — průřez moderní správou stavu. Stavové automaty, stav proxy, úložiště atomů, odvozené atomy, spouštěče efektů založené na generátorech — každá knihovna pracuje s jiným typem reaktivity.
- **escodegen / acorn-walk / estraverse / magic-string** — nástroje pro AST. Generování kódu, procházení a nedestruktivní úpravy zdrojového kódu — stavební prvky každého transformátoru JS-nad-JS (nástroje pro sestavení, codemody, linters).
- **papaparse / lunr / yaml / sax / css-tree** — čisté parsery a tokenizéry. CSV, fulltextový vyhledávací index, YAML 1.2, streamovací parser ve stylu SAX XML a AST CSS. Různé gramatiky, všechny jsou dobrými indikátory problémů při skenování na úrovni znaků a chování regulárních výrazů.

## Přidávání dalších

Přidejte nový adresář do `tests/Popular/<name>/` se strukturou tří souborů a poté:

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

Sada PHPUnit jej při příštím spuštění automaticky objeví a CI jej zahrne, protože změna se týká `tests/Popular/`.

Dobří kandidáti k přidání: `chevrotain` (kombinátor parserů, prověřuje uzávěry a regulární výrazy), `nanoid` (hranice kryptografie a náhodnosti), `date-fns` (časová pásma nad rámec dayjs).
