@zenithbuild/runtime 0.7.5 → 0.7.7
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/diagnostics-production.d.ts +11 -0
- package/dist/diagnostics-production.js +279 -0
- package/dist/events.js +2 -2
- package/dist/expressions.d.ts +0 -1
- package/dist/expressions.js +128 -150
- package/dist/hydrate.js +32 -67
- package/dist/markup.js +7 -7
- package/dist/payload.d.ts +9 -10
- package/dist/payload.js +128 -219
- package/dist/render.js +99 -117
- package/dist/runtime-template-profile.d.ts +20 -0
- package/dist/runtime-template-profile.js +141 -0
- package/dist/scanner.js +2 -2
- package/dist/template.d.ts +7 -1
- package/dist/template.js +25 -23
- package/package.json +1 -1
package/dist/hydrate.js
CHANGED
|
@@ -10,7 +10,7 @@ import { createNodeResolver } from './scanner.js';
|
|
|
10
10
|
import { bindEventMarkers } from './events.js';
|
|
11
11
|
import { _applyMarkerValue } from './render.js';
|
|
12
12
|
export { _createContextualFragment, _coerceText } from './render.js';
|
|
13
|
-
// Raw HTML boundary
|
|
13
|
+
// Raw HTML boundary lock lives in render.js:
|
|
14
14
|
// attrName.toLowerCase() === 'innerhtml'
|
|
15
15
|
// innerHTML bindings are forbidden in Zenith
|
|
16
16
|
// attrName.toLowerCase() === 'unsafehtml'
|
|
@@ -19,7 +19,7 @@ export function hydrate(payload) {
|
|
|
19
19
|
try {
|
|
20
20
|
const normalized = _validatePayload(payload);
|
|
21
21
|
_deepFreezePayload(payload);
|
|
22
|
-
const { root, expressions, markers, events, refs, stateValues, stateKeys, signals, components,
|
|
22
|
+
const { root, expressions, markers, events, refs, stateValues, stateKeys, signals, components, params, ssrData, props, exprFns } = normalized;
|
|
23
23
|
const componentBindings = Object.create(null);
|
|
24
24
|
const resolveNodes = createNodeResolver(root);
|
|
25
25
|
const signalMap = _createSignalMap(signals, stateValues);
|
|
@@ -28,12 +28,10 @@ export function hydrate(payload) {
|
|
|
28
28
|
components,
|
|
29
29
|
signalMap,
|
|
30
30
|
componentBindings,
|
|
31
|
-
route,
|
|
32
31
|
resolveNodes
|
|
33
32
|
});
|
|
34
|
-
const
|
|
33
|
+
const runtimeContext = {
|
|
35
34
|
expressions,
|
|
36
|
-
markers,
|
|
37
35
|
stateValues,
|
|
38
36
|
stateKeys,
|
|
39
37
|
signalMap,
|
|
@@ -43,22 +41,16 @@ export function hydrate(payload) {
|
|
|
43
41
|
props,
|
|
44
42
|
exprFns,
|
|
45
43
|
resolveNodes
|
|
44
|
+
};
|
|
45
|
+
const markerState = _hydrateMarkers({
|
|
46
|
+
...runtimeContext,
|
|
47
|
+
markers
|
|
46
48
|
});
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
root,
|
|
50
|
-
expressions,
|
|
51
|
-
stateValues,
|
|
52
|
-
stateKeys,
|
|
53
|
-
signalMap,
|
|
54
|
-
componentBindings,
|
|
55
|
-
params,
|
|
56
|
-
ssrData,
|
|
57
|
-
props,
|
|
58
|
-
exprFns,
|
|
59
|
-
resolveNodes,
|
|
49
|
+
const renderContext = {
|
|
50
|
+
...runtimeContext,
|
|
60
51
|
...markerState
|
|
61
|
-
}
|
|
52
|
+
};
|
|
53
|
+
const renderMarkerByIndex = (index) => _renderMarker(renderContext, index);
|
|
62
54
|
_bindSignalSubscriptions(expressions, signalMap, stateValues, renderMarkerByIndex);
|
|
63
55
|
_bindComponentSignalSubscriptions(expressions, componentBindings, renderMarkerByIndex);
|
|
64
56
|
bindEventMarkers({
|
|
@@ -82,7 +74,7 @@ export function hydrate(payload) {
|
|
|
82
74
|
rethrowZenithRuntimeError(error, {
|
|
83
75
|
phase: 'hydrate',
|
|
84
76
|
code: 'BINDING_APPLY_FAILED',
|
|
85
|
-
hint: 'Inspect marker tables, expression bindings, and
|
|
77
|
+
hint: 'Inspect marker tables, expression bindings, and runtime diagnostics.',
|
|
86
78
|
docsLink: DOCS_LINKS.markerTable
|
|
87
79
|
});
|
|
88
80
|
}
|
|
@@ -121,13 +113,10 @@ function _hydrateRefs(refs, stateValues, resolveNodes) {
|
|
|
121
113
|
});
|
|
122
114
|
}
|
|
123
115
|
function _mountComponents(context) {
|
|
124
|
-
const { components, signalMap, componentBindings,
|
|
116
|
+
const { components, signalMap, componentBindings, resolveNodes } = context;
|
|
125
117
|
for (let i = 0; i < components.length; i++) {
|
|
126
118
|
const component = components[i];
|
|
127
|
-
const resolvedProps = Object.freeze(_resolveComponentProps(component.props || [], signalMap
|
|
128
|
-
component: component.instance,
|
|
129
|
-
route
|
|
130
|
-
}));
|
|
119
|
+
const resolvedProps = Object.freeze(_resolveComponentProps(component.props || [], signalMap));
|
|
131
120
|
const hosts = resolveNodes(component.selector, i, 'component', component.source);
|
|
132
121
|
for (let j = 0; j < hosts.length; j++) {
|
|
133
122
|
try {
|
|
@@ -176,7 +165,7 @@ function _mountComponents(context) {
|
|
|
176
165
|
code: 'COMPONENT_BOOTSTRAP_FAILED',
|
|
177
166
|
message: `Component bootstrap failed for "${component.instance}"`,
|
|
178
167
|
path: `component[${component.instance}]`,
|
|
179
|
-
hint: 'Fix the failing component and refresh
|
|
168
|
+
hint: 'Fix the failing component and refresh.',
|
|
180
169
|
docsLink: DOCS_LINKS.componentBootstrap,
|
|
181
170
|
source: component.source
|
|
182
171
|
});
|
|
@@ -188,49 +177,31 @@ function _mountComponents(context) {
|
|
|
188
177
|
}
|
|
189
178
|
}
|
|
190
179
|
function _hydrateMarkers(context) {
|
|
191
|
-
const { expressions, markers,
|
|
180
|
+
const { expressions, markers, resolveNodes } = context;
|
|
192
181
|
const markerByIndex = new Map();
|
|
193
182
|
const markerNodesByIndex = new Map();
|
|
194
|
-
const markerIndices = new Set();
|
|
195
|
-
const expressionMarkerIndices = new Set();
|
|
196
|
-
for (let i = 0; i < expressions.length; i++) {
|
|
197
|
-
const expression = expressions[i];
|
|
198
|
-
if (expressionMarkerIndices.has(expression.marker_index)) {
|
|
199
|
-
throw new Error(`[Zenith Runtime] duplicate expression marker_index ${expression.marker_index}`);
|
|
200
|
-
}
|
|
201
|
-
expressionMarkerIndices.add(expression.marker_index);
|
|
202
|
-
}
|
|
203
183
|
for (let i = 0; i < markers.length; i++) {
|
|
204
184
|
const marker = markers[i];
|
|
205
|
-
if (markerIndices.has(marker.index)) {
|
|
206
|
-
throw new Error(`[Zenith Runtime] duplicate marker index ${marker.index}`);
|
|
207
|
-
}
|
|
208
|
-
markerIndices.add(marker.index);
|
|
209
185
|
markerByIndex.set(marker.index, marker);
|
|
210
186
|
if (marker.kind === 'event') {
|
|
211
187
|
continue;
|
|
212
188
|
}
|
|
213
189
|
const nodes = resolveNodes(marker.selector, marker.index, marker.kind, marker.source);
|
|
214
190
|
markerNodesByIndex.set(marker.index, nodes);
|
|
215
|
-
const value =
|
|
191
|
+
const value = _evaluateMarkerBinding(context, expressions[marker.index], marker);
|
|
216
192
|
_applyMarkerValue(nodes, marker, value);
|
|
217
193
|
}
|
|
218
|
-
for (let i = 0; i < expressions.length; i++) {
|
|
219
|
-
if (!markerIndices.has(i)) {
|
|
220
|
-
throw new Error(`[Zenith Runtime] missing marker index ${i}`);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
194
|
return { markerByIndex, markerNodesByIndex };
|
|
224
195
|
}
|
|
225
|
-
function _renderMarker(context) {
|
|
226
|
-
const marker = context.markerByIndex.get(
|
|
196
|
+
function _renderMarker(context, index) {
|
|
197
|
+
const marker = context.markerByIndex.get(index);
|
|
227
198
|
if (!marker || marker.kind === 'event') {
|
|
228
199
|
return;
|
|
229
200
|
}
|
|
230
|
-
const nodes = context.markerNodesByIndex.get(
|
|
201
|
+
const nodes = context.markerNodesByIndex.get(index)
|
|
231
202
|
|| context.resolveNodes(marker.selector, marker.index, marker.kind, marker.source);
|
|
232
|
-
context.markerNodesByIndex.set(
|
|
233
|
-
const value =
|
|
203
|
+
context.markerNodesByIndex.set(index, nodes);
|
|
204
|
+
const value = _evaluateMarkerBinding(context, context.expressions[index], marker);
|
|
234
205
|
_applyMarkerValue(nodes, marker, value);
|
|
235
206
|
}
|
|
236
207
|
function _isSignalLike(candidate) {
|
|
@@ -265,16 +236,7 @@ function _bindSignalSubscriptions(expressions, signalMap, stateValues, renderMar
|
|
|
265
236
|
_recordSignalMarkerDependency(dependentMarkersBySignal, stateValues[expression.state_index], expression.marker_index);
|
|
266
237
|
}
|
|
267
238
|
}
|
|
268
|
-
|
|
269
|
-
const unsubscribe = targetSignal.subscribe(() => {
|
|
270
|
-
for (let i = 0; i < markerIndexes.length; i++) {
|
|
271
|
-
renderMarkerByIndex(markerIndexes[i]);
|
|
272
|
-
}
|
|
273
|
-
});
|
|
274
|
-
if (typeof unsubscribe === 'function') {
|
|
275
|
-
_registerDisposer(unsubscribe);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
239
|
+
_subscribeMarkerDependencies(dependentMarkersBySignal, renderMarkerByIndex);
|
|
278
240
|
}
|
|
279
241
|
function _bindComponentSignalSubscriptions(expressions, componentBindings, renderMarkerByIndex) {
|
|
280
242
|
const dependentMarkersByComponentSignal = new Map();
|
|
@@ -285,10 +247,7 @@ function _bindComponentSignalSubscriptions(expressions, componentBindings, rende
|
|
|
285
247
|
}
|
|
286
248
|
const instanceBindings = componentBindings[expression.component_instance];
|
|
287
249
|
const candidate = instanceBindings?.[expression.component_binding];
|
|
288
|
-
if (!candidate
|
|
289
|
-
continue;
|
|
290
|
-
}
|
|
291
|
-
if (typeof candidate.get !== 'function' || typeof candidate.subscribe !== 'function') {
|
|
250
|
+
if (!_isSignalLike(candidate)) {
|
|
292
251
|
continue;
|
|
293
252
|
}
|
|
294
253
|
if (!dependentMarkersByComponentSignal.has(candidate)) {
|
|
@@ -296,8 +255,14 @@ function _bindComponentSignalSubscriptions(expressions, componentBindings, rende
|
|
|
296
255
|
}
|
|
297
256
|
dependentMarkersByComponentSignal.get(candidate).push(expression.marker_index);
|
|
298
257
|
}
|
|
299
|
-
|
|
300
|
-
|
|
258
|
+
_subscribeMarkerDependencies(dependentMarkersByComponentSignal, renderMarkerByIndex);
|
|
259
|
+
}
|
|
260
|
+
function _evaluateMarkerBinding(context, expression, marker) {
|
|
261
|
+
return _evaluateExpression(expression, context.stateValues, context.stateKeys, context.signalMap, context.componentBindings, context.params, context.ssrData, marker.kind, context.props, context.exprFns, marker, null);
|
|
262
|
+
}
|
|
263
|
+
function _subscribeMarkerDependencies(dependencies, renderMarkerByIndex) {
|
|
264
|
+
for (const [targetSignal, markerIndexes] of dependencies.entries()) {
|
|
265
|
+
const unsubscribe = targetSignal.subscribe(() => {
|
|
301
266
|
for (let i = 0; i < markerIndexes.length; i++) {
|
|
302
267
|
renderMarkerByIndex(markerIndexes[i]);
|
|
303
268
|
}
|
package/dist/markup.js
CHANGED
|
@@ -30,7 +30,7 @@ export function _fragment(strings, ...values) {
|
|
|
30
30
|
phase: 'render',
|
|
31
31
|
code: 'NON_RENDERABLE_VALUE',
|
|
32
32
|
message: '__zenith_fragment must be called as a tagged template literal',
|
|
33
|
-
hint: 'This helper only accepts tagged
|
|
33
|
+
hint: 'This helper only accepts tagged templates.'
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
36
|
let result = '';
|
|
@@ -46,7 +46,7 @@ export function _fragment(strings, ...values) {
|
|
|
46
46
|
phase: 'render',
|
|
47
47
|
code: 'NON_RENDERABLE_VALUE',
|
|
48
48
|
message: 'Embedded markup expression contains forbidden <script> tag',
|
|
49
|
-
hint: 'Script tags are not allowed in embedded markup
|
|
49
|
+
hint: 'Script tags are not allowed in embedded markup.'
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
52
|
if (_FRAGMENT_EVENT_ATTR_RE.test(result)) {
|
|
@@ -54,7 +54,7 @@ export function _fragment(strings, ...values) {
|
|
|
54
54
|
phase: 'render',
|
|
55
55
|
code: 'NON_RENDERABLE_VALUE',
|
|
56
56
|
message: 'Embedded markup expression contains inline event handler (on*=)',
|
|
57
|
-
hint: 'Use on:event={handler}
|
|
57
|
+
hint: 'Use on:event={handler} instead of inline event attributes.'
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
60
|
if (_FRAGMENT_JS_URL_RE.test(result)) {
|
|
@@ -62,7 +62,7 @@ export function _fragment(strings, ...values) {
|
|
|
62
62
|
phase: 'render',
|
|
63
63
|
code: 'NON_RENDERABLE_VALUE',
|
|
64
64
|
message: 'Embedded markup expression contains javascript: URL',
|
|
65
|
-
hint: 'javascript: URLs are forbidden
|
|
65
|
+
hint: 'javascript: URLs are forbidden.'
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
result = result.replace(_FRAGMENT_SCRIPT_CLOSE_RE, '<\\/script');
|
|
@@ -99,7 +99,7 @@ function _fragmentInterpolate(val, interpolationIndex) {
|
|
|
99
99
|
phase: 'render',
|
|
100
100
|
code: 'NON_RENDERABLE_VALUE',
|
|
101
101
|
message: `Embedded markup interpolation[${interpolationIndex}] contains forbidden key "${keys[k]}"`,
|
|
102
|
-
hint: 'Prototype pollution keys are forbidden in embedded markup
|
|
102
|
+
hint: 'Prototype pollution keys are forbidden in embedded markup.'
|
|
103
103
|
});
|
|
104
104
|
}
|
|
105
105
|
}
|
|
@@ -107,14 +107,14 @@ function _fragmentInterpolate(val, interpolationIndex) {
|
|
|
107
107
|
phase: 'render',
|
|
108
108
|
code: 'NON_RENDERABLE_VALUE',
|
|
109
109
|
message: `Embedded markup interpolation[${interpolationIndex}] resolved to a non-renderable object`,
|
|
110
|
-
hint: 'Only
|
|
110
|
+
hint: 'Only primitives, arrays, and compiler-owned fragments are allowed.'
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
113
|
throwZenithRuntimeError({
|
|
114
114
|
phase: 'render',
|
|
115
115
|
code: 'NON_RENDERABLE_VALUE',
|
|
116
116
|
message: `Embedded markup interpolation[${interpolationIndex}] resolved to type "${typeof val}"`,
|
|
117
|
-
hint: 'Only
|
|
117
|
+
hint: 'Only primitives, arrays, and compiler-owned fragments are allowed.'
|
|
118
118
|
});
|
|
119
119
|
}
|
|
120
120
|
function _escapeFragmentHtml(input) {
|
package/dist/payload.d.ts
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
export function _validatePayload(payload: any):
|
|
1
|
+
export function _validatePayload(payload: any): {
|
|
2
2
|
root: any;
|
|
3
|
-
expressions: any
|
|
4
|
-
markers: any
|
|
5
|
-
events: any
|
|
3
|
+
expressions: any;
|
|
4
|
+
markers: any;
|
|
5
|
+
events: any;
|
|
6
6
|
refs: any;
|
|
7
|
-
stateValues: any
|
|
8
|
-
stateKeys: any
|
|
9
|
-
signals: any
|
|
7
|
+
stateValues: any;
|
|
8
|
+
stateKeys: any;
|
|
9
|
+
signals: any;
|
|
10
10
|
components: any;
|
|
11
|
-
route: any;
|
|
12
11
|
params: any;
|
|
13
12
|
ssrData: any;
|
|
14
13
|
props: any;
|
|
15
14
|
exprFns: any;
|
|
16
|
-
}
|
|
17
|
-
export function _resolveComponentProps(propTable: any, signalMap: any
|
|
15
|
+
};
|
|
16
|
+
export function _resolveComponentProps(propTable: any, signalMap: any): any;
|
|
18
17
|
export function _deepFreezePayload(obj: any): void;
|
|
19
18
|
export function _isHydrationRefObject(obj: any): boolean;
|
|
20
19
|
export function _isPlainObject(value: any): boolean;
|