@zenithbuild/cli 0.7.3 → 0.7.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 +18 -13
- package/dist/adapters/adapter-netlify.d.ts +1 -1
- package/dist/adapters/adapter-netlify.js +56 -13
- package/dist/adapters/adapter-node.js +8 -0
- package/dist/adapters/adapter-static-export.d.ts +5 -0
- package/dist/adapters/adapter-static-export.js +115 -0
- package/dist/adapters/adapter-types.d.ts +3 -1
- package/dist/adapters/adapter-types.js +5 -2
- package/dist/adapters/adapter-vercel.d.ts +1 -1
- package/dist/adapters/adapter-vercel.js +70 -13
- package/dist/adapters/copy-hosted-page-runtime.d.ts +1 -0
- package/dist/adapters/copy-hosted-page-runtime.js +49 -0
- package/dist/adapters/resolve-adapter.js +4 -0
- package/dist/adapters/route-rules.d.ts +5 -0
- package/dist/adapters/route-rules.js +9 -0
- package/dist/adapters/validate-hosted-resource-routes.d.ts +1 -0
- package/dist/adapters/validate-hosted-resource-routes.js +13 -0
- package/dist/auth/route-auth.d.ts +6 -0
- package/dist/auth/route-auth.js +236 -0
- package/dist/build/compiler-runtime.d.ts +10 -9
- package/dist/build/compiler-runtime.js +58 -2
- 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 +3 -1
- package/dist/build/server-script.js +35 -5
- package/dist/build-output-manifest.d.ts +3 -2
- package/dist/build-output-manifest.js +3 -0
- package/dist/build.js +32 -18
- package/dist/component-instance-ir.js +158 -52
- package/dist/dev-build-session.js +20 -6
- package/dist/dev-server.js +152 -55
- package/dist/download-result.d.ts +14 -0
- package/dist/download-result.js +148 -0
- 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/images/service.d.ts +13 -1
- package/dist/images/service.js +45 -15
- package/dist/index.js +8 -2
- package/dist/manifest.d.ts +15 -1
- package/dist/manifest.js +27 -7
- package/dist/preview.d.ts +13 -4
- package/dist/preview.js +261 -101
- package/dist/request-body.d.ts +1 -0
- package/dist/request-body.js +7 -0
- package/dist/request-origin.d.ts +2 -0
- package/dist/request-origin.js +45 -0
- package/dist/resource-manifest.d.ts +16 -0
- package/dist/resource-manifest.js +53 -0
- package/dist/resource-response.d.ts +34 -0
- package/dist/resource-response.js +71 -0
- package/dist/resource-route-module.d.ts +15 -0
- package/dist/resource-route-module.js +129 -0
- package/dist/route-check-support.d.ts +1 -0
- package/dist/route-check-support.js +4 -0
- package/dist/server-contract.d.ts +29 -6
- package/dist/server-contract.js +304 -42
- package/dist/server-error.d.ts +4 -0
- package/dist/server-error.js +36 -0
- package/dist/server-output.d.ts +4 -1
- package/dist/server-output.js +71 -10
- package/dist/server-runtime/node-server.js +67 -31
- package/dist/server-runtime/route-render.d.ts +27 -3
- package/dist/server-runtime/route-render.js +94 -53
- package/dist/server-script-composition.d.ts +13 -5
- package/dist/server-script-composition.js +29 -11
- package/dist/static-export-paths.d.ts +3 -0
- package/dist/static-export-paths.js +160 -0
- package/package.json +6 -3
|
@@ -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, export_paths: _unusedExportPaths, ...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) {
|
package/dist/build/page-loop.js
CHANGED
|
@@ -5,14 +5,14 @@ import { applyOccurrenceRewritePlans } from '../component-instance-ir.js';
|
|
|
5
5
|
import { collectExpandedComponentOccurrences } from '../component-occurrences.js';
|
|
6
6
|
import { expandComponents } from '../resolve-components.js';
|
|
7
7
|
import { composeServerScriptEnvelope, resolveAdjacentServerModules } from '../server-script-composition.js';
|
|
8
|
-
import { createTimedCompilerRunner } from './compiler-runtime.js';
|
|
8
|
+
import { createTimedCompilerRunner, mergePageImageMaterialization } from './compiler-runtime.js';
|
|
9
9
|
import { buildComponentExpressionRewrite, mergeExpressionRewriteMaps, resolveRewrittenBindingMetadata } from './expression-rewrites.js';
|
|
10
10
|
import { createPageIrMergeCache } from './merge-component-ir.js';
|
|
11
11
|
import { buildPageOwnerContext, runPageComponentLoop } from './page-component-loop.js';
|
|
12
|
-
import { applyExpressionRewrites,
|
|
12
|
+
import { applyExpressionRewrites, normalizeExpressionPayload, normalizeHoistedSourcePayload, rewriteLegacyMarkupIdentifiers, rewriteRefBindingIdentifiers } from './page-ir-normalization.js';
|
|
13
|
+
import { deferComponentRuntimeBlock } from './hoisted-code-transforms.js';
|
|
13
14
|
import { addBreakdown, emitPageLoopSummary, recordPageProfile } from './page-loop-metrics.js';
|
|
14
15
|
import { applyServerEnvelopeToPageIr, buildOccurrenceCountByPath, createPageBuildState, createPageLoopCaches, createPageLoopExecutionState } from './page-loop-state.js';
|
|
15
|
-
import { buildScopedIdentifierRewrite } from './scoped-identifier-rewrite.js';
|
|
16
16
|
import { extractServerScript } from './server-script.js';
|
|
17
17
|
/**
|
|
18
18
|
* @param {{
|
|
@@ -33,7 +33,7 @@ export async function buildPageEnvelopes(input) {
|
|
|
33
33
|
const { manifest, pagesDir, srcDir, registry, compilerOpts, compilerBin, routerEnabled, startupProfile, compilerTotals, emitCompilerWarning } = input;
|
|
34
34
|
const cacheState = input.pageLoopCaches || createPageLoopCaches();
|
|
35
35
|
const executionState = createPageLoopExecutionState();
|
|
36
|
-
const { componentIrCache, componentDocumentModeCache, componentExpressionRewriteCache,
|
|
36
|
+
const { componentIrCache, componentDocumentModeCache, componentExpressionRewriteCache, hoistedCodeTransformCache } = cacheState;
|
|
37
37
|
const { expressionRewriteMetrics, pagePhaseTotals, occurrenceApplyPhaseTotals, bindingResolutionTotals, scopedRewritePhaseTotals, mergePhaseTotals, componentLoopPhaseTotals, pageProfiles, envelopes } = executionState;
|
|
38
38
|
async function cooperativeYield() {
|
|
39
39
|
await new Promise((resolve) => setImmediate(resolve));
|
|
@@ -52,7 +52,7 @@ export async function buildPageEnvelopes(input) {
|
|
|
52
52
|
const pageOwnerExtractStartedAt = performance.now();
|
|
53
53
|
const pageOwnerSource = extractServerScript(rawSource, sourceFile, compilerOpts).source;
|
|
54
54
|
pagePhase.serverExtractMs += startupProfile.roundMs(performance.now() - pageOwnerExtractStartedAt);
|
|
55
|
-
const { guardPath: adjacentGuard, loadPath: adjacentLoad } = resolveAdjacentServerModules(sourceFile);
|
|
55
|
+
const { guardPath: adjacentGuard, loadPath: adjacentLoad, actionPath: adjacentAction } = resolveAdjacentServerModules(sourceFile);
|
|
56
56
|
const expandedStartedAt = performance.now();
|
|
57
57
|
const { expandedSource } = expandComponents(rawSource, registry, sourceFile);
|
|
58
58
|
pageExpandMs = startupProfile.roundMs(performance.now() - expandedStartedAt);
|
|
@@ -62,21 +62,24 @@ export async function buildPageEnvelopes(input) {
|
|
|
62
62
|
const compileSource = extractedServer.source;
|
|
63
63
|
await cooperativeYield();
|
|
64
64
|
const pageCompileStartedAt = performance.now();
|
|
65
|
-
|
|
65
|
+
let pageIr = timedRunCompiler('page', sourceFile, compileSource, compilerOpts, { compilerToolchain: compilerBin, onWarning: emitCompilerWarning });
|
|
66
66
|
pageCompileMs = startupProfile.roundMs(performance.now() - pageCompileStartedAt);
|
|
67
67
|
const composedServer = composeServerScriptEnvelope({
|
|
68
68
|
sourceFile,
|
|
69
69
|
inlineServerScript: extractedServer.serverScript,
|
|
70
70
|
adjacentGuardPath: adjacentGuard,
|
|
71
|
-
adjacentLoadPath: adjacentLoad
|
|
71
|
+
adjacentLoadPath: adjacentLoad,
|
|
72
|
+
adjacentActionPath: adjacentAction
|
|
72
73
|
});
|
|
73
74
|
const hasGuard = composedServer.serverScript?.has_guard === true;
|
|
74
75
|
const hasLoad = composedServer.serverScript?.has_load === true;
|
|
76
|
+
const hasAction = composedServer.serverScript?.has_action === true;
|
|
75
77
|
applyServerEnvelopeToPageIr({
|
|
76
78
|
pageIr,
|
|
77
79
|
composedServer,
|
|
78
80
|
hasGuard,
|
|
79
81
|
hasLoad,
|
|
82
|
+
hasAction,
|
|
80
83
|
entry,
|
|
81
84
|
srcDir,
|
|
82
85
|
sourceFile
|
|
@@ -89,7 +92,8 @@ export async function buildPageEnvelopes(input) {
|
|
|
89
92
|
const pageAmbiguousExpressionMap = new Set();
|
|
90
93
|
const knownRefKeys = new Set();
|
|
91
94
|
const componentOccurrencePlans = [];
|
|
92
|
-
const
|
|
95
|
+
const imagePropsLiterals = [];
|
|
96
|
+
const { pageOwnerCompileMs: resolvedPageOwnerCompileMs, pageOwnerExpressionRewrite } = await buildPageOwnerContext({
|
|
93
97
|
componentOccurrences,
|
|
94
98
|
sourceFile,
|
|
95
99
|
pageOwnerSource,
|
|
@@ -97,13 +101,12 @@ export async function buildPageEnvelopes(input) {
|
|
|
97
101
|
compilerBin,
|
|
98
102
|
timedRunCompiler,
|
|
99
103
|
cooperativeYield,
|
|
100
|
-
templateExpressionCache,
|
|
101
104
|
expressionRewriteMetrics,
|
|
102
105
|
startupProfile
|
|
103
106
|
});
|
|
104
107
|
pageOwnerCompileMs = resolvedPageOwnerCompileMs;
|
|
105
108
|
const pageSelfRewriteStartedAt = performance.now();
|
|
106
|
-
const pageSelfExpressionRewrite = buildComponentExpressionRewrite(
|
|
109
|
+
const pageSelfExpressionRewrite = buildComponentExpressionRewrite(pageIr, expressionRewriteMetrics);
|
|
107
110
|
pagePhase.selfRewriteMs = startupProfile.roundMs(performance.now() - pageSelfRewriteStartedAt);
|
|
108
111
|
mergeExpressionRewriteMaps(pageExpressionRewriteMap, pageExpressionBindingMap, pageAmbiguousExpressionMap, pageSelfExpressionRewrite, pageIrMergeCache, pageBindingResolutionBreakdown);
|
|
109
112
|
const componentLoopStartedAt = performance.now();
|
|
@@ -127,10 +130,8 @@ export async function buildPageEnvelopes(input) {
|
|
|
127
130
|
componentIrCache,
|
|
128
131
|
componentDocumentModeCache,
|
|
129
132
|
componentExpressionRewriteCache,
|
|
130
|
-
templateExpressionCache,
|
|
131
133
|
expressionRewriteMetrics,
|
|
132
134
|
pageOwnerExpressionRewrite,
|
|
133
|
-
pageOwnerScopeRewrite,
|
|
134
135
|
pageIr,
|
|
135
136
|
pageIrMergeCache,
|
|
136
137
|
seenStaticImports,
|
|
@@ -139,6 +140,7 @@ export async function buildPageEnvelopes(input) {
|
|
|
139
140
|
pageAmbiguousExpressionMap,
|
|
140
141
|
knownRefKeys,
|
|
141
142
|
componentOccurrencePlans,
|
|
143
|
+
imagePropsLiterals,
|
|
142
144
|
pagePhase,
|
|
143
145
|
pageBindingResolutionBreakdown,
|
|
144
146
|
pageMergeBreakdown,
|
|
@@ -150,25 +152,25 @@ export async function buildPageEnvelopes(input) {
|
|
|
150
152
|
pageComponentCacheHits = pageStats.pageComponentCacheHits;
|
|
151
153
|
pageComponentCacheMisses = pageStats.pageComponentCacheMisses;
|
|
152
154
|
pagePhase.componentLoopMs = startupProfile.roundMs(performance.now() - componentLoopStartedAt);
|
|
155
|
+
if (imagePropsLiterals.length > 0) {
|
|
156
|
+
pageIr = mergePageImageMaterialization(pageIr, imagePropsLiterals, {
|
|
157
|
+
compilerToolchain: compilerBin
|
|
158
|
+
});
|
|
159
|
+
}
|
|
153
160
|
const occurrencePlanApplyStartedAt = performance.now();
|
|
154
161
|
applyOccurrenceRewritePlans(pageIr, componentOccurrencePlans, (rewrite, binding) => resolveRewrittenBindingMetadata(pageIrMergeCache, rewrite, binding, pageBindingResolutionBreakdown), pageOccurrenceApplyBreakdown);
|
|
155
162
|
pagePhase.occurrencePlanApplyMs = startupProfile.roundMs(performance.now() - occurrencePlanApplyStartedAt);
|
|
156
163
|
const expressionApplyStartedAt = performance.now();
|
|
157
164
|
applyExpressionRewrites(pageIr, pageExpressionRewriteMap, pageExpressionBindingMap, pageAmbiguousExpressionMap);
|
|
158
165
|
pagePhase.expressionApplyMs = startupProfile.roundMs(performance.now() - expressionApplyStartedAt);
|
|
159
|
-
const scopedRewriteStartedAt = performance.now();
|
|
160
|
-
const scopedRewritePlanStartedAt = performance.now();
|
|
161
|
-
const scopedRewritePlan = buildScopedIdentifierRewrite(pageIr);
|
|
162
|
-
pagePhase.scopedRewritePlanMs = startupProfile.roundMs(performance.now() - scopedRewritePlanStartedAt);
|
|
163
|
-
const scopedRewriteApplyStartedAt = performance.now();
|
|
164
|
-
applyScopedIdentifierRewrites(pageIr, scopedRewritePlan, pageScopedRewriteBreakdown);
|
|
165
|
-
pagePhase.scopedRewriteApplyMs = startupProfile.roundMs(performance.now() - scopedRewriteApplyStartedAt);
|
|
166
|
-
pagePhase.scopedRewriteMs = startupProfile.roundMs(performance.now() - scopedRewriteStartedAt);
|
|
167
166
|
const normalizeStartedAt = performance.now();
|
|
168
|
-
synthesizeSignalBackedCompiledExpressions(pageIr);
|
|
169
167
|
normalizeExpressionPayload(pageIr);
|
|
170
168
|
normalizeHoistedSourcePayload(pageIr);
|
|
171
|
-
|
|
169
|
+
if (Array.isArray(pageIr?.hoisted?.code) && pageIr.hoisted.code.length > 0) {
|
|
170
|
+
pageIr.hoisted.code = pageIr.hoisted.code
|
|
171
|
+
.map((entry) => deferComponentRuntimeBlock(entry, hoistedCodeTransformCache, expressionRewriteMetrics))
|
|
172
|
+
.filter((entry) => typeof entry === 'string' && entry.trim().length > 0);
|
|
173
|
+
}
|
|
172
174
|
rewriteLegacyMarkupIdentifiers(pageIr);
|
|
173
175
|
rewriteRefBindingIdentifiers(pageIr, knownRefKeys);
|
|
174
176
|
pagePhase.normalizeMs = startupProfile.roundMs(performance.now() - normalizeStartedAt);
|
|
@@ -182,6 +184,9 @@ export async function buildPageEnvelopes(input) {
|
|
|
182
184
|
route: entry.path,
|
|
183
185
|
file: sourceFile,
|
|
184
186
|
ir: pageIr,
|
|
187
|
+
image_materialization: Array.isArray(pageIr.image_materialization)
|
|
188
|
+
? pageIr.image_materialization
|
|
189
|
+
: [],
|
|
185
190
|
router: routerEnabled
|
|
186
191
|
});
|
|
187
192
|
recordPageProfile({
|
|
@@ -1,29 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @param {object | null | undefined} ir
|
|
3
|
-
* @returns {{ map: Map<string, string>, ambiguous: Set<string> }}
|
|
4
|
-
*/
|
|
5
|
-
export function buildScopedIdentifierRewrite(ir: object | null | undefined): {
|
|
6
|
-
map: Map<string, string>;
|
|
7
|
-
ambiguous: Set<string>;
|
|
8
|
-
};
|
|
9
|
-
/**
|
|
10
|
-
* @param {string} expr
|
|
11
|
-
* @param {{
|
|
12
|
-
* expressionRewrite?: { map?: Map<string, string>, ambiguous?: Set<string> } | null,
|
|
13
|
-
* scopeRewrite?: { map?: Map<string, string>, ambiguous?: Set<string> } | null
|
|
14
|
-
* } | null} rewriteContext
|
|
15
|
-
* @returns {string}
|
|
16
|
-
*/
|
|
17
|
-
export function rewritePropsExpression(expr: string, rewriteContext?: {
|
|
18
|
-
expressionRewrite?: {
|
|
19
|
-
map?: Map<string, string>;
|
|
20
|
-
ambiguous?: Set<string>;
|
|
21
|
-
} | null;
|
|
22
|
-
scopeRewrite?: {
|
|
23
|
-
map?: Map<string, string>;
|
|
24
|
-
ambiguous?: Set<string>;
|
|
25
|
-
} | null;
|
|
26
|
-
} | null): string;
|
|
27
1
|
/**
|
|
28
2
|
* @param {string | null | undefined} compiledExpr
|
|
29
3
|
* @param {{
|
|
@@ -41,6 +15,10 @@ export function resolveCompiledPropsExpression(compiledExpr: string | null | und
|
|
|
41
15
|
}>;
|
|
42
16
|
} | null | undefined): string | null;
|
|
43
17
|
/**
|
|
18
|
+
* The only allowed downstream props rewrite boundary is compiler-owned exact lookup.
|
|
19
|
+
* If the compiler did not emit a mapping for the attr expression, CLI keeps the
|
|
20
|
+
* original expression text without attempting identifier reinterpretation.
|
|
21
|
+
*
|
|
44
22
|
* @param {string} expr
|
|
45
23
|
* @param {{
|
|
46
24
|
* expressionRewrite?: {
|
|
@@ -49,8 +27,7 @@ export function resolveCompiledPropsExpression(compiledExpr: string | null | und
|
|
|
49
27
|
* ambiguous?: Set<string>,
|
|
50
28
|
* signals?: Array<{ state_index?: number }>,
|
|
51
29
|
* stateBindings?: Array<{ key?: string }>
|
|
52
|
-
* } | null
|
|
53
|
-
* scopeRewrite?: { map?: Map<string, string>, ambiguous?: Set<string> } | null
|
|
30
|
+
* } | null
|
|
54
31
|
* } | null} rewriteContext
|
|
55
32
|
* @returns {string}
|
|
56
33
|
*/
|
|
@@ -68,45 +45,61 @@ export function resolvePropsValueCode(expr: string, rewriteContext?: {
|
|
|
68
45
|
key?: string;
|
|
69
46
|
}>;
|
|
70
47
|
} | null;
|
|
71
|
-
scopeRewrite?: {
|
|
72
|
-
map?: Map<string, string>;
|
|
73
|
-
ambiguous?: Set<string>;
|
|
74
|
-
} | null;
|
|
75
48
|
} | null): string;
|
|
76
49
|
/**
|
|
77
50
|
* @param {string} attrs
|
|
78
51
|
* @param {{
|
|
79
|
-
* expressionRewrite?: {
|
|
80
|
-
*
|
|
52
|
+
* expressionRewrite?: {
|
|
53
|
+
* map?: Map<string, string>,
|
|
54
|
+
* bindings?: Map<string, { compiled_expr?: string | null }>,
|
|
55
|
+
* ambiguous?: Set<string>,
|
|
56
|
+
* signals?: Array<{ state_index?: number }>,
|
|
57
|
+
* stateBindings?: Array<{ key?: string }>
|
|
58
|
+
* } | null
|
|
81
59
|
* } | null} rewriteContext
|
|
82
60
|
* @returns {string}
|
|
83
61
|
*/
|
|
84
62
|
export function renderPropsLiteralFromAttrs(attrs: string, rewriteContext?: {
|
|
85
63
|
expressionRewrite?: {
|
|
86
64
|
map?: Map<string, string>;
|
|
65
|
+
bindings?: Map<string, {
|
|
66
|
+
compiled_expr?: string | null;
|
|
67
|
+
}>;
|
|
87
68
|
ambiguous?: Set<string>;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
69
|
+
signals?: Array<{
|
|
70
|
+
state_index?: number;
|
|
71
|
+
}>;
|
|
72
|
+
stateBindings?: Array<{
|
|
73
|
+
key?: string;
|
|
74
|
+
}>;
|
|
92
75
|
} | null;
|
|
93
76
|
} | null): string;
|
|
94
77
|
/**
|
|
95
78
|
* @param {string} source
|
|
96
79
|
* @param {string} attrs
|
|
97
80
|
* @param {{
|
|
98
|
-
* expressionRewrite?: {
|
|
99
|
-
*
|
|
81
|
+
* expressionRewrite?: {
|
|
82
|
+
* map?: Map<string, string>,
|
|
83
|
+
* bindings?: Map<string, { compiled_expr?: string | null }>,
|
|
84
|
+
* ambiguous?: Set<string>,
|
|
85
|
+
* signals?: Array<{ state_index?: number }>,
|
|
86
|
+
* stateBindings?: Array<{ key?: string }>
|
|
87
|
+
* } | null
|
|
100
88
|
* } | null} rewriteContext
|
|
101
89
|
* @returns {string}
|
|
102
90
|
*/
|
|
103
91
|
export function injectPropsPrelude(source: string, attrs: string, rewriteContext?: {
|
|
104
92
|
expressionRewrite?: {
|
|
105
93
|
map?: Map<string, string>;
|
|
94
|
+
bindings?: Map<string, {
|
|
95
|
+
compiled_expr?: string | null;
|
|
96
|
+
}>;
|
|
106
97
|
ambiguous?: Set<string>;
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
98
|
+
signals?: Array<{
|
|
99
|
+
state_index?: number;
|
|
100
|
+
}>;
|
|
101
|
+
stateBindings?: Array<{
|
|
102
|
+
key?: string;
|
|
103
|
+
}>;
|
|
111
104
|
} | null;
|
|
112
105
|
} | null): string;
|