function setupStatefulComponent(instance, isSSR) {
var _a;
const Component = instance.type;
{
if (Component.name) {
validateComponentName(Component.name, instance.appContext.config);
}
if (Component.components) {
const names = Object.keys(Component.components);
for (let i = 0; i < names.length; i++) {
validateComponentName(names[i], instance.appContext.config);
}
}
if (Component.directives) {
const names = Object.keys(Component.directives);
for (let i = 0; i < names.length; i++) {
validateDirectiveName(names[i]);
}
}
if (Component.compilerOptions && isRuntimeOnly()) {
warn(`"compilerOptions" is only supported when using a build of Vue that ` +
`includes the runtime compiler. Since you are using a runtime-only ` +
`build, the options should be passed via your build tool config instead.`);
}
}
// 0. create render proxy property access cache
instance.accessCache = Object.create(null);
// 1. create public instance / render proxy
// also mark it raw so it's never observed
instance.proxy = reactivity.markRaw(new Proxy(instance.ctx, PublicInstanceProxyHandlers));
{
exposePropsOnRenderContext(instance);
}
// 2. call setup()
const { setup } = Component;
if (setup) {
const setupContext = (instance.setupContext =
setup.length > 1 ? createSetupContext(instance) : null);
setCurrentInstance(instance);
reactivity.pauseTracking();
const setupResult = callWithErrorHandling(setup, instance, 0 /* ErrorCodes.SETUP_FUNCTION */, [reactivity.shallowReadonly(instance.props) , setupContext]);
reactivity.resetTracking();
unsetCurrentInstance();
if (shared.isPromise(setupResult)) {
setupResult.then(unsetCurrentInstance, unsetCurrentInstance);
if (isSSR) {
// return the promise so server-renderer can wait on it
return setupResult
.then((resolvedResult) => {
handleSetupResult(instance, resolvedResult, isSSR);
})
.catch(e => {
handleError(e, instance, 0 /* ErrorCodes.SETUP_FUNCTION */);
});
}
else {
// async setup returned Promise.
// bail here and wait for re-entry.
instance.asyncDep = setupResult;
if (!instance.suspense) {
const name = (_a = Component.name) !== null && _a !== void 0 ? _a : 'Anonymous';
warn(`Component <${name}>: setup function returned a promise, but no ` +
`<Suspense> boundary was found in the parent component tree. ` +
`A component with async setup() must be nested in a <Suspense> ` +
`in order to be rendered.`);
}
}
}
else {
handleSetupResult(instance, setupResult, isSSR);
}
}
else {
finishComponentSetup(instance, isSSR);
}
}
function createSetupContext(instance) {
const expose = exposed => {
if (instance.exposed) {
warn(`expose() should be called only once per setup().`);
}
instance.exposed = exposed || {};
};
let attrs;
{
// We use getters in dev in case libs like test-utils overwrite instance
// properties (overwrites should not be done in prod)
return Object.freeze({
get attrs() {
return attrs || (attrs = createAttrsProxy(instance));
},
get slots() {
return reactivity.shallowReadonly(instance.slots);
},
get emit() {
return (event, ...args) => instance.emit(event, ...args);
},
expose
});
}
}
if (shared.isPromise(setupResult)) {
setupResult.then(unsetCurrentInstance, unsetCurrentInstance);
if (isSSR) {
// return the promise so server-renderer can wait on it
return setupResult
.then((resolvedResult) => {
handleSetupResult(instance, resolvedResult, isSSR);
})
.catch(e => {
handleError(e, instance, 0 /* ErrorCodes.SETUP_FUNCTION */);
});
}
else {
// async setup returned Promise.
// bail here and wait for re-entry.
instance.asyncDep = setupResult;
if (!instance.suspense) {
const name = (_a = Component.name) !== null && _a !== void 0 ? _a : 'Anonymous';
warn(`Component <${name}>: setup function returned a promise, but no ` +
`<Suspense> boundary was found in the parent component tree. ` +
`A component with async setup() must be nested in a <Suspense> ` +
`in order to be rendered.`);
}
}
}
function handleSetupResult(instance, setupResult, isSSR) {
if (shared.isFunction(setupResult)) {
// setup returned an inline render function
if (instance.type.__ssrInlineRender) {
// when the function's name is `ssrRender` (compiled by SFC inline mode),
// set it as ssrRender instead.
instance.ssrRender = setupResult;
}
else {
instance.render = setupResult;
}
}
else if (shared.isObject(setupResult)) {
if (isVNode(setupResult)) {
warn(`setup() should not return VNodes directly - ` +
`return a render function instead.`);
}
// setup returned bindings.
// assuming a render function compiled from template is present.
{
instance.devtoolsRawSetupState = setupResult;
}
instance.setupState = reactivity.proxyRefs(setupResult);
{
exposeSetupStateOnRenderContext(instance);
}
}
else if (setupResult !== undefined) {
warn(`setup() should return an object. Received: ${setupResult === null ? 'null' : typeof setupResult}`);
}
finishComponentSetup(instance, isSSR);
}
function finishComponentSetup(instance, isSSR, skipOptions) {
const Component = instance.type;
// template / render function normalization
// could be already set when returned from setup()
if (!instance.render) {
// only do on-the-fly compile if not in SSR - SSR on-the-fly compilation
// is done by server-renderer
if (!isSSR && compile && !Component.render) {
const template = Component.template;
if (template) {
{
startMeasure(instance, `compile`);
}
const { isCustomElement, compilerOptions } = instance.appContext.config;
const { delimiters, compilerOptions: componentCompilerOptions } = Component;
const finalCompilerOptions = shared.extend(shared.extend({
isCustomElement,
delimiters
}, compilerOptions), componentCompilerOptions);
Component.render = compile(template, finalCompilerOptions);
{
endMeasure(instance, `compile`);
}
}
}
instance.render = (Component.render || shared.NOOP);
// for runtime-compiled render functions using `with` blocks, the render
// proxy used needs a different `has` handler which is more performant and
// also only allows a whitelist of globals to fallthrough.
if (installWithProxy) {
installWithProxy(instance);
}
}
// support for 2.x options
{
setCurrentInstance(instance);
reactivity.pauseTracking();
applyOptions(instance);
reactivity.resetTracking();
unsetCurrentInstance();
}
// warn missing template/render
// the runtime compilation of template in SSR is done by server-render
if (!Component.render && instance.render === shared.NOOP && !isSSR) {
/* istanbul ignore if */
if (!compile && Component.template) {
warn(`Component provided template option but ` +
`runtime compilation is not supported in this build of Vue.` +
(``) /* should not happen */);
}
else {
warn(`Component is missing template or render function.`);
}
}
}
function setupStatefulComponent(instance, isSSR) {
var _a;
const Component = instance.type;
{
if (Component.name) {
validateComponentName(Component.name, instance.appContext.config);
}
if (Component.components) {
const names = Object.keys(Component.components);
for (let i = 0; i < names.length; i++) {
validateComponentName(names[i], instance.appContext.config);
}
}
if (Component.directives) {
const names = Object.keys(Component.directives);
for (let i = 0; i < names.length; i++) {
validateDirectiveName(names[i]);
}
}
if (Component.compilerOptions && isRuntimeOnly()) {
warn(`"compilerOptions" is only supported when using a build of Vue that ` +
`includes the runtime compiler. Since you are using a runtime-only ` +
`build, the options should be passed via your build tool config instead.`);
}
}
// 0. create render proxy property access cache
instance.accessCache = Object.create(null);
// 1. create public instance / render proxy
// also mark it raw so it's never observed
instance.proxy = reactivity.markRaw(new Proxy(instance.ctx, PublicInstanceProxyHandlers));
{
exposePropsOnRenderContext(instance);
}
// 2. call setup()
const { setup } = Component;
if (setup) {
const setupContext = (instance.setupContext =
setup.length > 1 ? createSetupContext(instance) : null);
setCurrentInstance(instance);
reactivity.pauseTracking();
const setupResult = callWithErrorHandling(setup, instance, 0 /* ErrorCodes.SETUP_FUNCTION */, [reactivity.shallowReadonly(instance.props) , setupContext]);
reactivity.resetTracking();
unsetCurrentInstance();
if (shared.isPromise(setupResult)) {
setupResult.then(unsetCurrentInstance, unsetCurrentInstance);
if (isSSR) {
// return the promise so server-renderer can wait on it
return setupResult
.then((resolvedResult) => {
handleSetupResult(instance, resolvedResult, isSSR);
})
.catch(e => {
handleError(e, instance, 0 /* ErrorCodes.SETUP_FUNCTION */);
});
}
else {
// async setup returned Promise.
// bail here and wait for re-entry.
instance.asyncDep = setupResult;
if (!instance.suspense) {
const name = (_a = Component.name) !== null && _a !== void 0 ? _a : 'Anonymous';
warn(`Component <${name}>: setup function returned a promise, but no ` +
`<Suspense> boundary was found in the parent component tree. ` +
`A component with async setup() must be nested in a <Suspense> ` +
`in order to be rendered.`);
}
}
}
else {
handleSetupResult(instance, setupResult, isSSR);
}
}
else {
finishComponentSetup(instance, isSSR);
}
}
function createSetupContext(instance) {
const expose = exposed => {
if (instance.exposed) {
warn(`expose() should be called only once per setup().`);
}
instance.exposed = exposed || {};
};
let attrs;
{
// We use getters in dev in case libs like test-utils overwrite instance
// properties (overwrites should not be done in prod)
return Object.freeze({
get attrs() {
return attrs || (attrs = createAttrsProxy(instance));
},
get slots() {
return reactivity.shallowReadonly(instance.slots);
},
get emit() {
return (event, ...args) => instance.emit(event, ...args);
},
expose
});
}
}
if (shared.isPromise(setupResult)) {
setupResult.then(unsetCurrentInstance, unsetCurrentInstance);
if (isSSR) {
// return the promise so server-renderer can wait on it
return setupResult
.then((resolvedResult) => {
handleSetupResult(instance, resolvedResult, isSSR);
})
.catch(e => {
handleError(e, instance, 0 /* ErrorCodes.SETUP_FUNCTION */);
});
}
else {
// async setup returned Promise.
// bail here and wait for re-entry.
instance.asyncDep = setupResult;
if (!instance.suspense) {
const name = (_a = Component.name) !== null && _a !== void 0 ? _a : 'Anonymous';
warn(`Component <${name}>: setup function returned a promise, but no ` +
`<Suspense> boundary was found in the parent component tree. ` +
`A component with async setup() must be nested in a <Suspense> ` +
`in order to be rendered.`);
}
}
}
function handleSetupResult(instance, setupResult, isSSR) {
if (shared.isFunction(setupResult)) {
// setup returned an inline render function
if (instance.type.__ssrInlineRender) {
// when the function's name is `ssrRender` (compiled by SFC inline mode),
// set it as ssrRender instead.
instance.ssrRender = setupResult;
}
else {
instance.render = setupResult;
}
}
else if (shared.isObject(setupResult)) {
if (isVNode(setupResult)) {
warn(`setup() should not return VNodes directly - ` +
`return a render function instead.`);
}
// setup returned bindings.
// assuming a render function compiled from template is present.
{
instance.devtoolsRawSetupState = setupResult;
}
instance.setupState = reactivity.proxyRefs(setupResult);
{
exposeSetupStateOnRenderContext(instance);
}
}
else if (setupResult !== undefined) {
warn(`setup() should return an object. Received: ${setupResult === null ? 'null' : typeof setupResult}`);
}
finishComponentSetup(instance, isSSR);
}
function finishComponentSetup(instance, isSSR, skipOptions) {
const Component = instance.type;
// template / render function normalization
// could be already set when returned from setup()
if (!instance.render) {
// only do on-the-fly compile if not in SSR - SSR on-the-fly compilation
// is done by server-renderer
if (!isSSR && compile && !Component.render) {
const template = Component.template;
if (template) {
{
startMeasure(instance, `compile`);
}
const { isCustomElement, compilerOptions } = instance.appContext.config;
const { delimiters, compilerOptions: componentCompilerOptions } = Component;
const finalCompilerOptions = shared.extend(shared.extend({
isCustomElement,
delimiters
}, compilerOptions), componentCompilerOptions);
Component.render = compile(template, finalCompilerOptions);
{
endMeasure(instance, `compile`);
}
}
}
instance.render = (Component.render || shared.NOOP);
// for runtime-compiled render functions using `with` blocks, the render
// proxy used needs a different `has` handler which is more performant and
// also only allows a whitelist of globals to fallthrough.
if (installWithProxy) {
installWithProxy(instance);
}
}
// support for 2.x options
{
setCurrentInstance(instance);
reactivity.pauseTracking();
applyOptions(instance);
reactivity.resetTracking();
unsetCurrentInstance();
}
// warn missing template/render
// the runtime compilation of template in SSR is done by server-render
if (!Component.render && instance.render === shared.NOOP && !isSSR) {
/* istanbul ignore if */
if (!compile && Component.template) {
warn(`Component provided template option but ` +
`runtime compilation is not supported in this build of Vue.` +
(``) /* should not happen */);
}
else {
warn(`Component is missing template or render function.`);
}
}
}