
# Populaarsed paketid

Spetsifikatsioonile vastavus ei taga, et päris teegid töötavad. Isegi 99% testidest test262 läbivad JS mootorid rikuvad tootmiskoodi käivitamisel sageli midagi, sest teegid sõltuvad paljudest spetsifikatsiooni nüanssidest — kindlas järjekorras toimivatest Proxy püünistest, `Function.prototype.toString` kujust, keeruliste sisenditega regexi käitumisest ja sellest, kuidas `Object.keys` järjestus mõjutab arvutatud atribuutide nimesid.

Phasis kontrollib **204 laialdaselt kasutatava teegi** baiditäpsust Node.js-ga (V8). Need asuvad hoidlas kataloogis `tests/Popular/` ning CI käivitab need iga kord, kui mootori lähtekood või testikomplekt muutub.

## Katvus kategooriate kaupa

| Kategooria | Teegid |
|---|---|
| **Parserid / 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 |
| **Mallide loomine / 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 |
| **Utiliidid / funktsionaalne** | 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 |
| **Objektidele juurdepääs** | 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 |
| **Valideerimine / skeem** | 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 |
| **Kuupäev / kellaaeg** | dayjs 1.11.20, date-fns 4.1.0, timeago.js 4.0.2, luxon 3.7.3, moment 2.30.2 |
| **Matemaatika / arvud** | 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 |
| **Räsimine / krüpto** | 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 |
| **Otsing / erinevused** | 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 / andmevormingud** | 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 |
| **Sõned / keeleteadus** | 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 / veeb** | 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 |
| **Tihendamine / kodeerimine / arhiiv** | pako 2.1.0, lz-string 1.5.0, base64-js 1.5.1, JSZip 3.10.1 |
| **Värv** | 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 |
| **Kloonimine / võrdsus** | rfdc 1.4.1, klona 2.0.6, fast-copy 3.0.2 |
| **Vormindamine / kuvamine** | ms 2.1.3, bytes 3.1.2 |
| **ID-d / UUID-d** | uuid 10.0.0, hexoid 2.0.0, ulid 3.0.1, cuid2 2.2.2, short-unique-id 5.4.3 |
| **Tüübi tuvastamine / 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 / konfiguratsioon** | semver 7.6.3, compare-versions 6.1.1, semver-compare 1.0.0 |
| **Vahemälud / jõudlus** | lru-cache 11.0.2, marky 1.3.0, array-flatten 3.0.0, arr-diff 4.0.0 |
| **Asünkroonsus / sündmused** | 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 |
| **Reaktiivne olek** | 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 / stiilid** | postcss 8.5.7, stylis 4.3.6, css-tree 3.0.4 |
| **Ehitamine / AST / kompilaatorid** | 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 (kompilaator), typescript 6.0.3 |
| **MQTT / protokoll** | mqtt-packet 9.0.4 |
| **GraphQL** | graphql-js 16.11.0 |
| **Süntaksi esiletõstmine** | highlight.js 11.11.1 |
| **Testimine / kontrollid** | chai 6.2.1 |

Kokku: **204 teeki**, mis jäljendavad kõik täpselt Node'i väljundit. Kõik on fikseeritud viimase uuenduse ajal saadaolevale uusimale lähteversioonile.

## Kuidas see töötab

Iga stsenaarium on `tests/Popular/<lib>/` kataloog kolme failiga:

```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` on PHPUnit andmepakkuja test, mis teeb järgmist:

1. Laadib `lodash.js` + `runner.js` uude `new Phasis\Engine()`-i.
2. Salvestab `console.log` väljundi puhvrisse.
3. Kontrollib, et salvestatud puhver on bait-baidilt võrdne väärtusega `oracle.txt`.

Loo kontrollväärtus uuesti käsuga:

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

(Kasutatakse komplekti kuuluva teegi versiooni uuendamisel — käivitab testi uuesti päris Node'is ja kirjutab `oracle.txt` üle.)

## CI kontrollvärav

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

Käivitub tõukamiste ja tõmbepäringute korral, mis on suunatud `main`-i ja muudavad `src/`, `tests/Popular/`, `phpunit.xml.dist`, Composer faile või töövoogu ennast, samuti käsitsi käivitamisel. Kaks etappi:

1. **Phasis pool** — käivitab PHPUnit `popular` testikomplekti, mis käivitab iga teegi läbi Phasis ja võrdleb tulemusi sisse kantud kontrollväärtusega. Ebaõnnestub, kui kasvõi üks bait erineb.
2. **Node'i korduskontroll** — käivitab `node tests/Popular/gen-oracle.js …` iga teegi puhul ja kontrollib, et värskelt loodud kontrollväärtus vastab sisse kantule. Tuvastab lahknevuse olukorras „komplekti kuuluv teek uuendati, kuid kontrollväärtust ei uuendatud”.

Mõlemad peavad enne PR-i ühendamist läbima. test262 edukas tulemus, mis rikub lodash'i, ei ole vastuvõetav; samuti pole vastuvõetav lodash'i edukas tulemus, mis rikub test262-t.

## Miks just need teegid

- **acorn** — parsimine on mis tahes JS mootori kõige hapram osa. See katab kõik süntaktilised erijuhud, mida tänapäevane JS juurde toob. Kui Phasis suudab acorni abil parsida suvalist tänapäevast koodi, on käituskeskkond töökindel.
- **mustache.js** — mallide loomine on üks manustatud kasutusjuhtudest, millele Phasis on selgesõnaliselt suunatud (README esimene konkreetne näide on „mallimootorid”). Mustache katsetab iteratsiooni, ulatuse lahendamist ja stringide teisendamist samas järjekorras nagu päris mallides.
- **lodash** — maailma enim kasutatud JS utiliiditeek. Selle 300+ funktsioonid kasutavad kaudselt kõiki standardteegi meetodeid. Kui lodash töötab, toimivad ka üldised andmete teisendamise JS.
- **marked** — Markdowni renderdamine. Praktiline ning katsetab regulaaravaldisi (palju) ja stringitöötlust koos ridadevahelise olekuga. Toob esile regulaaravaldise mootori erinevused PCRE2 (Phasis varuvariandi) ja V8 Irregexpi vahel.
- **dayjs** — kuupäeva ja kellaaja arvutused põhjustavad sageli ühe võrra nihkes vigu, mida ükski test262 juhtum ei tuvasta. dayjs katab konstruktorite variandid, arvutused suveajaga samaväärsete kuupiiride ületamisel ning vormingutokenite laiendamise ligikaudu samades kooditeedes, mida kasutab iga JS kuupäevateek.
- **bignumber.js** — suvalise täpsusega aritmeetika ilma TypedArrays-ita katsetab stringipõhist arvude parsimist, suurte täisarvude korrutamise ja jagamise tsükleid ning ümardamisrežiimi valimist — kõik puhtas JS-is, nii et kogu koormus jääb mootorile. Toob esile kõik peened vead arvu ja stringi teisendamisel.
- **json5** — leebe JSON parsimine kasutab palju märgiklasside regulaaravaldisi ja olekuga tokeniseerimist. Hea proovikivi nii regulaaravaldiste korrektsuse kui ka stringi läbimise erijuhtude jaoks.
- **fuse.js** — Babeliga transpileeritud UMD, mis katsetab `_classCallCheck`-i (`this instanceof Ctor` mustrit, mida kasutavad kõik ES6-eelsed transpileeritud klassid) ning kogu bitap-algoritmi häguseks sobitamiseks. Sellist ülesehitust kasutavad kõik Babeliga transpileeritud teegid, nii et mis tahes Fuse'i rikkuv muudatus mõjutab poolt npm ökosüsteemist.
- **handlebars** — täisfunktsionaalne malliteek kompileerimise ja seejärel renderdamisega. Katsetab teed käituskeskkonnas, kus puudub `eval`, läbi ühe suure `compile()`-kirje, AST läbimise, abifunktsioonide väljakutsumise dünaamilise otsingutabeli kaudu ning `SafeString` brändikontrolli, mis kasutab realm'ideüleselt `instanceof`-i. Vastukaal mustache.js lihtsamale mallide läbikäijale.
- **zod** — skeemide valideerimine käitusajal. Sügavad klassihierarhiad (`ZodString`, `ZodObject`, `ZodArray`, `ZodUnion`, …), mille meetodiaheldus tagastab täpsustatud alamklasse; struktureeritud veateadete vormindamine, kus JS-i poolel peab `.issues`-i massiivi struktuur bait-baidilt Node'i omaga kattuma; ning diskriminaatori ja literaalse sildi mustrid. Katsetab objektorienteeritud valideerimiskoodi, mis ümbritseb poolt tänapäevastest TypeScript rakendustest.
- **typescript** — *tegelik* TypeScript kompilaator, mis töötab manustatud mootoris. 9 MB tihendatud kompilaatorikoodi, mis parsib suvalise TS-i uuesti, läbib AST-d ja väljastab JS-i — kõige raskema võimaliku puhta JS koormuse. Kui Phasis suudab transpileerida geneerikuid, async/await-i, loendeid ja klassihierarhiaid `tsc`-ga bait-baidilt samaväärseks, on keele semantika korrektne.
- **prettier** — kindla stiiliga JS vormindaja. JS vormindamine koos JS-ga puudutab mootori kõiki spetsifikatsiooni erijuhte sama juhtvoo kaudu, mida kasutatakse ka sinu koodi vormindamisel — see on ainulaadselt nõudlik koormus.
- **svelte/compiler** — Svelte eraldiseisev kompilaator. Parsib `.svelte` lähtekoodi, läbib AST-d ja väljastab JS nii kliendi kui ka SSR-i sihtmärgi jaoks.
- **terser / @babel/parser / postcss** — JS minimeerija, JS parser, CSS järeltöötleja. Kümned tuhanded read tihendatud koodi, mis parsivad suvalise sisendi uuesti — just siin ilmnevad haruldased AST-kujud.
- **ajv** — JSON skeemide valideerija, mis kompileerib iga skeemi JIT-i abil `new Function(...)` kaudu kohandatud valideerimisfunktsiooniks. Katsetab Function-konstruktori rada, millele tugineb enamik skeemi- ja malliteeke.
- **mobx** — puhverserveritel põhinev reaktiivne olek. Iga vaadeldava väärtuse lugemine läbib Proxy `get` lõksu, mis registreerib sõltuvuse; iga kirjutamine käivitab reaktsioonid. Koormustest Proxy taristule, vaadeldavatele kaartidele, massiividele ja pesastatud objektidele ning automaatse käivitaja ajastajale.
- **cheerio / htmlparser2** — jQuery serveripoolne versioon kiire HTML parseri peal. Valikumootori parsimine, DOM-i laadne läbimine, atribuutide muutmine ja HTML jadastamine ühes paketis.
- **graphql-js / jsonata** — GraphQL võrdlusimplementatsioon ja JSON päringukeel. Mõlemad kasutavad palju skeeme, valideerimist ja rekursiivseid hindajaid — tüüpiline kood, mis rakendab andmekihti brauseris.
- **JSZip** — asünkroonne ZIP-arhiivi koostaja. Suunab töö `setImmediate`-põhise ajastamise kaudu ja loob päris binaarväljundi, katsetades nii taimerite liidest kui ka `Uint8Array`-mahukaid teid.
- **moment / luxon** — kuupäeva ja kellaaja arvutused. moment on muudetav, käsitsi optimeeritud UMD; luxon on tänapäevane muutumatu ümberkirjutus. Koos katavad need vormindamise, parsimise ning ajavööndite lõikes samaväärsed kuu- ja aastaarvutused.
- **mqtt-packet** — puhas JS MQTT 3.1.1 / 5.0 koodek. Baiditaseme pakkimine ja dekodeerimine ning baasi 64 tähestikust välja jäävate märkide klasside regulaaravaldised, mis katsetavad Annex-B grammatika erijuhte.
- **xstate / valtio / nanostores / jotai / redux-saga** — tänapäevane olekuhalduse valik. Olekumasinad, puhverserveri olek, aatomipoed, tuletatud aatomid ja generaatoripõhised efektikäivitajad — iga teek kasutab reaktiivsuse eri tahku.
- **escodegen / acorn-walk / estraverse / magic-string** — AST tööriistad. Koodi genereerimine, läbimine ja lähtekoodi mittekahjustav muutmine — iga JS-i peal töötava JS teisendaja ehituskivid (ehitustööriistad, koodimoodid, lintijad).
- **papaparse / lunr / yaml / sax / css-tree** — ainult parserid ja tokeniseerijad. CSV, täistekstiotsingu indeks, YAML 1.2, voogedastav SAX-laadne XML ja CSS AST. Eri grammatikad, kõik head proovikivid märgitaseme skannimise ja regulaaravaldiste käitumise jaoks.

## Lisamine

Lisa kataloogi `tests/Popular/<name>/` uus kolme failiga alamkataloog ja seejärel:

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

PHPUnit komplekt leiab selle järgmisel käivitamisel automaatselt ning CI kaasab selle, sest muudatus puudutab `tests/Popular/`-i.

Head kandidaadid lisamiseks: `chevrotain` (parseri kombinaator, katsetab sulundeid ja regulaaravaldisi), `nanoid` (krüpto ja juhuslikkuse piir), `date-fns` (ajavööndite tugi lisaks dayjs-ile).
