@vertz/ui-server 0.2.28 → 0.2.30
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/dist/bun-dev-server.d.ts +24 -1
- package/dist/bun-dev-server.js +99 -68
- package/dist/bun-plugin/index.d.ts +2 -2
- package/dist/index.d.ts +21 -0
- package/dist/index.js +17 -476
- package/dist/shared/chunk-bd0sgykf.js +1468 -0
- package/dist/ssr/index.d.ts +75 -2
- package/dist/ssr/index.js +1 -1
- package/package.json +5 -5
- package/dist/shared/chunk-yr65qdge.js +0 -764
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
collectStreamChunks,
|
|
3
|
+
compileThemeCached,
|
|
3
4
|
createAccessSetScript,
|
|
4
5
|
createRequestContext,
|
|
5
6
|
createSSRDataChunk,
|
|
@@ -10,16 +11,21 @@ import {
|
|
|
10
11
|
encodeChunk,
|
|
11
12
|
escapeAttr,
|
|
12
13
|
escapeHtml,
|
|
14
|
+
evaluateAccessRule,
|
|
13
15
|
getAccessSetForSSR,
|
|
14
16
|
getStreamingRuntimeScript,
|
|
17
|
+
matchUrlToPatterns,
|
|
18
|
+
reconstructDescriptors,
|
|
15
19
|
renderToStream,
|
|
16
20
|
resetSlotCounter,
|
|
17
21
|
safeSerialize,
|
|
18
22
|
serializeToHtml,
|
|
19
23
|
ssrDiscoverQueries,
|
|
24
|
+
ssrRenderSinglePass,
|
|
20
25
|
ssrRenderToString,
|
|
21
|
-
streamToString
|
|
22
|
-
|
|
26
|
+
streamToString,
|
|
27
|
+
toPrefetchSession
|
|
28
|
+
} from "./shared/chunk-bd0sgykf.js";
|
|
23
29
|
import {
|
|
24
30
|
clearGlobalSSRTimeout,
|
|
25
31
|
createSSRAdapter,
|
|
@@ -384,7 +390,7 @@ ${options.head}` : headHtml;
|
|
|
384
390
|
});
|
|
385
391
|
}
|
|
386
392
|
// src/render-to-html.ts
|
|
387
|
-
import {
|
|
393
|
+
import { getInjectedCSS } from "@vertz/ui";
|
|
388
394
|
async function twoPassRender(options) {
|
|
389
395
|
options.app();
|
|
390
396
|
const queries = getSSRQueries();
|
|
@@ -403,7 +409,7 @@ async function twoPassRender(options) {
|
|
|
403
409
|
const pendingQueries = queries.filter((q) => !q.resolved);
|
|
404
410
|
const vnode = options.app();
|
|
405
411
|
const collectedCSS = getInjectedCSS();
|
|
406
|
-
const themeCss = options.theme ?
|
|
412
|
+
const themeCss = options.theme ? compileThemeCached(options.theme, options.fallbackMetrics).css : "";
|
|
407
413
|
const allStyles = [themeCss, ...options.styles ?? [], ...collectedCSS].filter(Boolean);
|
|
408
414
|
const styleTags = allStyles.length > 0 ? `<style>${allStyles.join(`
|
|
409
415
|
`)}</style>` : "";
|
|
@@ -483,48 +489,6 @@ async function renderToHTML(appOrOptions, maybeOptions) {
|
|
|
483
489
|
}
|
|
484
490
|
});
|
|
485
491
|
}
|
|
486
|
-
// src/ssr-access-evaluator.ts
|
|
487
|
-
function toPrefetchSession(ssrAuth, accessSet) {
|
|
488
|
-
if (!ssrAuth || ssrAuth.status !== "authenticated" || !ssrAuth.user) {
|
|
489
|
-
return { status: "unauthenticated" };
|
|
490
|
-
}
|
|
491
|
-
const roles = ssrAuth.user.role ? [ssrAuth.user.role] : undefined;
|
|
492
|
-
const entitlements = accessSet != null ? Object.fromEntries(Object.entries(accessSet.entitlements).map(([name, check]) => [name, check.allowed])) : undefined;
|
|
493
|
-
return {
|
|
494
|
-
status: "authenticated",
|
|
495
|
-
roles,
|
|
496
|
-
entitlements,
|
|
497
|
-
tenantId: ssrAuth.user.tenantId
|
|
498
|
-
};
|
|
499
|
-
}
|
|
500
|
-
function evaluateAccessRule(rule, session) {
|
|
501
|
-
switch (rule.type) {
|
|
502
|
-
case "public":
|
|
503
|
-
return true;
|
|
504
|
-
case "authenticated":
|
|
505
|
-
return session.status === "authenticated";
|
|
506
|
-
case "role":
|
|
507
|
-
if (session.status !== "authenticated")
|
|
508
|
-
return false;
|
|
509
|
-
return session.roles?.some((r) => rule.roles.includes(r)) === true;
|
|
510
|
-
case "entitlement":
|
|
511
|
-
if (session.status !== "authenticated")
|
|
512
|
-
return false;
|
|
513
|
-
return session.entitlements?.[rule.value] === true;
|
|
514
|
-
case "where":
|
|
515
|
-
return true;
|
|
516
|
-
case "fva":
|
|
517
|
-
return session.status === "authenticated";
|
|
518
|
-
case "deny":
|
|
519
|
-
return false;
|
|
520
|
-
case "all":
|
|
521
|
-
return rule.rules.every((r) => evaluateAccessRule(r, session));
|
|
522
|
-
case "any":
|
|
523
|
-
return rule.rules.some((r) => evaluateAccessRule(r, session));
|
|
524
|
-
default:
|
|
525
|
-
return false;
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
492
|
// src/ssr-aot-diagnostics.ts
|
|
529
493
|
var MAX_DIVERGENCES = 20;
|
|
530
494
|
|
|
@@ -701,429 +665,6 @@ function createAotManifestManager(options) {
|
|
|
701
665
|
}
|
|
702
666
|
};
|
|
703
667
|
}
|
|
704
|
-
// src/ssr-aot-pipeline.ts
|
|
705
|
-
import { compileTheme as compileTheme3 } from "@vertz/ui";
|
|
706
|
-
|
|
707
|
-
// src/ssr-route-matcher.ts
|
|
708
|
-
function matchUrlToPatterns(url, patterns) {
|
|
709
|
-
const path = (url.split("?")[0] ?? "").split("#")[0] ?? "";
|
|
710
|
-
const matches = [];
|
|
711
|
-
for (const pattern of patterns) {
|
|
712
|
-
const result = matchPattern(path, pattern);
|
|
713
|
-
if (result) {
|
|
714
|
-
matches.push(result);
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
matches.sort((a, b) => {
|
|
718
|
-
const aSegments = a.pattern.split("/").length;
|
|
719
|
-
const bSegments = b.pattern.split("/").length;
|
|
720
|
-
return aSegments - bSegments;
|
|
721
|
-
});
|
|
722
|
-
return matches;
|
|
723
|
-
}
|
|
724
|
-
function matchPattern(path, pattern) {
|
|
725
|
-
const pathSegments = path.split("/").filter(Boolean);
|
|
726
|
-
const patternSegments = pattern.split("/").filter(Boolean);
|
|
727
|
-
if (patternSegments.length > pathSegments.length)
|
|
728
|
-
return;
|
|
729
|
-
const params = {};
|
|
730
|
-
for (let i = 0;i < patternSegments.length; i++) {
|
|
731
|
-
const seg = patternSegments[i];
|
|
732
|
-
const val = pathSegments[i];
|
|
733
|
-
if (seg.startsWith(":")) {
|
|
734
|
-
params[seg.slice(1)] = val;
|
|
735
|
-
} else if (seg !== val) {
|
|
736
|
-
return;
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
return { pattern, params };
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
// src/ssr-single-pass.ts
|
|
743
|
-
import { compileTheme as compileTheme2 } from "@vertz/ui";
|
|
744
|
-
|
|
745
|
-
// src/ssr-manifest-prefetch.ts
|
|
746
|
-
function reconstructDescriptors(queries, routeParams, apiClient) {
|
|
747
|
-
if (!apiClient)
|
|
748
|
-
return [];
|
|
749
|
-
const result = [];
|
|
750
|
-
for (const query of queries) {
|
|
751
|
-
const descriptor = reconstructSingle(query, routeParams, apiClient);
|
|
752
|
-
if (descriptor) {
|
|
753
|
-
result.push(descriptor);
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
return result;
|
|
757
|
-
}
|
|
758
|
-
function reconstructSingle(query, routeParams, apiClient) {
|
|
759
|
-
const { entity, operation } = query;
|
|
760
|
-
if (!entity || !operation)
|
|
761
|
-
return;
|
|
762
|
-
const entitySdk = apiClient[entity];
|
|
763
|
-
if (!entitySdk)
|
|
764
|
-
return;
|
|
765
|
-
const method = entitySdk[operation];
|
|
766
|
-
if (typeof method !== "function")
|
|
767
|
-
return;
|
|
768
|
-
const args = buildFactoryArgs(query, routeParams);
|
|
769
|
-
if (args === undefined)
|
|
770
|
-
return;
|
|
771
|
-
try {
|
|
772
|
-
const descriptor = method(...args);
|
|
773
|
-
if (!descriptor || typeof descriptor._key !== "string" || typeof descriptor._fetch !== "function") {
|
|
774
|
-
return;
|
|
775
|
-
}
|
|
776
|
-
return { key: descriptor._key, fetch: descriptor._fetch };
|
|
777
|
-
} catch {
|
|
778
|
-
return;
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
function buildFactoryArgs(query, routeParams) {
|
|
782
|
-
const { operation, idParam, queryBindings } = query;
|
|
783
|
-
if (operation === "get") {
|
|
784
|
-
if (idParam) {
|
|
785
|
-
const id = routeParams[idParam];
|
|
786
|
-
if (!id)
|
|
787
|
-
return;
|
|
788
|
-
const options = resolveQueryBindings(queryBindings, routeParams);
|
|
789
|
-
if (options === undefined && queryBindings)
|
|
790
|
-
return;
|
|
791
|
-
return options ? [id, options] : [id];
|
|
792
|
-
}
|
|
793
|
-
return;
|
|
794
|
-
}
|
|
795
|
-
if (!queryBindings)
|
|
796
|
-
return [];
|
|
797
|
-
const resolved = resolveQueryBindings(queryBindings, routeParams);
|
|
798
|
-
if (resolved === undefined)
|
|
799
|
-
return;
|
|
800
|
-
return [resolved];
|
|
801
|
-
}
|
|
802
|
-
function resolveQueryBindings(bindings, routeParams) {
|
|
803
|
-
if (!bindings)
|
|
804
|
-
return;
|
|
805
|
-
const resolved = {};
|
|
806
|
-
if (bindings.where) {
|
|
807
|
-
const where = {};
|
|
808
|
-
for (const [key, value] of Object.entries(bindings.where)) {
|
|
809
|
-
if (value === null)
|
|
810
|
-
return;
|
|
811
|
-
if (typeof value === "string" && value.startsWith("$")) {
|
|
812
|
-
const paramName = value.slice(1);
|
|
813
|
-
const paramValue = routeParams[paramName];
|
|
814
|
-
if (!paramValue)
|
|
815
|
-
return;
|
|
816
|
-
where[key] = paramValue;
|
|
817
|
-
} else {
|
|
818
|
-
where[key] = value;
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
resolved.where = where;
|
|
822
|
-
}
|
|
823
|
-
if (bindings.select)
|
|
824
|
-
resolved.select = bindings.select;
|
|
825
|
-
if (bindings.include)
|
|
826
|
-
resolved.include = bindings.include;
|
|
827
|
-
if (bindings.orderBy)
|
|
828
|
-
resolved.orderBy = bindings.orderBy;
|
|
829
|
-
if (bindings.limit !== undefined)
|
|
830
|
-
resolved.limit = bindings.limit;
|
|
831
|
-
return resolved;
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
// src/ssr-single-pass.ts
|
|
835
|
-
async function ssrRenderSinglePass(module, url, options) {
|
|
836
|
-
if (options?.prefetch === false) {
|
|
837
|
-
return ssrRenderToString(module, url, options);
|
|
838
|
-
}
|
|
839
|
-
const normalizedUrl = url.endsWith("/index.html") ? url.slice(0, -"/index.html".length) || "/" : url;
|
|
840
|
-
const ssrTimeout = options?.ssrTimeout ?? 300;
|
|
841
|
-
ensureDomShim();
|
|
842
|
-
const zeroDiscoveryData = attemptZeroDiscovery(normalizedUrl, module, options, ssrTimeout);
|
|
843
|
-
if (zeroDiscoveryData) {
|
|
844
|
-
return renderWithPrefetchedData(module, normalizedUrl, zeroDiscoveryData, options);
|
|
845
|
-
}
|
|
846
|
-
const discoveryCtx = createRequestContext(normalizedUrl);
|
|
847
|
-
if (options?.ssrAuth) {
|
|
848
|
-
discoveryCtx.ssrAuth = options.ssrAuth;
|
|
849
|
-
}
|
|
850
|
-
const discoveredData = await ssrStorage.run(discoveryCtx, async () => {
|
|
851
|
-
try {
|
|
852
|
-
setGlobalSSRTimeout(ssrTimeout);
|
|
853
|
-
const createApp = resolveAppFactory(module);
|
|
854
|
-
createApp();
|
|
855
|
-
if (discoveryCtx.ssrRedirect) {
|
|
856
|
-
return { redirect: discoveryCtx.ssrRedirect };
|
|
857
|
-
}
|
|
858
|
-
if (discoveryCtx.pendingRouteComponents?.size) {
|
|
859
|
-
const entries = Array.from(discoveryCtx.pendingRouteComponents.entries());
|
|
860
|
-
const results = await Promise.allSettled(entries.map(([route, promise]) => Promise.race([
|
|
861
|
-
promise.then((mod) => ({ route, factory: mod.default })),
|
|
862
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error("lazy route timeout")), ssrTimeout))
|
|
863
|
-
])));
|
|
864
|
-
discoveryCtx.resolvedComponents = new Map;
|
|
865
|
-
for (const result of results) {
|
|
866
|
-
if (result.status === "fulfilled") {
|
|
867
|
-
const { route, factory } = result.value;
|
|
868
|
-
discoveryCtx.resolvedComponents.set(route, factory);
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
discoveryCtx.pendingRouteComponents = undefined;
|
|
872
|
-
}
|
|
873
|
-
const queries = getSSRQueries();
|
|
874
|
-
const eligibleQueries = filterByEntityAccess(queries, options?.manifest?.entityAccess, options?.prefetchSession);
|
|
875
|
-
const resolvedQueries = [];
|
|
876
|
-
if (eligibleQueries.length > 0) {
|
|
877
|
-
await Promise.allSettled(eligibleQueries.map(({ promise, timeout, resolve, key }) => Promise.race([
|
|
878
|
-
promise.then((data) => {
|
|
879
|
-
resolve(data);
|
|
880
|
-
resolvedQueries.push({ key, data });
|
|
881
|
-
return "resolved";
|
|
882
|
-
}),
|
|
883
|
-
new Promise((r) => setTimeout(r, timeout || ssrTimeout)).then(() => "timeout")
|
|
884
|
-
])));
|
|
885
|
-
}
|
|
886
|
-
return {
|
|
887
|
-
resolvedQueries,
|
|
888
|
-
resolvedComponents: discoveryCtx.resolvedComponents
|
|
889
|
-
};
|
|
890
|
-
} finally {
|
|
891
|
-
clearGlobalSSRTimeout();
|
|
892
|
-
}
|
|
893
|
-
});
|
|
894
|
-
if ("redirect" in discoveredData) {
|
|
895
|
-
return {
|
|
896
|
-
html: "",
|
|
897
|
-
css: "",
|
|
898
|
-
ssrData: [],
|
|
899
|
-
headTags: "",
|
|
900
|
-
redirect: discoveredData.redirect
|
|
901
|
-
};
|
|
902
|
-
}
|
|
903
|
-
const renderCtx = createRequestContext(normalizedUrl);
|
|
904
|
-
if (options?.ssrAuth) {
|
|
905
|
-
renderCtx.ssrAuth = options.ssrAuth;
|
|
906
|
-
}
|
|
907
|
-
for (const { key, data } of discoveredData.resolvedQueries) {
|
|
908
|
-
renderCtx.queryCache.set(key, data);
|
|
909
|
-
}
|
|
910
|
-
renderCtx.resolvedComponents = discoveredData.resolvedComponents ?? new Map;
|
|
911
|
-
return ssrStorage.run(renderCtx, async () => {
|
|
912
|
-
try {
|
|
913
|
-
setGlobalSSRTimeout(ssrTimeout);
|
|
914
|
-
const createApp = resolveAppFactory(module);
|
|
915
|
-
let themeCss = "";
|
|
916
|
-
let themePreloadTags = "";
|
|
917
|
-
if (module.theme) {
|
|
918
|
-
try {
|
|
919
|
-
const compiled = compileTheme2(module.theme, {
|
|
920
|
-
fallbackMetrics: options?.fallbackMetrics
|
|
921
|
-
});
|
|
922
|
-
themeCss = compiled.css;
|
|
923
|
-
themePreloadTags = compiled.preloadTags;
|
|
924
|
-
} catch (e) {
|
|
925
|
-
console.error("[vertz] Failed to compile theme export. Ensure your theme is created with defineTheme().", e);
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
const app = createApp();
|
|
929
|
-
const vnode = toVNode(app);
|
|
930
|
-
const stream = renderToStream(vnode);
|
|
931
|
-
const html = await streamToString(stream);
|
|
932
|
-
const css = collectCSS(themeCss, module);
|
|
933
|
-
const ssrData = discoveredData.resolvedQueries.map(({ key, data }) => ({
|
|
934
|
-
key,
|
|
935
|
-
data: JSON.parse(JSON.stringify(data))
|
|
936
|
-
}));
|
|
937
|
-
return {
|
|
938
|
-
html,
|
|
939
|
-
css,
|
|
940
|
-
ssrData,
|
|
941
|
-
headTags: themePreloadTags,
|
|
942
|
-
discoveredRoutes: renderCtx.discoveredRoutes,
|
|
943
|
-
matchedRoutePatterns: renderCtx.matchedRoutePatterns
|
|
944
|
-
};
|
|
945
|
-
} finally {
|
|
946
|
-
clearGlobalSSRTimeout();
|
|
947
|
-
}
|
|
948
|
-
});
|
|
949
|
-
}
|
|
950
|
-
function attemptZeroDiscovery(url, module, options, ssrTimeout) {
|
|
951
|
-
const manifest = options?.manifest;
|
|
952
|
-
if (!manifest?.routeEntries || !module.api)
|
|
953
|
-
return null;
|
|
954
|
-
const matches = matchUrlToPatterns(url, manifest.routePatterns);
|
|
955
|
-
if (matches.length === 0)
|
|
956
|
-
return null;
|
|
957
|
-
const allQueries = [];
|
|
958
|
-
let mergedParams = {};
|
|
959
|
-
for (const match of matches) {
|
|
960
|
-
const entry = manifest.routeEntries[match.pattern];
|
|
961
|
-
if (entry) {
|
|
962
|
-
allQueries.push(...entry.queries);
|
|
963
|
-
}
|
|
964
|
-
mergedParams = { ...mergedParams, ...match.params };
|
|
965
|
-
}
|
|
966
|
-
if (allQueries.length === 0)
|
|
967
|
-
return null;
|
|
968
|
-
const descriptors = reconstructDescriptors(allQueries, mergedParams, module.api);
|
|
969
|
-
if (descriptors.length === 0)
|
|
970
|
-
return null;
|
|
971
|
-
return prefetchFromDescriptors(descriptors, ssrTimeout);
|
|
972
|
-
}
|
|
973
|
-
async function prefetchFromDescriptors(descriptors, ssrTimeout) {
|
|
974
|
-
const resolvedQueries = [];
|
|
975
|
-
await Promise.allSettled(descriptors.map(({ key, fetch: fetchFn }) => Promise.race([
|
|
976
|
-
fetchFn().then((result) => {
|
|
977
|
-
const data = unwrapResult(result);
|
|
978
|
-
resolvedQueries.push({ key, data });
|
|
979
|
-
return "resolved";
|
|
980
|
-
}),
|
|
981
|
-
new Promise((r) => setTimeout(r, ssrTimeout)).then(() => "timeout")
|
|
982
|
-
])));
|
|
983
|
-
return { resolvedQueries };
|
|
984
|
-
}
|
|
985
|
-
function unwrapResult(result) {
|
|
986
|
-
if (result && typeof result === "object" && "ok" in result && "data" in result) {
|
|
987
|
-
const r = result;
|
|
988
|
-
if (r.ok)
|
|
989
|
-
return r.data;
|
|
990
|
-
}
|
|
991
|
-
return result;
|
|
992
|
-
}
|
|
993
|
-
async function renderWithPrefetchedData(module, normalizedUrl, prefetchedData, options) {
|
|
994
|
-
const data = await prefetchedData;
|
|
995
|
-
const ssrTimeout = options?.ssrTimeout ?? 300;
|
|
996
|
-
const renderCtx = createRequestContext(normalizedUrl);
|
|
997
|
-
if (options?.ssrAuth) {
|
|
998
|
-
renderCtx.ssrAuth = options.ssrAuth;
|
|
999
|
-
}
|
|
1000
|
-
for (const { key, data: queryData } of data.resolvedQueries) {
|
|
1001
|
-
renderCtx.queryCache.set(key, queryData);
|
|
1002
|
-
}
|
|
1003
|
-
renderCtx.resolvedComponents = new Map;
|
|
1004
|
-
return ssrStorage.run(renderCtx, async () => {
|
|
1005
|
-
try {
|
|
1006
|
-
setGlobalSSRTimeout(ssrTimeout);
|
|
1007
|
-
const createApp = resolveAppFactory(module);
|
|
1008
|
-
let themeCss = "";
|
|
1009
|
-
let themePreloadTags = "";
|
|
1010
|
-
if (module.theme) {
|
|
1011
|
-
try {
|
|
1012
|
-
const compiled = compileTheme2(module.theme, {
|
|
1013
|
-
fallbackMetrics: options?.fallbackMetrics
|
|
1014
|
-
});
|
|
1015
|
-
themeCss = compiled.css;
|
|
1016
|
-
themePreloadTags = compiled.preloadTags;
|
|
1017
|
-
} catch (e) {
|
|
1018
|
-
console.error("[vertz] Failed to compile theme export. Ensure your theme is created with defineTheme().", e);
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
const app = createApp();
|
|
1022
|
-
const vnode = toVNode(app);
|
|
1023
|
-
const stream = renderToStream(vnode);
|
|
1024
|
-
const html = await streamToString(stream);
|
|
1025
|
-
if (renderCtx.ssrRedirect) {
|
|
1026
|
-
return {
|
|
1027
|
-
html: "",
|
|
1028
|
-
css: "",
|
|
1029
|
-
ssrData: [],
|
|
1030
|
-
headTags: "",
|
|
1031
|
-
redirect: renderCtx.ssrRedirect,
|
|
1032
|
-
discoveredRoutes: renderCtx.discoveredRoutes,
|
|
1033
|
-
matchedRoutePatterns: renderCtx.matchedRoutePatterns
|
|
1034
|
-
};
|
|
1035
|
-
}
|
|
1036
|
-
const css = collectCSS(themeCss, module);
|
|
1037
|
-
const ssrData = data.resolvedQueries.map(({ key, data: d }) => ({
|
|
1038
|
-
key,
|
|
1039
|
-
data: JSON.parse(JSON.stringify(d))
|
|
1040
|
-
}));
|
|
1041
|
-
return {
|
|
1042
|
-
html,
|
|
1043
|
-
css,
|
|
1044
|
-
ssrData,
|
|
1045
|
-
headTags: themePreloadTags,
|
|
1046
|
-
discoveredRoutes: renderCtx.discoveredRoutes,
|
|
1047
|
-
matchedRoutePatterns: renderCtx.matchedRoutePatterns
|
|
1048
|
-
};
|
|
1049
|
-
} finally {
|
|
1050
|
-
clearGlobalSSRTimeout();
|
|
1051
|
-
}
|
|
1052
|
-
});
|
|
1053
|
-
}
|
|
1054
|
-
var domShimInstalled = false;
|
|
1055
|
-
function ensureDomShim() {
|
|
1056
|
-
if (domShimInstalled && typeof document !== "undefined")
|
|
1057
|
-
return;
|
|
1058
|
-
domShimInstalled = true;
|
|
1059
|
-
installDomShim();
|
|
1060
|
-
}
|
|
1061
|
-
function resolveAppFactory(module) {
|
|
1062
|
-
const createApp = module.default || module.App;
|
|
1063
|
-
if (typeof createApp !== "function") {
|
|
1064
|
-
throw new Error("App entry must export a default function or named App function");
|
|
1065
|
-
}
|
|
1066
|
-
return createApp;
|
|
1067
|
-
}
|
|
1068
|
-
function filterByEntityAccess(queries, entityAccess, session) {
|
|
1069
|
-
if (!entityAccess || !session)
|
|
1070
|
-
return queries;
|
|
1071
|
-
return queries.filter(({ key }) => {
|
|
1072
|
-
const entity = extractEntityFromKey(key);
|
|
1073
|
-
const method = extractMethodFromKey(key);
|
|
1074
|
-
if (!entity)
|
|
1075
|
-
return true;
|
|
1076
|
-
const entityRules = entityAccess[entity];
|
|
1077
|
-
if (!entityRules)
|
|
1078
|
-
return true;
|
|
1079
|
-
const rule = entityRules[method];
|
|
1080
|
-
if (!rule)
|
|
1081
|
-
return true;
|
|
1082
|
-
return evaluateAccessRule(rule, session);
|
|
1083
|
-
});
|
|
1084
|
-
}
|
|
1085
|
-
function extractEntityFromKey(key) {
|
|
1086
|
-
const pathStart = key.indexOf(":/");
|
|
1087
|
-
if (pathStart === -1)
|
|
1088
|
-
return;
|
|
1089
|
-
const path = key.slice(pathStart + 2);
|
|
1090
|
-
const firstSlash = path.indexOf("/");
|
|
1091
|
-
const questionMark = path.indexOf("?");
|
|
1092
|
-
if (firstSlash === -1 && questionMark === -1)
|
|
1093
|
-
return path;
|
|
1094
|
-
if (firstSlash === -1)
|
|
1095
|
-
return path.slice(0, questionMark);
|
|
1096
|
-
if (questionMark === -1)
|
|
1097
|
-
return path.slice(0, firstSlash);
|
|
1098
|
-
return path.slice(0, Math.min(firstSlash, questionMark));
|
|
1099
|
-
}
|
|
1100
|
-
function extractMethodFromKey(key) {
|
|
1101
|
-
const pathStart = key.indexOf(":/");
|
|
1102
|
-
if (pathStart === -1)
|
|
1103
|
-
return "list";
|
|
1104
|
-
const path = key.slice(pathStart + 2);
|
|
1105
|
-
const cleanPath = path.split("?")[0] ?? "";
|
|
1106
|
-
const segments = cleanPath.split("/").filter(Boolean);
|
|
1107
|
-
return segments.length > 1 ? "get" : "list";
|
|
1108
|
-
}
|
|
1109
|
-
function collectCSS(themeCss, module) {
|
|
1110
|
-
const alreadyIncluded = new Set;
|
|
1111
|
-
if (themeCss)
|
|
1112
|
-
alreadyIncluded.add(themeCss);
|
|
1113
|
-
if (module.styles) {
|
|
1114
|
-
for (const s of module.styles)
|
|
1115
|
-
alreadyIncluded.add(s);
|
|
1116
|
-
}
|
|
1117
|
-
const componentCss = module.getInjectedCSS ? module.getInjectedCSS().filter((s) => !alreadyIncluded.has(s)) : [];
|
|
1118
|
-
const themeTag = themeCss ? `<style data-vertz-css>${themeCss}</style>` : "";
|
|
1119
|
-
const globalTag = module.styles && module.styles.length > 0 ? `<style data-vertz-css>${module.styles.join(`
|
|
1120
|
-
`)}</style>` : "";
|
|
1121
|
-
const componentTag = componentCss.length > 0 ? `<style data-vertz-css>${componentCss.join(`
|
|
1122
|
-
`)}</style>` : "";
|
|
1123
|
-
return [themeTag, globalTag, componentTag].filter(Boolean).join(`
|
|
1124
|
-
`);
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
668
|
// src/ssr-aot-pipeline.ts
|
|
1128
669
|
function createHoles(holeNames, module, url, queryCache, ssrAuth) {
|
|
1129
670
|
if (holeNames.length === 0)
|
|
@@ -1140,7 +681,7 @@ function createHoles(holeNames, module, url, queryCache, ssrAuth) {
|
|
|
1140
681
|
}
|
|
1141
682
|
holeCtx.resolvedComponents = new Map;
|
|
1142
683
|
return ssrStorage.run(holeCtx, () => {
|
|
1143
|
-
|
|
684
|
+
ensureDomShim();
|
|
1144
685
|
const factory = resolveHoleComponent(module, name);
|
|
1145
686
|
if (!factory) {
|
|
1146
687
|
return `<!-- AOT hole: ${name} not found -->`;
|
|
@@ -1211,7 +752,7 @@ async function ssrRenderAot(module, url, options) {
|
|
|
1211
752
|
const css = collectCSSFromModule(module, options.fallbackMetrics);
|
|
1212
753
|
const ssrData = [];
|
|
1213
754
|
for (const [key, data2] of queryCache) {
|
|
1214
|
-
ssrData.push({ key, data:
|
|
755
|
+
ssrData.push({ key, data: data2 });
|
|
1215
756
|
}
|
|
1216
757
|
return {
|
|
1217
758
|
html,
|
|
@@ -1229,11 +770,11 @@ function isAotDebugEnabled() {
|
|
|
1229
770
|
return false;
|
|
1230
771
|
return env === "1" || env.split(",").includes("aot");
|
|
1231
772
|
}
|
|
1232
|
-
var
|
|
1233
|
-
function
|
|
1234
|
-
if (
|
|
773
|
+
var domShimInstalled = false;
|
|
774
|
+
function ensureDomShim() {
|
|
775
|
+
if (domShimInstalled && typeof document !== "undefined")
|
|
1235
776
|
return;
|
|
1236
|
-
|
|
777
|
+
domShimInstalled = true;
|
|
1237
778
|
installDomShim();
|
|
1238
779
|
}
|
|
1239
780
|
function collectCSSFromModule(module, fallbackMetrics) {
|
|
@@ -1241,7 +782,7 @@ function collectCSSFromModule(module, fallbackMetrics) {
|
|
|
1241
782
|
let preloadTags = "";
|
|
1242
783
|
if (module.theme) {
|
|
1243
784
|
try {
|
|
1244
|
-
const compiled =
|
|
785
|
+
const compiled = compileThemeCached(module.theme, fallbackMetrics);
|
|
1245
786
|
themeCss = compiled.css;
|
|
1246
787
|
preloadTags = compiled.preloadTags;
|
|
1247
788
|
} catch (e) {
|