evolit 0.4.4 → 0.4.5
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 +6 -1
- package/package.json +1 -1
- package/src/compiler.js +21 -20
- package/src/litsx-pipeline.js +97 -9
package/README.md
CHANGED
|
@@ -444,12 +444,17 @@ configuration therefore stays isolated per render, extracted SSR data is read
|
|
|
444
444
|
before the scope closes, and integration response headers are included before
|
|
445
445
|
the response is cached.
|
|
446
446
|
|
|
447
|
-
The supported SSR combination is `evolit@0.4.
|
|
447
|
+
The supported SSR combination is `evolit@0.4.5` or newer,
|
|
448
448
|
`@litsx/core@1.0.0-next.8` or newer, and `@litsx/urql@0.4.2` or newer. Evolit
|
|
449
449
|
resolves the server-conditioned URQL adapter from the application project and
|
|
450
450
|
uses that same module instance for setup, request resources, route rendering,
|
|
451
451
|
SSR extraction, and cleanup.
|
|
452
452
|
|
|
453
|
+
The concurrent UnoCSS + URQL regression gate is validated with
|
|
454
|
+
`evolit@0.4.5`, `@litsx/compiler@1.0.0-next.13`,
|
|
455
|
+
`@litsx/ssr@1.0.0-next.5`, `@litsx/unocss@1.0.0-next.8`,
|
|
456
|
+
`@litsx/urql@0.4.2`, and `unocss@66.8.1`.
|
|
457
|
+
|
|
453
458
|
## Extensions
|
|
454
459
|
|
|
455
460
|
Optional integrations are configured explicitly in `evolit.config.js`. Core only coordinates their
|
package/package.json
CHANGED
package/src/compiler.js
CHANGED
|
@@ -28,6 +28,7 @@ const RESOLVABLE_IMPORT_EXTENSIONS = [
|
|
|
28
28
|
const developmentGraphCache = new Map();
|
|
29
29
|
const developmentGraphDependencies = new Map();
|
|
30
30
|
const developmentModuleNamespaceCache = new Map();
|
|
31
|
+
const productionModuleNamespaceCache = new Map();
|
|
31
32
|
const developmentGraphVersions = new Map();
|
|
32
33
|
const developmentUnmanagedImportWarnings = new Set();
|
|
33
34
|
const projectPathAliasesCache = new Map();
|
|
@@ -1785,34 +1786,34 @@ export async function emitClientStaticAssets(assetPaths, options = {}) {
|
|
|
1785
1786
|
|
|
1786
1787
|
export async function importCompiledModule(entryPath, options = {}) {
|
|
1787
1788
|
const mode = options.mode ?? "development";
|
|
1788
|
-
const normalizedOptions =
|
|
1789
|
-
|
|
1790
|
-
: options
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1789
|
+
const normalizedOptions = {
|
|
1790
|
+
...options,
|
|
1791
|
+
projectRoot: path.resolve(options.projectRoot ?? process.cwd()),
|
|
1792
|
+
};
|
|
1793
|
+
const cacheKey = getDevelopmentGraphCacheKey(path.resolve(entryPath), normalizedOptions);
|
|
1794
|
+
const moduleCache = mode === "development"
|
|
1795
|
+
? developmentModuleNamespaceCache
|
|
1796
|
+
: productionModuleNamespaceCache;
|
|
1797
|
+
const cachedModule = moduleCache.get(cacheKey);
|
|
1795
1798
|
if (cachedModule) {
|
|
1796
1799
|
return cachedModule;
|
|
1797
1800
|
}
|
|
1798
1801
|
|
|
1799
|
-
const
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
developmentModuleNamespaceCache.set(cacheKey, pendingModule);
|
|
1809
|
-
}
|
|
1802
|
+
const pendingModule = (async () => {
|
|
1803
|
+
const { entrypoint } = await compileModuleGraph(entryPath, normalizedOptions);
|
|
1804
|
+
const moduleUrl = new URL(pathToFileURL(entrypoint).href);
|
|
1805
|
+
if (mode === "development") {
|
|
1806
|
+
moduleUrl.searchParams.set("t", String(developmentGraphVersions.get(cacheKey) ?? 0));
|
|
1807
|
+
}
|
|
1808
|
+
return import(moduleUrl.href);
|
|
1809
|
+
})();
|
|
1810
|
+
moduleCache.set(cacheKey, pendingModule);
|
|
1810
1811
|
|
|
1811
1812
|
try {
|
|
1812
1813
|
return await pendingModule;
|
|
1813
1814
|
} catch (error) {
|
|
1814
|
-
if (
|
|
1815
|
-
|
|
1815
|
+
if (moduleCache.get(cacheKey) === pendingModule) {
|
|
1816
|
+
moduleCache.delete(cacheKey);
|
|
1816
1817
|
}
|
|
1817
1818
|
throw error;
|
|
1818
1819
|
}
|
package/src/litsx-pipeline.js
CHANGED
|
@@ -206,8 +206,13 @@ export async function createLitsxPipeline({ projectRoot, mode, config } = {}) {
|
|
|
206
206
|
const instances = [];
|
|
207
207
|
const names = new Set();
|
|
208
208
|
let disposed = false;
|
|
209
|
+
let closing = false;
|
|
209
210
|
let generation = 0;
|
|
210
211
|
let finalizedGeneration = -1;
|
|
212
|
+
let finalizationFlight = null;
|
|
213
|
+
let invalidationFlight = null;
|
|
214
|
+
let queuedFinalization = null;
|
|
215
|
+
let disposalPromise = null;
|
|
211
216
|
const dependencies = new Set();
|
|
212
217
|
const processedModules = new Set();
|
|
213
218
|
const moduleDependencies = new Map();
|
|
@@ -288,7 +293,7 @@ export async function createLitsxPipeline({ projectRoot, mode, config } = {}) {
|
|
|
288
293
|
}
|
|
289
294
|
|
|
290
295
|
function assertActive() {
|
|
291
|
-
if (disposed) throw new Error("This LitSX pipeline has already been disposed.");
|
|
296
|
+
if (closing || disposed) throw new Error("This LitSX pipeline has already been disposed.");
|
|
292
297
|
}
|
|
293
298
|
|
|
294
299
|
function recordContribution(integrationName, moduleId, contribution) {
|
|
@@ -496,16 +501,43 @@ export async function createLitsxPipeline({ projectRoot, mode, config } = {}) {
|
|
|
496
501
|
evolitDependencies: [...(moduleDependencies.get(moduleId) ?? [])].sort(),
|
|
497
502
|
};
|
|
498
503
|
},
|
|
499
|
-
|
|
504
|
+
finalize(context = {}) {
|
|
500
505
|
assertActive();
|
|
501
|
-
if (
|
|
506
|
+
if (invalidationFlight) {
|
|
507
|
+
if (queuedFinalization) return queuedFinalization.promise;
|
|
508
|
+
const awaitedInvalidation = invalidationFlight.promise;
|
|
509
|
+
const promise = awaitedInvalidation.then(() => {
|
|
510
|
+
if (queuedFinalization?.promise === promise) queuedFinalization = null;
|
|
511
|
+
return pipeline.finalize(context);
|
|
512
|
+
});
|
|
513
|
+
queuedFinalization = { promise };
|
|
514
|
+
promise.then(
|
|
515
|
+
() => {
|
|
516
|
+
if (queuedFinalization?.promise === promise) queuedFinalization = null;
|
|
517
|
+
},
|
|
518
|
+
() => {
|
|
519
|
+
if (queuedFinalization?.promise === promise) queuedFinalization = null;
|
|
520
|
+
},
|
|
521
|
+
);
|
|
522
|
+
return promise;
|
|
523
|
+
}
|
|
524
|
+
if (finalizedGeneration === generation) return Promise.resolve(null);
|
|
525
|
+
if (finalizationFlight?.generation === generation) return finalizationFlight.promise;
|
|
526
|
+
if (finalizationFlight) {
|
|
527
|
+
return finalizationFlight.promise.then(
|
|
528
|
+
() => pipeline.finalize(context),
|
|
529
|
+
() => pipeline.finalize(context),
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
const targetGeneration = generation;
|
|
533
|
+
const publishGeneration = async () => {
|
|
502
534
|
if (moduleDependencies.delete("<graph>")) rebuildDependencies();
|
|
503
535
|
removeOwnedContributions("<graph>");
|
|
504
536
|
for (const { descriptor, instance } of instances) {
|
|
505
537
|
if (typeof instance.finalize !== "function") continue;
|
|
506
538
|
try {
|
|
507
539
|
const contribution = normalizeContribution(
|
|
508
|
-
await instance.finalize(Object.freeze({ ...context, generation, mode })),
|
|
540
|
+
await instance.finalize(Object.freeze({ ...context, generation: targetGeneration, mode })),
|
|
509
541
|
descriptor.name,
|
|
510
542
|
resolvedProjectRoot,
|
|
511
543
|
);
|
|
@@ -539,6 +571,7 @@ export async function createLitsxPipeline({ projectRoot, mode, config } = {}) {
|
|
|
539
571
|
hadPreviousRoot: false,
|
|
540
572
|
installed: false,
|
|
541
573
|
};
|
|
574
|
+
rootOperations.push(operation);
|
|
542
575
|
if (outputs.length > 0) {
|
|
543
576
|
operation.stagingRoot = `${root}.staging-${randomUUID()}`;
|
|
544
577
|
await ensureDirectory(operation.stagingRoot);
|
|
@@ -558,7 +591,6 @@ export async function createLitsxPipeline({ projectRoot, mode, config } = {}) {
|
|
|
558
591
|
if (output.kind === "style" && output.document) manifest.documentStyles.push(record);
|
|
559
592
|
}
|
|
560
593
|
}
|
|
561
|
-
rootOperations.push(operation);
|
|
562
594
|
}
|
|
563
595
|
|
|
564
596
|
for (const { output, integrationName } of pendingOutputs.values()) {
|
|
@@ -634,10 +666,22 @@ export async function createLitsxPipeline({ projectRoot, mode, config } = {}) {
|
|
|
634
666
|
if (operation.stagingRoot) publishedRoots.set(operation.integrationName, operation.root);
|
|
635
667
|
else publishedRoots.delete(operation.integrationName);
|
|
636
668
|
}
|
|
637
|
-
finalizedGeneration =
|
|
669
|
+
finalizedGeneration = targetGeneration;
|
|
638
670
|
return manifest;
|
|
671
|
+
};
|
|
672
|
+
const promise = publishGeneration();
|
|
673
|
+
finalizationFlight = { generation: targetGeneration, promise };
|
|
674
|
+
promise.then(
|
|
675
|
+
() => {
|
|
676
|
+
if (finalizationFlight?.promise === promise) finalizationFlight = null;
|
|
677
|
+
},
|
|
678
|
+
() => {
|
|
679
|
+
if (finalizationFlight?.promise === promise) finalizationFlight = null;
|
|
680
|
+
},
|
|
681
|
+
);
|
|
682
|
+
return promise;
|
|
639
683
|
},
|
|
640
|
-
|
|
684
|
+
invalidate(changedPaths = null) {
|
|
641
685
|
assertActive();
|
|
642
686
|
const paths = Array.isArray(changedPaths)
|
|
643
687
|
? changedPaths.map((entry) => canonicalDependency(resolvedProjectRoot, entry))
|
|
@@ -645,6 +689,26 @@ export async function createLitsxPipeline({ projectRoot, mode, config } = {}) {
|
|
|
645
689
|
const affected = paths == null || paths.some((entry) => (
|
|
646
690
|
dependencies.has(entry) || processedModules.has(entry)
|
|
647
691
|
));
|
|
692
|
+
const previousInvalidation = invalidationFlight?.promise ?? null;
|
|
693
|
+
const activeFinalization = finalizationFlight?.promise ?? null;
|
|
694
|
+
const promise = (async () => {
|
|
695
|
+
if (previousInvalidation) {
|
|
696
|
+
try {
|
|
697
|
+
await previousInvalidation;
|
|
698
|
+
} catch {
|
|
699
|
+
// A later invalidation is allowed to recover from an earlier failure.
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
if (activeFinalization) {
|
|
703
|
+
try {
|
|
704
|
+
await activeFinalization;
|
|
705
|
+
} catch {
|
|
706
|
+
// Failed finalization leaves the generation retryable before invalidation.
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
if (closing || disposed) {
|
|
710
|
+
throw new Error("This LitSX pipeline has already been disposed.");
|
|
711
|
+
}
|
|
648
712
|
for (const { descriptor, instance } of instances) {
|
|
649
713
|
if (typeof instance.invalidate !== "function") continue;
|
|
650
714
|
try {
|
|
@@ -661,6 +725,17 @@ export async function createLitsxPipeline({ projectRoot, mode, config } = {}) {
|
|
|
661
725
|
}
|
|
662
726
|
}
|
|
663
727
|
return affected;
|
|
728
|
+
})();
|
|
729
|
+
invalidationFlight = { promise };
|
|
730
|
+
promise.then(
|
|
731
|
+
() => {
|
|
732
|
+
if (invalidationFlight?.promise === promise) invalidationFlight = null;
|
|
733
|
+
},
|
|
734
|
+
() => {
|
|
735
|
+
if (invalidationFlight?.promise === promise) invalidationFlight = null;
|
|
736
|
+
},
|
|
737
|
+
);
|
|
738
|
+
return promise;
|
|
664
739
|
},
|
|
665
740
|
async forget(moduleId) {
|
|
666
741
|
assertActive();
|
|
@@ -683,8 +758,19 @@ export async function createLitsxPipeline({ projectRoot, mode, config } = {}) {
|
|
|
683
758
|
await removePath(virtualModule);
|
|
684
759
|
}
|
|
685
760
|
},
|
|
686
|
-
|
|
687
|
-
if (
|
|
761
|
+
dispose() {
|
|
762
|
+
if (disposalPromise) return disposalPromise;
|
|
763
|
+
if (disposed) return Promise.resolve();
|
|
764
|
+
closing = true;
|
|
765
|
+
disposalPromise = (async () => {
|
|
766
|
+
for (const flight of [queuedFinalization, invalidationFlight, finalizationFlight]) {
|
|
767
|
+
if (!flight) continue;
|
|
768
|
+
try {
|
|
769
|
+
await flight.promise;
|
|
770
|
+
} catch {
|
|
771
|
+
// The original caller owns a lifecycle error; disposal still completes.
|
|
772
|
+
}
|
|
773
|
+
}
|
|
688
774
|
disposed = true;
|
|
689
775
|
let firstError = null;
|
|
690
776
|
for (const { descriptor, instance } of [...instances].reverse()) {
|
|
@@ -696,6 +782,8 @@ export async function createLitsxPipeline({ projectRoot, mode, config } = {}) {
|
|
|
696
782
|
}
|
|
697
783
|
await removePath(virtualRoot);
|
|
698
784
|
if (firstError) throw firstError;
|
|
785
|
+
})();
|
|
786
|
+
return disposalPromise;
|
|
699
787
|
},
|
|
700
788
|
};
|
|
701
789
|
|