@ecopages/lit 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,284 +1,112 @@
1
- import "@lit-labs/ssr/lib/install-global-dom-shim.js";
2
- import { IntegrationRenderer } from "@ecopages/core/route-renderer/integration-renderer";
3
- import { render } from "@lit-labs/ssr";
4
- import { html as staticHtml, unsafeStatic } from "lit/static-html.js";
5
- import { LitSsrLazyPreloader } from "./lit-ssr-lazy-preloader.js";
6
- import { PLUGIN_NAME } from "./lit.plugin.js";
7
- const HTML_TEMPLATE_SLOT_MARKER = "<--content-->";
8
- const COMPONENT_CHILDREN_SLOT_MARKER = "<!--eco-lit-component-children-->";
9
- const ESCAPED_COMPONENT_CHILDREN_SLOT_MARKER = "&lt;!--eco-lit-component-children--&gt;";
10
- const DOUBLE_ESCAPED_COMPONENT_CHILDREN_SLOT_MARKER = "&amp;lt;!--eco-lit-component-children--&amp;gt;";
11
- const DUPLICATE_DECLARATIVE_SHADOW_ROOT_ATTRIBUTE = /\sshadowroot=(['"])(open|closed)\1(?=\sshadowrootmode=\1\2\1)/g;
12
- class LitRenderer extends IntegrationRenderer {
13
- name = PLUGIN_NAME;
14
- async resolveQueuedBoundaryChildren(children, queuedResolutionsByToken, resolveToken) {
15
- if (children === void 0) {
16
- return void 0;
17
- }
18
- let renderedChildren = typeof children === "string" ? children : await this.renderValueToString(children);
19
- renderedChildren = await this.resolveQueuedBoundaryTokens(
20
- renderedChildren,
21
- queuedResolutionsByToken,
22
- resolveToken
23
- );
24
- return renderedChildren;
25
- }
26
- async resolveQueuedBoundaryHtml(html, runtimeContext) {
27
- const queuedBoundaryResolution = await this.resolveRendererOwnedQueuedBoundaryHtml({
28
- html,
29
- runtimeContext,
30
- queueLabel: "Lit",
31
- renderQueuedChildren: async (children, _runtimeContext, queuedResolutionsByToken, resolveToken) => {
32
- const renderedChildren = await this.resolveQueuedBoundaryChildren(
33
- children,
34
- queuedResolutionsByToken,
35
- resolveToken
36
- );
1
+ import { createIntegrationRenderer } from '@ecopages/core/integration';
2
+ import { resolveQueuedTokens } from '@ecopages/core/integration';
3
+ import { CUSTOM_ELEMENT_SSR_PRELOAD_CACHE_SCOPES, CustomElementScriptPreloader, } from '@ecopages/core/integration';
4
+ import { requireAppRuntime } from '@ecopages/core/integration';
5
+ import { createCustomElementServerModuleImporter } from '@ecopages/core/integration';
6
+ import { ensureLitDomShim } from './dom-shim.js';
7
+ import { LIT_PLUGIN_NAME } from './lit.constants.js';
8
+ import { injectLitRenderedChildren, LIT_COMPONENT_CHILDREN_SLOT_MARKER, normalizeLitHtml, renderLitValueToString, } from './utils/lit-html-rendering.js';
9
+ /**
10
+ * Creates the Lit renderer class with a lazy worker-session lookup.
11
+ *
12
+ * @remarks
13
+ * The plugin may create its renderer before `setup()` assigns the static render session, so hooks read the
14
+ * session when they run instead of capturing its construction-time value.
15
+ */
16
+ export function createLitRenderer(getRenderSession = () => undefined) {
17
+ return createIntegrationRenderer(LIT_PLUGIN_NAME, ({ appConfig, resolveComponentDependencies, resolveDependencyPath }) => {
18
+ const ssrScriptPreloader = new CustomElementScriptPreloader({
19
+ cacheScope: CUSTOM_ELEMENT_SSR_PRELOAD_CACHE_SCOPES.lit,
20
+ preloadScopes: requireAppRuntime(appConfig).customElementSsrPreloadScopes,
21
+ logLabel: 'lit',
22
+ requireLazyScriptEntry: true,
23
+ resolveDependencyPath,
24
+ importServerModule: createCustomElementServerModuleImporter(appConfig, '.lit-ssr'),
25
+ });
26
+ const preloadSsrScripts = async (components) => {
27
+ ensureLitDomShim();
28
+ const renderSession = getRenderSession();
29
+ if (renderSession) {
30
+ await renderSession.preloadSsrScripts(components);
31
+ return;
32
+ }
33
+ await ssrScriptPreloader.preloadSsrScripts(components);
34
+ };
37
35
  return {
38
- assets: [],
39
- html: renderedChildren
36
+ beforeRender: async (renderOptions) => preloadSsrScripts([
37
+ renderOptions.Page,
38
+ renderOptions.Layout,
39
+ ...(renderOptions.pageDependencyComponents ?? []),
40
+ ]),
41
+ transformDocumentHtml: normalizeLitHtml,
42
+ renderRemote: (routeOptions) => renderLitPageInWorker(routeOptions, getRenderSession),
43
+ renderComponent: async (input) => {
44
+ await preloadSsrScripts([input.component]);
45
+ if (!isFunctionComponent(input.component)) {
46
+ throw new TypeError('Lit renderer expected a callable component.');
47
+ }
48
+ const component = input.component;
49
+ let renderedChildren;
50
+ if (input.children !== undefined) {
51
+ renderedChildren =
52
+ typeof input.children === 'string'
53
+ ? input.children
54
+ : await renderLitValueToString(input.children);
55
+ }
56
+ const props = renderedChildren === undefined
57
+ ? input.props
58
+ : {
59
+ ...input.props,
60
+ children: LIT_COMPONENT_CHILDREN_SLOT_MARKER,
61
+ };
62
+ const content = await component(props);
63
+ const renderedHtml = await renderLitValueToString(content);
64
+ const html = renderedChildren === undefined
65
+ ? renderedHtml
66
+ : injectLitRenderedChildren(renderedHtml, renderedChildren);
67
+ const assets = input.component.config?.dependencies
68
+ ? await resolveComponentDependencies([input.component])
69
+ : undefined;
70
+ return {
71
+ html,
72
+ canAttachAttributes: true,
73
+ integrationName: LIT_PLUGIN_NAME,
74
+ assets,
75
+ };
76
+ },
77
+ renderQueuedChildren: async (children, _runtimeContext, queuedResolutionsByToken, resolveToken) => {
78
+ if (children === undefined) {
79
+ return {};
80
+ }
81
+ if (typeof children !== 'string') {
82
+ return { children };
83
+ }
84
+ return { html: await resolveQueuedTokens(children, queuedResolutionsByToken, resolveToken) };
85
+ },
40
86
  };
41
- }
42
- });
43
- return {
44
- html: queuedBoundaryResolution.html,
45
- assets: queuedBoundaryResolution.assets.length > 0 ? queuedBoundaryResolution.assets : void 0
46
- };
47
- }
48
- normalizeDeclarativeShadowRootMarkup(markup) {
49
- return markup.replace(DUPLICATE_DECLARATIVE_SHADOW_ROOT_ATTRIBUTE, "");
50
- }
51
- createRenderableMarkup(markup) {
52
- return staticHtml`${unsafeStatic(markup)}`;
53
- }
54
- shouldRenderPageComponent() {
55
- return false;
56
- }
57
- async renderMarkupToString(markup) {
58
- let renderedHtml = "";
59
- for (const chunk of render(this.createRenderableMarkup(markup))) {
60
- renderedHtml += chunk;
61
- }
62
- return this.normalizeDeclarativeShadowRootMarkup(renderedHtml);
63
- }
64
- async renderValueToString(value) {
65
- if (typeof value === "string") {
66
- return await this.renderMarkupToString(value);
67
- }
68
- let renderedHtml = "";
69
- for (const chunk of render(value)) {
70
- renderedHtml += chunk;
71
- }
72
- return this.normalizeDeclarativeShadowRootMarkup(renderedHtml);
73
- }
74
- isLitManagedComponent(component) {
75
- return component?.config?.integration === this.name || component?.config?.__eco?.integration === this.name;
76
- }
77
- injectRenderedChildren(template, renderedChildren) {
78
- for (const marker of [
79
- COMPONENT_CHILDREN_SLOT_MARKER,
80
- ESCAPED_COMPONENT_CHILDREN_SLOT_MARKER,
81
- DOUBLE_ESCAPED_COMPONENT_CHILDREN_SLOT_MARKER
82
- ]) {
83
- if (template.includes(marker)) {
84
- return template.split(marker).join(renderedChildren);
85
- }
86
- }
87
- if (template.includes(HTML_TEMPLATE_SLOT_MARKER)) {
88
- return template.split(HTML_TEMPLATE_SLOT_MARKER).join(renderedChildren);
89
- }
90
- if (template.includes("</body>")) {
91
- return template.replace("</body>", `${renderedChildren}</body>`);
92
- }
93
- if (template.includes("</html>")) {
94
- return template.replace("</html>", `${renderedChildren}</html>`);
95
- }
96
- return `${template}${renderedChildren}`;
97
- }
98
- async renderHtmlTemplate(options) {
99
- if (!options.isLitManagedHtmlTemplate) {
100
- return String(
101
- await options.HtmlTemplate({
102
- metadata: options.metadata,
103
- children: options.renderedChildren,
104
- pageProps: options.pageProps
105
- })
106
- );
107
- }
108
- const template = await options.HtmlTemplate({
109
- metadata: options.metadata,
110
- children: HTML_TEMPLATE_SLOT_MARKER,
111
- pageProps: options.pageProps
112
87
  });
113
- return this.injectRenderedChildren(String(template), options.renderedChildren);
114
- }
115
- /**
116
- * Renders a Lit component boundary for component-level orchestration.
117
- *
118
- * SSR-eligible lazy scripts are preloaded first so custom elements registered
119
- * by the component can render their server markup even when the Lit renderer is
120
- * entered through cross-integration boundary handoff.
121
- *
122
- * Includes component-scoped dependency assets when declared.
123
- */
124
- async renderComponent(input) {
125
- await this.preloadSsrLazyScripts([input.component]);
126
- const component = input.component;
127
- let renderedChildren;
128
- if (input.children !== void 0) {
129
- renderedChildren = typeof input.children === "string" ? input.children : await this.renderValueToString(input.children);
130
- }
131
- let props = input.props;
132
- if (renderedChildren !== void 0) {
133
- props = {
134
- ...input.props,
135
- children: COMPONENT_CHILDREN_SLOT_MARKER
136
- };
88
+ }
89
+ export const LitRenderer = createLitRenderer();
90
+ function isFunctionComponent(component) {
91
+ return typeof component === 'function';
92
+ }
93
+ /**
94
+ * Renders a Lit page route in its build-scoped worker when request data can cross the worker boundary.
95
+ *
96
+ * @remarks
97
+ * Locals and explicit props stay in-process: locals are request objects, and the worker re-imports the route module.
98
+ */
99
+ async function renderLitPageInWorker(options, getRenderSession) {
100
+ const renderSession = getRenderSession();
101
+ if (!renderSession || options.locals !== undefined || options.props !== undefined) {
102
+ return undefined;
137
103
  }
138
- const content = await component(props);
139
- const renderedHtml = await this.renderValueToString(content);
140
- const html = renderedChildren === void 0 ? renderedHtml : this.injectRenderedChildren(renderedHtml, renderedChildren);
141
- const queuedBoundaryResolution = await this.resolveQueuedBoundaryHtml(
142
- html,
143
- this.getQueuedBoundaryRuntime(input)
144
- );
145
- const hasDependencies = Boolean(input.component.config?.dependencies);
146
- const canResolveAssets = typeof this.assetProcessingService?.processDependencies === "function";
147
- const assets = hasDependencies && canResolveAssets ? await this.processComponentDependencies([input.component]) : void 0;
148
- return {
149
- html: queuedBoundaryResolution.html,
150
- canAttachAttributes: true,
151
- rootTag: this.getRootTagName(queuedBoundaryResolution.html),
152
- integrationName: this.name,
153
- assets: this.htmlTransformer.dedupeProcessedAssets([
154
- ...assets ?? [],
155
- ...queuedBoundaryResolution.assets ?? []
156
- ])
157
- };
158
- }
159
- createComponentBoundaryRuntime(options) {
160
- return this.createQueuedBoundaryRuntime({
161
- boundaryInput: options.boundaryInput,
162
- rendererCache: options.rendererCache
104
+ const params = options.params ?? {};
105
+ const result = await renderSession.renderPageInWorker({
106
+ filePath: options.file,
107
+ params,
108
+ query: options.query,
163
109
  });
164
- }
165
- ssrLazyPreloader = new LitSsrLazyPreloader({
166
- resolveDependencyPath: this.resolveDependencyPath.bind(this),
167
- processDependencies: this.assetProcessingService?.processDependencies?.bind(this.assetProcessingService)
168
- });
169
- /**
170
- * Detects preload failures that are expected for browser-only modules.
171
- *
172
- * These errors are treated as non-fatal during SSR preload because some
173
- * lazy client scripts intentionally depend on browser globals.
174
- */
175
- isExpectedSsrPreloadError(error) {
176
- return this.ssrLazyPreloader.isExpectedSsrPreloadError(error);
177
- }
178
- /**
179
- * Collects lazy script file paths eligible for SSR preloading.
180
- *
181
- * Only per-entry lazy script dependencies with `ssr: true` are collected.
182
- * File-backed entries are required (`src` must be present);
183
- * inline content lazy entries are intentionally skipped.
184
- */
185
- collectSsrPreloadScripts(components) {
186
- return this.ssrLazyPreloader.collectSsrPreloadScripts(components);
187
- }
188
- /**
189
- * Preloads SSR-eligible lazy scripts to register custom elements before render.
190
- */
191
- async preloadSsrLazyScripts(components) {
192
- await this.ssrLazyPreloader.preloadSsrLazyScripts(components);
193
- }
194
- /**
195
- * Resolves the concrete JS entrypoint used for SSR preloading.
196
- *
197
- * Scripts are passed through the asset pipeline so preload imports can use
198
- * the same processed output shape as runtime dependencies.
199
- */
200
- async resolveSsrPreloadEntrypoint(scriptPath) {
201
- return this.ssrLazyPreloader.resolveSsrPreloadEntrypoint(scriptPath);
202
- }
203
- async render({
204
- params,
205
- query,
206
- props,
207
- locals,
208
- metadata,
209
- Page,
210
- Layout,
211
- HtmlTemplate
212
- }) {
213
- try {
214
- await this.preloadSsrLazyScripts([Page, Layout]);
215
- return await this.renderPageWithDocumentShell({
216
- page: {
217
- component: Page,
218
- props: {
219
- params,
220
- query,
221
- ...props,
222
- locals
223
- }
224
- },
225
- layout: Layout ? {
226
- component: Layout,
227
- props: locals ? { locals } : {}
228
- } : void 0,
229
- htmlTemplate: HtmlTemplate,
230
- metadata,
231
- pageProps: props || {},
232
- transformDocumentHtml: (html) => this.normalizeDeclarativeShadowRootMarkup(html)
233
- });
234
- } catch (error) {
235
- throw this.createRenderError("Error rendering page", error);
236
- }
237
- }
238
- async renderToResponse(view, props, ctx) {
239
- try {
240
- if (ctx.partial) {
241
- return this.renderPartialViewResponse({
242
- view,
243
- props,
244
- ctx,
245
- transformHtml: (html) => this.normalizeDeclarativeShadowRootMarkup(html)
246
- });
247
- }
248
- const viewConfig = view.config;
249
- const Layout = viewConfig?.layout;
250
- const HtmlTemplate = await this.getHtmlTemplate();
251
- const metadata = await this.resolveViewMetadata(view, props);
252
- await this.preloadSsrLazyScripts([view, Layout]);
253
- await this.prepareViewDependencies(view, Layout);
254
- const pageRender = await this.renderComponentBoundary({
255
- component: view,
256
- props: props ?? {}
257
- });
258
- const layoutRender = Layout ? await this.renderComponentBoundary({
259
- component: Layout,
260
- props: {},
261
- children: pageRender.html
262
- }) : void 0;
263
- const documentRender = await this.renderComponentBoundary({
264
- component: HtmlTemplate,
265
- props: {
266
- metadata,
267
- pageProps: props ?? {}
268
- },
269
- children: layoutRender?.html ?? pageRender.html
270
- });
271
- this.appendProcessedDependencies(pageRender.assets, layoutRender?.assets, documentRender.assets);
272
- const body = await this.finalizeResolvedHtml({
273
- html: `${this.DOC_TYPE}${this.normalizeDeclarativeShadowRootMarkup(documentRender.html)}`,
274
- partial: false
275
- });
276
- return this.createHtmlResponse(body, ctx);
277
- } catch (error) {
278
- throw this.createRenderError("Error rendering view", error);
279
- }
280
- }
110
+ const { html, ...metadata } = result;
111
+ return { body: html, ...metadata };
281
112
  }
282
- export {
283
- LitRenderer
284
- };
@@ -0,0 +1,17 @@
1
+ import type { LitStaticRenderWorkerErrorMessage } from './lit-static-render-protocol.js';
2
+ /**
3
+ * Turns an error thrown in the Lit worker into the message posted to the main thread.
4
+ *
5
+ * @remarks
6
+ * `postMessage` cannot carry an `Error` with its class, so the status of an `HttpError` travels as a field.
7
+ * Without it a page that throws `HttpError.NotFound()` would reach the main thread as a plain error and render as a 500.
8
+ */
9
+ export declare function toLitStaticRenderErrorMessage(error: unknown, id?: string): LitStaticRenderWorkerErrorMessage;
10
+ /**
11
+ * Rebuilds the error a Lit worker reported, as an `HttpError` when the worker's error carried a status.
12
+ *
13
+ * @remarks
14
+ * The worker-side name, message and stack are kept on `cause` because the rebuilt error's own stack points at the
15
+ * message handler, not at the page that threw.
16
+ */
17
+ export declare function fromLitStaticRenderErrorMessage(message: LitStaticRenderWorkerErrorMessage): Error;
@@ -0,0 +1,34 @@
1
+ import { HttpError } from '@ecopages/core/errors';
2
+ /**
3
+ * Turns an error thrown in the Lit worker into the message posted to the main thread.
4
+ *
5
+ * @remarks
6
+ * `postMessage` cannot carry an `Error` with its class, so the status of an `HttpError` travels as a field.
7
+ * Without it a page that throws `HttpError.NotFound()` would reach the main thread as a plain error and render as a 500.
8
+ */
9
+ export function toLitStaticRenderErrorMessage(error, id) {
10
+ if (!(error instanceof Error) && !HttpError.isHttpError(error)) {
11
+ return { type: 'error', id, message: String(error) };
12
+ }
13
+ const { message, name, stack } = error;
14
+ return {
15
+ type: 'error',
16
+ id,
17
+ message,
18
+ name,
19
+ stack,
20
+ status: HttpError.isHttpError(error) ? error.status : undefined,
21
+ };
22
+ }
23
+ /**
24
+ * Rebuilds the error a Lit worker reported, as an `HttpError` when the worker's error carried a status.
25
+ *
26
+ * @remarks
27
+ * The worker-side name, message and stack are kept on `cause` because the rebuilt error's own stack points at the
28
+ * message handler, not at the page that threw.
29
+ */
30
+ export function fromLitStaticRenderErrorMessage(message) {
31
+ const error = message.status === undefined ? new Error(message.message) : new HttpError(message.status, message.message);
32
+ error.cause = { name: message.name, message: message.message, stack: message.stack };
33
+ return error;
34
+ }
@@ -0,0 +1,46 @@
1
+ import type { PageParams, PageQuery } from '@ecopages/core';
2
+ import type { RouteRenderResult } from '@ecopages/core/integration';
3
+ /** A rendered page, its resolved metadata, and what the main thread needs to cache it. */
4
+ export type LitStaticRenderResult = Pick<RouteRenderResult, 'cacheStrategy' | 'sourceDependencyPaths' | 'metadata'> & {
5
+ html: string;
6
+ };
7
+ export type LitStaticRenderWorkerInitMessage = {
8
+ type: 'init';
9
+ configModulePath: string;
10
+ runtimeOrigin: string;
11
+ };
12
+ export type LitStaticRenderWorkerRenderMessage = {
13
+ type: 'render';
14
+ id: string;
15
+ filePath: string;
16
+ /** Route params; multi-value keys stay as `string[]`. */
17
+ params: PageParams;
18
+ /** Serializable route query; preserves multi-value keys as `string[]`. */
19
+ query?: PageQuery;
20
+ };
21
+ export type LitStaticRenderWorkerShutdownMessage = {
22
+ type: 'shutdown';
23
+ };
24
+ export type LitStaticRenderWorkerRequestMessage = LitStaticRenderWorkerInitMessage | LitStaticRenderWorkerRenderMessage | LitStaticRenderWorkerShutdownMessage;
25
+ export type LitStaticRenderWorkerReadyMessage = {
26
+ type: 'ready';
27
+ };
28
+ export type LitStaticRenderWorkerResultMessage = {
29
+ type: 'result';
30
+ id: string;
31
+ } & LitStaticRenderResult;
32
+ export type LitStaticRenderWorkerErrorMessage = {
33
+ type: 'error';
34
+ id?: string;
35
+ message: string;
36
+ /** Worker-side error name, kept as the rebuilt error's cause. */
37
+ name?: string;
38
+ /** Worker-side stack, kept as the rebuilt error's cause. */
39
+ stack?: string;
40
+ /** Present when the thrown error was an `HttpError`, so the main thread can rebuild one with the same status. */
41
+ status?: number;
42
+ };
43
+ export type LitStaticRenderWorkerShutdownCompleteMessage = {
44
+ type: 'shutdown-complete';
45
+ };
46
+ export type LitStaticRenderWorkerResponseMessage = LitStaticRenderWorkerReadyMessage | LitStaticRenderWorkerResultMessage | LitStaticRenderWorkerErrorMessage | LitStaticRenderWorkerShutdownCompleteMessage;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { RouteRenderResult } from '@ecopages/core/integration';
2
+ import type { LitStaticRenderResult } from './lit-static-render-protocol.js';
3
+ /**
4
+ * Turns a route render into the message the worker posts back to the main thread.
5
+ *
6
+ * @remarks
7
+ * The resolved `metadata` travels with the HTML so the main thread can decide sitemap eligibility
8
+ * from the render instead of loading the page again.
9
+ */
10
+ export declare function toLitStaticRenderResult(result: RouteRenderResult): Promise<LitStaticRenderResult>;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Turns a route render into the message the worker posts back to the main thread.
3
+ *
4
+ * @remarks
5
+ * The resolved `metadata` travels with the HTML so the main thread can decide sitemap eligibility
6
+ * from the render instead of loading the page again.
7
+ */
8
+ export async function toLitStaticRenderResult(result) {
9
+ const { body, cacheStrategy, sourceDependencyPaths, metadata } = result;
10
+ const rendered = { cacheStrategy, sourceDependencyPaths, metadata };
11
+ if (typeof body === 'string') {
12
+ return { html: body, ...rendered };
13
+ }
14
+ if (Buffer.isBuffer(body)) {
15
+ return { html: body.toString('utf8'), ...rendered };
16
+ }
17
+ if (body instanceof ReadableStream) {
18
+ return { html: await new Response(body).text(), ...rendered };
19
+ }
20
+ throw new TypeError(`Unsupported Lit static render body type: ${typeof body}`);
21
+ }
@@ -0,0 +1,63 @@
1
+ import type { PageParams, PageQuery } from '@ecopages/core';
2
+ import type { StaticExportContext } from '@ecopages/core/integration';
3
+ import { type CustomElementSsrPreloadComponent } from '@ecopages/core/integration';
4
+ import type { CustomElementScriptPreloadScopeState } from '@ecopages/core/integration';
5
+ import { LitStaticRenderWorkerClient } from './lit-static-render-worker-client.js';
6
+ import type { LitStaticRenderResult } from './lit-static-render-protocol.js';
7
+ import type { AssetDefinition, AssetProcessingIntegration, ProcessedAsset } from '@ecopages/core/integration';
8
+ type LitStaticRenderWorkerClientContract = Pick<LitStaticRenderWorkerClient, 'start' | 'renderPage' | 'dispose'>;
9
+ type LitStaticRenderSessionOptions = {
10
+ preloadScopes: Map<string, CustomElementScriptPreloadScopeState>;
11
+ integration?: AssetProcessingIntegration;
12
+ resolveDependencyPath: (componentDir: string, sourcePath: string) => string;
13
+ processDependencies: (dependencies: AssetDefinition[], integration?: AssetProcessingIntegration) => Promise<ProcessedAsset[]>;
14
+ getInvalidationVersion?: () => number;
15
+ createWorkerClient?: (input: {
16
+ configModulePath: string;
17
+ runtimeOrigin: string;
18
+ }) => LitStaticRenderWorkerClientContract;
19
+ };
20
+ /**
21
+ * Plugin-runtime-scoped Lit server render session.
22
+ *
23
+ * @remarks
24
+ * Owns worker lifecycle and SSR preload for Lit page routes during static export
25
+ * and runtime/dev requests. Injected into `LitRenderer` via a lazy accessor from
26
+ * `LitPlugin`; there is no process-global coordinator.
27
+ *
28
+ * Worker init identity is sticky for the first `{ configModulePath, runtimeOrigin }`.
29
+ * Later `ensureWorker` calls with the same identity are no-ops; a different identity
30
+ * recreates the worker so stale config/origin is never silently reused.
31
+ */
32
+ export declare class LitStaticRenderSession {
33
+ private readonly preloader;
34
+ private readonly createWorkerClient;
35
+ private workerClient;
36
+ private workerIdentity;
37
+ private readonly getInvalidationVersion;
38
+ private workerInvalidationVersion;
39
+ private renderChain;
40
+ constructor(options: LitStaticRenderSessionOptions);
41
+ /**
42
+ * Ensures the static render worker is running for the given identity.
43
+ *
44
+ * @remarks
45
+ * First successful start sticks that identity. Matching re-entry is a no-op.
46
+ * A different `configModulePath` or `runtimeOrigin` disposes and recreates.
47
+ */
48
+ ensureWorker(input: {
49
+ configModulePath: string;
50
+ runtimeOrigin: string;
51
+ }): Promise<void>;
52
+ preloadStaticRoutes(context: StaticExportContext): Promise<void>;
53
+ preloadSsrScripts(components: Array<CustomElementSsrPreloadComponent | undefined>): Promise<void>;
54
+ renderPageInWorker(input: {
55
+ filePath: string;
56
+ params: PageParams;
57
+ query?: PageQuery;
58
+ }): Promise<LitStaticRenderResult>;
59
+ dispose(): Promise<void>;
60
+ private preloadLitRoutes;
61
+ private isLitRoute;
62
+ }
63
+ export {};