-
Notifications
You must be signed in to change notification settings - Fork 30.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
src: implement whatwg's URLPattern spec #56452
base: main
Are you sure you want to change the base?
Conversation
Review requested:
|
Can you elaborate? libuv is a C library so I don't think exceptions exist there, and I'm pretty sure V8 is built with exceptions disabled. |
My bad UV does not enable exceptions. Referencing v8.gyp file:
|
This is not really V8. It's a build-time executable (torque) used to generate code for V8 |
ada::url_pattern_options options{}; | ||
Local<Value> ignore_case; | ||
if (obj->Get(env->context(), | ||
FIXED_ONE_BYTE_STRING(env->isolate(), "ignoreCase")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider adding to env-properties.h
|
||
MaybeLocal<Value> URLPattern::Hash() const { | ||
auto context = env()->context(); | ||
return ToV8Value(context, url_pattern_.get_hash()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the key challenge here is that this will copy the string on every call. Any chance of memoizing the string once created.
src/node_url_pattern.cc
Outdated
URLPattern::URLPattern(Environment* env, | ||
Local<Object> object, | ||
ada::url_pattern&& url_pattern) | ||
: BaseObject(env, object) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We likely should introduce this as experimental in the first release, even if it graduates from experimental quickly. There should likely be a warning emitted on the first construction.
@@ -1571,6 +1572,7 @@ module.exports = { | |||
toPathIfFileURL, | |||
installObjectURLMethods, | |||
URL, | |||
URLPattern, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs docs added.
if (!url_pattern->Protocol().ToLocal(&result)) { | ||
return; | ||
} | ||
info.GetReturnValue().Set(result); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (!url_pattern->Protocol().ToLocal(&result)) { | |
return; | |
} | |
info.GetReturnValue().Set(result); | |
if (url_pattern->Protocol().ToLocal(&result)) { | |
info.GetReturnValue().Set(result); | |
} |
a bit more compact to invert the checks on these.
void URLPattern::New(const FunctionCallbackInfo<Value>& args) { | ||
Environment* env = Environment::GetCurrent(args); | ||
|
||
CHECK(args.IsConstructCall()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since this constructor is exposed directly to users, this should throw an exception rather than abort
Can you also include a fairly simple benchmark? |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #56452 +/- ##
==========================================
- Coverage 89.16% 88.67% -0.50%
==========================================
Files 661 664 +3
Lines 191421 192025 +604
Branches 36845 36633 -212
==========================================
- Hits 170673 170270 -403
- Misses 13615 14539 +924
- Partials 7133 7216 +83
|
BufferValue input_buffer(env->isolate(), args[0]); | ||
CHECK_NOT_NULL(*input_buffer); | ||
input = input_buffer.ToString(); | ||
} else if (args[0]->IsObject()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It’s not part of spec but can we add a “is URL instance” fast path here? To avoid re-normalizing each URL property (as with the JsObject route)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we can. I haven't started working on optimizations yet due to the inconsistencies between the spec and WPT.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t think this is a good pattern to land in Node.js. Specifically, a server using this will create one per route and iterate in a loop. This will be slow, specifically if you need to match the last of the list.
(This feedback was provided when URLPattern was standardized and essentially ignored).
For this to be useful, we would need to have a Node.js-specific API to organize these URLPattern in a radix prefix trie and actually do the matching all at once.
I can possibly be persuaded that we need this for Web platform compatibility, but it’s not that popular either (unlike fetch()).
@jasnell I’ll try to build this and get a benchmark going against the ecosystem routers. |
Right now, this pull-request does not pass WPT, and not at all optimized. Any benchmarks will not be beneficial. |
I'm +1 on adding it to Node.js, I like more WP compatibility and I feel like it's an api that could be useful for libraries. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have landed plenty of inefficient Web API's. Don't see why this would be different. I'm of the consistent opinion that we should implement them but strongly discourage their use for any performance sensitive code.
Just out of curiosity, why can't we port the Chromium's implementation but instead need to reimplement this ourselves? (I am not a maintainer) |
The chromium implementation depends on quite a few chromium/blink internals that we don't have here. That kind of reuse is difficult to just make happen. This ada-based implementation is standalone, has no other dependencies, etc. It's actually easier overall just to write it from scratch than to repurpose that other impl. |
65631d9
to
4e224f9
Compare
022eefd
to
af23313
Compare
One worry worth highlighting here is that, IIUC, the architecture of this PR will use a separate regexp library for the regexps that show up in the That could be confusing for developers, as I assume the feature overlap will not be the same. For example, I wonder what results you would get after this PR for: new URLPattern("https://example.com/:id([\\p{Decimal_Number}--[1-9]])").test("https://example.com/0");
new RegExp("[\\p{Decimal_Number}--[1-9]]", "v").test("0"); In Chromium we have architected our I suspect a similar architecture would not fit that well for you, given the different boundaries between Ada / Node.js. But maybe Ada could have some sort of regexp-matcher-callback system which would allow the use of V8's regexps instead of |
This is a good idea. I think that if we introduce this as experimental initially we can do this in a separate step though, before it graduates to supported. |
You're right. I think we should also wait for the web-platform tests to be fixed or discussed before releasing an URLPattern implementation that is spec compliant but not Chromium compliant. |
2dcb81a
to
ad8610c
Compare
ad8610c
to
261359f
Compare
Co-authored-by: Daniel Lemire (@lemire)
Blocked
This is blocked from landing due to the old macOS machines we use in our infrastructure (cc @nodejs/build)
Notes:
TODOs
cc @nodejs/cpp-reviewers
Fixes #40844