evolit 0.3.0 → 0.4.0
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.
- package/README.md +62 -0
- package/package.json +7 -1
- package/src/build.js +65 -10
- package/src/client-assets.js +1 -0
- package/src/compiler.js +53 -11
- package/src/deployment-runtime.js +60 -6
- package/src/index.js +3 -0
- package/src/litsx-pipeline.d.ts +137 -0
- package/src/litsx-pipeline.js +705 -0
- package/src/render.js +1 -0
- package/src/server-setup.js +2 -1
- package/src/server.js +40 -1
package/README.md
CHANGED
|
@@ -321,6 +321,68 @@ server components and helpers that do not receive route props directly. It retur
|
|
|
321
321
|
Reading `getRouteState().url` has the same dynamic-rendering semantics as `requestUrl()`; reading
|
|
322
322
|
`params` and `searchParams` participates in the normal segment-cache key tracking.
|
|
323
323
|
|
|
324
|
+
## LitSX compiler integrations
|
|
325
|
+
|
|
326
|
+
`evolit.config.js` can configure the native LitSX compiler and register build-tool-neutral LitSX
|
|
327
|
+
integrations. The same declaration is used by development, SSR, hydration, production builds and
|
|
328
|
+
the standalone runtime:
|
|
329
|
+
|
|
330
|
+
```js
|
|
331
|
+
import { litsxUnoCss } from "@litsx/unocss";
|
|
332
|
+
import { defineEvolitConfig } from "evolit/litsx";
|
|
333
|
+
|
|
334
|
+
export default defineEvolitConfig({
|
|
335
|
+
litsx: {
|
|
336
|
+
compiler: {
|
|
337
|
+
sourceMaps: true,
|
|
338
|
+
},
|
|
339
|
+
integrations: [litsxUnoCss()],
|
|
340
|
+
},
|
|
341
|
+
});
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
This is the complete Evolit + UnoCSS setup. The application does not coordinate compiler plugins,
|
|
345
|
+
virtual modules, generation, finalization or global CSS links, and it does not need Vite or
|
|
346
|
+
PostCSS. `@litsx/unocss` remains the owner of candidate extraction and CSS generation; Evolit only
|
|
347
|
+
executes its neutral LitSX lifecycle.
|
|
348
|
+
|
|
349
|
+
`compiler` accepts the public `TransformLitsxOptions` surface except the values Evolit must own for
|
|
350
|
+
correct server and browser graphs. Evolit always supplies the current `filename`, selects `ssr` per
|
|
351
|
+
target and forces native lowering with `reactCompat: false`; `compiler.sourceMaps` can override the
|
|
352
|
+
existing per-pipeline default without changing applications that omit `litsx`.
|
|
353
|
+
Authoring and output plugins contributed by the application and integrations are composed in
|
|
354
|
+
declaration order rather than replacing framework invariants.
|
|
355
|
+
|
|
356
|
+
An integration is a descriptor with a unique `name` and `create(context)` method. Each call to
|
|
357
|
+
`create` belongs to exactly one development server, build or standalone runtime, so mutable caches
|
|
358
|
+
must live on the returned instance, never on the descriptor. An instance can contribute:
|
|
359
|
+
|
|
360
|
+
- `compiler`: native compiler options, including authoring and output plugins.
|
|
361
|
+
- `resolveModule`: sources for integration-owned virtual modules in both server and browser graphs.
|
|
362
|
+
- `processModule`: post-processing, observable dependencies and preliminary outputs for a compiled
|
|
363
|
+
module.
|
|
364
|
+
- `finalize`: graph-wide assets, styles or modules after every reachable module is known.
|
|
365
|
+
- `invalidate` and `forget`: configuration/dependency refresh and removal of stale module state.
|
|
366
|
+
- `dispose`: idempotent cleanup when the owning server, build or runtime closes.
|
|
367
|
+
|
|
368
|
+
Declared outputs use stable IDs unique within the pipeline and one of `asset`, `module` or `style`. A module
|
|
369
|
+
may expose a safe `virtual:` specifier; a style with `document: true` is content-hashed, included in
|
|
370
|
+
the client asset manifest and linked once in the document. Evolit publishes a generation only after
|
|
371
|
+
every integration finalizes successfully, so a failed generation cannot expose a partial mix of
|
|
372
|
+
old and new assets.
|
|
373
|
+
|
|
374
|
+
In development, dependencies reported by compiler plugins and lifecycle hooks are watched together
|
|
375
|
+
with application modules. Invalidating a dependency advances the integration generation, evicts
|
|
376
|
+
affected compiled modules and calls `forget` for modules that leave the graph. Configuration reload
|
|
377
|
+
therefore removes obsolete results instead of accumulating them. Hook failures identify the
|
|
378
|
+
integration, lifecycle phase and relevant module in development; production errors keep the same
|
|
379
|
+
context while redacting project-local absolute paths.
|
|
380
|
+
|
|
381
|
+
For native Shadow DOM, `@litsx/unocss` serializes component preflight inside each Declarative Shadow
|
|
382
|
+
Root, preserves authored `Component.styles` before generated utilities, and emits the document
|
|
383
|
+
theme/custom-property layers once. Those document variables inherit through Shadow Roots and the
|
|
384
|
+
browser hydrates the server result without switching to `react-compat`.
|
|
385
|
+
|
|
324
386
|
## Server Setup
|
|
325
387
|
|
|
326
388
|
Server integrations that need one-time application setup can be registered with
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "evolit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "A convention-driven application framework for LitSX and web components.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "yarn@4.10.3",
|
|
@@ -34,6 +34,10 @@
|
|
|
34
34
|
"browser": "./src/extensions-client.js",
|
|
35
35
|
"default": "./src/extensions.js"
|
|
36
36
|
},
|
|
37
|
+
"./litsx": {
|
|
38
|
+
"types": "./src/litsx-pipeline.d.ts",
|
|
39
|
+
"default": "./src/litsx-pipeline.js"
|
|
40
|
+
},
|
|
37
41
|
"./internal/development-hot": "./src/development-hot-client.js"
|
|
38
42
|
},
|
|
39
43
|
"scripts": {
|
|
@@ -79,8 +83,10 @@
|
|
|
79
83
|
}
|
|
80
84
|
},
|
|
81
85
|
"devDependencies": {
|
|
86
|
+
"@litsx/unocss": "1.0.0-next.8",
|
|
82
87
|
"@playwright/test": "^1.62.0",
|
|
83
88
|
"@webcomponents/scoped-custom-element-registry": "^0.0.10",
|
|
89
|
+
"unocss": "66.8.1",
|
|
84
90
|
"vite": "^8.1.5"
|
|
85
91
|
}
|
|
86
92
|
}
|
package/src/build.js
CHANGED
|
@@ -58,6 +58,7 @@ import {
|
|
|
58
58
|
runWithOptionalSsrUrqlScope,
|
|
59
59
|
} from "./urql-ssr.js";
|
|
60
60
|
import { runServerSetup } from "./server-setup.js";
|
|
61
|
+
import { createLitsxPipeline, mergeLitsxAssetsIntoManifest } from "./litsx-pipeline.js";
|
|
61
62
|
|
|
62
63
|
const CONTENT_TYPE_BY_EXTENSION = new Map([
|
|
63
64
|
[".css", "text/css; charset=utf-8"],
|
|
@@ -163,11 +164,20 @@ async function writeDeploymentRuntimeEntry(buildRoot) {
|
|
|
163
164
|
|
|
164
165
|
export async function buildProject(projectRoot, options = {}) {
|
|
165
166
|
const evolitConfig = await loadEvolitConfig(projectRoot);
|
|
166
|
-
const
|
|
167
|
+
const litsxPipeline = await createLitsxPipeline({
|
|
167
168
|
projectRoot,
|
|
168
169
|
mode: "production",
|
|
169
|
-
evolitConfig,
|
|
170
|
+
config: evolitConfig,
|
|
170
171
|
});
|
|
172
|
+
let serverSetupCleanup = null;
|
|
173
|
+
let buildError = null;
|
|
174
|
+
try {
|
|
175
|
+
serverSetupCleanup = await runServerSetup({
|
|
176
|
+
projectRoot,
|
|
177
|
+
mode: "production",
|
|
178
|
+
evolitConfig,
|
|
179
|
+
litsxPipeline,
|
|
180
|
+
});
|
|
171
181
|
const extensions = resolveEvolitExtensions(evolitConfig);
|
|
172
182
|
const extensionClientDescriptors = getExtensionClientDescriptors(extensions);
|
|
173
183
|
const packageClientSpecifiers = new Set(
|
|
@@ -194,6 +204,7 @@ export async function buildProject(projectRoot, options = {}) {
|
|
|
194
204
|
sourceMaps: false,
|
|
195
205
|
ssr: true,
|
|
196
206
|
target: "server",
|
|
207
|
+
litsxPipeline,
|
|
197
208
|
});
|
|
198
209
|
result.packageImports.forEach((specifier) => ssrPackageImports.add(specifier));
|
|
199
210
|
return result;
|
|
@@ -202,7 +213,7 @@ export async function buildProject(projectRoot, options = {}) {
|
|
|
202
213
|
function getEntryInventory(entryPath) {
|
|
203
214
|
let inventory = inventoriesBySourceEntry.get(entryPath);
|
|
204
215
|
if (!inventory) {
|
|
205
|
-
inventory = collectClientGraphInventory([entryPath], { projectRoot });
|
|
216
|
+
inventory = collectClientGraphInventory([entryPath], { projectRoot, litsxPipeline });
|
|
206
217
|
inventoriesBySourceEntry.set(entryPath, inventory);
|
|
207
218
|
}
|
|
208
219
|
return inventory;
|
|
@@ -216,6 +227,7 @@ export async function buildProject(projectRoot, options = {}) {
|
|
|
216
227
|
mode: "production",
|
|
217
228
|
sourceMaps: true,
|
|
218
229
|
target: "client",
|
|
230
|
+
litsxPipeline,
|
|
219
231
|
});
|
|
220
232
|
clientModule = path.relative(clientBuild.outputRoot, clientBuild.entrypoint)
|
|
221
233
|
.split(path.sep)
|
|
@@ -235,6 +247,7 @@ export async function buildProject(projectRoot, options = {}) {
|
|
|
235
247
|
mode: "production",
|
|
236
248
|
ssr: true,
|
|
237
249
|
target: "server",
|
|
250
|
+
litsxPipeline,
|
|
238
251
|
});
|
|
239
252
|
const methods = Object.keys(handlerModule)
|
|
240
253
|
.filter((name) => /^[A-Z]+$/.test(name) && typeof handlerModule[name] === "function")
|
|
@@ -345,18 +358,20 @@ export async function buildProject(projectRoot, options = {}) {
|
|
|
345
358
|
}
|
|
346
359
|
|
|
347
360
|
sharedVendorOptions.additionalEntrySpecifiers = [...packageClientSpecifiers].sort();
|
|
348
|
-
|
|
361
|
+
let clientAssets = await emitBundledClientAssets(projectRoot, {
|
|
349
362
|
entryClientModules,
|
|
350
363
|
additionalVendorSpecifiers: sharedVendorOptions.additionalEntrySpecifiers,
|
|
351
364
|
serverAssetImportsByEntry,
|
|
352
365
|
clientBoundariesByEntry,
|
|
353
366
|
});
|
|
367
|
+
const integrationOutputs = await litsxPipeline?.finalize({
|
|
368
|
+
routes,
|
|
369
|
+
routeHandlers,
|
|
370
|
+
});
|
|
371
|
+
clientAssets = mergeLitsxAssetsIntoManifest(clientAssets, integrationOutputs);
|
|
354
372
|
const staticAssetPublicUrls = createStaticAssetPublicUrlMap(clientAssets);
|
|
355
373
|
await rewriteServerAssetPlaceholders(projectRoot, clientAssets);
|
|
356
374
|
|
|
357
|
-
const routeResolver = await createRouteResolver(projectRoot, "production", {
|
|
358
|
-
staticAssetPublicUrls,
|
|
359
|
-
});
|
|
360
375
|
const sharedRuntime = await buildSharedVendorRuntime(projectRoot, "production", sharedVendorOptions);
|
|
361
376
|
clientAssets.sharedImports = { ...sharedRuntime.imports };
|
|
362
377
|
const packageImports = sharedRuntime.imports;
|
|
@@ -364,6 +379,11 @@ export async function buildProject(projectRoot, options = {}) {
|
|
|
364
379
|
assetManifest: clientAssets,
|
|
365
380
|
packageImports,
|
|
366
381
|
});
|
|
382
|
+
const routeResolver = await createRouteResolver(projectRoot, "production", {
|
|
383
|
+
staticAssetPublicUrls,
|
|
384
|
+
assetResolver,
|
|
385
|
+
litsxPipeline,
|
|
386
|
+
});
|
|
367
387
|
const hydrationModuleUrl = await resolveSharedVendorModuleUrl(
|
|
368
388
|
projectRoot,
|
|
369
389
|
"production",
|
|
@@ -423,7 +443,21 @@ export async function buildProject(projectRoot, options = {}) {
|
|
|
423
443
|
}
|
|
424
444
|
continue;
|
|
425
445
|
}
|
|
426
|
-
|
|
446
|
+
const directPublicUrl = assetResolver(moduleId)
|
|
447
|
+
?? (clientAssets.byPublicPath?.[moduleId] ? moduleId : null);
|
|
448
|
+
if (directPublicUrl) {
|
|
449
|
+
if (Array.isArray(result.clientImports)) {
|
|
450
|
+
result.clientImports = result.clientImports.map((value) => (
|
|
451
|
+
value === moduleId ? directPublicUrl : value
|
|
452
|
+
));
|
|
453
|
+
}
|
|
454
|
+
if (Array.isArray(result.hydrationData?.clientImports)) {
|
|
455
|
+
result.hydrationData.clientImports = result.hydrationData.clientImports.map((value) => (
|
|
456
|
+
value === moduleId ? directPublicUrl : value
|
|
457
|
+
));
|
|
458
|
+
}
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
427
461
|
const importerPath = routeResult.boundaryModule
|
|
428
462
|
?? routeResult.route?.page
|
|
429
463
|
?? path.join(projectRoot, "app", "page.jsx");
|
|
@@ -473,6 +507,7 @@ export async function buildProject(projectRoot, options = {}) {
|
|
|
473
507
|
])]
|
|
474
508
|
: [];
|
|
475
509
|
const styleUrls = [...new Set([
|
|
510
|
+
...(clientAssets.documentStyles ?? []),
|
|
476
511
|
...collectTransitiveStyleUrls(clientImports, clientAssets),
|
|
477
512
|
...resolveServerStyleUrls(routeResult, projectRoot, clientAssets),
|
|
478
513
|
])];
|
|
@@ -650,6 +685,11 @@ export async function buildProject(projectRoot, options = {}) {
|
|
|
650
685
|
cache: sortedRouteCache.find((entry) => entry.pathname === artifact.routePathname)?.cache
|
|
651
686
|
?? "static",
|
|
652
687
|
})),
|
|
688
|
+
...(integrationOutputs?.assets ?? []).map((asset) => ({
|
|
689
|
+
kind: asset.kind,
|
|
690
|
+
outputPath: toBuildRelativePath(projectRoot, asset.outputPath),
|
|
691
|
+
integration: asset.integration,
|
|
692
|
+
})),
|
|
653
693
|
],
|
|
654
694
|
};
|
|
655
695
|
const manifestPath = path.join(buildRoot, MANIFEST_FILENAME);
|
|
@@ -676,7 +716,22 @@ export async function buildProject(projectRoot, options = {}) {
|
|
|
676
716
|
await writeJson(path.join(buildRoot, DEPLOY_ASSETS_MANIFEST_FILENAME), deployAssets);
|
|
677
717
|
await writeJson(path.join(buildRoot, DEPLOY_SERVER_MANIFEST_FILENAME), deployServer);
|
|
678
718
|
|
|
679
|
-
await serverSetupCleanup?.();
|
|
680
|
-
|
|
681
719
|
return manifestPath;
|
|
720
|
+
} catch (error) {
|
|
721
|
+
buildError = error;
|
|
722
|
+
throw error;
|
|
723
|
+
} finally {
|
|
724
|
+
let cleanupError = null;
|
|
725
|
+
try {
|
|
726
|
+
await serverSetupCleanup?.();
|
|
727
|
+
} catch (error) {
|
|
728
|
+
cleanupError = error;
|
|
729
|
+
}
|
|
730
|
+
try {
|
|
731
|
+
await litsxPipeline?.dispose();
|
|
732
|
+
} catch (error) {
|
|
733
|
+
cleanupError ??= error;
|
|
734
|
+
}
|
|
735
|
+
if (!buildError && cleanupError) throw cleanupError;
|
|
736
|
+
}
|
|
682
737
|
}
|
package/src/client-assets.js
CHANGED
|
@@ -2483,6 +2483,7 @@ export function normalizeClientAssetManifest(manifest) {
|
|
|
2483
2483
|
manifest.clientBoundariesByEntry && typeof manifest.clientBoundariesByEntry === "object"
|
|
2484
2484
|
? manifest.clientBoundariesByEntry
|
|
2485
2485
|
: {},
|
|
2486
|
+
documentStyles: Array.isArray(manifest.documentStyles) ? manifest.documentStyles : [],
|
|
2486
2487
|
assets: manifest.assets,
|
|
2487
2488
|
};
|
|
2488
2489
|
}
|
package/src/compiler.js
CHANGED
|
@@ -182,14 +182,28 @@ async function transformModuleSource(source, {
|
|
|
182
182
|
sourcePath,
|
|
183
183
|
sourceMaps,
|
|
184
184
|
ssr = false,
|
|
185
|
+
target = ssr ? "server" : "client",
|
|
186
|
+
litsxPipeline = null,
|
|
185
187
|
}) {
|
|
186
188
|
if (isLitsxAuthoredModule(sourcePath, source)) {
|
|
187
|
-
const
|
|
188
|
-
filename: sourcePath,
|
|
189
|
-
sourceMaps,
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
189
|
+
const compilerOptions = litsxPipeline
|
|
190
|
+
? litsxPipeline.getCompilerOptions({ filename: sourcePath, sourceMaps, ssr })
|
|
191
|
+
: { filename: sourcePath, sourceMaps, ssr };
|
|
192
|
+
const transformed = restoreSideEffectImports(
|
|
193
|
+
source,
|
|
194
|
+
sourcePath,
|
|
195
|
+
await transformLitsx(source, compilerOptions),
|
|
196
|
+
compilerOptions.sourceMaps === true,
|
|
197
|
+
);
|
|
198
|
+
return litsxPipeline
|
|
199
|
+
? litsxPipeline.processModule(transformed, {
|
|
200
|
+
source,
|
|
201
|
+
sourcePath,
|
|
202
|
+
sourceMaps: compilerOptions.sourceMaps === true,
|
|
203
|
+
ssr: ssr === true,
|
|
204
|
+
target,
|
|
205
|
+
})
|
|
206
|
+
: transformed;
|
|
193
207
|
}
|
|
194
208
|
|
|
195
209
|
if (sourcePath.endsWith(".ts")) {
|
|
@@ -963,6 +977,7 @@ async function rewriteRelativeSpecifiers({
|
|
|
963
977
|
serverExportsByModule,
|
|
964
978
|
packageImports,
|
|
965
979
|
dynamicImportDirectories,
|
|
980
|
+
litsxPipeline,
|
|
966
981
|
}) {
|
|
967
982
|
const magicSource = new MagicString(code);
|
|
968
983
|
let didRewrite = false;
|
|
@@ -974,10 +989,19 @@ async function rewriteRelativeSpecifiers({
|
|
|
974
989
|
for (const reference of moduleReferences.staticReferences) {
|
|
975
990
|
const { specifier } = reference;
|
|
976
991
|
|
|
977
|
-
const
|
|
992
|
+
const virtualImportPath = litsxPipeline
|
|
993
|
+
? await litsxPipeline.resolveModule(specifier, {
|
|
994
|
+
importer: sourcePath,
|
|
995
|
+
target,
|
|
996
|
+
ssr: target === "server",
|
|
997
|
+
sourceMaps,
|
|
998
|
+
})
|
|
999
|
+
: null;
|
|
1000
|
+
|
|
1001
|
+
const aliasedImportPath = !virtualImportPath && isBareSpecifier(specifier)
|
|
978
1002
|
? await resolveProjectMappedImport(projectRoot, sourcePath, specifier)
|
|
979
1003
|
: null;
|
|
980
|
-
const packageImportPath = isBareSpecifier(specifier) && !aliasedImportPath
|
|
1004
|
+
const packageImportPath = !virtualImportPath && isBareSpecifier(specifier) && !aliasedImportPath
|
|
981
1005
|
? await resolveProjectPackageImport(projectRoot, sourcePath, specifier)
|
|
982
1006
|
: null;
|
|
983
1007
|
const packageAssetPath = packageImportPath && isStaticAssetPath(packageImportPath)
|
|
@@ -987,6 +1011,7 @@ async function rewriteRelativeSpecifiers({
|
|
|
987
1011
|
if (
|
|
988
1012
|
target === "server"
|
|
989
1013
|
&& isBareSpecifier(specifier)
|
|
1014
|
+
&& !virtualImportPath
|
|
990
1015
|
&& !aliasedImportPath
|
|
991
1016
|
&& !packageAssetPath
|
|
992
1017
|
) {
|
|
@@ -996,6 +1021,7 @@ async function rewriteRelativeSpecifiers({
|
|
|
996
1021
|
if (
|
|
997
1022
|
target === "client"
|
|
998
1023
|
&& isBareSpecifier(specifier)
|
|
1024
|
+
&& !virtualImportPath
|
|
999
1025
|
&& !aliasedImportPath
|
|
1000
1026
|
&& !packageAssetPath
|
|
1001
1027
|
) {
|
|
@@ -1010,11 +1036,12 @@ async function rewriteRelativeSpecifiers({
|
|
|
1010
1036
|
continue;
|
|
1011
1037
|
}
|
|
1012
1038
|
|
|
1013
|
-
if (!isRelativeSpecifier(specifier) && !aliasedImportPath && !packageAssetPath) {
|
|
1039
|
+
if (!virtualImportPath && !isRelativeSpecifier(specifier) && !aliasedImportPath && !packageAssetPath) {
|
|
1014
1040
|
continue;
|
|
1015
1041
|
}
|
|
1016
1042
|
|
|
1017
|
-
const resolvedImportPath =
|
|
1043
|
+
const resolvedImportPath = virtualImportPath
|
|
1044
|
+
?? packageAssetPath
|
|
1018
1045
|
?? aliasedImportPath
|
|
1019
1046
|
?? await resolveImportPath(sourcePath, specifier);
|
|
1020
1047
|
if (!resolvedImportPath) {
|
|
@@ -1033,6 +1060,9 @@ async function rewriteRelativeSpecifiers({
|
|
|
1033
1060
|
|
|
1034
1061
|
if (shouldCompileModule(resolvedImportPath)) {
|
|
1035
1062
|
compiledImportPath = await compileModule(resolvedImportPath);
|
|
1063
|
+
if (virtualImportPath) {
|
|
1064
|
+
litsxPipeline?.registerResolvedModule(specifier, resolvedImportPath, compiledImportPath);
|
|
1065
|
+
}
|
|
1036
1066
|
const serverExports = serverExportsByModule?.get(resolvedImportPath) ?? new Set();
|
|
1037
1067
|
const importedNames = importedNamesBySpecifier.get(specifier) ?? new Set();
|
|
1038
1068
|
if (
|
|
@@ -1245,6 +1275,7 @@ function getDevelopmentGraphCacheKey(entryPath, options) {
|
|
|
1245
1275
|
options.target ?? "server",
|
|
1246
1276
|
options.ssr === true ? "ssr" : "client",
|
|
1247
1277
|
options.sourceMaps === false ? "without-maps" : "with-maps",
|
|
1278
|
+
options.litsxPipeline?.identity?.id ?? "default-litsx",
|
|
1248
1279
|
].join("::");
|
|
1249
1280
|
}
|
|
1250
1281
|
|
|
@@ -1358,6 +1389,7 @@ async function compileModuleGraphUncached(entryPath, options = {}) {
|
|
|
1358
1389
|
staticAssetPublicUrls = null,
|
|
1359
1390
|
onDevelopmentEvent,
|
|
1360
1391
|
managedSourceRoots,
|
|
1392
|
+
litsxPipeline,
|
|
1361
1393
|
} = options;
|
|
1362
1394
|
|
|
1363
1395
|
const outputRoot = getTypedOutputRoot(projectRoot, mode, target);
|
|
@@ -1394,6 +1426,8 @@ async function compileModuleGraphUncached(entryPath, options = {}) {
|
|
|
1394
1426
|
sourcePath,
|
|
1395
1427
|
sourceMaps,
|
|
1396
1428
|
ssr,
|
|
1429
|
+
target,
|
|
1430
|
+
litsxPipeline,
|
|
1397
1431
|
});
|
|
1398
1432
|
const isServerComponentModule = isCompiledServerComponentModule(transformed.code);
|
|
1399
1433
|
const isMixedComponentModule = isServerComponentModule
|
|
@@ -1439,6 +1473,7 @@ async function compileModuleGraphUncached(entryPath, options = {}) {
|
|
|
1439
1473
|
serverExportsByModule,
|
|
1440
1474
|
packageImports,
|
|
1441
1475
|
dynamicImportDirectories,
|
|
1476
|
+
litsxPipeline,
|
|
1442
1477
|
});
|
|
1443
1478
|
|
|
1444
1479
|
await fs.writeFile(outputPath, rewritten.code, "utf8");
|
|
@@ -1467,7 +1502,12 @@ async function compileModuleGraphUncached(entryPath, options = {}) {
|
|
|
1467
1502
|
return {
|
|
1468
1503
|
entrypoint: await compileModule(entryPath),
|
|
1469
1504
|
outputRoot,
|
|
1470
|
-
sourceFiles: [...new Set([
|
|
1505
|
+
sourceFiles: [...new Set([
|
|
1506
|
+
...visited.keys(),
|
|
1507
|
+
...staticAssetFiles,
|
|
1508
|
+
...(litsxPipeline?.dependencies ?? []),
|
|
1509
|
+
])],
|
|
1510
|
+
integrationDependencies: litsxPipeline?.dependencies ?? [],
|
|
1471
1511
|
watchedDirectories: [...dynamicImportDirectories],
|
|
1472
1512
|
packageImports: [...packageImports].sort(),
|
|
1473
1513
|
};
|
|
@@ -1625,6 +1665,8 @@ export async function collectClientGraphInventory(entryPaths, options = {}) {
|
|
|
1625
1665
|
projectRoot,
|
|
1626
1666
|
sourcePath,
|
|
1627
1667
|
sourceMaps: false,
|
|
1668
|
+
target: "client",
|
|
1669
|
+
litsxPipeline: options.litsxPipeline,
|
|
1628
1670
|
});
|
|
1629
1671
|
const isServer = isCompiledServerComponentModule(transformed.code);
|
|
1630
1672
|
const isComponent = isCompiledClientBoundaryModule(transformed.code);
|
|
@@ -53,6 +53,7 @@ import {
|
|
|
53
53
|
runRequestExtensions,
|
|
54
54
|
} from "./extensions.js";
|
|
55
55
|
import { runServerSetup } from "./server-setup.js";
|
|
56
|
+
import { createLitsxPipeline, mergeLitsxAssetsIntoManifest } from "./litsx-pipeline.js";
|
|
56
57
|
|
|
57
58
|
function isBarePackageModuleId(value) {
|
|
58
59
|
return typeof value === "string"
|
|
@@ -259,6 +260,7 @@ export async function createRequestRenderer({
|
|
|
259
260
|
onDevelopmentEvent,
|
|
260
261
|
managedSourceRoots,
|
|
261
262
|
extensions = [],
|
|
263
|
+
litsxPipeline = null,
|
|
262
264
|
}) {
|
|
263
265
|
let currentAssetManifest = normalizeClientAssetManifest(assetManifest);
|
|
264
266
|
const extensionClientDescriptors = getExtensionClientDescriptors(extensions);
|
|
@@ -325,7 +327,11 @@ export async function createRequestRenderer({
|
|
|
325
327
|
function getDevelopmentEntryInventory(entryPath) {
|
|
326
328
|
let inventory = devInventoryByEntry.get(entryPath);
|
|
327
329
|
if (!inventory) {
|
|
328
|
-
inventory = collectClientGraphInventory([entryPath], {
|
|
330
|
+
inventory = collectClientGraphInventory([entryPath], {
|
|
331
|
+
projectRoot,
|
|
332
|
+
managedSourceRoots,
|
|
333
|
+
litsxPipeline,
|
|
334
|
+
});
|
|
329
335
|
devInventoryByEntry.set(entryPath, inventory);
|
|
330
336
|
inventory.catch(() => {
|
|
331
337
|
if (devInventoryByEntry.get(entryPath) === inventory) devInventoryByEntry.delete(entryPath);
|
|
@@ -337,6 +343,7 @@ export async function createRequestRenderer({
|
|
|
337
343
|
const resolver = await createRouteResolver(projectRoot, mode, {
|
|
338
344
|
onDevelopmentEvent,
|
|
339
345
|
managedSourceRoots,
|
|
346
|
+
litsxPipeline,
|
|
340
347
|
segmentRenderCache: sharedSegmentRenderCache,
|
|
341
348
|
getStaticAssetPublicUrls() {
|
|
342
349
|
return createStaticAssetPublicUrlMap(currentAssetManifest);
|
|
@@ -359,6 +366,7 @@ export async function createRequestRenderer({
|
|
|
359
366
|
target: "client",
|
|
360
367
|
onDevelopmentEvent,
|
|
361
368
|
managedSourceRoots,
|
|
369
|
+
litsxPipeline,
|
|
362
370
|
});
|
|
363
371
|
devPreparedClientModules.add(clientModuleKey);
|
|
364
372
|
devClientModuleDependencies.set(
|
|
@@ -387,7 +395,13 @@ export async function createRequestRenderer({
|
|
|
387
395
|
clientBoundariesByEntry: devClientBoundariesByEntry,
|
|
388
396
|
additionalVendorSpecifiers: [...packageClientSpecifiers],
|
|
389
397
|
});
|
|
390
|
-
|
|
398
|
+
const integrationOutputs = await litsxPipeline?.finalize({
|
|
399
|
+
assetManifest: bundledClientAssets.manifest,
|
|
400
|
+
});
|
|
401
|
+
currentAssetManifest = mergeLitsxAssetsIntoManifest(
|
|
402
|
+
bundledClientAssets.manifest,
|
|
403
|
+
integrationOutputs,
|
|
404
|
+
);
|
|
391
405
|
devPreviousAssetOutputPaths = new Set();
|
|
392
406
|
currentAssetResolver = createAssetResolver(projectRoot, {
|
|
393
407
|
assetManifest: currentAssetManifest,
|
|
@@ -625,6 +639,7 @@ export async function createRequestRenderer({
|
|
|
625
639
|
: [];
|
|
626
640
|
const styleUrls = currentAssetManifest
|
|
627
641
|
? [...new Set([
|
|
642
|
+
...(currentAssetManifest.documentStyles ?? []),
|
|
628
643
|
...collectTransitiveStyleUrls(clientImports, currentAssetManifest),
|
|
629
644
|
...resolveServerStyleUrls(routeResult, projectRoot, currentAssetManifest),
|
|
630
645
|
])]
|
|
@@ -857,6 +872,7 @@ export async function createRequestRenderer({
|
|
|
857
872
|
target: "client",
|
|
858
873
|
onDevelopmentEvent,
|
|
859
874
|
managedSourceRoots,
|
|
875
|
+
litsxPipeline,
|
|
860
876
|
});
|
|
861
877
|
}
|
|
862
878
|
return;
|
|
@@ -936,7 +952,10 @@ export async function createDeploymentRuntime({
|
|
|
936
952
|
evolitConfig: configuredEvolitConfig,
|
|
937
953
|
} = {}) {
|
|
938
954
|
const evolitConfig = configuredEvolitConfig ?? await loadEvolitConfig(projectRoot);
|
|
939
|
-
const
|
|
955
|
+
const litsxPipeline = await createLitsxPipeline({ projectRoot, mode, config: evolitConfig });
|
|
956
|
+
let serverSetupCleanup = null;
|
|
957
|
+
try {
|
|
958
|
+
serverSetupCleanup = await runServerSetup({ projectRoot, mode, evolitConfig, litsxPipeline });
|
|
940
959
|
const extensions = resolveEvolitExtensions(evolitConfig);
|
|
941
960
|
const extensionClientSpecifiers = getExtensionClientDescriptors(extensions).map((descriptor) => descriptor.module);
|
|
942
961
|
const effectiveManagedSourceRoots = managedSourceRoots
|
|
@@ -994,18 +1013,26 @@ export async function createDeploymentRuntime({
|
|
|
994
1013
|
onDevelopmentEvent,
|
|
995
1014
|
managedSourceRoots: effectiveManagedSourceRoots,
|
|
996
1015
|
extensions,
|
|
1016
|
+
litsxPipeline,
|
|
997
1017
|
});
|
|
1018
|
+
let closed = false;
|
|
998
1019
|
|
|
999
1020
|
return {
|
|
1000
1021
|
assets,
|
|
1001
1022
|
cache: renderer.responseCacheController,
|
|
1002
1023
|
renderer,
|
|
1024
|
+
get litsxDependencies() {
|
|
1025
|
+
return litsxPipeline?.dependencies ?? [];
|
|
1026
|
+
},
|
|
1003
1027
|
async invalidateDevelopmentState(changedPaths = null) {
|
|
1004
1028
|
if (mode !== "development") {
|
|
1005
1029
|
return;
|
|
1006
1030
|
}
|
|
1007
1031
|
|
|
1008
|
-
const
|
|
1032
|
+
const litsxInvalidated = await litsxPipeline?.invalidate(changedPaths);
|
|
1033
|
+
const invalidationResult = await renderer.invalidateDevelopmentState(
|
|
1034
|
+
litsxInvalidated ? null : changedPaths,
|
|
1035
|
+
);
|
|
1009
1036
|
if (typeof effectiveResponseCacheRuntime.store.clear === "function") {
|
|
1010
1037
|
await effectiveResponseCacheRuntime.store.clear();
|
|
1011
1038
|
}
|
|
@@ -1075,6 +1102,7 @@ export async function createDeploymentRuntime({
|
|
|
1075
1102
|
const { routeResult, response } = await renderer.renderRoute(resolvedRequest, routePolicyResult, {
|
|
1076
1103
|
extensionState: extensionResult,
|
|
1077
1104
|
});
|
|
1105
|
+
await litsxPipeline?.finalize({ routeResult, assetManifest: renderer.assetManifest });
|
|
1078
1106
|
runtimeState.assetManifest = normalizeClientAssetManifest(renderer.assetManifest);
|
|
1079
1107
|
return formatResponseForRequest(
|
|
1080
1108
|
request,
|
|
@@ -1082,13 +1110,39 @@ export async function createDeploymentRuntime({
|
|
|
1082
1110
|
);
|
|
1083
1111
|
},
|
|
1084
1112
|
async close() {
|
|
1113
|
+
if (closed) return;
|
|
1114
|
+
closed = true;
|
|
1115
|
+
let cleanupError = null;
|
|
1085
1116
|
const revalidationTasks = this.revalidationTasks;
|
|
1086
1117
|
if (revalidationTasks) {
|
|
1087
|
-
|
|
1118
|
+
try {
|
|
1119
|
+
await Promise.all(revalidationTasks.values());
|
|
1120
|
+
} catch (error) {
|
|
1121
|
+
cleanupError = error;
|
|
1122
|
+
}
|
|
1088
1123
|
}
|
|
1089
|
-
|
|
1124
|
+
try {
|
|
1125
|
+
await serverSetupCleanup?.();
|
|
1126
|
+
} catch (error) {
|
|
1127
|
+
cleanupError = error;
|
|
1128
|
+
}
|
|
1129
|
+
try {
|
|
1130
|
+
await litsxPipeline?.dispose();
|
|
1131
|
+
} catch (error) {
|
|
1132
|
+
cleanupError ??= error;
|
|
1133
|
+
}
|
|
1134
|
+
if (cleanupError) throw cleanupError;
|
|
1090
1135
|
},
|
|
1091
1136
|
};
|
|
1137
|
+
} catch (error) {
|
|
1138
|
+
try {
|
|
1139
|
+
await serverSetupCleanup?.();
|
|
1140
|
+
} catch {}
|
|
1141
|
+
try {
|
|
1142
|
+
await litsxPipeline?.dispose();
|
|
1143
|
+
} catch {}
|
|
1144
|
+
throw error;
|
|
1145
|
+
}
|
|
1092
1146
|
}
|
|
1093
1147
|
|
|
1094
1148
|
function addNavigationVaryHeader(response) {
|
package/src/index.js
CHANGED
|
@@ -124,6 +124,9 @@ export { getRequestContext } from "./request-context.js";
|
|
|
124
124
|
/** Defines an Evolit extension for use in evolit.config.js. */
|
|
125
125
|
export { defineEvolitPlugin } from "./extensions.js";
|
|
126
126
|
|
|
127
|
+
/** Defines a typed Evolit configuration, including the native LitSX pipeline. */
|
|
128
|
+
export { defineEvolitConfig, defineLitsxIntegration } from "./litsx-pipeline.js";
|
|
129
|
+
|
|
127
130
|
/**
|
|
128
131
|
* Returns the incoming request URL. Reading it makes the current route dynamic.
|
|
129
132
|
*
|