server-renderer.cjs.js 37 KB

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