@vue/server-renderer 3.2.45 → 3.2.46
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ssrContextKey, warn as warn$1, Fragment, Static, Comment, Text, mergeProps, ssrUtils, createApp,
|
|
2
|
-
import { makeMap, isOn,
|
|
1
|
+
import { createVNode, ssrContextKey, warn as warn$1, Fragment, Static, Comment, Text, mergeProps, ssrUtils, createApp, initDirectivesForSSR } from 'vue';
|
|
2
|
+
import { makeMap, isOn, isSVGTag, propsToAttrMap, isBooleanAttr, includeBooleanAttr, isSSRSafeAttrName, escapeHtml, normalizeClass, isString, normalizeStyle, stringifyStyle, isArray, toDisplayString, isFunction, isObject, looseEqual, looseIndexOf, isPromise, NOOP, escapeHtmlComment, isVoidTag } from '@vue/shared';
|
|
3
3
|
export { includeBooleanAttr as ssrIncludeBooleanAttr } from '@vue/shared';
|
|
4
4
|
|
|
5
5
|
// leading comma for empty string ""
|
|
@@ -73,13 +73,69 @@ function ssrRenderStyle(raw) {
|
|
|
73
73
|
return escapeHtml(stringifyStyle(styles));
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
function
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
function ssrRenderComponent(comp, props = null, children = null, parentComponent = null, slotScopeId) {
|
|
77
|
+
return renderComponentVNode(createVNode(comp, props, children), parentComponent, slotScopeId);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function ssrRenderSlot(slots, slotName, slotProps, fallbackRenderFn, push, parentComponent, slotScopeId) {
|
|
81
|
+
// template-compiled slots are always rendered as fragments
|
|
82
|
+
push(`<!--[-->`);
|
|
83
|
+
ssrRenderSlotInner(slots, slotName, slotProps, fallbackRenderFn, push, parentComponent, slotScopeId);
|
|
84
|
+
push(`<!--]-->`);
|
|
85
|
+
}
|
|
86
|
+
function ssrRenderSlotInner(slots, slotName, slotProps, fallbackRenderFn, push, parentComponent, slotScopeId, transition) {
|
|
87
|
+
const slotFn = slots[slotName];
|
|
88
|
+
if (slotFn) {
|
|
89
|
+
const slotBuffer = [];
|
|
90
|
+
const bufferedPush = (item) => {
|
|
91
|
+
slotBuffer.push(item);
|
|
92
|
+
};
|
|
93
|
+
const ret = slotFn(slotProps, bufferedPush, parentComponent, slotScopeId ? ' ' + slotScopeId : '');
|
|
94
|
+
if (isArray(ret)) {
|
|
95
|
+
// normal slot
|
|
96
|
+
renderVNodeChildren(push, ret, parentComponent, slotScopeId);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// ssr slot.
|
|
100
|
+
// check if the slot renders all comments, in which case use the fallback
|
|
101
|
+
let isEmptySlot = true;
|
|
102
|
+
if (transition) {
|
|
103
|
+
isEmptySlot = false;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
for (let i = 0; i < slotBuffer.length; i++) {
|
|
107
|
+
if (!isComment(slotBuffer[i])) {
|
|
108
|
+
isEmptySlot = false;
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (isEmptySlot) {
|
|
114
|
+
if (fallbackRenderFn) {
|
|
115
|
+
fallbackRenderFn();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
for (let i = 0; i < slotBuffer.length; i++) {
|
|
120
|
+
push(slotBuffer[i]);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
else if (fallbackRenderFn) {
|
|
126
|
+
fallbackRenderFn();
|
|
81
127
|
}
|
|
82
128
|
}
|
|
129
|
+
const commentTestRE = /^<!--.*-->$/s;
|
|
130
|
+
const commentRE = /<!--[^]*?-->/gm;
|
|
131
|
+
function isComment(item) {
|
|
132
|
+
if (typeof item !== 'string' || !commentTestRE.test(item))
|
|
133
|
+
return false;
|
|
134
|
+
// if item is '<!---->' or '<!--[-->' or '<!--]-->', return true directly
|
|
135
|
+
if (item.length <= 8)
|
|
136
|
+
return true;
|
|
137
|
+
return !item.replace(commentRE, '').trim();
|
|
138
|
+
}
|
|
83
139
|
|
|
84
140
|
function ssrRenderTeleport(parentPush, contentRenderFn, target, disabled, parentComponent) {
|
|
85
141
|
parentPush('<!--teleport start-->');
|
|
@@ -104,891 +160,852 @@ function ssrRenderTeleport(parentPush, contentRenderFn, target, disabled, parent
|
|
|
104
160
|
parentPush('<!--teleport end-->');
|
|
105
161
|
}
|
|
106
162
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
// A buffer array can contain one of the following:
|
|
110
|
-
// - plain string
|
|
111
|
-
// - A resolved buffer (recursive arrays of strings that can be unrolled
|
|
112
|
-
// synchronously)
|
|
113
|
-
// - An async buffer (a Promise that resolves to a resolved buffer)
|
|
114
|
-
function createBuffer() {
|
|
115
|
-
let appendable = false;
|
|
116
|
-
const buffer = [];
|
|
117
|
-
return {
|
|
118
|
-
getBuffer() {
|
|
119
|
-
// Return static buffer and await on items during unroll stage
|
|
120
|
-
return buffer;
|
|
121
|
-
},
|
|
122
|
-
push(item) {
|
|
123
|
-
const isStringItem = isString(item);
|
|
124
|
-
if (appendable && isStringItem) {
|
|
125
|
-
buffer[buffer.length - 1] += item;
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
buffer.push(item);
|
|
129
|
-
}
|
|
130
|
-
appendable = isStringItem;
|
|
131
|
-
if (isPromise(item) || (isArray(item) && item.hasAsync)) {
|
|
132
|
-
// promise, or child buffer with async, mark as async.
|
|
133
|
-
// this allows skipping unnecessary await ticks during unroll stage
|
|
134
|
-
buffer.hasAsync = true;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
};
|
|
163
|
+
function ssrInterpolate(value) {
|
|
164
|
+
return escapeHtml(toDisplayString(value));
|
|
138
165
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
166
|
+
|
|
167
|
+
Symbol((process.env.NODE_ENV !== 'production') ? 'iterate' : '');
|
|
168
|
+
Symbol((process.env.NODE_ENV !== 'production') ? 'Map key iterate' : '');
|
|
169
|
+
let shouldTrack = true;
|
|
170
|
+
const trackStack = [];
|
|
171
|
+
function pauseTracking() {
|
|
172
|
+
trackStack.push(shouldTrack);
|
|
173
|
+
shouldTrack = false;
|
|
174
|
+
}
|
|
175
|
+
function resetTracking() {
|
|
176
|
+
const last = trackStack.pop();
|
|
177
|
+
shouldTrack = last === undefined ? true : last;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function toRaw(observed) {
|
|
181
|
+
const raw = observed && observed["__v_raw" /* ReactiveFlags.RAW */];
|
|
182
|
+
return raw ? toRaw(raw) : observed;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function isRef(r) {
|
|
186
|
+
return !!(r && r.__v_isRef === true);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const stack = [];
|
|
190
|
+
function pushWarningContext(vnode) {
|
|
191
|
+
stack.push(vnode);
|
|
192
|
+
}
|
|
193
|
+
function popWarningContext() {
|
|
194
|
+
stack.pop();
|
|
195
|
+
}
|
|
196
|
+
function warn(msg, ...args) {
|
|
197
|
+
if (!(process.env.NODE_ENV !== 'production'))
|
|
198
|
+
return;
|
|
199
|
+
// avoid props formatting or warn handler tracking deps that might be mutated
|
|
200
|
+
// during patch, leading to infinite recursion.
|
|
201
|
+
pauseTracking();
|
|
202
|
+
const instance = stack.length ? stack[stack.length - 1].component : null;
|
|
203
|
+
const appWarnHandler = instance && instance.appContext.config.warnHandler;
|
|
204
|
+
const trace = getComponentTrace();
|
|
205
|
+
if (appWarnHandler) {
|
|
206
|
+
callWithErrorHandling(appWarnHandler, instance, 11 /* ErrorCodes.APP_WARN_HANDLER */, [
|
|
207
|
+
msg + args.join(''),
|
|
208
|
+
instance && instance.proxy,
|
|
209
|
+
trace
|
|
210
|
+
.map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`)
|
|
211
|
+
.join('\n'),
|
|
212
|
+
trace
|
|
213
|
+
]);
|
|
155
214
|
}
|
|
156
215
|
else {
|
|
157
|
-
|
|
216
|
+
const warnArgs = [`[Vue warn]: ${msg}`, ...args];
|
|
217
|
+
/* istanbul ignore if */
|
|
218
|
+
if (trace.length &&
|
|
219
|
+
// avoid spamming console during tests
|
|
220
|
+
!false) {
|
|
221
|
+
warnArgs.push(`\n`, ...formatTrace(trace));
|
|
222
|
+
}
|
|
223
|
+
console.warn(...warnArgs);
|
|
158
224
|
}
|
|
225
|
+
resetTracking();
|
|
159
226
|
}
|
|
160
|
-
function
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
let root = renderComponentRoot(instance);
|
|
165
|
-
// #5817 scope ID attrs not falling through if functional component doesn't
|
|
166
|
-
// have props
|
|
167
|
-
if (!comp.props) {
|
|
168
|
-
for (const key in instance.attrs) {
|
|
169
|
-
if (key.startsWith(`data-v-`)) {
|
|
170
|
-
(root.props || (root.props = {}))[key] = ``;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
renderVNode(push, (instance.subTree = root), instance, slotScopeId);
|
|
227
|
+
function getComponentTrace() {
|
|
228
|
+
let currentVNode = stack[stack.length - 1];
|
|
229
|
+
if (!currentVNode) {
|
|
230
|
+
return [];
|
|
175
231
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
// since there cannot be state mutations during render.
|
|
185
|
-
for (const e of instance.scope.effects) {
|
|
186
|
-
if (e.computed)
|
|
187
|
-
e.computed._cacheable = true;
|
|
188
|
-
}
|
|
189
|
-
const ssrRender = instance.ssrRender || comp.ssrRender;
|
|
190
|
-
if (ssrRender) {
|
|
191
|
-
// optimized
|
|
192
|
-
// resolve fallthrough attrs
|
|
193
|
-
let attrs = instance.inheritAttrs !== false ? instance.attrs : undefined;
|
|
194
|
-
let hasCloned = false;
|
|
195
|
-
let cur = instance;
|
|
196
|
-
while (true) {
|
|
197
|
-
const scopeId = cur.vnode.scopeId;
|
|
198
|
-
if (scopeId) {
|
|
199
|
-
if (!hasCloned) {
|
|
200
|
-
attrs = { ...attrs };
|
|
201
|
-
hasCloned = true;
|
|
202
|
-
}
|
|
203
|
-
attrs[scopeId] = '';
|
|
204
|
-
}
|
|
205
|
-
const parent = cur.parent;
|
|
206
|
-
if (parent && parent.subTree && parent.subTree === cur.vnode) {
|
|
207
|
-
// parent is a non-SSR compiled component and is rendering this
|
|
208
|
-
// component as root. inherit its scopeId if present.
|
|
209
|
-
cur = parent;
|
|
210
|
-
}
|
|
211
|
-
else {
|
|
212
|
-
break;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
if (slotScopeId) {
|
|
216
|
-
if (!hasCloned)
|
|
217
|
-
attrs = { ...attrs };
|
|
218
|
-
attrs[slotScopeId.trim()] = '';
|
|
219
|
-
}
|
|
220
|
-
// set current rendering instance for asset resolution
|
|
221
|
-
const prev = setCurrentRenderingInstance(instance);
|
|
222
|
-
try {
|
|
223
|
-
ssrRender(instance.proxy, push, instance, attrs,
|
|
224
|
-
// compiler-optimized bindings
|
|
225
|
-
instance.props, instance.setupState, instance.data, instance.ctx);
|
|
226
|
-
}
|
|
227
|
-
finally {
|
|
228
|
-
setCurrentRenderingInstance(prev);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
else if (instance.render && instance.render !== NOOP) {
|
|
232
|
-
renderVNode(push, (instance.subTree = renderComponentRoot(instance)), instance, slotScopeId);
|
|
232
|
+
// we can't just use the stack because it will be incomplete during updates
|
|
233
|
+
// that did not start from the root. Re-construct the parent chain using
|
|
234
|
+
// instance parent pointers.
|
|
235
|
+
const normalizedStack = [];
|
|
236
|
+
while (currentVNode) {
|
|
237
|
+
const last = normalizedStack[0];
|
|
238
|
+
if (last && last.vnode === currentVNode) {
|
|
239
|
+
last.recurseCount++;
|
|
233
240
|
}
|
|
234
241
|
else {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
242
|
+
normalizedStack.push({
|
|
243
|
+
vnode: currentVNode,
|
|
244
|
+
recurseCount: 0
|
|
245
|
+
});
|
|
238
246
|
}
|
|
247
|
+
const parentInstance = currentVNode.component && currentVNode.component.parent;
|
|
248
|
+
currentVNode = parentInstance && parentInstance.vnode;
|
|
239
249
|
}
|
|
240
|
-
return
|
|
250
|
+
return normalizedStack;
|
|
241
251
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
push(children ? `<!--${escapeHtmlComment(children)}-->` : `<!---->`);
|
|
250
|
-
break;
|
|
251
|
-
case Static:
|
|
252
|
-
push(children);
|
|
253
|
-
break;
|
|
254
|
-
case Fragment:
|
|
255
|
-
if (vnode.slotScopeIds) {
|
|
256
|
-
slotScopeId =
|
|
257
|
-
(slotScopeId ? slotScopeId + ' ' : '') + vnode.slotScopeIds.join(' ');
|
|
258
|
-
}
|
|
259
|
-
push(`<!--[-->`); // open
|
|
260
|
-
renderVNodeChildren(push, children, parentComponent, slotScopeId);
|
|
261
|
-
push(`<!--]-->`); // close
|
|
262
|
-
break;
|
|
263
|
-
default:
|
|
264
|
-
if (shapeFlag & 1 /* ShapeFlags.ELEMENT */) {
|
|
265
|
-
renderElementVNode(push, vnode, parentComponent, slotScopeId);
|
|
266
|
-
}
|
|
267
|
-
else if (shapeFlag & 6 /* ShapeFlags.COMPONENT */) {
|
|
268
|
-
push(renderComponentVNode(vnode, parentComponent, slotScopeId));
|
|
269
|
-
}
|
|
270
|
-
else if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) {
|
|
271
|
-
renderTeleportVNode(push, vnode, parentComponent, slotScopeId);
|
|
272
|
-
}
|
|
273
|
-
else if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
|
|
274
|
-
renderVNode(push, vnode.ssContent, parentComponent, slotScopeId);
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
warn$1('[@vue/server-renderer] Invalid VNode type:', type, `(${typeof type})`);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
252
|
+
/* istanbul ignore next */
|
|
253
|
+
function formatTrace(trace) {
|
|
254
|
+
const logs = [];
|
|
255
|
+
trace.forEach((entry, i) => {
|
|
256
|
+
logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry));
|
|
257
|
+
});
|
|
258
|
+
return logs;
|
|
280
259
|
}
|
|
281
|
-
function
|
|
282
|
-
|
|
283
|
-
|
|
260
|
+
function formatTraceEntry({ vnode, recurseCount }) {
|
|
261
|
+
const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
|
|
262
|
+
const isRoot = vnode.component ? vnode.component.parent == null : false;
|
|
263
|
+
const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`;
|
|
264
|
+
const close = `>` + postfix;
|
|
265
|
+
return vnode.props
|
|
266
|
+
? [open, ...formatProps(vnode.props), close]
|
|
267
|
+
: [open + close];
|
|
268
|
+
}
|
|
269
|
+
/* istanbul ignore next */
|
|
270
|
+
function formatProps(props) {
|
|
271
|
+
const res = [];
|
|
272
|
+
const keys = Object.keys(props);
|
|
273
|
+
keys.slice(0, 3).forEach(key => {
|
|
274
|
+
res.push(...formatProp(key, props[key]));
|
|
275
|
+
});
|
|
276
|
+
if (keys.length > 3) {
|
|
277
|
+
res.push(` ...`);
|
|
284
278
|
}
|
|
279
|
+
return res;
|
|
285
280
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
props = applySSRDirectives(vnode, props, dirs);
|
|
281
|
+
/* istanbul ignore next */
|
|
282
|
+
function formatProp(key, value, raw) {
|
|
283
|
+
if (isString(value)) {
|
|
284
|
+
value = JSON.stringify(value);
|
|
285
|
+
return raw ? value : [`${key}=${value}`];
|
|
292
286
|
}
|
|
293
|
-
if (
|
|
294
|
-
|
|
287
|
+
else if (typeof value === 'number' ||
|
|
288
|
+
typeof value === 'boolean' ||
|
|
289
|
+
value == null) {
|
|
290
|
+
return raw ? value : [`${key}=${value}`];
|
|
295
291
|
}
|
|
296
|
-
if (
|
|
297
|
-
|
|
292
|
+
else if (isRef(value)) {
|
|
293
|
+
value = formatProp(key, toRaw(value.value), true);
|
|
294
|
+
return raw ? value : [`${key}=Ref<`, value, `>`];
|
|
298
295
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
let curVnode = vnode;
|
|
302
|
-
while (curParent && curVnode === curParent.subTree) {
|
|
303
|
-
curVnode = curParent.vnode;
|
|
304
|
-
if (curVnode.scopeId) {
|
|
305
|
-
openTag += ` ${curVnode.scopeId}`;
|
|
306
|
-
}
|
|
307
|
-
curParent = curParent.parent;
|
|
296
|
+
else if (isFunction(value)) {
|
|
297
|
+
return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
|
|
308
298
|
}
|
|
309
|
-
|
|
310
|
-
|
|
299
|
+
else {
|
|
300
|
+
value = toRaw(value);
|
|
301
|
+
return raw ? value : [`${key}=`, value];
|
|
311
302
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const ErrorTypeStrings = {
|
|
306
|
+
["sp" /* LifecycleHooks.SERVER_PREFETCH */]: 'serverPrefetch hook',
|
|
307
|
+
["bc" /* LifecycleHooks.BEFORE_CREATE */]: 'beforeCreate hook',
|
|
308
|
+
["c" /* LifecycleHooks.CREATED */]: 'created hook',
|
|
309
|
+
["bm" /* LifecycleHooks.BEFORE_MOUNT */]: 'beforeMount hook',
|
|
310
|
+
["m" /* LifecycleHooks.MOUNTED */]: 'mounted hook',
|
|
311
|
+
["bu" /* LifecycleHooks.BEFORE_UPDATE */]: 'beforeUpdate hook',
|
|
312
|
+
["u" /* LifecycleHooks.UPDATED */]: 'updated',
|
|
313
|
+
["bum" /* LifecycleHooks.BEFORE_UNMOUNT */]: 'beforeUnmount hook',
|
|
314
|
+
["um" /* LifecycleHooks.UNMOUNTED */]: 'unmounted hook',
|
|
315
|
+
["a" /* LifecycleHooks.ACTIVATED */]: 'activated hook',
|
|
316
|
+
["da" /* LifecycleHooks.DEACTIVATED */]: 'deactivated hook',
|
|
317
|
+
["ec" /* LifecycleHooks.ERROR_CAPTURED */]: 'errorCaptured hook',
|
|
318
|
+
["rtc" /* LifecycleHooks.RENDER_TRACKED */]: 'renderTracked hook',
|
|
319
|
+
["rtg" /* LifecycleHooks.RENDER_TRIGGERED */]: 'renderTriggered hook',
|
|
320
|
+
[0 /* ErrorCodes.SETUP_FUNCTION */]: 'setup function',
|
|
321
|
+
[1 /* ErrorCodes.RENDER_FUNCTION */]: 'render function',
|
|
322
|
+
[2 /* ErrorCodes.WATCH_GETTER */]: 'watcher getter',
|
|
323
|
+
[3 /* ErrorCodes.WATCH_CALLBACK */]: 'watcher callback',
|
|
324
|
+
[4 /* ErrorCodes.WATCH_CLEANUP */]: 'watcher cleanup function',
|
|
325
|
+
[5 /* ErrorCodes.NATIVE_EVENT_HANDLER */]: 'native event handler',
|
|
326
|
+
[6 /* ErrorCodes.COMPONENT_EVENT_HANDLER */]: 'component event handler',
|
|
327
|
+
[7 /* ErrorCodes.VNODE_HOOK */]: 'vnode hook',
|
|
328
|
+
[8 /* ErrorCodes.DIRECTIVE_HOOK */]: 'directive hook',
|
|
329
|
+
[9 /* ErrorCodes.TRANSITION_HOOK */]: 'transition hook',
|
|
330
|
+
[10 /* ErrorCodes.APP_ERROR_HANDLER */]: 'app errorHandler',
|
|
331
|
+
[11 /* ErrorCodes.APP_WARN_HANDLER */]: 'app warnHandler',
|
|
332
|
+
[12 /* ErrorCodes.FUNCTION_REF */]: 'ref function',
|
|
333
|
+
[13 /* ErrorCodes.ASYNC_COMPONENT_LOADER */]: 'async component loader',
|
|
334
|
+
[14 /* ErrorCodes.SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' +
|
|
335
|
+
'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core'
|
|
336
|
+
};
|
|
337
|
+
function callWithErrorHandling(fn, instance, type, args) {
|
|
338
|
+
let res;
|
|
339
|
+
try {
|
|
340
|
+
res = args ? fn(...args) : fn();
|
|
341
|
+
}
|
|
342
|
+
catch (err) {
|
|
343
|
+
handleError(err, instance, type);
|
|
344
|
+
}
|
|
345
|
+
return res;
|
|
346
|
+
}
|
|
347
|
+
function handleError(err, instance, type, throwInDev = true) {
|
|
348
|
+
const contextVNode = instance ? instance.vnode : null;
|
|
349
|
+
if (instance) {
|
|
350
|
+
let cur = instance.parent;
|
|
351
|
+
// the exposed instance is the render proxy to keep it consistent with 2.x
|
|
352
|
+
const exposedInstance = instance.proxy;
|
|
353
|
+
// in production the hook receives only the error code
|
|
354
|
+
const errorInfo = (process.env.NODE_ENV !== 'production') ? ErrorTypeStrings[type] : type;
|
|
355
|
+
while (cur) {
|
|
356
|
+
const errorCapturedHooks = cur.ec;
|
|
357
|
+
if (errorCapturedHooks) {
|
|
358
|
+
for (let i = 0; i < errorCapturedHooks.length; i++) {
|
|
359
|
+
if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
327
363
|
}
|
|
364
|
+
cur = cur.parent;
|
|
328
365
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
renderVNodeChildren(push, children, parentComponent, slotScopeId);
|
|
335
|
-
}
|
|
366
|
+
// app-level handling
|
|
367
|
+
const appErrorHandler = instance.appContext.config.errorHandler;
|
|
368
|
+
if (appErrorHandler) {
|
|
369
|
+
callWithErrorHandling(appErrorHandler, null, 10 /* ErrorCodes.APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]);
|
|
370
|
+
return;
|
|
336
371
|
}
|
|
337
|
-
push(`</${tag}>`);
|
|
338
372
|
}
|
|
373
|
+
logError(err, type, contextVNode, throwInDev);
|
|
339
374
|
}
|
|
340
|
-
function
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
if (getSSRProps) {
|
|
346
|
-
const props = getSSRProps(binding, vnode);
|
|
347
|
-
if (props)
|
|
348
|
-
toMerge.push(props);
|
|
375
|
+
function logError(err, type, contextVNode, throwInDev = true) {
|
|
376
|
+
if ((process.env.NODE_ENV !== 'production')) {
|
|
377
|
+
const info = ErrorTypeStrings[type];
|
|
378
|
+
if (contextVNode) {
|
|
379
|
+
pushWarningContext(contextVNode);
|
|
349
380
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
function renderTeleportVNode(push, vnode, parentComponent, slotScopeId) {
|
|
354
|
-
const target = vnode.props && vnode.props.to;
|
|
355
|
-
const disabled = vnode.props && vnode.props.disabled;
|
|
356
|
-
if (!target) {
|
|
357
|
-
if (!disabled) {
|
|
358
|
-
warn$1(`[@vue/server-renderer] Teleport is missing target prop.`);
|
|
381
|
+
warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
|
|
382
|
+
if (contextVNode) {
|
|
383
|
+
popWarningContext();
|
|
359
384
|
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
ssrRenderTeleport(push, push => {
|
|
367
|
-
renderVNodeChildren(push, vnode.children, parentComponent, slotScopeId);
|
|
368
|
-
}, target, disabled || disabled === '', parentComponent);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
const { isVNode } = ssrUtils;
|
|
372
|
-
async function unrollBuffer(buffer) {
|
|
373
|
-
if (buffer.hasAsync) {
|
|
374
|
-
let ret = '';
|
|
375
|
-
for (let i = 0; i < buffer.length; i++) {
|
|
376
|
-
let item = buffer[i];
|
|
377
|
-
if (isPromise(item)) {
|
|
378
|
-
item = await item;
|
|
379
|
-
}
|
|
380
|
-
if (isString(item)) {
|
|
381
|
-
ret += item;
|
|
382
|
-
}
|
|
383
|
-
else {
|
|
384
|
-
ret += await unrollBuffer(item);
|
|
385
|
-
}
|
|
385
|
+
// crash in dev by default so it's more noticeable
|
|
386
|
+
if (throwInDev) {
|
|
387
|
+
throw err;
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
console.error(err);
|
|
386
391
|
}
|
|
387
|
-
return ret;
|
|
388
392
|
}
|
|
389
393
|
else {
|
|
390
|
-
//
|
|
391
|
-
|
|
392
|
-
return unrollBufferSync(buffer);
|
|
394
|
+
// recover in prod to reduce the impact on end-user
|
|
395
|
+
console.error(err);
|
|
393
396
|
}
|
|
394
397
|
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
398
|
+
|
|
399
|
+
const classifyRE = /(?:^|[-_])(\w)/g;
|
|
400
|
+
const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '');
|
|
401
|
+
function getComponentName(Component, includeInferred = true) {
|
|
402
|
+
return isFunction(Component)
|
|
403
|
+
? Component.displayName || Component.name
|
|
404
|
+
: Component.name || (includeInferred && Component.__name);
|
|
405
|
+
}
|
|
406
|
+
/* istanbul ignore next */
|
|
407
|
+
function formatComponentName(instance, Component, isRoot = false) {
|
|
408
|
+
let name = getComponentName(Component);
|
|
409
|
+
if (!name && Component.__file) {
|
|
410
|
+
const match = Component.__file.match(/([^/\\]+)\.\w+$/);
|
|
411
|
+
if (match) {
|
|
412
|
+
name = match[1];
|
|
405
413
|
}
|
|
406
414
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
415
|
+
if (!name && instance && instance.parent) {
|
|
416
|
+
// try to infer the name based on reverse resolution
|
|
417
|
+
const inferFromRegistry = (registry) => {
|
|
418
|
+
for (const key in registry) {
|
|
419
|
+
if (registry[key] === Component) {
|
|
420
|
+
return key;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
name =
|
|
425
|
+
inferFromRegistry(instance.components ||
|
|
426
|
+
instance.parent.type.components) || inferFromRegistry(instance.appContext.components);
|
|
413
427
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
await resolveTeleports(context);
|
|
422
|
-
if (context.__watcherHandles) {
|
|
423
|
-
for (const unwatch of context.__watcherHandles) {
|
|
424
|
-
unwatch();
|
|
428
|
+
return name ? classify(name) : isRoot ? `App` : `Anonymous`;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function ssrRenderList(source, renderItem) {
|
|
432
|
+
if (isArray(source) || isString(source)) {
|
|
433
|
+
for (let i = 0, l = source.length; i < l; i++) {
|
|
434
|
+
renderItem(source[i], i);
|
|
425
435
|
}
|
|
426
436
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
for (
|
|
433
|
-
|
|
434
|
-
// created eagerly in parallel.
|
|
435
|
-
context.teleports[key] = await unrollBuffer(await Promise.all([context.__teleportBuffers[key]]));
|
|
437
|
+
else if (typeof source === 'number') {
|
|
438
|
+
if ((process.env.NODE_ENV !== 'production') && !Number.isInteger(source)) {
|
|
439
|
+
warn(`The v-for range expect an integer value but got ${source}.`);
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
for (let i = 0; i < source; i++) {
|
|
443
|
+
renderItem(i + 1, i);
|
|
436
444
|
}
|
|
437
445
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
const
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
for (let i = 0; i < buffer.length; i++) {
|
|
444
|
-
let item = buffer[i];
|
|
445
|
-
if (isPromise(item)) {
|
|
446
|
-
item = await item;
|
|
447
|
-
}
|
|
448
|
-
if (isString(item)) {
|
|
449
|
-
stream.push(item);
|
|
446
|
+
else if (isObject(source)) {
|
|
447
|
+
if (source[Symbol.iterator]) {
|
|
448
|
+
const arr = Array.from(source);
|
|
449
|
+
for (let i = 0, l = arr.length; i < l; i++) {
|
|
450
|
+
renderItem(arr[i], i);
|
|
450
451
|
}
|
|
451
|
-
|
|
452
|
-
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
const keys = Object.keys(source);
|
|
455
|
+
for (let i = 0, l = keys.length; i < l; i++) {
|
|
456
|
+
const key = keys[i];
|
|
457
|
+
renderItem(source[key], key, i);
|
|
453
458
|
}
|
|
454
459
|
}
|
|
455
460
|
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
async function ssrRenderSuspense(push, { default: renderContent }) {
|
|
464
|
+
if (renderContent) {
|
|
465
|
+
renderContent();
|
|
466
|
+
}
|
|
456
467
|
else {
|
|
457
|
-
|
|
458
|
-
// ticks
|
|
459
|
-
unrollBufferSync$1(buffer, stream);
|
|
468
|
+
push(`<!---->`);
|
|
460
469
|
}
|
|
461
470
|
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
471
|
+
|
|
472
|
+
function ssrGetDirectiveProps(instance, dir, value, arg, modifiers = {}) {
|
|
473
|
+
if (typeof dir !== 'function' && dir.getSSRProps) {
|
|
474
|
+
return (dir.getSSRProps({
|
|
475
|
+
dir,
|
|
476
|
+
instance,
|
|
477
|
+
value,
|
|
478
|
+
oldValue: undefined,
|
|
479
|
+
arg,
|
|
480
|
+
modifiers
|
|
481
|
+
}, null) || {});
|
|
472
482
|
}
|
|
483
|
+
return {};
|
|
473
484
|
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
485
|
+
|
|
486
|
+
const ssrLooseEqual = looseEqual;
|
|
487
|
+
function ssrLooseContain(arr, value) {
|
|
488
|
+
return looseIndexOf(arr, value) > -1;
|
|
489
|
+
}
|
|
490
|
+
// for <input :type="type" v-model="model" value="value">
|
|
491
|
+
function ssrRenderDynamicModel(type, model, value) {
|
|
492
|
+
switch (type) {
|
|
493
|
+
case 'radio':
|
|
494
|
+
return looseEqual(model, value) ? ' checked' : '';
|
|
495
|
+
case 'checkbox':
|
|
496
|
+
return (isArray(model) ? ssrLooseContain(model, value) : model)
|
|
497
|
+
? ' checked'
|
|
498
|
+
: '';
|
|
499
|
+
default:
|
|
500
|
+
// text types
|
|
501
|
+
return ssrRenderAttr('value', model);
|
|
478
502
|
}
|
|
479
|
-
// rendering an app
|
|
480
|
-
const vnode = createVNode(input._component, input._props);
|
|
481
|
-
vnode.appContext = input._context;
|
|
482
|
-
// provide the ssr context to the tree
|
|
483
|
-
input.provide(ssrContextKey, context);
|
|
484
|
-
Promise.resolve(renderComponentVNode(vnode))
|
|
485
|
-
.then(buffer => unrollBuffer$1(buffer, stream))
|
|
486
|
-
.then(() => resolveTeleports(context))
|
|
487
|
-
.then(() => {
|
|
488
|
-
if (context.__watcherHandles) {
|
|
489
|
-
for (const unwatch of context.__watcherHandles) {
|
|
490
|
-
unwatch();
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
})
|
|
494
|
-
.then(() => stream.push(null))
|
|
495
|
-
.catch(error => {
|
|
496
|
-
stream.destroy(error);
|
|
497
|
-
});
|
|
498
|
-
return stream;
|
|
499
503
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
504
|
+
// for <input v-bind="obj" v-model="model">
|
|
505
|
+
function ssrGetDynamicModelProps(existingProps = {}, model) {
|
|
506
|
+
const { type, value } = existingProps;
|
|
507
|
+
switch (type) {
|
|
508
|
+
case 'radio':
|
|
509
|
+
return looseEqual(model, value) ? { checked: true } : null;
|
|
510
|
+
case 'checkbox':
|
|
511
|
+
return (isArray(model) ? ssrLooseContain(model, value) : model)
|
|
512
|
+
? { checked: true }
|
|
513
|
+
: null;
|
|
514
|
+
default:
|
|
515
|
+
// text types
|
|
516
|
+
return { value: model };
|
|
517
|
+
}
|
|
506
518
|
}
|
|
507
|
-
|
|
508
|
-
|
|
519
|
+
|
|
520
|
+
function ssrCompile(template, instance) {
|
|
521
|
+
// TODO: this branch should now work in ESM builds, enable it in a minor
|
|
509
522
|
{
|
|
510
|
-
throw new Error(`
|
|
511
|
-
|
|
512
|
-
`
|
|
523
|
+
throw new Error(`On-the-fly template compilation is not supported in the ESM build of ` +
|
|
524
|
+
`@vue/server-renderer. All templates must be pre-compiled into ` +
|
|
525
|
+
`render functions.`);
|
|
513
526
|
}
|
|
514
527
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
528
|
+
|
|
529
|
+
const { createComponentInstance, setCurrentRenderingInstance, setupComponent, renderComponentRoot, normalizeVNode } = ssrUtils;
|
|
530
|
+
// Each component has a buffer array.
|
|
531
|
+
// A buffer array can contain one of the following:
|
|
532
|
+
// - plain string
|
|
533
|
+
// - A resolved buffer (recursive arrays of strings that can be unrolled
|
|
534
|
+
// synchronously)
|
|
535
|
+
// - An async buffer (a Promise that resolves to a resolved buffer)
|
|
536
|
+
function createBuffer() {
|
|
537
|
+
let appendable = false;
|
|
538
|
+
const buffer = [];
|
|
539
|
+
return {
|
|
540
|
+
getBuffer() {
|
|
541
|
+
// Return static buffer and await on items during unroll stage
|
|
542
|
+
return buffer;
|
|
543
|
+
},
|
|
544
|
+
push(item) {
|
|
545
|
+
const isStringItem = isString(item);
|
|
546
|
+
if (appendable && isStringItem) {
|
|
547
|
+
buffer[buffer.length - 1] += item;
|
|
520
548
|
}
|
|
521
549
|
else {
|
|
522
|
-
|
|
550
|
+
buffer.push(item);
|
|
551
|
+
}
|
|
552
|
+
appendable = isStringItem;
|
|
553
|
+
if (isPromise(item) || (isArray(item) && item.hasAsync)) {
|
|
554
|
+
// promise, or child buffer with async, mark as async.
|
|
555
|
+
// this allows skipping unnecessary await ticks during unroll stage
|
|
556
|
+
buffer.hasAsync = true;
|
|
523
557
|
}
|
|
524
|
-
},
|
|
525
|
-
destroy(err) {
|
|
526
|
-
writable.destroy(err);
|
|
527
558
|
}
|
|
528
|
-
}
|
|
559
|
+
};
|
|
529
560
|
}
|
|
530
|
-
function
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
561
|
+
function renderComponentVNode(vnode, parentComponent = null, slotScopeId) {
|
|
562
|
+
const instance = createComponentInstance(vnode, parentComponent, null);
|
|
563
|
+
const res = setupComponent(instance, true /* isSSR */);
|
|
564
|
+
const hasAsyncSetup = isPromise(res);
|
|
565
|
+
const prefetches = instance.sp; /* LifecycleHooks.SERVER_PREFETCH */
|
|
566
|
+
if (hasAsyncSetup || prefetches) {
|
|
567
|
+
let p = hasAsyncSetup
|
|
568
|
+
? res
|
|
569
|
+
: Promise.resolve();
|
|
570
|
+
if (prefetches) {
|
|
571
|
+
p = p
|
|
572
|
+
.then(() => Promise.all(prefetches.map(prefetch => prefetch.call(instance.proxy))))
|
|
573
|
+
// Note: error display is already done by the wrapped lifecycle hook function.
|
|
574
|
+
.catch(() => { });
|
|
575
|
+
}
|
|
576
|
+
return p.then(() => renderComponentSubTree(instance, slotScopeId));
|
|
535
577
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
destroy(err) {
|
|
552
|
-
controller.error(err);
|
|
578
|
+
else {
|
|
579
|
+
return renderComponentSubTree(instance, slotScopeId);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
function renderComponentSubTree(instance, slotScopeId) {
|
|
583
|
+
const comp = instance.type;
|
|
584
|
+
const { getBuffer, push } = createBuffer();
|
|
585
|
+
if (isFunction(comp)) {
|
|
586
|
+
let root = renderComponentRoot(instance);
|
|
587
|
+
// #5817 scope ID attrs not falling through if functional component doesn't
|
|
588
|
+
// have props
|
|
589
|
+
if (!comp.props) {
|
|
590
|
+
for (const key in instance.attrs) {
|
|
591
|
+
if (key.startsWith(`data-v-`)) {
|
|
592
|
+
(root.props || (root.props = {}))[key] = ``;
|
|
553
593
|
}
|
|
554
|
-
}
|
|
555
|
-
},
|
|
556
|
-
cancel() {
|
|
557
|
-
cancelled = true;
|
|
594
|
+
}
|
|
558
595
|
}
|
|
559
|
-
|
|
560
|
-
}
|
|
561
|
-
function pipeToWebWritable(input, context = {}, writable) {
|
|
562
|
-
const writer = writable.getWriter();
|
|
563
|
-
const encoder = new TextEncoder();
|
|
564
|
-
// #4287 CloudFlare workers do not implement `ready` property
|
|
565
|
-
let hasReady = false;
|
|
566
|
-
try {
|
|
567
|
-
hasReady = isPromise(writer.ready);
|
|
596
|
+
renderVNode(push, (instance.subTree = root), instance, slotScopeId);
|
|
568
597
|
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
598
|
+
else {
|
|
599
|
+
if ((!instance.render || instance.render === NOOP) &&
|
|
600
|
+
!instance.ssrRender &&
|
|
601
|
+
!comp.ssrRender &&
|
|
602
|
+
isString(comp.template)) {
|
|
603
|
+
comp.ssrRender = ssrCompile(comp.template);
|
|
604
|
+
}
|
|
605
|
+
// perf: enable caching of computed getters during render
|
|
606
|
+
// since there cannot be state mutations during render.
|
|
607
|
+
for (const e of instance.scope.effects) {
|
|
608
|
+
if (e.computed)
|
|
609
|
+
e.computed._cacheable = true;
|
|
610
|
+
}
|
|
611
|
+
const ssrRender = instance.ssrRender || comp.ssrRender;
|
|
612
|
+
if (ssrRender) {
|
|
613
|
+
// optimized
|
|
614
|
+
// resolve fallthrough attrs
|
|
615
|
+
let attrs = instance.inheritAttrs !== false ? instance.attrs : undefined;
|
|
616
|
+
let hasCloned = false;
|
|
617
|
+
let cur = instance;
|
|
618
|
+
while (true) {
|
|
619
|
+
const scopeId = cur.vnode.scopeId;
|
|
620
|
+
if (scopeId) {
|
|
621
|
+
if (!hasCloned) {
|
|
622
|
+
attrs = { ...attrs };
|
|
623
|
+
hasCloned = true;
|
|
624
|
+
}
|
|
625
|
+
attrs[scopeId] = '';
|
|
626
|
+
}
|
|
627
|
+
const parent = cur.parent;
|
|
628
|
+
if (parent && parent.subTree && parent.subTree === cur.vnode) {
|
|
629
|
+
// parent is a non-SSR compiled component and is rendering this
|
|
630
|
+
// component as root. inherit its scopeId if present.
|
|
631
|
+
cur = parent;
|
|
632
|
+
}
|
|
633
|
+
else {
|
|
634
|
+
break;
|
|
635
|
+
}
|
|
574
636
|
}
|
|
575
|
-
if (
|
|
576
|
-
|
|
637
|
+
if (slotScopeId) {
|
|
638
|
+
if (!hasCloned)
|
|
639
|
+
attrs = { ...attrs };
|
|
640
|
+
attrs[slotScopeId.trim()] = '';
|
|
577
641
|
}
|
|
578
|
-
|
|
579
|
-
|
|
642
|
+
// set current rendering instance for asset resolution
|
|
643
|
+
const prev = setCurrentRenderingInstance(instance);
|
|
644
|
+
try {
|
|
645
|
+
ssrRender(instance.proxy, push, instance, attrs,
|
|
646
|
+
// compiler-optimized bindings
|
|
647
|
+
instance.props, instance.setupState, instance.data, instance.ctx);
|
|
648
|
+
}
|
|
649
|
+
finally {
|
|
650
|
+
setCurrentRenderingInstance(prev);
|
|
580
651
|
}
|
|
581
|
-
},
|
|
582
|
-
destroy(err) {
|
|
583
|
-
// TODO better error handling?
|
|
584
|
-
console.log(err);
|
|
585
|
-
writer.close();
|
|
586
652
|
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
function ssrRenderComponent(comp, props = null, children = null, parentComponent = null, slotScopeId) {
|
|
591
|
-
return renderComponentVNode(createVNode(comp, props, children), parentComponent, slotScopeId);
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
function ssrRenderSlot(slots, slotName, slotProps, fallbackRenderFn, push, parentComponent, slotScopeId) {
|
|
595
|
-
// template-compiled slots are always rendered as fragments
|
|
596
|
-
push(`<!--[-->`);
|
|
597
|
-
ssrRenderSlotInner(slots, slotName, slotProps, fallbackRenderFn, push, parentComponent, slotScopeId);
|
|
598
|
-
push(`<!--]-->`);
|
|
599
|
-
}
|
|
600
|
-
function ssrRenderSlotInner(slots, slotName, slotProps, fallbackRenderFn, push, parentComponent, slotScopeId, transition) {
|
|
601
|
-
const slotFn = slots[slotName];
|
|
602
|
-
if (slotFn) {
|
|
603
|
-
const slotBuffer = [];
|
|
604
|
-
const bufferedPush = (item) => {
|
|
605
|
-
slotBuffer.push(item);
|
|
606
|
-
};
|
|
607
|
-
const ret = slotFn(slotProps, bufferedPush, parentComponent, slotScopeId ? ' ' + slotScopeId : '');
|
|
608
|
-
if (isArray(ret)) {
|
|
609
|
-
// normal slot
|
|
610
|
-
renderVNodeChildren(push, ret, parentComponent, slotScopeId);
|
|
653
|
+
else if (instance.render && instance.render !== NOOP) {
|
|
654
|
+
renderVNode(push, (instance.subTree = renderComponentRoot(instance)), instance, slotScopeId);
|
|
611
655
|
}
|
|
612
656
|
else {
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
657
|
+
const componentName = comp.name || comp.__file || `<Anonymous>`;
|
|
658
|
+
warn$1(`Component ${componentName} is missing template or render function.`);
|
|
659
|
+
push(`<!---->`);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
return getBuffer();
|
|
663
|
+
}
|
|
664
|
+
function renderVNode(push, vnode, parentComponent, slotScopeId) {
|
|
665
|
+
const { type, shapeFlag, children } = vnode;
|
|
666
|
+
switch (type) {
|
|
667
|
+
case Text:
|
|
668
|
+
push(escapeHtml(children));
|
|
669
|
+
break;
|
|
670
|
+
case Comment:
|
|
671
|
+
push(children ? `<!--${escapeHtmlComment(children)}-->` : `<!---->`);
|
|
672
|
+
break;
|
|
673
|
+
case Static:
|
|
674
|
+
push(children);
|
|
675
|
+
break;
|
|
676
|
+
case Fragment:
|
|
677
|
+
if (vnode.slotScopeIds) {
|
|
678
|
+
slotScopeId =
|
|
679
|
+
(slotScopeId ? slotScopeId + ' ' : '') + vnode.slotScopeIds.join(' ');
|
|
618
680
|
}
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
681
|
+
push(`<!--[-->`); // open
|
|
682
|
+
renderVNodeChildren(push, children, parentComponent, slotScopeId);
|
|
683
|
+
push(`<!--]-->`); // close
|
|
684
|
+
break;
|
|
685
|
+
default:
|
|
686
|
+
if (shapeFlag & 1 /* ShapeFlags.ELEMENT */) {
|
|
687
|
+
renderElementVNode(push, vnode, parentComponent, slotScopeId);
|
|
626
688
|
}
|
|
627
|
-
if (
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
689
|
+
else if (shapeFlag & 6 /* ShapeFlags.COMPONENT */) {
|
|
690
|
+
push(renderComponentVNode(vnode, parentComponent, slotScopeId));
|
|
691
|
+
}
|
|
692
|
+
else if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) {
|
|
693
|
+
renderTeleportVNode(push, vnode, parentComponent, slotScopeId);
|
|
694
|
+
}
|
|
695
|
+
else if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
|
|
696
|
+
renderVNode(push, vnode.ssContent, parentComponent, slotScopeId);
|
|
631
697
|
}
|
|
632
698
|
else {
|
|
633
|
-
|
|
634
|
-
push(slotBuffer[i]);
|
|
635
|
-
}
|
|
699
|
+
warn$1('[@vue/server-renderer] Invalid VNode type:', type, `(${typeof type})`);
|
|
636
700
|
}
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
else if (fallbackRenderFn) {
|
|
640
|
-
fallbackRenderFn();
|
|
641
701
|
}
|
|
642
702
|
}
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
return false;
|
|
648
|
-
// if item is '<!---->' or '<!--[-->' or '<!--]-->', return true directly
|
|
649
|
-
if (item.length <= 8)
|
|
650
|
-
return true;
|
|
651
|
-
return !item.replace(commentRE, '').trim();
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
function ssrInterpolate(value) {
|
|
655
|
-
return escapeHtml(toDisplayString(value));
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
function toRaw(observed) {
|
|
659
|
-
const raw = observed && observed["__v_raw" /* ReactiveFlags.RAW */];
|
|
660
|
-
return raw ? toRaw(raw) : observed;
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
function isRef(r) {
|
|
664
|
-
return !!(r && r.__v_isRef === true);
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
const stack = [];
|
|
668
|
-
function pushWarningContext(vnode) {
|
|
669
|
-
stack.push(vnode);
|
|
670
|
-
}
|
|
671
|
-
function popWarningContext() {
|
|
672
|
-
stack.pop();
|
|
703
|
+
function renderVNodeChildren(push, children, parentComponent, slotScopeId) {
|
|
704
|
+
for (let i = 0; i < children.length; i++) {
|
|
705
|
+
renderVNode(push, normalizeVNode(children[i]), parentComponent, slotScopeId);
|
|
706
|
+
}
|
|
673
707
|
}
|
|
674
|
-
function
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
if (appWarnHandler) {
|
|
681
|
-
callWithErrorHandling(appWarnHandler, instance, 11 /* ErrorCodes.APP_WARN_HANDLER */, [
|
|
682
|
-
msg + args.join(''),
|
|
683
|
-
instance && instance.proxy,
|
|
684
|
-
trace
|
|
685
|
-
.map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`)
|
|
686
|
-
.join('\n'),
|
|
687
|
-
trace
|
|
688
|
-
]);
|
|
708
|
+
function renderElementVNode(push, vnode, parentComponent, slotScopeId) {
|
|
709
|
+
const tag = vnode.type;
|
|
710
|
+
let { props, children, shapeFlag, scopeId, dirs } = vnode;
|
|
711
|
+
let openTag = `<${tag}`;
|
|
712
|
+
if (dirs) {
|
|
713
|
+
props = applySSRDirectives(vnode, props, dirs);
|
|
689
714
|
}
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
715
|
+
if (props) {
|
|
716
|
+
openTag += ssrRenderAttrs(props, tag);
|
|
717
|
+
}
|
|
718
|
+
if (scopeId) {
|
|
719
|
+
openTag += ` ${scopeId}`;
|
|
720
|
+
}
|
|
721
|
+
// inherit parent chain scope id if this is the root node
|
|
722
|
+
let curParent = parentComponent;
|
|
723
|
+
let curVnode = vnode;
|
|
724
|
+
while (curParent && curVnode === curParent.subTree) {
|
|
725
|
+
curVnode = curParent.vnode;
|
|
726
|
+
if (curVnode.scopeId) {
|
|
727
|
+
openTag += ` ${curVnode.scopeId}`;
|
|
697
728
|
}
|
|
698
|
-
|
|
729
|
+
curParent = curParent.parent;
|
|
699
730
|
}
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
let currentVNode = stack[stack.length - 1];
|
|
703
|
-
if (!currentVNode) {
|
|
704
|
-
return [];
|
|
731
|
+
if (slotScopeId) {
|
|
732
|
+
openTag += ` ${slotScopeId}`;
|
|
705
733
|
}
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
734
|
+
push(openTag + `>`);
|
|
735
|
+
if (!isVoidTag(tag)) {
|
|
736
|
+
let hasChildrenOverride = false;
|
|
737
|
+
if (props) {
|
|
738
|
+
if (props.innerHTML) {
|
|
739
|
+
hasChildrenOverride = true;
|
|
740
|
+
push(props.innerHTML);
|
|
741
|
+
}
|
|
742
|
+
else if (props.textContent) {
|
|
743
|
+
hasChildrenOverride = true;
|
|
744
|
+
push(escapeHtml(props.textContent));
|
|
745
|
+
}
|
|
746
|
+
else if (tag === 'textarea' && props.value) {
|
|
747
|
+
hasChildrenOverride = true;
|
|
748
|
+
push(escapeHtml(props.value));
|
|
749
|
+
}
|
|
714
750
|
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
751
|
+
if (!hasChildrenOverride) {
|
|
752
|
+
if (shapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) {
|
|
753
|
+
push(escapeHtml(children));
|
|
754
|
+
}
|
|
755
|
+
else if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
|
|
756
|
+
renderVNodeChildren(push, children, parentComponent, slotScopeId);
|
|
757
|
+
}
|
|
720
758
|
}
|
|
721
|
-
|
|
722
|
-
currentVNode = parentInstance && parentInstance.vnode;
|
|
759
|
+
push(`</${tag}>`);
|
|
723
760
|
}
|
|
724
|
-
return normalizedStack;
|
|
725
761
|
}
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
const isRoot = vnode.component ? vnode.component.parent == null : false;
|
|
737
|
-
const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`;
|
|
738
|
-
const close = `>` + postfix;
|
|
739
|
-
return vnode.props
|
|
740
|
-
? [open, ...formatProps(vnode.props), close]
|
|
741
|
-
: [open + close];
|
|
742
|
-
}
|
|
743
|
-
/* istanbul ignore next */
|
|
744
|
-
function formatProps(props) {
|
|
745
|
-
const res = [];
|
|
746
|
-
const keys = Object.keys(props);
|
|
747
|
-
keys.slice(0, 3).forEach(key => {
|
|
748
|
-
res.push(...formatProp(key, props[key]));
|
|
749
|
-
});
|
|
750
|
-
if (keys.length > 3) {
|
|
751
|
-
res.push(` ...`);
|
|
762
|
+
function applySSRDirectives(vnode, rawProps, dirs) {
|
|
763
|
+
const toMerge = [];
|
|
764
|
+
for (let i = 0; i < dirs.length; i++) {
|
|
765
|
+
const binding = dirs[i];
|
|
766
|
+
const { dir: { getSSRProps } } = binding;
|
|
767
|
+
if (getSSRProps) {
|
|
768
|
+
const props = getSSRProps(binding, vnode);
|
|
769
|
+
if (props)
|
|
770
|
+
toMerge.push(props);
|
|
771
|
+
}
|
|
752
772
|
}
|
|
753
|
-
return
|
|
773
|
+
return mergeProps(rawProps || {}, ...toMerge);
|
|
754
774
|
}
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
value == null) {
|
|
764
|
-
return raw ? value : [`${key}=${value}`];
|
|
765
|
-
}
|
|
766
|
-
else if (isRef(value)) {
|
|
767
|
-
value = formatProp(key, toRaw(value.value), true);
|
|
768
|
-
return raw ? value : [`${key}=Ref<`, value, `>`];
|
|
769
|
-
}
|
|
770
|
-
else if (isFunction(value)) {
|
|
771
|
-
return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
|
|
775
|
+
function renderTeleportVNode(push, vnode, parentComponent, slotScopeId) {
|
|
776
|
+
const target = vnode.props && vnode.props.to;
|
|
777
|
+
const disabled = vnode.props && vnode.props.disabled;
|
|
778
|
+
if (!target) {
|
|
779
|
+
if (!disabled) {
|
|
780
|
+
warn$1(`[@vue/server-renderer] Teleport is missing target prop.`);
|
|
781
|
+
}
|
|
782
|
+
return [];
|
|
772
783
|
}
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
return
|
|
784
|
+
if (!isString(target)) {
|
|
785
|
+
warn$1(`[@vue/server-renderer] Teleport target must be a query selector string.`);
|
|
786
|
+
return [];
|
|
776
787
|
}
|
|
788
|
+
ssrRenderTeleport(push, push => {
|
|
789
|
+
renderVNodeChildren(push, vnode.children, parentComponent, slotScopeId);
|
|
790
|
+
}, target, disabled || disabled === '', parentComponent);
|
|
777
791
|
}
|
|
778
792
|
|
|
779
|
-
const
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
["rtg" /* LifecycleHooks.RENDER_TRIGGERED */]: 'renderTriggered hook',
|
|
794
|
-
[0 /* ErrorCodes.SETUP_FUNCTION */]: 'setup function',
|
|
795
|
-
[1 /* ErrorCodes.RENDER_FUNCTION */]: 'render function',
|
|
796
|
-
[2 /* ErrorCodes.WATCH_GETTER */]: 'watcher getter',
|
|
797
|
-
[3 /* ErrorCodes.WATCH_CALLBACK */]: 'watcher callback',
|
|
798
|
-
[4 /* ErrorCodes.WATCH_CLEANUP */]: 'watcher cleanup function',
|
|
799
|
-
[5 /* ErrorCodes.NATIVE_EVENT_HANDLER */]: 'native event handler',
|
|
800
|
-
[6 /* ErrorCodes.COMPONENT_EVENT_HANDLER */]: 'component event handler',
|
|
801
|
-
[7 /* ErrorCodes.VNODE_HOOK */]: 'vnode hook',
|
|
802
|
-
[8 /* ErrorCodes.DIRECTIVE_HOOK */]: 'directive hook',
|
|
803
|
-
[9 /* ErrorCodes.TRANSITION_HOOK */]: 'transition hook',
|
|
804
|
-
[10 /* ErrorCodes.APP_ERROR_HANDLER */]: 'app errorHandler',
|
|
805
|
-
[11 /* ErrorCodes.APP_WARN_HANDLER */]: 'app warnHandler',
|
|
806
|
-
[12 /* ErrorCodes.FUNCTION_REF */]: 'ref function',
|
|
807
|
-
[13 /* ErrorCodes.ASYNC_COMPONENT_LOADER */]: 'async component loader',
|
|
808
|
-
[14 /* ErrorCodes.SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' +
|
|
809
|
-
'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core'
|
|
810
|
-
};
|
|
811
|
-
function callWithErrorHandling(fn, instance, type, args) {
|
|
812
|
-
let res;
|
|
813
|
-
try {
|
|
814
|
-
res = args ? fn(...args) : fn();
|
|
815
|
-
}
|
|
816
|
-
catch (err) {
|
|
817
|
-
handleError(err, instance, type);
|
|
818
|
-
}
|
|
819
|
-
return res;
|
|
820
|
-
}
|
|
821
|
-
function handleError(err, instance, type, throwInDev = true) {
|
|
822
|
-
const contextVNode = instance ? instance.vnode : null;
|
|
823
|
-
if (instance) {
|
|
824
|
-
let cur = instance.parent;
|
|
825
|
-
// the exposed instance is the render proxy to keep it consistent with 2.x
|
|
826
|
-
const exposedInstance = instance.proxy;
|
|
827
|
-
// in production the hook receives only the error code
|
|
828
|
-
const errorInfo = (process.env.NODE_ENV !== 'production') ? ErrorTypeStrings[type] : type;
|
|
829
|
-
while (cur) {
|
|
830
|
-
const errorCapturedHooks = cur.ec;
|
|
831
|
-
if (errorCapturedHooks) {
|
|
832
|
-
for (let i = 0; i < errorCapturedHooks.length; i++) {
|
|
833
|
-
if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
|
|
834
|
-
return;
|
|
835
|
-
}
|
|
836
|
-
}
|
|
793
|
+
const { isVNode: isVNode$1 } = ssrUtils;
|
|
794
|
+
async function unrollBuffer$1(buffer) {
|
|
795
|
+
if (buffer.hasAsync) {
|
|
796
|
+
let ret = '';
|
|
797
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
798
|
+
let item = buffer[i];
|
|
799
|
+
if (isPromise(item)) {
|
|
800
|
+
item = await item;
|
|
801
|
+
}
|
|
802
|
+
if (isString(item)) {
|
|
803
|
+
ret += item;
|
|
804
|
+
}
|
|
805
|
+
else {
|
|
806
|
+
ret += await unrollBuffer$1(item);
|
|
837
807
|
}
|
|
838
|
-
cur = cur.parent;
|
|
839
|
-
}
|
|
840
|
-
// app-level handling
|
|
841
|
-
const appErrorHandler = instance.appContext.config.errorHandler;
|
|
842
|
-
if (appErrorHandler) {
|
|
843
|
-
callWithErrorHandling(appErrorHandler, null, 10 /* ErrorCodes.APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]);
|
|
844
|
-
return;
|
|
845
808
|
}
|
|
809
|
+
return ret;
|
|
810
|
+
}
|
|
811
|
+
else {
|
|
812
|
+
// sync buffer can be more efficiently unrolled without unnecessary await
|
|
813
|
+
// ticks
|
|
814
|
+
return unrollBufferSync$1(buffer);
|
|
846
815
|
}
|
|
847
|
-
logError(err, type, contextVNode, throwInDev);
|
|
848
816
|
}
|
|
849
|
-
function
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
|
|
856
|
-
if (contextVNode) {
|
|
857
|
-
popWarningContext();
|
|
858
|
-
}
|
|
859
|
-
// crash in dev by default so it's more noticeable
|
|
860
|
-
if (throwInDev) {
|
|
861
|
-
throw err;
|
|
817
|
+
function unrollBufferSync$1(buffer) {
|
|
818
|
+
let ret = '';
|
|
819
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
820
|
+
let item = buffer[i];
|
|
821
|
+
if (isString(item)) {
|
|
822
|
+
ret += item;
|
|
862
823
|
}
|
|
863
824
|
else {
|
|
864
|
-
|
|
825
|
+
// since this is a sync buffer, child buffers are never promises
|
|
826
|
+
ret += unrollBufferSync$1(item);
|
|
865
827
|
}
|
|
866
828
|
}
|
|
867
|
-
|
|
868
|
-
// recover in prod to reduce the impact on end-user
|
|
869
|
-
console.error(err);
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
const classifyRE = /(?:^|[-_])(\w)/g;
|
|
874
|
-
const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '');
|
|
875
|
-
function getComponentName(Component, includeInferred = true) {
|
|
876
|
-
return isFunction(Component)
|
|
877
|
-
? Component.displayName || Component.name
|
|
878
|
-
: Component.name || (includeInferred && Component.__name);
|
|
829
|
+
return ret;
|
|
879
830
|
}
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
831
|
+
async function renderToString(input, context = {}) {
|
|
832
|
+
if (isVNode$1(input)) {
|
|
833
|
+
// raw vnode, wrap with app (for context)
|
|
834
|
+
return renderToString(createApp({ render: () => input }), context);
|
|
835
|
+
}
|
|
836
|
+
// rendering an app
|
|
837
|
+
const vnode = createVNode(input._component, input._props);
|
|
838
|
+
vnode.appContext = input._context;
|
|
839
|
+
// provide the ssr context to the tree
|
|
840
|
+
input.provide(ssrContextKey, context);
|
|
841
|
+
const buffer = await renderComponentVNode(vnode);
|
|
842
|
+
const result = await unrollBuffer$1(buffer);
|
|
843
|
+
await resolveTeleports(context);
|
|
844
|
+
if (context.__watcherHandles) {
|
|
845
|
+
for (const unwatch of context.__watcherHandles) {
|
|
846
|
+
unwatch();
|
|
887
847
|
}
|
|
888
848
|
}
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
inferFromRegistry(instance.components ||
|
|
900
|
-
instance.parent.type.components) || inferFromRegistry(instance.appContext.components);
|
|
849
|
+
return result;
|
|
850
|
+
}
|
|
851
|
+
async function resolveTeleports(context) {
|
|
852
|
+
if (context.__teleportBuffers) {
|
|
853
|
+
context.teleports = context.teleports || {};
|
|
854
|
+
for (const key in context.__teleportBuffers) {
|
|
855
|
+
// note: it's OK to await sequentially here because the Promises were
|
|
856
|
+
// created eagerly in parallel.
|
|
857
|
+
context.teleports[key] = await unrollBuffer$1(await Promise.all([context.__teleportBuffers[key]]));
|
|
858
|
+
}
|
|
901
859
|
}
|
|
902
|
-
return name ? classify(name) : isRoot ? `App` : `Anonymous`;
|
|
903
860
|
}
|
|
904
861
|
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
862
|
+
const { isVNode } = ssrUtils;
|
|
863
|
+
async function unrollBuffer(buffer, stream) {
|
|
864
|
+
if (buffer.hasAsync) {
|
|
865
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
866
|
+
let item = buffer[i];
|
|
867
|
+
if (isPromise(item)) {
|
|
868
|
+
item = await item;
|
|
869
|
+
}
|
|
870
|
+
if (isString(item)) {
|
|
871
|
+
stream.push(item);
|
|
872
|
+
}
|
|
873
|
+
else {
|
|
874
|
+
await unrollBuffer(item, stream);
|
|
875
|
+
}
|
|
909
876
|
}
|
|
910
877
|
}
|
|
911
|
-
else
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
}
|
|
916
|
-
for (let i = 0; i < source; i++) {
|
|
917
|
-
renderItem(i + 1, i);
|
|
918
|
-
}
|
|
878
|
+
else {
|
|
879
|
+
// sync buffer can be more efficiently unrolled without unnecessary await
|
|
880
|
+
// ticks
|
|
881
|
+
unrollBufferSync(buffer, stream);
|
|
919
882
|
}
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
883
|
+
}
|
|
884
|
+
function unrollBufferSync(buffer, stream) {
|
|
885
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
886
|
+
let item = buffer[i];
|
|
887
|
+
if (isString(item)) {
|
|
888
|
+
stream.push(item);
|
|
926
889
|
}
|
|
927
890
|
else {
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
const key = keys[i];
|
|
931
|
-
renderItem(source[key], key, i);
|
|
932
|
-
}
|
|
891
|
+
// since this is a sync buffer, child buffers are never promises
|
|
892
|
+
unrollBufferSync(item, stream);
|
|
933
893
|
}
|
|
934
894
|
}
|
|
935
895
|
}
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
}
|
|
941
|
-
else {
|
|
942
|
-
push(`<!---->`);
|
|
896
|
+
function renderToSimpleStream(input, context, stream) {
|
|
897
|
+
if (isVNode(input)) {
|
|
898
|
+
// raw vnode, wrap with app (for context)
|
|
899
|
+
return renderToSimpleStream(createApp({ render: () => input }), context, stream);
|
|
943
900
|
}
|
|
901
|
+
// rendering an app
|
|
902
|
+
const vnode = createVNode(input._component, input._props);
|
|
903
|
+
vnode.appContext = input._context;
|
|
904
|
+
// provide the ssr context to the tree
|
|
905
|
+
input.provide(ssrContextKey, context);
|
|
906
|
+
Promise.resolve(renderComponentVNode(vnode))
|
|
907
|
+
.then(buffer => unrollBuffer(buffer, stream))
|
|
908
|
+
.then(() => resolveTeleports(context))
|
|
909
|
+
.then(() => {
|
|
910
|
+
if (context.__watcherHandles) {
|
|
911
|
+
for (const unwatch of context.__watcherHandles) {
|
|
912
|
+
unwatch();
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
})
|
|
916
|
+
.then(() => stream.push(null))
|
|
917
|
+
.catch(error => {
|
|
918
|
+
stream.destroy(error);
|
|
919
|
+
});
|
|
920
|
+
return stream;
|
|
944
921
|
}
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
922
|
+
/**
|
|
923
|
+
* @deprecated
|
|
924
|
+
*/
|
|
925
|
+
function renderToStream(input, context = {}) {
|
|
926
|
+
console.warn(`[@vue/server-renderer] renderToStream is deprecated - use renderToNodeStream instead.`);
|
|
927
|
+
return renderToNodeStream(input, context);
|
|
928
|
+
}
|
|
929
|
+
function renderToNodeStream(input, context = {}) {
|
|
930
|
+
{
|
|
931
|
+
throw new Error(`ESM build of renderToStream() does not support renderToNodeStream(). ` +
|
|
932
|
+
`Use pipeToNodeWritable() with an existing Node.js Writable stream ` +
|
|
933
|
+
`instance instead.`);
|
|
956
934
|
}
|
|
957
|
-
return {};
|
|
958
935
|
}
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
936
|
+
function pipeToNodeWritable(input, context = {}, writable) {
|
|
937
|
+
renderToSimpleStream(input, context, {
|
|
938
|
+
push(content) {
|
|
939
|
+
if (content != null) {
|
|
940
|
+
writable.write(content);
|
|
941
|
+
}
|
|
942
|
+
else {
|
|
943
|
+
writable.end();
|
|
944
|
+
}
|
|
945
|
+
},
|
|
946
|
+
destroy(err) {
|
|
947
|
+
writable.destroy(err);
|
|
948
|
+
}
|
|
949
|
+
});
|
|
963
950
|
}
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
case 'checkbox':
|
|
970
|
-
return (isArray(model) ? ssrLooseContain(model, value) : model)
|
|
971
|
-
? ' checked'
|
|
972
|
-
: '';
|
|
973
|
-
default:
|
|
974
|
-
// text types
|
|
975
|
-
return ssrRenderAttr('value', model);
|
|
951
|
+
function renderToWebStream(input, context = {}) {
|
|
952
|
+
if (typeof ReadableStream !== 'function') {
|
|
953
|
+
throw new Error(`ReadableStream constructor is not available in the global scope. ` +
|
|
954
|
+
`If the target environment does support web streams, consider using ` +
|
|
955
|
+
`pipeToWebWritable() with an existing WritableStream instance instead.`);
|
|
976
956
|
}
|
|
957
|
+
const encoder = new TextEncoder();
|
|
958
|
+
let cancelled = false;
|
|
959
|
+
return new ReadableStream({
|
|
960
|
+
start(controller) {
|
|
961
|
+
renderToSimpleStream(input, context, {
|
|
962
|
+
push(content) {
|
|
963
|
+
if (cancelled)
|
|
964
|
+
return;
|
|
965
|
+
if (content != null) {
|
|
966
|
+
controller.enqueue(encoder.encode(content));
|
|
967
|
+
}
|
|
968
|
+
else {
|
|
969
|
+
controller.close();
|
|
970
|
+
}
|
|
971
|
+
},
|
|
972
|
+
destroy(err) {
|
|
973
|
+
controller.error(err);
|
|
974
|
+
}
|
|
975
|
+
});
|
|
976
|
+
},
|
|
977
|
+
cancel() {
|
|
978
|
+
cancelled = true;
|
|
979
|
+
}
|
|
980
|
+
});
|
|
977
981
|
}
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
const
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
return (isArray(model) ? ssrLooseContain(model, value) : model)
|
|
986
|
-
? { checked: true }
|
|
987
|
-
: null;
|
|
988
|
-
default:
|
|
989
|
-
// text types
|
|
990
|
-
return { value: model };
|
|
982
|
+
function pipeToWebWritable(input, context = {}, writable) {
|
|
983
|
+
const writer = writable.getWriter();
|
|
984
|
+
const encoder = new TextEncoder();
|
|
985
|
+
// #4287 CloudFlare workers do not implement `ready` property
|
|
986
|
+
let hasReady = false;
|
|
987
|
+
try {
|
|
988
|
+
hasReady = isPromise(writer.ready);
|
|
991
989
|
}
|
|
990
|
+
catch (e) { }
|
|
991
|
+
renderToSimpleStream(input, context, {
|
|
992
|
+
async push(content) {
|
|
993
|
+
if (hasReady) {
|
|
994
|
+
await writer.ready;
|
|
995
|
+
}
|
|
996
|
+
if (content != null) {
|
|
997
|
+
return writer.write(encoder.encode(content));
|
|
998
|
+
}
|
|
999
|
+
else {
|
|
1000
|
+
return writer.close();
|
|
1001
|
+
}
|
|
1002
|
+
},
|
|
1003
|
+
destroy(err) {
|
|
1004
|
+
// TODO better error handling?
|
|
1005
|
+
console.log(err);
|
|
1006
|
+
writer.close();
|
|
1007
|
+
}
|
|
1008
|
+
});
|
|
992
1009
|
}
|
|
993
1010
|
|
|
994
1011
|
initDirectivesForSSR();
|