Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
316 commits
Select commit Hold shift + click to select a range
7875bbf
docs(router): mark F7/F10 complete in §7 progress + traceability matrix
parkrevil Apr 28, 2026
8a97815
refactor(router): stage A4 — sealed/built helpers, prefix cleanup, bu…
parkrevil Apr 28, 2026
14a3f23
docs(router): mark F8(reg)/F18/F22 complete in §7 + matrix (A4 follow…
parkrevil Apr 28, 2026
44e66f9
docs(router): align F22 finding + A4 prescription with empirical hot-…
parkrevil Apr 28, 2026
dc4683c
refactor(router): stage A5 — wildcard-name conflict scoped to method …
parkrevil Apr 28, 2026
8b0742a
docs(router): mark F9 complete in §7 + matrix (A5 follow-up)
parkrevil Apr 28, 2026
51aed28
test(router): add cross-method static/wildcard coexistence spec (A5 f…
parkrevil Apr 28, 2026
31c9759
docs(router): record A5-fix (51aed28) static/wildcard spec in §7
parkrevil Apr 28, 2026
d64863f
refactor(router): stage A6 — MethodRegistry.getCodeMap() (F11)
parkrevil Apr 28, 2026
76f31cb
docs(router): mark F11 complete + entire stage A done in §7
parkrevil Apr 28, 2026
b5c7198
test(router): assert wildcardNamesByMethod is frozen too (A6 follow-up)
parkrevil Apr 28, 2026
e533620
refactor(router): stage B1 — extract Registration into pipeline/regis…
parkrevil Apr 29, 2026
f1ae517
docs(router): mark B1 complete in §7
parkrevil Apr 29, 2026
ea9e587
test(router): repair vacuous wildcardNamesByMethod freeze assertion (…
parkrevil Apr 29, 2026
01686c6
refactor(router): stage B2 — extract Build into pipeline/build + shar…
parkrevil Apr 29, 2026
921101a
docs(router): mark B2 complete in §7
parkrevil Apr 29, 2026
8648b64
refactor(router): convert Build class to function + doc internal/ + B…
parkrevil Apr 29, 2026
f0fd139
refactor(router): stage B3 — extract codegen into codegen/emitter (F1…
parkrevil Apr 29, 2026
6c185cd
docs(router): mark B3 complete + F2 partial in §7
parkrevil Apr 29, 2026
e734e63
refactor(router): drop dead identity normalizePath fallback (B3 follo…
parkrevil Apr 29, 2026
02fddc6
refactor(router): stage B4 — extract MatchLayer (cold-path only) (F1)
parkrevil Apr 29, 2026
b779487
docs(router): mark B4 complete + record scope deviation in §3 B4 step
parkrevil Apr 29, 2026
553bc42
refactor(router): stage B5 — strip Router to a thin facade (F1)
parkrevil Apr 29, 2026
c37ebf4
docs(router): mark B5 complete + entire stage B done in §7
parkrevil Apr 29, 2026
b09d231
docs(router): align §5 directory structure with B5 deviation
parkrevil Apr 29, 2026
35f480c
refactor(router): stage C1 — codegen alignment (move + escape policy …
parkrevil Apr 29, 2026
caefda8
docs(router): mark C1 complete + record F16 fresh-counter scope decision
parkrevil Apr 29, 2026
d45cb68
docs(codegen): tighten escape.ts docstring (C1 follow-up)
parkrevil Apr 29, 2026
c38b686
refactor(router): apply escapeJsString to segment-walk codegen sites …
parkrevil Apr 29, 2026
5f3a652
refactor(router): drop 4 gratuitous indirections (escapeJsString / Re…
parkrevil Apr 29, 2026
ac025b5
docs(router): record 5f3a652 cleanup in §5 + §7 + matrix
parkrevil Apr 29, 2026
e91ff1c
refactor(router): unexport MatchLayerDeps + scrub stale escapeJsStrin…
parkrevil Apr 29, 2026
4db5e89
refactor(router): stage C2 — extract walker-strategy.ts (F12 partial)
parkrevil Apr 29, 2026
caf078c
docs(router): mark C2 complete + entire stage C done in §7
parkrevil Apr 29, 2026
469425f
refactor(codegen): drop unused WalkerStrategy enum + tidy emitter imp…
parkrevil Apr 29, 2026
5ecbe14
perf(matcher): extract tryMatchParam helper from recursive walker (D1…
parkrevil Apr 29, 2026
b9548ec
docs(router): mark D1 (F17) complete in §7 + matrix
parkrevil Apr 29, 2026
df662e7
docs(matcher): JSDoc on tryMatchParam (D1 follow-up)
parkrevil Apr 29, 2026
3edcdd4
docs(matcher): fix tryMatchParam JSDoc closure list (D1 follow-up²)
parkrevil Apr 29, 2026
19c49ed
docs(router): stage D2 — full bench diff vs baseline (all 4 sources)
parkrevil Apr 29, 2026
413ae40
docs(router): mark D1+D2 follow-ups + entire stage D complete in §7
parkrevil Apr 29, 2026
c8cde92
refactor(router): E1+E2 — fix types→matcher layering, pin public API
parkrevil Apr 29, 2026
7242618
docs(router): correct E2 test-count delta (573→576, not 576→579)
parkrevil Apr 29, 2026
79e432b
refactor(router): arrow methods + closure capture + freeze + drop cle…
parkrevil Apr 29, 2026
2a6fa37
docs(router): rewrite README to match current code surface
parkrevil Apr 29, 2026
94882a5
chore(router): add verification reproducers
parkrevil May 1, 2026
caead8d
feat(router): ensure build atomicity and state integrity via undoLog …
parkrevil May 1, 2026
5e90768
refactor(router): eliminate dead code and unreachable branches
parkrevil May 1, 2026
2059283
refactor(router): enhance encapsulation and optimize data structures
parkrevil May 1, 2026
0643c35
feat(router): enforce strict snake_case/camelCase parameter naming
parkrevil May 1, 2026
c648e49
perf(router): add regression guards and optimize terminals
parkrevil May 1, 2026
036172a
perf(router): optimize miss cache eviction
parkrevil May 1, 2026
87486ba
perf(router): implement ultimate Bun/JSC optimizations
parkrevil May 1, 2026
77c23f6
perf(router): achieve 14ns matching via offset-based traversal and mo…
parkrevil May 1, 2026
e3fb72e
docs(router): finalize ULTIMATE.md blueprint with measurement-driven …
parkrevil May 6, 2026
97b866d
docs(router): patch ULTIMATE.md with measured findings + add POC harn…
parkrevil May 7, 2026
dd0f9d6
feat(router): reject empty/non-token method names and unsafe path bytes
parkrevil May 7, 2026
d78d65e
test(router): split secure-profile fixtures into per-policy files
parkrevil May 7, 2026
b0d93f0
feat(router): expand secure-profile validation across types, options,…
parkrevil May 7, 2026
a8ff8aa
feat(router): emit option-invalid, path-empty-segment, path-too-long,…
parkrevil May 7, 2026
419d387
feat(router): wire profile/trailingSlash/pathCaseSensitive and per-bu…
parkrevil May 7, 2026
4d434ec
feat(router): split policy modules and honour the compat profile
parkrevil May 7, 2026
0704fd3
feat(router): align public surface with the documented spec
parkrevil May 7, 2026
775ca45
feat(router): runtime secure path scanner
parkrevil May 7, 2026
ea7d032
feat(router): single-factory match path with clone-on-cache-hit params
parkrevil May 7, 2026
25c1934
router: wildcard prefix index + identity registry (P4)
parkrevil May 7, 2026
d9333c7
router: typed undo records, static-by-method, static-first match, cod…
parkrevil May 7, 2026
b2efbfc
router: post-seal single-static-chain compaction (P7)
parkrevil May 7, 2026
36ebf7e
router: external/Bun.serve baseline phase split + capability matrix (P8)
parkrevil May 7, 2026
8274ca8
router: external baseline correctness gate + wrong-method axis (P8)
parkrevil May 7, 2026
1caf5b1
router: final gate measurement report (P9)
parkrevil May 7, 2026
a08b422
router: rewrite comparison bench for apples-to-apples adapter sanity
parkrevil May 7, 2026
76140a3
router: drop runtime path scanner + restore single-method fast path
parkrevil May 7, 2026
94d65e9
router: closure-capture per-method walker for single-method dispatch
parkrevil May 8, 2026
9cf3738
router: Infinity option guard + match-state size from option + per-pa…
parkrevil May 8, 2026
becd567
router: inline single-static-child cache on SegmentNode (M4 / Phase 7…
parkrevil May 8, 2026
1f889e6
perf(router): pack terminal metadata into Int32Array slab
parkrevil May 8, 2026
91d3703
perf(router): canonical-path peek before normalization
parkrevil May 8, 2026
e474651
perf(router): apply verified Bun-best techniques (Tier A)
parkrevil May 8, 2026
e065851
perf(router): static-first ordering + offset-based singleChildKey probe
parkrevil May 8, 2026
c842f4a
perf(router): freeze cached params on write, return reference on hit
parkrevil May 8, 2026
2a42dad
perf(router): drop runtime query strip and length guards
parkrevil May 8, 2026
ef2589e
refactor(router): apply E-sweep P0 cleanups
parkrevil May 8, 2026
6311b21
feat(router): tighten build-time RFC validation
parkrevil May 8, 2026
9d5347d
fix(router): emit `optional-expansion-limit` for 2^N expansion cap
parkrevil May 8, 2026
2cd30de
perf(router): prune snapshot of build-only structures
parkrevil May 8, 2026
c0c86e3
perf(router): auto Bun.shrink() + compactMemory() for RSS reclaim
parkrevil May 11, 2026
9e497c9
perf(router): drain build transients every 10k routes
parkrevil May 11, 2026
c35a199
refactor(router): drop process.env / globalThis defense for Bun-nativ…
parkrevil May 11, 2026
0f9a5cd
perf(router): drop undo log at every successful build-chunk boundary
parkrevil May 11, 2026
d5a9be0
perf(router): trim 3 sparse PrefixTrieNode fields into WeakMaps
parkrevil May 11, 2026
412a693
perf(router): tenant-prefix factor + auto-compact + first-call tier-up
parkrevil May 11, 2026
d60a2a6
perf(router): only auto-compact when factor was applied
parkrevil May 11, 2026
dc6582c
perf(router): drop factor probe from non-factored iterative walker scope
parkrevil May 11, 2026
d8cd949
docs(router): explain leafStoreOf depth bound = MAX_SEGMENTS
parkrevil May 11, 2026
f3207f2
fix(router): emitter cleanup — drop var redeclaration + record real w…
parkrevil May 12, 2026
ed67ee2
perf(router): codegen NaN check via self-compare instead of isNaN()
parkrevil May 12, 2026
94b02f9
refactor(router): drop deprecated Bun.shrink, keep Bun.gc(true)
parkrevil May 12, 2026
dbd264d
refactor(router): make compactMemory internal, drop from public API
parkrevil May 12, 2026
f3138c4
refactor(router): drop compactMemory entirely — libpas scavenger hand…
parkrevil May 12, 2026
5ea7727
chore(router): drop unused factorApplied flag
parkrevil May 12, 2026
71df0f5
chore(router): drop dead aliasJournal + bench wait 400ms→800ms
parkrevil May 12, 2026
0d0769b
chore(router): drop unused ParamMetadata interface
parkrevil May 12, 2026
42c9c54
chore(router): purge unused exports across modules
parkrevil May 12, 2026
b1fb276
fix(router): avoid spread-arg cap when re-seeding pendingRoutes
parkrevil May 12, 2026
4c54bd7
chore(router): demote ShapeTelemetry to file-local
parkrevil May 12, 2026
0cc2028
refactor(router): drop dead routeOptions infrastructure
parkrevil May 12, 2026
0fa4212
perf(router): method dispatch + build cleanups (measured)
parkrevil May 12, 2026
978cdf5
perf(router): 3 measured method-domain wins
parkrevil May 12, 2026
5c87746
perf(router): swap-on-restore + tchar lookup table
parkrevil May 12, 2026
063695a
perf(router): inline charCodeAt scan beats indexOf on short paths
parkrevil May 12, 2026
ee45f75
bench(router): segment-walker depth probes (S, T, U)
parkrevil May 12, 2026
bec0c97
bench(router): recursion vs iterative + insert cost probes (V, W)
parkrevil May 12, 2026
12e513b
perf(router): drop remaining closure-based undo entries
parkrevil May 12, 2026
5f835ee
bench(router): subtree-shape cost probe (X)
parkrevil May 12, 2026
248d9e2
bench(router): codegen quality + cumulative probes (Y, Z, AA, BB, CC,…
parkrevil May 12, 2026
5ebd5a3
perf(router): codegen emitter charCodeAt scan for slash locator
parkrevil May 12, 2026
29610c3
chore(router): drop dead exports + redundant re-export module
parkrevil May 12, 2026
55dbf27
chore(router): drop dead per-shape codegen-disable feedback path
parkrevil May 12, 2026
a730a8d
chore(router): drop dead OptionalParamDefaults methods
parkrevil May 12, 2026
c753329
chore(router): drop dead surface across the audit findings
parkrevil May 12, 2026
82a250e
chore(router): repair stale bench/test references found by full audit
parkrevil May 12, 2026
5d047f3
fix(router): land risky audit items behind a single defaults source
parkrevil May 12, 2026
e2f5459
revert(router): drop ROUTER_DEFAULTS — restore inline option defaults
parkrevil May 12, 2026
2bd6125
chore(router): drop confirmed-dead defensive checks
parkrevil May 12, 2026
6f32193
refactor(router): inline single-call wrappers + drop validateOptions
parkrevil May 12, 2026
e6d5436
chore(router): drop dead 'option-invalid' kind + retyping cast
parkrevil May 12, 2026
6c605ed
chore(router): drop more dead surface uncovered by line-by-line audit
parkrevil May 12, 2026
677b6cf
chore(router): drop more uncovered dead in segment-tree + registration
parkrevil May 12, 2026
b3d4f7d
chore(router): collapse repeated planAndCommit fail-path + drop dead …
parkrevil May 12, 2026
faf23a3
refactor(router): drop maxParams option + derive paramOffsets at buil…
parkrevil May 13, 2026
0082994
refactor(router): drop maxPathLength/maxSegmentLength/maxSegmentCount…
parkrevil May 13, 2026
d935a80
chore(router): drop unused MatchConfig import in walker-strategy
parkrevil May 13, 2026
6cedaed
refactor(router): drop maxOptionalExpansions / maxExpandedRoutes / ma…
parkrevil May 13, 2026
2e83474
refactor(router): drop dead Result wrapper from expandOptional
parkrevil May 13, 2026
f429f73
refactor(router): drop unused telemetry + diagnostic surfaces
parkrevil May 13, 2026
71474db
bench(router): add first-call latency probe + verify warmup is load-b…
parkrevil May 13, 2026
304fa9f
refactor(router): drop unmeasurable MAX_FANOUT cap + collectWarmupPat…
parkrevil May 13, 2026
e9fcf8d
perf(router): drop missCache — measured net-negative across all workl…
parkrevil May 13, 2026
ecf340c
perf(router): replace subtreeShape string hash with direct structural…
parkrevil May 13, 2026
5dc06bf
perf(router): replace path.split('/') with manual charCodeAt scan in …
parkrevil May 13, 2026
0c26573
perf(router): skip segments.join('/') when normalized path already ca…
parkrevil May 13, 2026
4833f39
perf(router): inline factoryCache key build, drop intermediate map+join
parkrevil May 14, 2026
3ea590f
perf(router): pchar grammar lookup table replaces 8-branch char check
parkrevil May 14, 2026
858865d
perf(router): fast-path expandOptional when no optional segments
parkrevil May 14, 2026
ffa06ff
perf(router): pre-allocate per-method hitCache at build
parkrevil May 14, 2026
b5f6715
refactor(router): drop dead `tr0 !== null` ternary in single-method emit
parkrevil May 14, 2026
40b02af
refactor(router): drop dead `factory !== undefined` check
parkrevil May 14, 2026
1c40c21
refactor(router): skip trailing-slash recheck emit when trimSlash is on
parkrevil May 14, 2026
ed2c429
refactor(router): drop dead lazy hc-init branch in emitter
parkrevil May 14, 2026
e3c14ff
perf(router): apply tenant-factor under single-static-chain root prefix
parkrevil May 14, 2026
f26f669
perf(router): multi-prefix factor for root.staticChildren with multip…
parkrevil May 14, 2026
7dd7c92
perf(router): collapse per-variant paramsFactories into one super-fac…
parkrevil May 14, 2026
50b92bf
feat(router): cap optional-segment count per route at 4
parkrevil May 14, 2026
50ae4a7
test(router): bench harnesses for optional cap N decision
parkrevil May 14, 2026
46593b0
fix(router): rollback presentBitmaskByTerminal + multi-prefix factor …
parkrevil May 14, 2026
7fab673
fix(router): subtreeShapesEqual must compare terminal-store presence
parkrevil May 14, 2026
eb2c345
test(router): regression + walker-tier coverage for final-review fixes
parkrevil May 14, 2026
89868e5
test(router): full RouterErrorKind reproducer + percent-decode + inte…
parkrevil May 15, 2026
a940370
test(router): leafStoreOf + factor-detect edge branches
parkrevil May 15, 2026
4b4219f
test(router): close codex STILL_OPEN coverage gaps (wildcard %2F + 3-…
parkrevil May 15, 2026
bb54179
fix(router): leafStoreOf rejects multi-terminal subtree + cacheSize v…
parkrevil May 15, 2026
dcf4c83
fix+test(router): close codex 3rd-pass STILL_OPEN findings
parkrevil May 15, 2026
e4c09ab
docs(router): correct cache semantics in README (AUDIT4-004)
parkrevil May 15, 2026
ef89d07
test(router): cover route-parse suggestion branches (AUDIT4-007)
parkrevil May 15, 2026
5b54ee5
test(router): stress + lifecycle + recursive walker fixtures
parkrevil May 15, 2026
f5d185c
fix+docs(router): AUDIT5 pass — empty path guard + build cleanup + RE…
parkrevil May 15, 2026
537d3f9
chore(router): purge ad-hoc bench probes, retain only regression-guar…
parkrevil May 15, 2026
cd0faf9
fix(router): routeConflict.conflictsWith no longer reports the method…
parkrevil May 15, 2026
37920ec
refactor(router): split segment-walk.ts into per-tier walker modules …
parkrevil May 15, 2026
569481a
refactor(router): extract super-factory codegen into src/codegen/supe…
parkrevil May 15, 2026
e02a877
refactor(router): split segment-tree.ts by responsibility (817 → 348 …
parkrevil May 15, 2026
46ccef8
refactor(router): F8/F9 — collapse matcher→codegen leak + drop undo s…
parkrevil May 15, 2026
c6a12cb
refactor(router): extract terminal-slab packing + wildcard-method exp…
parkrevil May 15, 2026
c77e647
refactor(router): hoist segment-tree data model into neutral src/tree/
parkrevil May 15, 2026
8d47e52
refactor(router): enforce barrel exports + collapse cross-layer dead …
parkrevil May 15, 2026
f09afd2
refactor(router): decompose compileMatchFn + Registration.seal monoliths
parkrevil May 15, 2026
7ba3e29
refactor(router): hoist runtime contract types to break codegen↔match…
parkrevil May 15, 2026
a521d46
chore: stop tracking .claude/scheduled_tasks.lock (runtime artifact)
parkrevil May 15, 2026
19aa8d5
chore: untrack .claude/scheduled_tasks.lock runtime artifact
parkrevil May 15, 2026
1341c2b
refactor(router): drop dead code + prune barrel re-exports + tighten …
parkrevil May 15, 2026
435a6d7
refactor(router): decompose Router constructor (171 LOC → 50 LOC orch…
parkrevil May 15, 2026
a3dd132
refactor(router): extract attachWildcardTail/attachTerminal from plan…
parkrevil May 15, 2026
d99965f
refactor(router): split insertIntoSegmentTree by part type (231 LOC →…
parkrevil May 15, 2026
1dbb382
refactor(router): split compileDynamicRoute (120 LOC → 38 LOC orchest…
parkrevil May 15, 2026
60ecc25
refactor(router): split 4 build-time monoliths (parse/expand/regex/co…
parkrevil May 15, 2026
ac1942e
refactor(router): decompose all 5 walker bodies + emitNode (perf pres…
parkrevil May 15, 2026
118b485
refactor(router): tighten policy — drop runtime lenience, reject sile…
parkrevil May 15, 2026
3cbaf58
docs+refactor(router): align README with current policy + purge resid…
parkrevil May 16, 2026
56749e3
test(router): add factored-walker shape coverage spec
parkrevil May 16, 2026
52fc03d
refactor(router): purge unreachable walkSharedSubtree branches
parkrevil May 16, 2026
6843ddb
refactor(router): purge dead branches in factor-detect and traversal …
parkrevil May 16, 2026
12b8f57
refactor(router): drop LEAF_STORE_MAX_DEPTH cap + centralize undo casts
parkrevil May 16, 2026
2ee3bf1
test(router): consolidate helpers + tighten assertions + fix misleadi…
parkrevil May 16, 2026
3cfecac
test(router): rename _helpers → test-utils + add direct helper unit s…
parkrevil May 16, 2026
e99a88c
test(router): add direct unit specs for state-heavy + emit helpers
parkrevil May 16, 2026
6d20099
refactor(router): align validation policy + RFC 3987 IRI + uniform er…
parkrevil May 16, 2026
a662c1a
perf(router): skip duplicate post-normalize bucket probe when sp===path
parkrevil May 16, 2026
6db23a0
docs(router): update bench tables for Opt-A measurements
parkrevil May 16, 2026
bd080d5
perf(router): first-char switch dispatch for sibling-dense static chi…
parkrevil May 16, 2026
15496d8
perf(router): rebind match() directly to compiled impl after build
parkrevil May 16, 2026
6c66451
perf(router): activeMethodMask short-circuits wrong-method in one branch
parkrevil May 16, 2026
d10c04c
perf(router): root-first-char mask skips walker call on guaranteed miss
parkrevil May 16, 2026
ef904ec
perf(router): emit string-switch over active method names (multi-method)
parkrevil May 16, 2026
b0ce7c2
perf(router): move root-mask gate before hit-cache probe
parkrevil May 16, 2026
4473ccb
docs(router): reflect 17/23 1st-place baseline + add solo bench
parkrevil May 16, 2026
ebb6b98
perf(router): drop unused factory args after string-switch dispatch
parkrevil May 16, 2026
04b3657
perf(router): switch on method.charCodeAt(0) instead of string switch
parkrevil May 16, 2026
9571c67
docs(router): final baseline after Try G/J — 16-17/23 1st + memoirist…
parkrevil May 16, 2026
4ce3717
perf(router): wrapper-split matchImpl for multi-method dispatch
parkrevil May 17, 2026
0362dea
docs(router): wrapper-split closes wrong-method gap to memoirist floor
parkrevil May 17, 2026
a7f856d
perf(router): method.length bitmask gate before charCode switch
parkrevil May 17, 2026
f34d581
perf(router): defer param offset writes until terminal success
parkrevil May 17, 2026
bc6eadb
docs(router): expand solo bench to 23 scenarios + record post-deferra…
parkrevil May 17, 2026
801113b
perf(router): per-method dispatch table for multi-method matchImpl
parkrevil May 17, 2026
2a1826e
perf(router): store method codes in table, call matchActive directly
parkrevil May 17, 2026
0e7524e
docs(router): record post-Option-A baseline + 5-run probe medians
parkrevil May 17, 2026
0dcb33c
docs(router): record direct 100k zipbul vs memoirist measurement
parkrevil May 17, 2026
4bba75e
perf(router): path-first static lookup table (multi-method only)
parkrevil May 17, 2026
6262137
docs(router): record post-path-first 15/23 1st baseline
parkrevil May 17, 2026
263a070
chore(router): drop internal subpath from publish exports
parkrevil May 17, 2026
d219e70
docs(router): consumer-facing README review (Codex line-by-line)
parkrevil May 17, 2026
0678ca2
docs(router): second-pass README polish (typos + table escapes + cons…
parkrevil May 17, 2026
5141c5f
docs(router): IRI fix + GitHub admonitions + TOC + horizontal rules
parkrevil May 17, 2026
49e9511
chore(router): bench audit, harness fixes, full-pair process isolation
parkrevil May 18, 2026
2b26272
chore(toolkit): lint/format/dead-code stack + router lint compliance
parkrevil May 18, 2026
c50596f
chore(router): upgrade lint stack to latest + delete RELEASE_GATE.md
parkrevil May 18, 2026
df66353
chore(router): remove 17 unused exports (knip clean)
parkrevil May 18, 2026
85ca2ad
docs(router): README deep-review pass (Korean grammar + accuracy fixes)
parkrevil May 18, 2026
c8ff7c9
docs(router): publish real bench numbers + README perf rewrite
parkrevil May 18, 2026
70e377b
docs(router): fix Korean particle spacing in perf intro
parkrevil May 18, 2026
960d22d
docs(router): tighten Bun-only framework references + clarify meta.so…
parkrevil May 18, 2026
53e436a
refactor(router)!: convert all string literal unions to enums
parkrevil May 19, 2026
d734574
fix(router): post-enum-refactor leftover string literals
parkrevil May 19, 2026
ce12271
docs(router): README options block uses enums (not literals)
parkrevil May 19, 2026
2251c2b
refactor(router)!: 2-state enums -> boolean (TrailingSlash, OptionalP…
parkrevil May 19, 2026
f938797
test(router): align describe/it text with new boolean option names + …
parkrevil May 19, 2026
c990e6d
chore: move ULTIMATE.md from packages/router/ to top-level knoldr/
parkrevil May 19, 2026
033e10d
docs(router)!: strip all source comments; rewrite JSDoc only on publi…
parkrevil May 19, 2026
815fe71
fix(router): resolve 12 defects from round-4 line-by-line audit
parkrevil May 19, 2026
d89a2c0
refactor(router): drop explicit UndoKind values; let TS auto-number
parkrevil May 19, 2026
6bb82a9
refactor(router): cleanup 5 of 6 audit findings; bench any/as left as-is
parkrevil May 19, 2026
a1c5eda
test(router): fix typo "should cap honor" -> "should honor" in route-…
parkrevil May 19, 2026
8f77a9f
fix(router): correct case-insensitive matching, switch build to bunup…
parkrevil May 22, 2026
b9dd2e9
test(router): adopt stryker mutation testing; close pattern-tester bo…
parkrevil May 25, 2026
029c30c
test(router): close boundary/capacity assertion gaps found by mutatio…
parkrevil May 25, 2026
7fcfe21
test(router): close factor-detect tenant-factor pattern gap found by …
parkrevil May 25, 2026
b7bdf2a
Merge branch 'main' into feat/router
parkrevil May 25, 2026
562b9c0
fix(repo): regenerate bun.lock after main merge (remove conflict mark…
parkrevil May 25, 2026
e96e7f5
test(router): close per-file coverage gaps so CI coverage gate passes
parkrevil May 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions .changeset/router-bench-audit-and-isolation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
"@zipbul/router": patch
---

Bench audit, lint/format tooling setup, router lint compliance, circular-dep removal. **No published API change** — `dist/` is unaffected; consumers see no behavioral difference.

## Part 1 — Bench audit & harness fixes (line-by-line + Codex/Explore second-opinion)

### Measurement correctness (output was lying)

- `router.bench.ts`: removed non-existent `enableCache`, `ignoreTrailingSlash`, `caseSensitive` options (silently ignored by `RouterOptions`). The cache-hit vs no-cache and case-insensitive benches were measuring nothing of the kind; sections deleted. `fullOptionsRouter` now uses the real options (`trailingSlash: 'ignore'`, `pathCaseSensitive: false`). Static-match 10/100/500/1000 collapsed to a single hash-bucket bench (all four are O(1) static-bucket lookups; the four-row scaling was misleading).
- `100k-verification.ts`: `100k churn` scenario removed — hit/miss paths were fixed strings, defeating the advertised "unique-path churn" intent. Real churn measurement already lives in `cacheTraversalFeasibility()`. `100k-gate-runner.ts` scenarios list updated.
- `complex-shapes.bench.ts`: `regex` shape now skips memoirist with `regex: null` (was registering a tester-less variant under the "regex (testers)" label — apples-to-oranges vs zipbul). Label corrected from "2 testers" to "3 testers".
- `comparison.bench.ts`: `miss` scenario's `wrongMethod` axis now hits a registered path; the previous unregistered path collapsed wrong-method into the plain miss axis.
- `regression-snapshot.ts`: `p99NsPerOp` JSON field renamed to `maxNsPerOp`. With TRIALS=11 the nearest-rank p99 index lands on the max sample.

### Statistical honesty

- `helpers.ts` `percentile()`: docstring warns small-N inputs collapse p75/p99 to max. `100k-gate-runner.ts`, `100k-external-baselines.ts`: `buildP75/P99` collapsed to `buildMax`. `100k-bun-serve-baseline.ts`: `warmedP99` removed.
- `first-call-latency.ts`: replaced local `Math.floor(n*0.99)` with shared `percentile()`.

### Methodology consistency

- `100k-external-baselines.ts`: `find-my-way` adapter uses `{ ignoreTrailingSlash: true }` matching `100k-external-correctness.ts`. `settleScavenger()` called before `mem()` baseline.
- `100k-verification.ts`: removed `candidateMicrobench()` and `tryUrlPatternBaseline()` (didn't measure zipbul Router).

### Cross-router fairness — full pair isolation

- `comparison.bench.ts`: 7 adapters × 7 scenarios = **49 fresh-process pairs**. Worker takes `argv = [adapter, scenarioLabel]`. Sanity-gate failures print structured reasons.
- `complex-shapes.bench.ts`: 3 routers × 11 shapes = **33 fresh-process pairs** with per-shape build functions (no JIT pollution from sibling shapes). Unsupported pairs print `skip=true reason=unsupported`.

### Dead-code purge

- Deleted `bench/comparison-solo.bench.ts`, `bench/baseline/percent-gate.bench.txt`.
- Removed unused `supports` field, `skipFor` parameter in `100k-external-correctness.ts`.
- Removed unused devDependencies `@hattip/router` and `itty-router` (referenced only by since-deleted benches).

### Walker-fallback bench note

`walker-fallbacks.bench.ts`: header note that the three benches measure each walker on the workload that triggers its selection — route counts and match paths differ, so the timings are per-walker sanity numbers, not cross-walker comparisons.

## Part 2 — Lint/format/dead-code tooling (toolkit-wide)

Copied from `zipbul/` sibling repo for consistency with the broader Zipbul ecosystem standards. All configs at toolkit root (`.oxlintrc.jsonc`, `.oxfmtrc.jsonc`, `knip.json`). Root `package.json` scripts: `typecheck`, `lint`, `format`, `format:check`, `knip`, `dpdm`. devDependencies pinned to versions matching the sibling repo (`oxlint@^1.41.0`, `oxlint-tsgolint@^0.11.1`, `oxfmt@^0.26.0`, `knip@^5.63.1`, `dpdm@^4.2.0`).

### tsconfig stricter (`toolkit/tsconfig.json`)

`noUnusedLocals`, `noUnusedParameters`, `noPropertyAccessFromIndexSignature` all enabled (was `false`). Router passes cleanly.

### Sensible overrides (`.oxlintrc.jsonc`)

- `packages/router/bench/**/*.ts`: `no-explicit-any`, `no-loop-func`, `import/no-dynamic-require`, `default-case` off. Adapter testing against 7 external routers with disparate return shapes requires loose typing; per-shape `Shape` union switches use exhaustive type-narrowing that TypeScript verifies.
- `**/*.spec.ts`/`**/*.test.ts`: `no-explicit-any` off (intentional `any` for type-error coverage); `jest/no-conditional-in-test` off (Result-type narrowing `if (err.data.kind === 'X')` is legitimate TypeScript narrowing, not a test antipattern).

### Router exports-last refactor (12 files)

All `export function`/`export interface`/`export class` declarations moved to a single bottom `export { ... }` / `export type { ... }` block per file. Files touched: `pattern-tester.ts`, `path-policy.ts`, `wildcard-method-expand.ts`, `emitter.ts`, `prefix-factor.ts`, `factor-detect.ts`, `path-parser.ts`, `route-expand.ts`, `wildcard-prefix-index.ts`, `router.ts`, `pipeline/registration.ts`, `codegen/segment-compile.ts`, `tree/segment-tree.ts`.

### Circular dependency removal

Extracted `SegmentNode` + `ParamSegment` interfaces from `src/tree/segment-tree.ts` into a new `src/tree/node-types.ts`. `segment-tree.ts` now imports the types from `./node-types` and re-exports them; `undo.ts` also imports from `./node-types`. Eliminates the type-only `segment-tree → undo → segment-tree` cycle that `dpdm` flagged.

### Test/spec import dedup

- `src/builder/path-parser.spec.ts`, `src/builder/route-expand.spec.ts`, `src/router.spec.ts`: merged duplicate inline imports (one at top, one mid-file) into single top imports — fixes `import/no-duplicates` and `import/first`.

### Format pass

`oxfmt` applied to every `.ts`, `.md`, `.json` in the monorepo. 204 files reformatted (printWidth 130, trailingComma all, sorted package.json scripts, sorted imports per group).

## Verification

- `bunx tsc --noEmit -p packages/router/tsconfig.json` — 0 errors.
- `bun test` (router-scoped) — 999 pass / 0 fail / 9533 expects.
- `bunx oxlint packages/router` — 0 warnings / 0 errors.
- `bunx dpdm packages/router/src/**/*.ts packages/router/index.ts` — no circular dependencies.
- Bench worker smoke runs confirmed for `comparison.bench.ts`, `complex-shapes.bench.ts`, `cache-cardinality.bench.ts`, `walker-fallbacks.bench.ts`, `first-call-latency.ts`, `regression-snapshot.ts`, `router.bench.ts`, `100k-verification.ts`, `100k-external-correctness.ts`. `100k-gate-runner.ts` regex parser still matches `100k-verification.ts` output format.

## Known follow-ups (out of router scope)

- `cors`, `multipart`, `rate-limiter`, `result`, `query-parser` still have lint violations (53 errors total across those packages). Pre-existing; not addressed in this PR. Tracking separately.
- `knip` reports ~11 router exports + 9 router types as unused outside their own file. Most are internal helpers (`flushStaticBuffer`, `emitParamBranch`, etc.) — safe to delete or keep as internal-API surface. Decided not to remove now to avoid scope creep.
- Pre-existing stale `dist/` artifacts in `packages/result` and `packages/shared` cause 26 cross-package test failures when running `bun test` from monorepo root. Unrelated; tracked separately.
24 changes: 24 additions & 0 deletions .changeset/router-build-fix-and-match-correctness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
"@zipbul/router": minor
---

Fix a broken published build and several match-time correctness defects.

## Build

- **Fixed a broken build configuration.** The `bun build --packages external` + `sideEffects: false` combination triggered a Bun bundler bug (oven-sh/bun#18008) that emitted an 84-byte stub re-exporting undeclared identifiers — the produced `dist` could not be imported. The build now uses `bunup` (Bun-native library bundler), emitting a working ESM bundle, a `.d.ts`, and a linked source map. `sideEffects: false` was removed (it provides no benefit for a server-side library and was the bug trigger).

## Match-time correctness

- **`:param` immediately followed by a `*name` star wildcard now matches an empty tail.** `/:p/*rest` against `/x` now returns `{ p: 'x', rest: '' }` (previously `null`). The compiled match function diverged from the reference walkers on this shape.
- **Case-insensitive matching (`pathCaseSensitive: false`) no longer mutates captured values.** Case-folding now applies to route selection only; captured `:param` and `*wildcard` values keep their original case (e.g. `/Users/:id` + `/USERS/AbC` → `{ id: 'AbC' }`, previously `'abc'`). Folding is now ASCII-only (length-preserving) instead of `String.toLowerCase()`: a captured value containing a length-changing non-ASCII char (e.g. `İ`, whose `toLowerCase()` is two code units) no longer corrupts the capture offsets (`/:id/x` + `/İ/x` → `{ id: 'İ' }`, previously `{ id: 'İ/' }`). Since URL paths are ASCII (RFC 3986; non-ASCII arrives percent-encoded), ASCII folding is complete.
- **Case-insensitive hit cache no longer serves stale captures.** The dynamic-match cache was keyed on the case-folded path, so two case-variant inputs (`/u/AbC`, `/u/aBc`) collapsed to one entry and the second returned the first's captured value. The cache is now keyed on the non-folded (but still trailing-slash-trimmed) path, so each case-variant keeps its own capture while same-path and trailing-slash-variant inputs still cache-hit.
- **Regex param fast-path no longer over-matches.** `:id(\w+)` (and `\w{1,}`) now correctly rejects hyphens, matching the actual `\w` semantics.
- **Optional + regex params are now supported.** `:id(\d+)?` builds and matches (`/x/42` → `{ id: '42' }`, `/x` absent, `/x/abc` no match); previously rejected with a misleading `path-query` error.
- **Non-ASCII HTTP method tokens are now rejected** with `method-invalid-token` (RFC 7230/9110 token grammar is ASCII-only); previously accepted.
- **A raw `?` in a non-param segment is now rejected** (`/a?` → `path-query`); the `?` optional decorator is accepted only on param segments.

## Internal

- Removed dead code: the unused `OptionalParamDefaults` class, `MethodRegistry.get()`/`size`, and the unreachable nullable-value path in the hit cache.
- Per-route build rollback now restores `maxParamsObserved`.
47 changes: 47 additions & 0 deletions .changeset/router-options-enum-to-boolean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
"@zipbul/router": major
---

BREAKING: collapse two 2-state public enums into booleans on `RouterOptions`.

The `TrailingSlash` and `OptionalParamBehavior` enums each had only two
members. They were boolean choices dressed up as enums — the internal
pipeline already converted both to booleans before consuming them
(`router.ts:95`, `build.ts:106`). Replacing the enums with booleans
removes ceremony from every call site without changing runtime behavior.

### Migration

```ts
// Before
import { Router, TrailingSlash, OptionalParamBehavior } from '@zipbul/router';
new Router({
trailingSlash: TrailingSlash.Strict,
optionalParamBehavior: OptionalParamBehavior.SetUndefined,
});

// After
import { Router } from '@zipbul/router';
new Router({
ignoreTrailingSlash: false,
omitMissingOptional: false,
});
```

| Old | New |
| :----------------------------------------------------------- | :----------------------------- |
| `{ trailingSlash: TrailingSlash.Strict }` | `{ ignoreTrailingSlash: false }` |
| `{ trailingSlash: TrailingSlash.Ignore }` (default) | `{ ignoreTrailingSlash: true }` (or omit) |
| `{ optionalParamBehavior: OptionalParamBehavior.Omit }` (default) | `{ omitMissingOptional: true }` (or omit) |
| `{ optionalParamBehavior: OptionalParamBehavior.SetUndefined }` | `{ omitMissingOptional: false }` |

Defaults are unchanged: trailing slash is ignored by default; missing
optional parameters are omitted from `params` by default.

### Public export surface

The two enum names are removed from the public exports. Remaining
exports: `Router`, `RouterError`, `MatchSource`, `RouterErrorKind`.
`MatchSource` (3 members) and `RouterErrorKind` (21 members) remain
enums — both have enough cardinality that the enum form carries
meaningful information.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:

- uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.9"
bun-version: '1.3.9'

- run: bun install --frozen-lockfile

Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ jobs:

- uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.9"
bun-version: '1.3.9'

- uses: actions/setup-node@v4
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
node-version: '24'
registry-url: 'https://registry.npmjs.org'

- run: bun install --frozen-lockfile

Expand Down Expand Up @@ -65,7 +65,7 @@ jobs:
with:
publish: bun run scripts/publish.ts
version: bunx changeset version
title: "chore: version packages"
commit: "chore: version packages"
title: 'chore: version packages'
commit: 'chore: version packages'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ dist
# code coverage
coverage
*.lcov

.claude/scheduled_tasks.lock
43 changes: 43 additions & 0 deletions .oxfmtrc.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",

// Prettier-compatible core options
"printWidth": 130,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"jsxSingleQuote": false,
"quoteProps": "as-needed",
"trailingComma": "all",
"bracketSpacing": true,
"bracketSameLine": false,
"arrowParens": "avoid",
"proseWrap": "preserve",
"embeddedLanguageFormatting": "auto",
"endOfLine": "lf",
"insertFinalNewline": true,
"ignorePatterns": [],
"experimentalSortPackageJson": {
"sortScripts": true,
},
"experimentalSortImports": {
"customGroups": [],
"groups": [
"type-import",
["value-builtin", "value-external"],
"type-internal",
"value-internal",
["type-parent", "type-sibling", "type-index"],
["value-parent", "value-sibling", "value-index"],
"unknown",
],
"ignoreCase": true,
"internalPattern": ["~/", "@/"],
"newlinesBetween": true,
"order": "asc",
"partitionByComment": false,
"partitionByNewline": false,
"sortSideEffects": false,
},
}
Loading
Loading