@@ -61,6 +61,7 @@ using v8::FunctionTemplate;
6161using  v8::Global;
6262using  v8::Isolate;
6363using  v8::Local;
64+ using  v8::LocalVector;
6465using  v8::MaybeLocal;
6566using  v8::Name;
6667using  v8::NewStringType;
@@ -284,27 +285,56 @@ MaybeLocal<Value> URLPattern::URLPatternInit::ToJsObject(
284285    Environment* env, const  ada::url_pattern_init& init) {
285286  auto  isolate = env->isolate ();
286287  auto  context = env->context ();
287-   auto  result = Object::New (isolate);
288288
289-   const  auto  trySet = [&](auto  name, const  std::optional<std::string>& val) {
290-     if  (!val) return  true ;
291-     Local<Value> temp;
292-     return  ToV8Value (context, *val).ToLocal (&temp) &&
293-            result->Set (context, name, temp).IsJust ();
289+   auto  tmpl = env->urlpatterninit_template ();
290+   if  (tmpl.IsEmpty ()) {
291+     static  constexpr  std::string_view namesVec[] = {
292+         " protocol" 
293+         " username" 
294+         " password" 
295+         " hostname" 
296+         " port" 
297+         " pathname" 
298+         " search" 
299+         " hash" 
300+         " baseURL" 
301+     };
302+     tmpl = DictionaryTemplate::New (isolate, namesVec);
303+     env->set_urlpatterninit_template (tmpl);
304+   }
305+ 
306+   MaybeLocal<Value> values[] = {
307+       Undefined (isolate),  //  protocol
308+       Undefined (isolate),  //  username
309+       Undefined (isolate),  //  password
310+       Undefined (isolate),  //  hostname
311+       Undefined (isolate),  //  port
312+       Undefined (isolate),  //  pathname
313+       Undefined (isolate),  //  search
314+       Undefined (isolate),  //  hash
315+       Undefined (isolate),  //  baseURL
316+   };
317+ 
318+   int  idx = 0 ;
319+   Local<Value> temp;
320+   const  auto  trySet = [&](const  std::optional<std::string>& val) {
321+     if  (val.has_value ()) {
322+       if  (!ToV8Value (context, *val).ToLocal (&temp)) {
323+         return  false ;
324+       }
325+       values[idx] = temp;
326+     }
327+     idx++;
328+     return  true ;
294329  };
295330
296-   if  (!trySet (env->protocol_string (), init.protocol ) ||
297-       !trySet (env->username_string (), init.username ) ||
298-       !trySet (env->password_string (), init.password ) ||
299-       !trySet (env->hostname_string (), init.hostname ) ||
300-       !trySet (env->port_string (), init.port ) ||
301-       !trySet (env->pathname_string (), init.pathname ) ||
302-       !trySet (env->search_string (), init.search ) ||
303-       !trySet (env->hash_string (), init.hash ) ||
304-       !trySet (env->base_url_string (), init.base_url )) {
331+   if  (!trySet (init.protocol ) || !trySet (init.username ) ||
332+       !trySet (init.password ) || !trySet (init.hostname ) || !trySet (init.port ) ||
333+       !trySet (init.pathname ) || !trySet (init.search ) || !trySet (init.hash ) ||
334+       !trySet (init.base_url )) {
305335    return  {};
306336  }
307-   return  result ;
337+   return  NewDictionaryInstance (env-> context (), tmpl, values) ;
308338}
309339
310340std::optional<ada::url_pattern_init> URLPattern::URLPatternInit::FromJsObject (
@@ -364,12 +394,16 @@ MaybeLocal<Object> URLPattern::URLPatternComponentResult::ToJSObject(
364394    Environment* env, const  ada::url_pattern_component_result& result) {
365395  auto  isolate = env->isolate ();
366396  auto  context = env->context ();
367-   auto  parsed_group = Object::New (isolate);
397+   LocalVector<Name> group_names (isolate);
398+   LocalVector<Value> group_values (isolate);
399+   group_names.reserve (result.groups .size ());
400+   group_values.reserve (result.groups .size ());
368401  for  (const  auto & [group_key, group_value] : result.groups ) {
369402    Local<Value> key;
370403    if  (!ToV8Value (context, group_key).ToLocal (&key)) {
371404      return  {};
372405    }
406+     group_names.push_back (key.As <Name>());
373407    Local<Value> value;
374408    if  (group_value) {
375409      if  (!ToV8Value (env->context (), *group_value).ToLocal (&value)) {
@@ -378,19 +412,30 @@ MaybeLocal<Object> URLPattern::URLPatternComponentResult::ToJSObject(
378412    } else  {
379413      value = Undefined (isolate);
380414    }
381-     if  (parsed_group->Set (context, key, value).IsNothing ()) {
382-       return  {};
383-     }
415+     group_values.push_back (value);
384416  }
417+   auto  parsed_group = Object::New (isolate,
418+                                   Object::New (isolate),
419+                                   group_names.data (),
420+                                   group_values.data (),
421+                                   group_names.size ());
422+ 
385423  Local<Value> input;
386424  if  (!ToV8Value (env->context (), result.input ).ToLocal (&input)) {
387425    return  {};
388426  }
389-   Local<Name> names[] = {env->input_string (), env->groups_string ()};
390-   Local<Value> values[] = {input, parsed_group};
391-   DCHECK_EQ (arraysize (names), arraysize (values));
392-   return  Object::New (
393-       isolate, Object::New (isolate), names, values, arraysize (names));
427+ 
428+   auto  tmpl = env->urlpatterncomponentresult_template ();
429+   if  (tmpl.IsEmpty ()) {
430+     static  constexpr  std::string_view namesVec[] = {
431+         " input" 
432+         " groups" 
433+     };
434+     tmpl = DictionaryTemplate::New (isolate, namesVec);
435+     env->set_urlpatterncomponentresult_template (tmpl);
436+   }
437+   MaybeLocal<Value> values[] = {input, parsed_group};
438+   return  NewDictionaryInstance (env->context (), tmpl, values);
394439}
395440
396441MaybeLocal<Value> URLPattern::URLPatternResult::ToJSValue (
0 commit comments