
# Paket populer

Kesesuaian dengan spesifikasi tidak menjamin pustaka sungguhan berfungsi. Engine JS yang lulus 99 % test262 tetap sering bermasalah pada kode produksi karena pustaka bergantung pada banyak "sudut spesifikasi" — trap Proxy dalam urutan tertentu, bentuk `Function.prototype.toString`, perilaku regex pada masukan yang rumit, dan cara persis pengurutan `Object.keys` berinteraksi dengan nama properti komputasi.

Phasis memverifikasi **204 pustaka yang banyak digunakan** byte demi byte terhadap Node.js (V8). Pustaka tersebut berada di `tests/Popular/` dalam repo, dan CI menjalankannya setiap kali kode sumber engine atau rangkaian pengujian berubah.

## Cakupan berdasarkan kategori

| Kategori | Pustaka |
|---|---|
| **Parser / 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 |
| **Templating / 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 |
| **Utilitas / Fungsional** | 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 |
| **Akses objek** | 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 |
| **Validasi / Skema** | 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 |
| **Tanggal / waktu** | dayjs 1.11.20, date-fns 4.1.0, timeago.js 4.0.2, luxon 3.7.3, moment 2.30.2 |
| **Matematika / angka** | 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 / kripto** | 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 |
| **Pencarian / 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 / format data** | 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 |
| **String / linguistik** | 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 |
| **Kompresi / encoding / arsip** | pako 2.1.0, lz-string 1.5.0, base64-js 1.5.1, JSZip 3.10.1 |
| **Warna** | 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 |
| **Klon / kesetaraan** | rfdc 1.4.1, klona 2.0.6, fast-copy 3.0.2 |
| **Format / tampilan** | 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 |
| **Deteksi tipe / 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 / konfigurasi** | semver 7.6.3, compare-versions 6.1.1, semver-compare 1.0.0 |
| **Cache / performa** | lru-cache 11.0.2, marky 1.3.0, array-flatten 3.0.0, arr-diff 4.0.0 |
| **Asinkron / event** | 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 |
| **Status reaktif** | 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 / gaya** | postcss 8.5.7, stylis 4.3.6, css-tree 3.0.4 |
| **Build / AST / compiler** | 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 / protokol** | mqtt-packet 9.0.4 |
| **GraphQL** | graphql-js 16.11.0 |
| **Penyorotan sintaks** | highlight.js 11.11.1 |
| **Pengujian / asersi** | chai 6.2.1 |

Total: **204 pustaka** semuanya menghasilkan keluaran Node yang persis sama. Semuanya dipatok ke rilis upstream terbaru saat pembaruan terakhir.

## Cara kerjanya

Setiap skenario adalah direktori `tests/Popular/<lib>/` dengan tiga file:

```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` adalah pengujian penyedia data PHPUnit yang:

1. Memuat `lodash.js` + `runner.js` ke dalam `new Phasis\Engine()` yang baru.
2. Menangkap keluaran `console.log` ke dalam buffer.
3. Memastikan buffer yang ditangkap sama persis per byte dengan `oracle.txt`.

Buat ulang oracle dengan:

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

(Digunakan saat Anda memperbarui pustaka yang dibundel — menjalankan ulang runner di Node sungguhan dan menimpa `oracle.txt`.)

## Gerbang CI

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

Berjalan pada push dan pull request ke `main` yang mengubah `src/`, `tests/Popular/`, `phpunit.xml.dist`, file Composer atau alur kerja itu sendiri, serta saat dijalankan secara manual. Ada dua langkah:

1. **Sisi Phasis** — menjalankan rangkaian pengujian PHPUnit `popular`, yang mengeksekusi setiap pustaka melalui Phasis dan membandingkannya dengan oracle yang telah dikomit. Gagal jika ada satu byte saja yang berbeda.
2. **Verifikasi ulang Node** — menjalankan `node tests/Popular/gen-oracle.js …` untuk setiap pustaka dan memastikan oracle yang baru dibuat ulang cocok dengan yang ada di repositori. Mendeteksi perbedaan akibat "pustaka vendored diperbarui tanpa memperbarui oracle".

Keduanya harus lulus sebelum PR digabungkan. Kemenangan test262 yang merusak lodash tidak dapat diterima; kemenangan lodash yang merusak test262 juga tidak dapat diterima.

## Alasan memilih pustaka ini

- **acorn** — parsing adalah bagian paling rentan dalam engine JS mana pun. Acorn menguji setiap kasus khusus sintaksis yang ditambahkan JS modern. Jika Phasis dapat mem-parsing kode modern sembarang dengan acorn, runtime-nya andal.
- **mustache.js** — templating adalah salah satu penggunaan embedding yang secara khusus ditargetkan oleh Phasis (contoh konkret pertama dalam README adalah "mesin templating"). Mustache menguji iterasi, resolusi lingkup, dan transformasi string dalam urutan yang digunakan template sungguhan.
- **lodash** — pustaka utilitas JS yang paling banyak digunakan di dunia. Lebih dari 300 fungsinya secara transitif menyentuh setiap metode pustaka standar. Jika lodash berfungsi, JS transformasi data generik juga berfungsi.
- **marked** — perenderan markdown. Praktis dan menguji regex (banyak sekali) serta manipulasi string dengan status lintas baris. Mengungkap perbedaan engine regex antara PCRE2 (fallback milik Phasis) dan Irregexp milik V8.
- **dayjs** — aritmetika tanggal/waktu adalah sumber klasik kesalahan selisih satu yang tidak dapat ditangkap oleh kasus test262 mana pun. dayjs menguji variasi konstruktor, aritmetika melintasi batas bulan yang setara dengan DST, serta perluasan token format pada jalur kode yang kurang lebih sama dengan yang digunakan setiap pustaka tanggal JS.
- **bignumber.js** — aritmetika presisi arbitrer tanpa TypedArrays menguji parsing angka berbasis string, perulangan perkalian/pembagian bilangan besar, dan pemilihan mode pembulatan — semuanya dalam JS murni sehingga seluruh beban ditanggung engine. Mengungkap kerusakan tersembunyi dalam konversi Number ↔ String.
- **json5** — parsing JSON yang lebih longgar sangat mengandalkan regex kelas karakter dan tokenisasi berstatus. Uji penanda yang baik untuk ketepatan regex dan batas iterasi string.
- **fuse.js** — UMD hasil transpile Babel yang menguji `_classCallCheck` (pola `this instanceof Ctor` yang digunakan setiap kelas hasil transpile sebelum ES6) serta algoritme pencocokan fuzzy bitap secara lengkap. Bentuk yang digunakan setiap pustaka hasil transpile Babel, sehingga apa pun yang merusak Fuse juga merusak separuh ekosistem npm.
- **handlebars** — templating berfitur lengkap dengan kompilasi lalu perenderan. Menguji jalur runtime tanpa `eval` melalui satu entri `compile()` yang sangat besar, traversal AST, pemanggilan helper melalui tabel pencarian dinamis, dan pemeriksaan brand `SafeString` yang menggunakan `instanceof` lintas realm. Menjadi pembanding bagi penjelajah template mustache.js yang lebih sederhana.
- **zod** — validasi skema saat runtime. Hierarki kelas yang padat (`ZodString`, `ZodObject`, `ZodArray`, `ZodUnion`, …) dengan perantaian metode yang mengembalikan subkelas yang disempurnakan, pemformatan kesalahan terstruktur dengan bentuk larik `.issues` sisi JS yang harus cocok dengan Node byte demi byte, serta pola discriminator/tag literal. Menguji jenis kode validasi berat OO yang membungkus separuh aplikasi TypeScript modern.
- **typescript** — compiler TypeScript *sesungguhnya* yang berjalan di engine tertanam. Compiler minifikasi 9 MB yang mem-parsing ulang TS sembarang, menelusuri AST, dan menghasilkan JS — payload JS murni terberat yang dapat dibayangkan. Jika Phasis dapat mentranspilasi generik, async/await, enum, dan hierarki kelas dengan hasil byte demi byte yang sama dengan `tsc`, semantik bahasanya andal.
- **prettier** — formatter JS yang berpendirian kuat. Memformat JS *dengan* JS berarti setiap sudut spesifikasi yang ditangani engine disentuh oleh alur kontrol yang sama dengan yang memformat kode Anda — beban kerja yang sangat menuntut.
- **svelte/compiler** — compiler mandiri milik Svelte. Mem-parsing sumber `.svelte`, menelusuri AST, dan menghasilkan JS untuk target client dan SSR.
- **terser / @babel/parser / postcss** — minifier JS, parser JS, post-processor CSS. Puluhan ribu baris kode yang diminifikasi dan di-parse ulang dari input sembarang — area tempat bentuk AST yang langka muncul.
- **ajv** — validator skema JSON yang mengompilasi setiap skema dengan JIT menjadi fungsi validator khusus melalui `new Function(...)`. Menguji jalur konstruktor Function yang diandalkan sebagian besar pustaka skema/templat.
- **mobx** — state reaktif berbasis proxy. Setiap pembacaan observable melewati trap Proxy `get` yang mendaftarkan dependensi; setiap penulisan memicu reaksi. Uji tekanan untuk infrastruktur Proxy, Map / array / objek bertingkat yang observable, dan penjadwal autorun.
- **cheerio / htmlparser2** — jQuery sisi server yang dibangun di atas parser HTML cepat. Parsing mesin selektor, penelusuran bergaya DOM, manipulasi atribut, dan serialisasi HTML dalam satu paket.
- **graphql-js / jsonata** — implementasi referensi GraphQL dan bahasa kueri JSON. Keduanya banyak menggunakan skema, validasi, dan evaluator rekursif — kode khas "lapisan data di browser".
- **JSZip** — pembuat arsip ZIP asinkron. Mengarahkan pekerjaan melalui penjadwalan berbasis `setImmediate` dan menghasilkan keluaran biner sungguhan, menguji permukaan timer dan jalur yang banyak menggunakan `Uint8Array`.
- **moment / luxon** — aritmetika tanggal/waktu. moment adalah UMD mutable yang disetel manual; luxon adalah penulisan ulang immutable modern. Bersama-sama, keduanya mencakup seluruh permukaan pemformatan, parsing, dan aritmetika bulan/tahun yang setara zona waktu.
- **mqtt-packet** — codec MQTT JS murni 3.1.1 / 5.0. Pengemasan dan dekode tingkat byte, serta kelas karakter regex base64 non-alfabet yang menguji batas tata bahasa Annex-B.
- **xstate / valtio / nanostores / jotai / redux-saga** — ragam pengelolaan state modern. Mesin state, state proxy, penyimpanan atom, atom turunan, pelaksana efek berbasis generator — setiap pustaka menguji bentuk reaktivitas yang berbeda.
- **escodegen / acorn-walk / estraverse / magic-string** — perkakas AST. Pembuatan kode, traversal, dan pengeditan sumber tanpa merusak — blok penyusun untuk transformator JS-di-JS apa pun (alat build, codemod, linter).
- **papaparse / lunr / yaml / sax / css-tree** — parser dan tokenizer murni. CSV, indeks pencarian teks lengkap, YAML 1.2, XML bergaya SAX streaming, dan AST CSS. Tata bahasa yang berbeda, semuanya cocok untuk mendeteksi pemindaian tingkat karakter dan perilaku regex.

## Menambahkan lainnya

Tambahkan direktori baru di bawah `tests/Popular/<name>/` dengan struktur tiga file, lalu:

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

Suite PHPUnit akan menemukannya secara otomatis pada proses berikutnya, dan CI akan menyertakannya karena perubahan menyentuh `tests/Popular/`.

Kandidat kuat yang layak ditambahkan: `chevrotain` (parser combinator, menguji closure + regex), `nanoid` (batas kriptografi/keacakan), `date-fns` (cakupan zona waktu di luar dayjs).
