@zenithbuild/cli 0.7.3 → 0.7.4
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 +14 -11
- package/dist/adapters/adapter-netlify.js +1 -0
- package/dist/adapters/adapter-node.js +8 -0
- package/dist/adapters/adapter-vercel.js +1 -0
- package/dist/build/compiler-runtime.d.ts +10 -9
- package/dist/build/compiler-runtime.js +51 -1
- package/dist/build/compiler-signal-expression.d.ts +1 -0
- package/dist/build/compiler-signal-expression.js +155 -0
- package/dist/build/expression-rewrites.d.ts +1 -6
- package/dist/build/expression-rewrites.js +61 -65
- package/dist/build/page-component-loop.d.ts +3 -13
- package/dist/build/page-component-loop.js +21 -46
- package/dist/build/page-ir-normalization.d.ts +0 -8
- package/dist/build/page-ir-normalization.js +13 -234
- package/dist/build/page-loop-state.d.ts +6 -9
- package/dist/build/page-loop-state.js +9 -8
- package/dist/build/page-loop.js +27 -22
- package/dist/build/scoped-identifier-rewrite.d.ts +37 -44
- package/dist/build/scoped-identifier-rewrite.js +28 -128
- package/dist/build/server-script.d.ts +2 -1
- package/dist/build/server-script.js +29 -3
- package/dist/build.js +5 -3
- package/dist/component-instance-ir.js +158 -52
- package/dist/dev-build-session.js +20 -6
- package/dist/dev-server.js +82 -39
- package/dist/framework-components/Image.zen +1 -1
- package/dist/images/materialization-plan.d.ts +1 -0
- package/dist/images/materialization-plan.js +6 -0
- package/dist/images/materialize.d.ts +5 -3
- package/dist/images/materialize.js +24 -109
- package/dist/images/router-manifest.d.ts +1 -0
- package/dist/images/router-manifest.js +49 -0
- package/dist/index.js +8 -2
- package/dist/manifest.js +3 -2
- package/dist/preview.d.ts +4 -3
- package/dist/preview.js +87 -53
- package/dist/request-body.d.ts +2 -0
- package/dist/request-body.js +13 -0
- package/dist/request-origin.d.ts +2 -0
- package/dist/request-origin.js +45 -0
- package/dist/route-check-support.d.ts +1 -0
- package/dist/route-check-support.js +4 -0
- package/dist/server-contract.d.ts +15 -0
- package/dist/server-contract.js +102 -32
- package/dist/server-error.d.ts +4 -0
- package/dist/server-error.js +34 -0
- package/dist/server-output.d.ts +2 -0
- package/dist/server-output.js +13 -0
- package/dist/server-runtime/node-server.js +33 -27
- package/dist/server-runtime/route-render.d.ts +3 -3
- package/dist/server-runtime/route-render.js +20 -31
- package/dist/server-script-composition.d.ts +11 -5
- package/dist/server-script-composition.js +25 -10
- package/package.json +6 -3
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
2
|
import { performance } from 'node:perf_hooks';
|
|
3
3
|
import { cloneComponentIrForInstance } from '../component-instance-ir.js';
|
|
4
|
+
import { renderPropsLiteralFromAttrs } from './scoped-identifier-rewrite.js';
|
|
4
5
|
import { extractTemplate, isDocumentMode } from '../resolve-components.js';
|
|
5
6
|
import { buildComponentExpressionRewrite, mergeExpressionRewriteMaps, resolveStateKeyFromBindings } from './expression-rewrites.js';
|
|
6
7
|
import { mergeComponentIr } from './merge-component-ir.js';
|
|
7
|
-
import { buildScopedIdentifierRewrite } from './scoped-identifier-rewrite.js';
|
|
8
8
|
import { stripStyleBlocks } from './compiler-runtime.js';
|
|
9
9
|
import { extractDeclaredIdentifiers } from './typescript-expression-utils.js';
|
|
10
10
|
function createEmptyExpressionRewrite() {
|
|
@@ -17,12 +17,6 @@ function createEmptyExpressionRewrite() {
|
|
|
17
17
|
sequence: []
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
-
function createEmptyScopeRewrite() {
|
|
21
|
-
return {
|
|
22
|
-
map: new Map(),
|
|
23
|
-
ambiguous: new Set()
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
20
|
async function resolveComponentIr({ compPath, componentSource, compilerOpts, compilerBin, timedRunCompiler, cooperativeYield, componentIrCache, compilerTotals, pageStats, startupProfile, emitCompilerWarning }) {
|
|
27
21
|
let compIr;
|
|
28
22
|
if (componentIrCache.has(compPath)) {
|
|
@@ -51,24 +45,23 @@ function resolveDocumentMode({ compPath, componentSource, componentDocumentModeC
|
|
|
51
45
|
}
|
|
52
46
|
return docMode;
|
|
53
47
|
}
|
|
54
|
-
function resolveComponentExpressionRewrite({ compPath,
|
|
48
|
+
function resolveComponentExpressionRewrite({ compPath, compIr, expressionRewriteMetrics, componentExpressionRewriteCache, pageComponentLoopBreakdown, startupProfile }) {
|
|
55
49
|
let expressionRewrite = componentExpressionRewriteCache.get(compPath);
|
|
56
50
|
if (!expressionRewrite) {
|
|
57
51
|
const startedAt = performance.now();
|
|
58
|
-
expressionRewrite = buildComponentExpressionRewrite(
|
|
52
|
+
expressionRewrite = buildComponentExpressionRewrite(compIr, expressionRewriteMetrics);
|
|
59
53
|
pageComponentLoopBreakdown.componentExpressionRewriteBuildMs += startupProfile.roundMs(performance.now() - startedAt);
|
|
60
54
|
componentExpressionRewriteCache.set(compPath, expressionRewrite);
|
|
61
55
|
}
|
|
62
56
|
return expressionRewrite;
|
|
63
57
|
}
|
|
64
|
-
async function resolveOwnerRewriteContext({ occurrence, sourceFile, compilerOpts, compilerBin, timedRunCompiler, cooperativeYield, componentIrCache, componentExpressionRewriteCache,
|
|
58
|
+
async function resolveOwnerRewriteContext({ occurrence, sourceFile, compilerOpts, compilerBin, timedRunCompiler, cooperativeYield, componentIrCache, componentExpressionRewriteCache, expressionRewriteMetrics, startupProfile, compilerTotals, emitCompilerWarning, pageComponentLoopBreakdown, pageStats, pageOwnerExpressionRewrite }) {
|
|
65
59
|
const ownerPath = typeof occurrence.ownerPath === 'string' && occurrence.ownerPath.length > 0
|
|
66
60
|
? occurrence.ownerPath
|
|
67
61
|
: sourceFile;
|
|
68
62
|
if (ownerPath === sourceFile) {
|
|
69
63
|
return {
|
|
70
|
-
attrExpressionRewrite: pageOwnerExpressionRewrite
|
|
71
|
-
attrScopeRewrite: pageOwnerScopeRewrite
|
|
64
|
+
attrExpressionRewrite: pageOwnerExpressionRewrite
|
|
72
65
|
};
|
|
73
66
|
}
|
|
74
67
|
let ownerIr = componentIrCache.get(ownerPath);
|
|
@@ -97,20 +90,13 @@ async function resolveOwnerRewriteContext({ occurrence, sourceFile, compilerOpts
|
|
|
97
90
|
pageComponentLoopBreakdown.ownerSourceReadMs += startupProfile.roundMs(performance.now() - ownerSourceReadStartedAt);
|
|
98
91
|
}
|
|
99
92
|
const startedAt = performance.now();
|
|
100
|
-
attrExpressionRewrite = buildComponentExpressionRewrite(
|
|
93
|
+
attrExpressionRewrite = buildComponentExpressionRewrite(ownerIr, expressionRewriteMetrics);
|
|
101
94
|
pageComponentLoopBreakdown.ownerExpressionRewriteBuildMs += startupProfile.roundMs(performance.now() - startedAt);
|
|
102
95
|
componentExpressionRewriteCache.set(ownerPath, attrExpressionRewrite);
|
|
103
96
|
}
|
|
104
|
-
|
|
105
|
-
if (!attrScopeRewrite) {
|
|
106
|
-
const startedAt = performance.now();
|
|
107
|
-
attrScopeRewrite = buildScopedIdentifierRewrite(ownerIr);
|
|
108
|
-
pageComponentLoopBreakdown.ownerScopeRewriteBuildMs += startupProfile.roundMs(performance.now() - startedAt);
|
|
109
|
-
componentScopeRewriteCache.set(ownerPath, attrScopeRewrite);
|
|
110
|
-
}
|
|
111
|
-
return { attrExpressionRewrite, attrScopeRewrite };
|
|
97
|
+
return { attrExpressionRewrite };
|
|
112
98
|
}
|
|
113
|
-
function resolveInstanceState({ useIsolatedInstance, compIr,
|
|
99
|
+
function resolveInstanceState({ useIsolatedInstance, compIr, expressionRewriteMetrics, expressionRewrite, startupProfile, pagePhase, componentInstanceCounter }) {
|
|
114
100
|
if (!useIsolatedInstance) {
|
|
115
101
|
return {
|
|
116
102
|
instanceIr: compIr,
|
|
@@ -123,7 +109,7 @@ function resolveInstanceState({ useIsolatedInstance, compIr, compPath, component
|
|
|
123
109
|
const cloned = cloneComponentIrForInstance(compIr, componentInstanceCounter, extractDeclaredIdentifiers, resolveStateKeyFromBindings);
|
|
124
110
|
pagePhase.cloneMs += startupProfile.roundMs(performance.now() - cloneStartedAt);
|
|
125
111
|
const instanceRewriteStartedAt = performance.now();
|
|
126
|
-
const instanceRewrite = buildComponentExpressionRewrite(
|
|
112
|
+
const instanceRewrite = buildComponentExpressionRewrite(cloned.ir, expressionRewriteMetrics);
|
|
127
113
|
pagePhase.instanceRewriteMs += startupProfile.roundMs(performance.now() - instanceRewriteStartedAt);
|
|
128
114
|
return {
|
|
129
115
|
instanceIr: cloned.ir,
|
|
@@ -132,12 +118,11 @@ function resolveInstanceState({ useIsolatedInstance, compIr, compPath, component
|
|
|
132
118
|
componentInstanceCounter: componentInstanceCounter + 1
|
|
133
119
|
};
|
|
134
120
|
}
|
|
135
|
-
export async function buildPageOwnerContext({ componentOccurrences, sourceFile, pageOwnerSource, compilerOpts, compilerBin, timedRunCompiler, cooperativeYield,
|
|
121
|
+
export async function buildPageOwnerContext({ componentOccurrences, sourceFile, pageOwnerSource, compilerOpts, compilerBin, timedRunCompiler, cooperativeYield, expressionRewriteMetrics, startupProfile }) {
|
|
136
122
|
if (componentOccurrences.length === 0) {
|
|
137
123
|
return {
|
|
138
124
|
pageOwnerCompileMs: 0,
|
|
139
|
-
pageOwnerExpressionRewrite: createEmptyExpressionRewrite()
|
|
140
|
-
pageOwnerScopeRewrite: createEmptyScopeRewrite()
|
|
125
|
+
pageOwnerExpressionRewrite: createEmptyExpressionRewrite()
|
|
141
126
|
};
|
|
142
127
|
}
|
|
143
128
|
await cooperativeYield();
|
|
@@ -146,12 +131,10 @@ export async function buildPageOwnerContext({ componentOccurrences, sourceFile,
|
|
|
146
131
|
const pageOwnerCompileMs = startupProfile.roundMs(performance.now() - ownerStartedAt);
|
|
147
132
|
return {
|
|
148
133
|
pageOwnerCompileMs,
|
|
149
|
-
pageOwnerExpressionRewrite: buildComponentExpressionRewrite(
|
|
150
|
-
pageOwnerScopeRewrite: buildScopedIdentifierRewrite(pageOwnerIr)
|
|
134
|
+
pageOwnerExpressionRewrite: buildComponentExpressionRewrite(pageOwnerIr, expressionRewriteMetrics)
|
|
151
135
|
};
|
|
152
136
|
}
|
|
153
|
-
export async function runPageComponentLoop({ componentOccurrences, occurrenceCountByPath, sourceFile, registry, compilerOpts, compilerBin, timedRunCompiler, cooperativeYield, startupProfile, compilerTotals, emitCompilerWarning, componentIrCache, componentDocumentModeCache, componentExpressionRewriteCache,
|
|
154
|
-
const componentScopeRewriteCache = new Map();
|
|
137
|
+
export async function runPageComponentLoop({ componentOccurrences, occurrenceCountByPath, sourceFile, registry, compilerOpts, compilerBin, timedRunCompiler, cooperativeYield, startupProfile, compilerTotals, emitCompilerWarning, componentIrCache, componentDocumentModeCache, componentExpressionRewriteCache, expressionRewriteMetrics, pageOwnerExpressionRewrite, pageIr, pageIrMergeCache, seenStaticImports, pageExpressionRewriteMap, pageExpressionBindingMap, pageAmbiguousExpressionMap, knownRefKeys, componentOccurrencePlans, imagePropsLiterals, pagePhase, pageBindingResolutionBreakdown, pageMergeBreakdown, pageComponentLoopBreakdown, hoistedCodeTransformCache, pageStats }) {
|
|
155
138
|
let componentInstanceCounter = 0;
|
|
156
139
|
for (const occurrence of componentOccurrences) {
|
|
157
140
|
await cooperativeYield();
|
|
@@ -186,17 +169,13 @@ export async function runPageComponentLoop({ componentOccurrences, occurrenceCou
|
|
|
186
169
|
});
|
|
187
170
|
const expressionRewrite = resolveComponentExpressionRewrite({
|
|
188
171
|
compPath,
|
|
189
|
-
componentSource,
|
|
190
172
|
compIr,
|
|
191
|
-
compilerOpts,
|
|
192
|
-
compilerBin,
|
|
193
|
-
templateExpressionCache,
|
|
194
173
|
expressionRewriteMetrics,
|
|
195
174
|
componentExpressionRewriteCache,
|
|
196
175
|
pageComponentLoopBreakdown,
|
|
197
176
|
startupProfile
|
|
198
177
|
});
|
|
199
|
-
const { attrExpressionRewrite
|
|
178
|
+
const { attrExpressionRewrite } = await resolveOwnerRewriteContext({
|
|
200
179
|
occurrence,
|
|
201
180
|
sourceFile,
|
|
202
181
|
compilerOpts,
|
|
@@ -205,26 +184,23 @@ export async function runPageComponentLoop({ componentOccurrences, occurrenceCou
|
|
|
205
184
|
cooperativeYield,
|
|
206
185
|
componentIrCache,
|
|
207
186
|
componentExpressionRewriteCache,
|
|
208
|
-
componentScopeRewriteCache,
|
|
209
|
-
templateExpressionCache,
|
|
210
187
|
expressionRewriteMetrics,
|
|
211
188
|
startupProfile,
|
|
212
189
|
compilerTotals,
|
|
213
190
|
emitCompilerWarning,
|
|
214
191
|
pageComponentLoopBreakdown,
|
|
215
192
|
pageStats,
|
|
216
|
-
pageOwnerExpressionRewrite
|
|
217
|
-
pageOwnerScopeRewrite
|
|
193
|
+
pageOwnerExpressionRewrite
|
|
218
194
|
});
|
|
195
|
+
if (compName === 'Image') {
|
|
196
|
+
imagePropsLiterals.push(renderPropsLiteralFromAttrs(occurrence.attrs || '', {
|
|
197
|
+
expressionRewrite: attrExpressionRewrite
|
|
198
|
+
}));
|
|
199
|
+
}
|
|
219
200
|
const useIsolatedInstance = occurrenceCount > 1;
|
|
220
201
|
const instanceState = resolveInstanceState({
|
|
221
202
|
useIsolatedInstance,
|
|
222
203
|
compIr,
|
|
223
|
-
compPath,
|
|
224
|
-
componentSource,
|
|
225
|
-
compilerOpts,
|
|
226
|
-
compilerBin,
|
|
227
|
-
templateExpressionCache,
|
|
228
204
|
expressionRewriteMetrics,
|
|
229
205
|
expressionRewrite,
|
|
230
206
|
startupProfile,
|
|
@@ -239,8 +215,7 @@ export async function runPageComponentLoop({ componentOccurrences, occurrenceCou
|
|
|
239
215
|
documentMode: isDocMode,
|
|
240
216
|
componentAttrs: typeof occurrence.attrs === 'string' ? occurrence.attrs : '',
|
|
241
217
|
componentAttrsRewrite: {
|
|
242
|
-
expressionRewrite: attrExpressionRewrite
|
|
243
|
-
scopeRewrite: attrScopeRewrite
|
|
218
|
+
expressionRewrite: attrExpressionRewrite
|
|
244
219
|
}
|
|
245
220
|
}, seenStaticImports, knownRefKeys, pageIrMergeCache, pageMergeBreakdown, hoistedCodeTransformCache);
|
|
246
221
|
pagePhase.mergeMs += startupProfile.roundMs(performance.now() - mergeStartedAt);
|
|
@@ -10,14 +10,6 @@ export function rewriteRefBindingIdentifiers(pageIr: object, preferredKeys?: Set
|
|
|
10
10
|
* @param {Set<string>} ambiguous
|
|
11
11
|
*/
|
|
12
12
|
export function applyExpressionRewrites(pageIr: object, expressionMap: Map<string, string>, bindingMap: Map<string, object>, ambiguous: Set<string>): void;
|
|
13
|
-
/**
|
|
14
|
-
* @param {object} pageIr
|
|
15
|
-
* @param {object} scopeRewrite
|
|
16
|
-
* @param {Record<string, number> | null} [scopedMetrics]
|
|
17
|
-
*/
|
|
18
|
-
export function applyScopedIdentifierRewrites(pageIr: object, scopeRewrite: object, scopedMetrics?: Record<string, number> | null): void;
|
|
19
|
-
export function synthesizeSignalBackedCompiledExpressions(pageIr: any): void;
|
|
20
|
-
export function normalizeExpressionBindingDependencies(pageIr: any): void;
|
|
21
13
|
export function normalizeExpressionPayload(pageIr: any): void;
|
|
22
14
|
export function normalizeHoistedSourcePayload(pageIr: any): void;
|
|
23
15
|
export function rewriteLegacyMarkupIdentifiers(pageIr: any): void;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { rewritePropsExpression } from './scoped-identifier-rewrite.js';
|
|
2
1
|
import { resolveStateKeyFromBindings } from './expression-rewrites.js';
|
|
3
2
|
import { expandScopedShorthandPropertiesInSource, normalizeTypeScriptExpression } from './typescript-expression-utils.js';
|
|
4
3
|
/**
|
|
@@ -69,236 +68,6 @@ export function applyExpressionRewrites(pageIr, expressionMap, bindingMap, ambig
|
|
|
69
68
|
}
|
|
70
69
|
}
|
|
71
70
|
}
|
|
72
|
-
/**
|
|
73
|
-
* @param {object} pageIr
|
|
74
|
-
* @param {object} scopeRewrite
|
|
75
|
-
* @param {Record<string, number> | null} [scopedMetrics]
|
|
76
|
-
*/
|
|
77
|
-
export function applyScopedIdentifierRewrites(pageIr, scopeRewrite, scopedMetrics = null) {
|
|
78
|
-
if (!Array.isArray(pageIr?.expressions) || pageIr.expressions.length === 0) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
const bindings = Array.isArray(pageIr.expression_bindings) ? pageIr.expression_bindings : [];
|
|
82
|
-
const scopeMap = scopeRewrite?.map instanceof Map ? scopeRewrite.map : null;
|
|
83
|
-
const scopeAmbiguous = scopeRewrite?.ambiguous instanceof Set ? scopeRewrite.ambiguous : null;
|
|
84
|
-
const scopeCandidates = scopeMap instanceof Map
|
|
85
|
-
? new Set([...scopeMap.keys()].filter((identifier) => typeof identifier === 'string'
|
|
86
|
-
&& identifier.length > 0
|
|
87
|
-
&& !(scopeAmbiguous instanceof Set && scopeAmbiguous.has(identifier))))
|
|
88
|
-
: null;
|
|
89
|
-
const rewriteContext = { scopeRewrite };
|
|
90
|
-
const rewriteCache = new Map();
|
|
91
|
-
const shouldCheckIdentifierCandidate = (charCode, isStart) => {
|
|
92
|
-
if (charCode === 36 || charCode === 95)
|
|
93
|
-
return true;
|
|
94
|
-
if (charCode >= 65 && charCode <= 90)
|
|
95
|
-
return true;
|
|
96
|
-
if (charCode >= 97 && charCode <= 122)
|
|
97
|
-
return true;
|
|
98
|
-
if (!isStart && charCode >= 48 && charCode <= 57)
|
|
99
|
-
return true;
|
|
100
|
-
return false;
|
|
101
|
-
};
|
|
102
|
-
const canSkipScopedRewrite = (value) => {
|
|
103
|
-
if (!(scopeCandidates instanceof Set) || scopeCandidates.size === 0) {
|
|
104
|
-
return true;
|
|
105
|
-
}
|
|
106
|
-
let token = '';
|
|
107
|
-
for (let index = 0; index < value.length; index++) {
|
|
108
|
-
const charCode = value.charCodeAt(index);
|
|
109
|
-
if (shouldCheckIdentifierCandidate(charCode, token.length === 0)) {
|
|
110
|
-
token += value[index];
|
|
111
|
-
continue;
|
|
112
|
-
}
|
|
113
|
-
if (token.length > 0) {
|
|
114
|
-
if (scopeCandidates.has(token)) {
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
117
|
-
token = '';
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return token.length > 0 ? !scopeCandidates.has(token) : true;
|
|
121
|
-
};
|
|
122
|
-
const addScopedMetric = (key, value) => {
|
|
123
|
-
if (!scopedMetrics || typeof scopedMetrics !== 'object' || !Number.isFinite(value)) {
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
scopedMetrics[key] = (scopedMetrics[key] || 0) + value;
|
|
127
|
-
};
|
|
128
|
-
const rewriteScoped = (value) => {
|
|
129
|
-
if (typeof value !== 'string') {
|
|
130
|
-
return value;
|
|
131
|
-
}
|
|
132
|
-
addScopedMetric('totalValues', 1);
|
|
133
|
-
const cached = rewriteCache.get(value);
|
|
134
|
-
if (typeof cached === 'string') {
|
|
135
|
-
addScopedMetric('cacheHitCount', 1);
|
|
136
|
-
return cached;
|
|
137
|
-
}
|
|
138
|
-
addScopedMetric('cacheMissCount', 1);
|
|
139
|
-
const missStartedAt = performance.now();
|
|
140
|
-
const identifierCheckStartedAt = performance.now();
|
|
141
|
-
const shouldSkip = canSkipScopedRewrite(value);
|
|
142
|
-
const identifierCheckMs = performance.now() - identifierCheckStartedAt;
|
|
143
|
-
addScopedMetric('identifierCheckMs', identifierCheckMs);
|
|
144
|
-
if (shouldSkip) {
|
|
145
|
-
addScopedMetric('fastSkipCount', 1);
|
|
146
|
-
addScopedMetric('fastSkipMs', identifierCheckMs);
|
|
147
|
-
rewriteCache.set(value, value);
|
|
148
|
-
addScopedMetric('unchangedMissCount', 1);
|
|
149
|
-
addScopedMetric('cacheMissMs', performance.now() - missStartedAt);
|
|
150
|
-
return value;
|
|
151
|
-
}
|
|
152
|
-
const rewriteCallStartedAt = performance.now();
|
|
153
|
-
const rewritten = rewritePropsExpression(value, rewriteContext);
|
|
154
|
-
addScopedMetric('rewriteCallMs', performance.now() - rewriteCallStartedAt);
|
|
155
|
-
addScopedMetric(rewritten === value ? 'unchangedMissCount' : 'changedMissCount', 1);
|
|
156
|
-
addScopedMetric('cacheMissMs', performance.now() - missStartedAt);
|
|
157
|
-
rewriteCache.set(value, rewritten);
|
|
158
|
-
return rewritten;
|
|
159
|
-
};
|
|
160
|
-
for (let index = 0; index < pageIr.expressions.length; index++) {
|
|
161
|
-
const current = pageIr.expressions[index];
|
|
162
|
-
if (typeof current === 'string') {
|
|
163
|
-
pageIr.expressions[index] = rewriteScoped(current);
|
|
164
|
-
}
|
|
165
|
-
if (!bindings[index] || typeof bindings[index] !== 'object') {
|
|
166
|
-
continue;
|
|
167
|
-
}
|
|
168
|
-
if (typeof bindings[index].literal === 'string') {
|
|
169
|
-
bindings[index].literal = rewriteScoped(bindings[index].literal);
|
|
170
|
-
}
|
|
171
|
-
if (typeof bindings[index].compiled_expr === 'string') {
|
|
172
|
-
bindings[index].compiled_expr = rewriteScoped(bindings[index].compiled_expr);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
export function synthesizeSignalBackedCompiledExpressions(pageIr) {
|
|
177
|
-
if (!Array.isArray(pageIr?.expression_bindings) || pageIr.expression_bindings.length === 0) {
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
const stateBindings = Array.isArray(pageIr?.hoisted?.state) ? pageIr.hoisted.state : [];
|
|
181
|
-
const signals = Array.isArray(pageIr?.signals) ? pageIr.signals : [];
|
|
182
|
-
if (stateBindings.length === 0 || signals.length === 0) {
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
const signalBackedStateIndices = new Set(signals
|
|
186
|
-
.map((signal) => signal?.state_index)
|
|
187
|
-
.filter((value) => Number.isInteger(value)));
|
|
188
|
-
const signalIndexByStateKey = new Map();
|
|
189
|
-
for (let index = 0; index < signals.length; index++) {
|
|
190
|
-
const stateIndex = signals[index]?.state_index;
|
|
191
|
-
const stateKey = Number.isInteger(stateIndex) ? stateBindings[stateIndex]?.key : null;
|
|
192
|
-
if (typeof stateKey === 'string' && stateKey.length > 0) {
|
|
193
|
-
signalIndexByStateKey.set(stateKey, index);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
if (signalIndexByStateKey.size === 0) {
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
for (let index = 0; index < pageIr.expression_bindings.length; index++) {
|
|
200
|
-
const binding = pageIr.expression_bindings[index];
|
|
201
|
-
if (!binding || typeof binding !== 'object') {
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
204
|
-
if (typeof binding.compiled_expr === 'string' && binding.compiled_expr.includes('signalMap.get(')) {
|
|
205
|
-
continue;
|
|
206
|
-
}
|
|
207
|
-
const candidate = typeof binding.literal === 'string' && binding.literal.trim().length > 0
|
|
208
|
-
? binding.literal
|
|
209
|
-
: typeof pageIr.expressions?.[index] === 'string'
|
|
210
|
-
? pageIr.expressions[index]
|
|
211
|
-
: null;
|
|
212
|
-
if (typeof candidate !== 'string' || candidate.trim().length === 0) {
|
|
213
|
-
continue;
|
|
214
|
-
}
|
|
215
|
-
if (Number.isInteger(binding.state_index) &&
|
|
216
|
-
!signalBackedStateIndices.has(binding.state_index)) {
|
|
217
|
-
continue;
|
|
218
|
-
}
|
|
219
|
-
let rewritten = candidate;
|
|
220
|
-
const signalIndices = [];
|
|
221
|
-
for (const [stateKey, signalIndex] of signalIndexByStateKey.entries()) {
|
|
222
|
-
if (!rewritten.includes(stateKey)) {
|
|
223
|
-
continue;
|
|
224
|
-
}
|
|
225
|
-
const escaped = stateKey.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
226
|
-
const pattern = new RegExp(`(?<!\\.)\\b${escaped}\\b`, 'g');
|
|
227
|
-
if (!pattern.test(rewritten)) {
|
|
228
|
-
continue;
|
|
229
|
-
}
|
|
230
|
-
rewritten = rewritten.replace(pattern, `signalMap.get(${signalIndex}).get()`);
|
|
231
|
-
signalIndices.push(signalIndex);
|
|
232
|
-
}
|
|
233
|
-
if (rewritten === candidate || signalIndices.length === 0) {
|
|
234
|
-
continue;
|
|
235
|
-
}
|
|
236
|
-
const uniqueSignalIndices = [...new Set(signalIndices)].sort((a, b) => a - b);
|
|
237
|
-
binding.compiled_expr = rewritten;
|
|
238
|
-
binding.signal_indices = uniqueSignalIndices;
|
|
239
|
-
if (uniqueSignalIndices.length === 1) {
|
|
240
|
-
binding.signal_index = uniqueSignalIndices[0];
|
|
241
|
-
const stateIndex = signals[uniqueSignalIndices[0]]?.state_index;
|
|
242
|
-
if (Number.isInteger(stateIndex)) {
|
|
243
|
-
binding.state_index = stateIndex;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
export function normalizeExpressionBindingDependencies(pageIr) {
|
|
249
|
-
if (!Array.isArray(pageIr?.expression_bindings) || pageIr.expression_bindings.length === 0) {
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
const signals = Array.isArray(pageIr.signals) ? pageIr.signals : [];
|
|
253
|
-
const dependencyRe = /signalMap\.get\((\d+)\)/g;
|
|
254
|
-
for (const binding of pageIr.expression_bindings) {
|
|
255
|
-
if (!binding || typeof binding !== 'object' || typeof binding.compiled_expr !== 'string') {
|
|
256
|
-
continue;
|
|
257
|
-
}
|
|
258
|
-
const indices = [];
|
|
259
|
-
dependencyRe.lastIndex = 0;
|
|
260
|
-
let match;
|
|
261
|
-
while ((match = dependencyRe.exec(binding.compiled_expr)) !== null) {
|
|
262
|
-
const index = Number.parseInt(match[1], 10);
|
|
263
|
-
if (Number.isInteger(index)) {
|
|
264
|
-
indices.push(index);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
if (indices.length === 0) {
|
|
268
|
-
continue;
|
|
269
|
-
}
|
|
270
|
-
let signalIndices = [...new Set(indices)].sort((a, b) => a - b);
|
|
271
|
-
if (Number.isInteger(binding.state_index)) {
|
|
272
|
-
const owningSignalIndices = signals
|
|
273
|
-
.map((signal, index) => signal?.state_index === binding.state_index ? index : null)
|
|
274
|
-
.filter((value) => Number.isInteger(value));
|
|
275
|
-
const extractedMatchState = signalIndices.length > 0 &&
|
|
276
|
-
signalIndices.every((index) => signals[index]?.state_index === binding.state_index);
|
|
277
|
-
if (owningSignalIndices.length > 0 && !extractedMatchState) {
|
|
278
|
-
signalIndices = owningSignalIndices;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
if (!Array.isArray(binding.signal_indices) ||
|
|
282
|
-
binding.signal_indices.length === 0 ||
|
|
283
|
-
binding.signal_indices.some((index) => signals[index]?.state_index !== binding.state_index)) {
|
|
284
|
-
binding.signal_indices = signalIndices;
|
|
285
|
-
}
|
|
286
|
-
if ((!Number.isInteger(binding.signal_index) ||
|
|
287
|
-
signals[binding.signal_index]?.state_index !== binding.state_index) &&
|
|
288
|
-
signalIndices.length === 1) {
|
|
289
|
-
binding.signal_index = signalIndices[0];
|
|
290
|
-
}
|
|
291
|
-
if (!Number.isInteger(binding.state_index) && Number.isInteger(binding.signal_index)) {
|
|
292
|
-
const stateIndex = signals[binding.signal_index]?.state_index;
|
|
293
|
-
if (Number.isInteger(stateIndex)) {
|
|
294
|
-
binding.state_index = stateIndex;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
if (signalIndices.length === 1) {
|
|
298
|
-
binding.compiled_expr = binding.compiled_expr.replace(/signalMap\.get\(\d+\)/g, `signalMap.get(${signalIndices[0]})`);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
71
|
export function normalizeExpressionPayload(pageIr) {
|
|
303
72
|
if (!Array.isArray(pageIr?.expressions) || pageIr.expressions.length === 0) {
|
|
304
73
|
return;
|
|
@@ -347,24 +116,34 @@ export function rewriteLegacyMarkupIdentifiers(pageIr) {
|
|
|
347
116
|
return;
|
|
348
117
|
}
|
|
349
118
|
const bindings = Array.isArray(pageIr.expression_bindings) ? pageIr.expression_bindings : [];
|
|
119
|
+
function failLegacyMarkup(source) {
|
|
120
|
+
throw new Error(`[Zenith:Build] Legacy ${LEGACY_MARKUP_IDENT}\`...\` markup syntax is unsupported. ` +
|
|
121
|
+
'Use embedded markup expressions with embeddedMarkupExpressions: true, or unsafeHTML={value} for explicit raw HTML.');
|
|
122
|
+
}
|
|
350
123
|
for (let i = 0; i < pageIr.expressions.length; i++) {
|
|
351
124
|
if (typeof pageIr.expressions[i] === 'string' && pageIr.expressions[i].includes(LEGACY_MARKUP_IDENT)) {
|
|
352
125
|
LEGACY_MARKUP_RE.lastIndex = 0;
|
|
353
|
-
|
|
126
|
+
if (LEGACY_MARKUP_RE.test(pageIr.expressions[i])) {
|
|
127
|
+
failLegacyMarkup(pageIr.expressions[i]);
|
|
128
|
+
}
|
|
354
129
|
}
|
|
355
130
|
if (bindings[i] &&
|
|
356
131
|
typeof bindings[i] === 'object' &&
|
|
357
132
|
typeof bindings[i].literal === 'string' &&
|
|
358
133
|
bindings[i].literal.includes(LEGACY_MARKUP_IDENT)) {
|
|
359
134
|
LEGACY_MARKUP_RE.lastIndex = 0;
|
|
360
|
-
|
|
135
|
+
if (LEGACY_MARKUP_RE.test(bindings[i].literal)) {
|
|
136
|
+
failLegacyMarkup(bindings[i].literal);
|
|
137
|
+
}
|
|
361
138
|
}
|
|
362
139
|
if (bindings[i] &&
|
|
363
140
|
typeof bindings[i] === 'object' &&
|
|
364
141
|
typeof bindings[i].compiled_expr === 'string' &&
|
|
365
142
|
bindings[i].compiled_expr.includes(LEGACY_MARKUP_IDENT)) {
|
|
366
143
|
LEGACY_MARKUP_RE.lastIndex = 0;
|
|
367
|
-
|
|
144
|
+
if (LEGACY_MARKUP_RE.test(bindings[i].compiled_expr)) {
|
|
145
|
+
failLegacyMarkup(bindings[i].compiled_expr);
|
|
146
|
+
}
|
|
368
147
|
}
|
|
369
148
|
}
|
|
370
149
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
export function createPageLoopState(): {
|
|
2
2
|
expressionRewriteMetrics: {
|
|
3
3
|
calls: number;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
templateCompileMs: number;
|
|
4
|
+
compilerOwnedBindings: number;
|
|
5
|
+
ambiguousBindings: number;
|
|
7
6
|
};
|
|
8
7
|
pagePhaseTotals: {
|
|
9
8
|
occurrenceCollectMs: number;
|
|
@@ -78,7 +77,6 @@ export function createPageLoopState(): {
|
|
|
78
77
|
componentIrCache: Map<any, any>;
|
|
79
78
|
componentDocumentModeCache: Map<any, any>;
|
|
80
79
|
componentExpressionRewriteCache: Map<any, any>;
|
|
81
|
-
templateExpressionCache: Map<any, any>;
|
|
82
80
|
hoistedCodeTransformCache: {
|
|
83
81
|
transpileToJs: Map<any, any>;
|
|
84
82
|
deferRuntime: Map<any, any>;
|
|
@@ -88,7 +86,6 @@ export function createPageLoopCaches(): {
|
|
|
88
86
|
componentIrCache: Map<any, any>;
|
|
89
87
|
componentDocumentModeCache: Map<any, any>;
|
|
90
88
|
componentExpressionRewriteCache: Map<any, any>;
|
|
91
|
-
templateExpressionCache: Map<any, any>;
|
|
92
89
|
hoistedCodeTransformCache: {
|
|
93
90
|
transpileToJs: Map<any, any>;
|
|
94
91
|
deferRuntime: Map<any, any>;
|
|
@@ -97,9 +94,8 @@ export function createPageLoopCaches(): {
|
|
|
97
94
|
export function createPageLoopExecutionState(): {
|
|
98
95
|
expressionRewriteMetrics: {
|
|
99
96
|
calls: number;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
templateCompileMs: number;
|
|
97
|
+
compilerOwnedBindings: number;
|
|
98
|
+
ambiguousBindings: number;
|
|
103
99
|
};
|
|
104
100
|
pagePhaseTotals: {
|
|
105
101
|
occurrenceCollectMs: number;
|
|
@@ -173,11 +169,12 @@ export function createPageLoopExecutionState(): {
|
|
|
173
169
|
envelopes: never[];
|
|
174
170
|
};
|
|
175
171
|
export function preparePageIrForMerge(pageIr: any): void;
|
|
176
|
-
export function applyServerEnvelopeToPageIr({ pageIr, composedServer, hasGuard, hasLoad, entry, srcDir, sourceFile }: {
|
|
172
|
+
export function applyServerEnvelopeToPageIr({ pageIr, composedServer, hasGuard, hasLoad, hasAction, entry, srcDir, sourceFile }: {
|
|
177
173
|
pageIr: any;
|
|
178
174
|
composedServer: any;
|
|
179
175
|
hasGuard: any;
|
|
180
176
|
hasLoad: any;
|
|
177
|
+
hasAction: any;
|
|
181
178
|
entry: any;
|
|
182
179
|
srcDir: any;
|
|
183
180
|
sourceFile: any;
|
|
@@ -11,7 +11,6 @@ export function createPageLoopCaches() {
|
|
|
11
11
|
componentIrCache: new Map(),
|
|
12
12
|
componentDocumentModeCache: new Map(),
|
|
13
13
|
componentExpressionRewriteCache: new Map(),
|
|
14
|
-
templateExpressionCache: new Map(),
|
|
15
14
|
hoistedCodeTransformCache: {
|
|
16
15
|
transpileToJs: new Map(),
|
|
17
16
|
deferRuntime: new Map()
|
|
@@ -22,9 +21,8 @@ export function createPageLoopExecutionState() {
|
|
|
22
21
|
return {
|
|
23
22
|
expressionRewriteMetrics: {
|
|
24
23
|
calls: 0,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
templateCompileMs: 0
|
|
24
|
+
compilerOwnedBindings: 0,
|
|
25
|
+
ambiguousBindings: 0
|
|
28
26
|
},
|
|
29
27
|
pagePhaseTotals: createPagePhaseTotals(),
|
|
30
28
|
occurrenceApplyPhaseTotals: createOccurrenceApplyPhaseTotals(),
|
|
@@ -48,22 +46,25 @@ export function preparePageIrForMerge(pageIr) {
|
|
|
48
46
|
pageIr.hoisted.state = pageIr.hoisted.state || [];
|
|
49
47
|
pageIr.hoisted.code = pageIr.hoisted.code || [];
|
|
50
48
|
}
|
|
51
|
-
export function applyServerEnvelopeToPageIr({ pageIr, composedServer, hasGuard, hasLoad, entry, srcDir, sourceFile }) {
|
|
49
|
+
export function applyServerEnvelopeToPageIr({ pageIr, composedServer, hasGuard, hasLoad, hasAction, entry, srcDir, sourceFile }) {
|
|
52
50
|
if (composedServer.serverScript) {
|
|
53
|
-
|
|
51
|
+
const { has_action: _unusedHasAction, ...serverScript } = composedServer.serverScript;
|
|
52
|
+
pageIr.server_script = serverScript;
|
|
54
53
|
pageIr.prerender = composedServer.serverScript.prerender === true;
|
|
55
54
|
if (pageIr.ssr_data === undefined) {
|
|
56
55
|
pageIr.ssr_data = null;
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
|
-
if (pageIr.prerender === true && (hasGuard || hasLoad)) {
|
|
58
|
+
if (pageIr.prerender === true && (hasGuard || hasLoad || hasAction)) {
|
|
60
59
|
throw new Error(`[zenith] Build failed for ${entry.file}: protected routes require SSR/runtime. ` +
|
|
61
|
-
'Cannot prerender a static route with a `guard` or `
|
|
60
|
+
'Cannot prerender a static route with a `guard`, `load`, or `action` function.');
|
|
62
61
|
}
|
|
63
62
|
pageIr.has_guard = hasGuard;
|
|
64
63
|
pageIr.has_load = hasLoad;
|
|
64
|
+
pageIr.has_action = hasAction;
|
|
65
65
|
pageIr.guard_module_ref = composedServer.guardPath ? relative(srcDir, composedServer.guardPath).replaceAll('\\', '/') : null;
|
|
66
66
|
pageIr.load_module_ref = composedServer.loadPath ? relative(srcDir, composedServer.loadPath).replaceAll('\\', '/') : null;
|
|
67
|
+
pageIr.action_module_ref = composedServer.actionPath ? relative(srcDir, composedServer.actionPath).replaceAll('\\', '/') : null;
|
|
67
68
|
preparePageIrForMerge(pageIr);
|
|
68
69
|
}
|
|
69
70
|
export function buildOccurrenceCountByPath(componentOccurrences) {
|