fix: retain resolved component paths

This commit is contained in:
root 2026-07-13 21:26:01 +00:00
parent 92baaa6299
commit 8da6cad305
5 changed files with 29 additions and 1 deletions

View File

@ -375,6 +375,11 @@ header free-functions are `inline`. The wasm backend exposes only declarations
old mutation handler, and verifies demand-priority convergence. A CLI request
still waits and returns only the current dependency result after rebuild
completion.
The component page also calls a parent once without its optional relative
child and again with that child activated. This guards the component-slot
cache invariant that a cache hit must restore both the function-table slot
and the resolved unit path; otherwise nested relative targets resolve from
the caller after a repeated parent invocation.
- **WebSocket end-to-end**: a headless client performs a raw WS handshake to
`:HTTP_PORT` with path `/site/tests/websockets.ws.uce` (self-resolving

View File

@ -23,6 +23,10 @@ RENDER(Request& context)
bool exists = component_exists("components/panel");
String resolved = component_resolve("components/panel");
String panel_markup = component("components/panel", props, context);
DValue lazy_props;
String lazy_first = component("components/lazy-parent", lazy_props, context);
lazy_props["show_child"].set_bool(true);
String lazy_second = component("components/lazy-parent", lazy_props, context);
String alias_markup = component("components/props_alias", props, context);
// Named handler through the string-returning component("unit:NAME") form
// (distinct path from component_render below): resolves __uce_component_HEADER
@ -42,6 +46,7 @@ RENDER(Request& context)
check("component_exists()", exists, exists ? "components/panel resolved as existing" : "components/panel missing");
check("component_resolve()", resolved != "", resolved);
check("component()", panel_markup.find("Component Output") != String::npos && panel_markup.find("This body comes from component()") != String::npos, panel_markup);
check("cached component retains path for a newly activated relative child", lazy_first.find("lazy-child") == String::npos && lazy_second.find("lazy-child") != String::npos, lazy_second);
check("COMPONENT(Request& props) alias", alias_markup.find("alias=Component Output") != String::npos && alias_markup.find("body=This body comes from component()") != String::npos, alias_markup);
check("component_render() named handler", footer_markup.find("Named footer render") != String::npos, footer_markup);
check("component(\"unit:NAME\") named handler", header_markup.find("Component Output") != String::npos && header_markup.find("This body comes from component()") == String::npos, header_markup);
@ -55,4 +60,4 @@ RENDER(Request& context)
site_tests_summary(passed, failed, skipped, "The panel fixture under site/tests/components exercises default and named component entry points.");
site_tests_page_end();
}
}

View File

@ -0,0 +1,4 @@
COMPONENT(Request& context)
{
<><span>lazy-child</span></>
}

View File

@ -0,0 +1,5 @@
COMPONENT(Request& context)
{
if(context.props["show_child"].to_bool())
print(component("lazy-child", context.props, context));
}

View File

@ -458,6 +458,7 @@ extern "C" int32_t uce_host_component_resolve(
// target → table slot, reset per request (workspaces die with the request,
// but a single workspace can render the same component many times)
static std::map<String, s32> wasm_component_slots;
static std::map<String, String> wasm_component_paths;
// These mirror small page-runtime pieces that cannot include compiler.cpp in
// the wasm core (compiler.cpp owns parser/clang/cache bookkeeping for the host
@ -521,7 +522,11 @@ static s32 wasm_resolve_target(String unit_target, String handler, String* resol
bool is_exists = (handler == "exists");
auto cached = wasm_component_slots.find(cache_key);
if(cached != wasm_component_slots.end() && !is_exists)
{
if(resolved_out)
*resolved_out = wasm_component_paths[cache_key];
return(cached->second);
}
char resolved[512];
String current = context ? context->resources.current_unit_file : "";
s32 slot = uce_host_component_resolve(
@ -531,7 +536,10 @@ static s32 wasm_resolve_target(String unit_target, String handler, String* resol
if(resolved_out && slot)
*resolved_out = String(resolved, strnlen(resolved, sizeof(resolved)));
if(!is_exists)
{
wasm_component_slots[cache_key] = slot;
wasm_component_paths[cache_key] = slot ? String(resolved, strnlen(resolved, sizeof(resolved))) : String("");
}
return(slot);
}
@ -768,6 +776,7 @@ void uce_wasm_core_reset_request()
wasm_request.out = "";
wasm_request.resources.current_unit_file = "";
wasm_component_slots.clear();
wasm_component_paths.clear();
}
// Host pushes the UCEB2-encoded request context into a guest buffer