Add a jsdom selector-engine adapter - #211
Merged
Merged
Conversation
jdalton
force-pushed
the
feat/jsdom-adapter
branch
11 times, most recently
from
September 5, 2026 23:43
a285d19 to
5975102
Compare
jdalton
force-pushed
the
feat/jsdom-adapter
branch
from
September 5, 2026 23:48
5975102 to
d7e01ee
Compare
This was referenced Sep 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Use nwsapi inside jsdom 30
Add a
DOMSelectorexport alongside the existing CommonJS factory. It lets npm replace jsdom 30's@asamuzakjp/dom-selectordependency with nwsapi without patching jsdom or its DOM prototypes.The adapter converts jsdom's internal nodes to public DOM nodes and routes queries, matches, and closest calls through nwsapi. It also supplies the CSS syntax trees that jsdom needs for stylesheet specificity.
css-treeis an optional peer dependency, already supplied by jsdom 30; ordinary nwsapi callers do not load it.The adapter loads
css-treeonly on the first stylesheetcheck(). DOM-only calls do not request it. A 256-entry cache reuses parsed selectors and generated branch text, never match results. DOM mutations stay visible, andclear(true)drops the syntax cache. The adapter checks all stylesheet rules without a subject prefilter. Existing selector bugs remain nwsapi's responsibility; this does not replace #178 or the other fixes.Tests
On Node 26.5.0, all 11 integration tests pass both locally and through a fresh npm install of the packed adapter. Coverage includes DOM wrappers, static NodeLists, ordering, scoped and detached queries, fragments, XML, mutations, errors, stylesheet specificity, lazy loading, missing peers, and bounded syntax caching.
A local microbenchmark of 10,000 warm stylesheet checks fell from 28.54 ms to 3.00 ms (median of seven runs). This measures repeated syntax reuse, not end-to-end jsdom performance. jsdom can also load
css-treeindependently.Run
node --test test/jsdom-adapter.test.cjsfor local checks. Runnode test/jsdom-adapter-package.cjsfor the real npm override check. The latter packs this checkout, installs jsdom 30.0.1 in a temporary consumer, overrides its selector dependency with that tarball, and runs the same suite without a module-cache substitution.The original reentry path also remains observable through this installed adapter. Across 300 real
Element.matches()calls, master reaches the depth-21 safety limit. With #178's factory, the same test creates one engine, makes 301 engine calls, reaches depth two, and never hits the limit. We can therefore move reentry coverage to jsdom 30 and remove the jsdom 26 alias from #210.Scope
This is one commit targeting master. The engine change is only the lazy CommonJS export. The adapter, tests, package inclusion, optional peer declaration, and usage documentation are separate from selector fixes. The README shows an override to the published npm package, using the version of a future release containing the adapter. The existing npm release does not yet contain it. The package test uses a temporary tarball only to verify the adapter before publication.