Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 259x 259x 505x 505x 505x 505x 505x 505x 189x 189x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 2337x 2x 2x 2x 2x 2x 2x 2335x 2337x | /**
* @file stringRenderer.js
* @description The seam that lets the string renderer leave a bundle.
*
* ## Why this exists
*
* The string renderer is the pre-IR rendering path: render the whole template
* to HTML, parse it, diff the result into the document, then re-scan the
* subtree for lists, deferred blocks and event handlers. It is about 87 KB of
* source -- roughly a quarter of a small application's bundle -- and since the
* IR lowers `<@if>`, `<@for>`, `<slot>`, `<@defer>` and component tags, most
* applications never execute a line of it.
*
* They were still paying for it, because `AvenxComponent` imported the four
* classes directly and an import is reachability. The classes were already
* behind lazy getters, so nothing was *constructed* -- but nothing was dropped
* either.
*
* So the import moved. `AvenxComponent` asks this registry, and the compiler
* adds the module that fills it only when at least one component in the build
* actually fell back. An application whose every template compiles does not
* reference the string renderer, and the bundler shakes it out.
*
* ## Deliberately tiny
*
* This module imports nothing. If it imported the renderer to provide a
* default, the renderer would be reachable again and the whole arrangement
* would achieve nothing.
*
* ## Temporary
*
* This is migration scaffolding. It exists for as long as there are template
* constructs the IR does not model -- suspense, error boundaries, deadlock
* boundaries, transitions, refs, declarative validation and dynamic component
* tags. When the last of those lowers, the string renderer goes and this module
* goes with it.
* @module lib/core/renderer/stringRenderer
*/
import { AvenxError, AvenxErrorCodes } from '../runtime/AvenxError.js';
/**
* The renderer classes, once something has installed them.
* @type {{DomPatcher: Function, ListManager: Function, DeferManager: Function,
* TemplateRenderer: Function}|null}
*/
let installed = null;
/**
* Registers the string renderer's classes.
*
* Called by `avenx-core/runtime/string-renderer`, which the compiler adds to
* the graph when a component falls back.
* @param {object} classes - The renderer classes.
* @param {Function} classes.DomPatcher - The DOM patcher.
* @param {Function} classes.ListManager - The list manager.
* @param {Function} classes.DeferManager - The defer manager.
* @param {Function} classes.TemplateRenderer - The template renderer.
*/
export function installStringRenderer(classes) {
installed = classes;
}
/**
* Whether the string renderer is available in this bundle.
* @returns {boolean} True when something installed it.
*/
export function hasStringRenderer() {
return installed !== null;
}
/**
* Returns the string renderer's classes.
*
* Throws rather than returning null when nothing installed it, because the
* caller is a component about to render and has no second option. Reaching
* here means a component without a render program ended up in a build that
* concluded no component needed one, which is a compiler fault and should read
* like one rather than like a missing method on undefined.
*
* The code is AVX_R34 and not the generic template-render error it used to
* borrow. Reusing AVX_R08 made this read as "an interpolation failed", which
* sent a developer looking at their expression -- the one place the fault was
* certainly not. It also made the condition invisible to `avenx explain`,
* because AVX_R08's entry describes something else entirely.
* @param {string} [componentName] - The component that needs the renderer, for
* the diagnostic.
* @returns {object} The renderer classes.
*/
export function requireStringRenderer(componentName = 'a component') {
if (!installed) {
throw new AvenxError(
AvenxErrorCodes.RENDERER_UNAVAILABLE,
componentName,
'the string renderer',
);
}
return installed;
}
|