feat(fragment): Web Fragments render engine — /@fragment gateway + render_engine switch [EE2-2313]#90
Merged
Merged
Conversation
…olves absolute [EE2-2313]
The fragment_gateway entry declared public_registry/metadata_http/private_ip
policies but NOT wippy.views:public_env_runtime — the one that permits
env.get on PUBLIC_*. Every sibling endpoint (list_components, find_by_tag,
render) declares it; the gateway was the odd one out.
Consequence chain: the gateway calls page_registry.resolve_base_url(), whose
env.get("PUBLIC_API_URL") then runs under the gateway's actor and is DENIED →
origin = "" → base_url stays relative (/app/app/main/) → the document fetch is
rejected by public_metadata_http_runtime, which only allows http(s)://* →
"Fragment document fetch failed: not allowed: /app/app/main/app.html".
So PUBLIC_API_URL was never broken as a value (.env has it; the facade in the
same process resolves it; the consumer binds env_storage for views) — it simply
could not be read from this runtime.
Also add the missing `workers: 4` to the gateway pool: every sibling endpoint in
this file declares it, and without it the pool's concurrency is inconsistent with
the file's own convention — a latent head-of-line stall for fragment traffic.
Gateway error message now includes the attempted URL, which is what made this
diagnosable.
Verified: document branch returns the transformed doc (<wf-html>/<wf-head>/
<wf-body>) with the host CSS links injected; fragment-poc A–G + H–I and
fragment-parity all green (3 passed).
…[EE2-2313] Stage 1A (BE). Surfaces a page's render engine so the host fork can read it: - page_registry.lua: extract `render_engine = meta.render_engine` in both extract_page_info and pages.get (raw/nil, per the nil-propagation convention); add the field to the PageDetail type. - bundled_meta.project_page_response: emit `wippy.renderEngine = w.renderEngine` (from the bundled wippy-meta.json), then a SCALAR (not deep-merge) YAML operator override — `page.render_engine` wins when present. Mirrors the proxy/config overlay precedence (YAML-first). - render.lua synthesize_from_registry: emit `renderEngine = page.render_engine` so unmigrated pages (no wippy-meta.json) still receive the operator override. Wire response stays wippy-component-1.0 (no schema bump): a new optional field with a defined absent behavior. Verified live: operator meta.render_engine: iframe on a page renders it as srcdoc under a global fragment deployment.
…emo [EE2-2313] Rename the gateway route /frag/ -> /@fragment/. Add per-branch Cache-Control: stub -> public,max-age=300 (no page, no can_access, deploy-stable); document + assets -> private (both are can_access-gated per user, so a shared/CDN cache would serve the 200 to users who fail the check - private = browser-only caching, the fail-safe; public/immutable is a future win gated on a per-page public flag). Memoize the host import-map fetch (was a synchronous GET on every fragment mount). Remove the dead strip_doctype/neutralize passes (defined but never called; reframed's writable-dom handles script activation).
… [EE2-2313] Split the fragment_gateway endpoints off api_router onto a new fragment_router ns.requirement (mirrors the api_router pattern), so the consumer mounts the gateway on its OWN top-level /@Fragment prefix instead of under /api/public - CDN-cache-routable and free of api.public's token_auth. Endpoint path is now router-relative (/{id}/{path...}); the router supplies /@Fragment. Investigation confirmed the two other deferred Part C items are genuinely infeasible: reframed 0.8.2 derives stub+document+assets from ONE src (elements.js:1099/1145/1185; no 3-URL split without forking the library), and the page descriptor carries only a URL - no fs handle, no fs.* policy in views, and absolute-URL pages have no local fs at all - so no GENERIC fs-direct read; the loopback http_client stays.
…bed [EE2-2313] Bump the Web Host CDN ref to webcomponents-1.0.46 across the checklist files (_index.yaml fe_facade_url default, Makefile WEB_HOST_CDN, README, config_handler_test) plus the stale config_dependency_test (1.0.39->1.0.46), and re-vendor the loading.js public_files embed from the live 1.0.46 CDN. Published as wippy/facade@0.6.28 (views@0.5.8 carries the fragment gateway, published from its already-committed source).
…ring, no boot abort [EE2-2313] The Web-Fragments gateway router is now owned by wippy/views: a self-declared http.router (`wippy.views.api:fragment_router`, prefix /@Fragment) bound to a new `server` ns.requirement that DEFAULTS to app:gateway. A consuming app needs zero fragment wiring and never aborts boot — a deployment that never enables fragments just boots on the iframe (main) engine, and opting into fragments is purely the facade `render_engine` switch plus the FE capability probe. This replaces the previous mandatory consumer-provided `fragment_router` requirement (no default), which aborted boot with "unresolved requirements" for any consumer that upgraded without wiring it — the failure mode was wrong: a missing value must degrade to iframe, not fail loud. Also removes the dead extract_and_merge_importmap function (never called; tripped the lint type check). Gateway comments reframed: iframe = main/default engine, Web Fragments = experimental opt-in. Verified: views lint (26 entries, clean) + test (94/94) green from src/views/test as CI runs them; app-template boots in fragment mode with no fragment wiring and /@Fragment routes to the gateway handler.
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.
Summary
Backend for the Web Fragments render engine (EE2-2313) — an experimental second page-render engine for the Wippy Web Host, alongside the main srcdoc-iframe engine (the default). A
view.pagerenders as areframedsame-origin realm reflected into a<web-fragment>shadow root; the iframe engine remains the default and unchanged.wippy/views(published0.5.9)/@fragment/{id}/{path...}gateway (api/fragment_gateway.lua) serving the reframing contract: a reframed stub (Sec-Fetch-Dest: iframe), the app document transformed for the realm, and asset proxying. Per-branchCache-Control(stub shared-cacheable; access-gated document/assetsprivate) and a memoized host import-map./@fragmentrouter.wippy/viewsself-declares thehttp.routerand binds it to a newserverrequirement that defaults toapp:gateway. A consuming app needs zero fragment wiring — overrideserveronly if yourhttp.serviceentry has a different id.renderEngineprojected into the page descriptor (page_registry.lua,bundled_meta.lua,api/render.lua).wippy/facade(published0.6.28)render_enginerequirement →hostConfig.renderEngine(defaultiframe; only the exact stringfragmentopts in).webcomponents-1.0.46; theloading.jspublic_filesembed re-vendored.Both published to the Hub. Docs: the Render Engines / Views / Facade pages in
wippy/docs.