refactor: reuse props logic from core

This commit is contained in:
Evan You 2024-12-03 16:48:28 +08:00
parent f8046a3e1a
commit 783d8b4d0d
No known key found for this signature in database
GPG Key ID: 00E9AB7A6704CE0A
12 changed files with 526 additions and 361 deletions

View File

@ -470,7 +470,7 @@ export interface ComponentInternalInstance {
* avoid unnecessary watcher trigger
* @internal
*/
propsDefaults: Data
propsDefaults: Data | null
/**
* setup related
* @internal
@ -647,7 +647,7 @@ export function createComponentInstance(
emitted: null,
// props default value
propsDefaults: EMPTY_OBJ,
propsDefaults: null,
// inheritAttrs
inheritAttrs: type.inheritAttrs,

View File

@ -282,11 +282,10 @@ export function updateProps(
const camelizedKey = camelize(key)
props[camelizedKey] = resolvePropValue(
options,
rawCurrentProps,
camelizedKey,
value,
instance,
false /* isAbsent */,
baseResolveDefault,
)
}
} else {
@ -331,10 +330,10 @@ export function updateProps(
) {
props[key] = resolvePropValue(
options,
rawCurrentProps,
key,
undefined,
instance,
baseResolveDefault,
true /* isAbsent */,
)
}
@ -428,16 +427,15 @@ function setFullProps(
}
if (needCastKeys) {
const rawCurrentProps = toRaw(props)
const castValues = rawCastValues || EMPTY_OBJ
for (let i = 0; i < needCastKeys.length; i++) {
const key = needCastKeys[i]
props[key] = resolvePropValue(
options!,
rawCurrentProps,
key,
castValues[key],
instance,
baseResolveDefault,
!hasOwn(castValues, key),
)
}
@ -446,14 +444,32 @@ function setFullProps(
return hasAttrsChanged
}
function resolvePropValue(
/**
* A type that allows both vdom and vapor instances
*/
type CommonInstance = Pick<
ComponentInternalInstance,
'props' | 'propsDefaults' | 'ce'
>
/**
* @internal for runtime-vapor
*/
export function resolvePropValue<T extends CommonInstance>(
options: NormalizedProps,
props: Data,
key: string,
value: unknown,
instance: ComponentInternalInstance,
isAbsent: boolean,
) {
instance: T,
/**
* Allow runtime-specific default resolution logic
*/
resolveDefault: (
factory: (props: Data) => unknown,
instance: T,
key: string,
) => unknown,
isAbsent = false,
): unknown {
const opt = options[key]
if (opt != null) {
const hasDefault = hasOwn(opt, 'default')
@ -465,19 +481,16 @@ function resolvePropValue(
!opt.skipFactory &&
isFunction(defaultValue)
) {
const { propsDefaults } = instance
if (key in propsDefaults) {
value = propsDefaults[key]
const cachedDefaults =
instance.propsDefaults || (instance.propsDefaults = {})
if (hasOwn(cachedDefaults, key)) {
value = cachedDefaults[key]
} else {
const reset = setCurrentInstance(instance)
value = propsDefaults[key] = defaultValue.call(
__COMPAT__ &&
isCompatEnabled(DeprecationTypes.PROPS_DEFAULT_THIS, instance)
? createPropsDefaultThis(instance, props, key)
: null,
props,
value = cachedDefaults[key] = resolveDefault(
defaultValue,
instance,
key,
)
reset()
}
} else {
value = defaultValue
@ -502,6 +515,27 @@ function resolvePropValue(
return value
}
/**
* runtime-dom-specific default resolving logic
*/
function baseResolveDefault(
factory: (props: Data) => unknown,
instance: ComponentInternalInstance,
key: string,
) {
let value
const reset = setCurrentInstance(instance)
const props = toRaw(instance.props)
value = factory.call(
__COMPAT__ && isCompatEnabled(DeprecationTypes.PROPS_DEFAULT_THIS, instance)
? createPropsDefaultThis(instance, props, key)
: null,
props,
)
reset()
return value
}
const mixinPropsCache = new WeakMap<ConcreteComponent, NormalizedPropsOptions>()
export function normalizePropsOptions(
@ -550,6 +584,22 @@ export function normalizePropsOptions(
return EMPTY_ARR as any
}
baseNormalizePropsOptions(raw, normalized, needCastKeys)
const res: NormalizedPropsOptions = [normalized, needCastKeys]
if (isObject(comp)) {
cache.set(comp, res)
}
return res
}
/**
* @internal for runtime-vapor only
*/
export function baseNormalizePropsOptions(
raw: ComponentPropsOptions | undefined,
normalized: NonNullable<NormalizedPropsOptions[0]>,
needCastKeys: NonNullable<NormalizedPropsOptions[1]>,
): void {
if (isArray(raw)) {
for (let i = 0; i < raw.length; i++) {
if (__DEV__ && !isString(raw[i])) {
@ -604,12 +654,6 @@ export function normalizePropsOptions(
}
}
}
const res: NormalizedPropsOptions = [normalized, needCastKeys]
if (isObject(comp)) {
cache.set(comp, res)
}
return res
}
function validatePropName(key: string) {

View File

@ -320,6 +320,7 @@ export type {
ExtractPropTypes,
ExtractPublicPropTypes,
ExtractDefaultPropTypes,
NormalizedPropsOptions,
} from './componentProps'
export type {
Directive,
@ -480,3 +481,10 @@ export const compatUtils = (
export const DeprecationTypes = (
__COMPAT__ ? _DeprecationTypes : null
) as typeof _DeprecationTypes
// VAPOR -----------------------------------------------------------------------
// **IMPORTANT** These APIs are exposed solely for @vue/runtime-vapor and may
// change without notice between versions. User code should never rely on them.
export { baseNormalizePropsOptions, resolvePropValue } from './componentProps'

View File

@ -0,0 +1,18 @@
import { normalizeContainer } from '../apiRender'
import { insert } from '../dom/element'
import { type Component, createComponent } from './component'
export function createVaporApp(comp: Component): any {
return {
mount(container: string | ParentNode) {
container = normalizeContainer(container)
// clear content before mounting
if (container.nodeType === 1 /* Node.ELEMENT_NODE */) {
container.textContent = ''
}
const instance = createComponent(comp)
insert(instance.block, container)
return instance
},
}
}

View File

@ -0,0 +1,184 @@
import {
type ComponentPropsOptions,
EffectScope,
type EmitsOptions,
type NormalizedPropsOptions,
} from '@vue/runtime-core'
import type { Block } from '../block'
import type { Data } from '@vue/runtime-shared'
import { pauseTracking, resetTracking } from '@vue/reactivity'
import { isFunction } from '@vue/shared'
import {
type RawProps,
getDynamicPropsHandlers,
initStaticProps,
} from './componentProps'
import { setDynamicProp } from '../dom/prop'
import { renderEffect } from './renderEffect'
export type Component = FunctionalComponent | ObjectComponent
export type SetupFn = (
props: any,
ctx: SetupContext,
) => Block | Data | undefined
export type FunctionalComponent = SetupFn &
Omit<ObjectComponent, 'setup'> & {
displayName?: string
} & SharedInternalOptions
export interface ObjectComponent
extends ComponentInternalOptions,
SharedInternalOptions {
setup?: SetupFn
inheritAttrs?: boolean
props?: ComponentPropsOptions
emits?: EmitsOptions
render?(ctx: any): Block
name?: string
vapor?: boolean
}
interface SharedInternalOptions {
__propsOptions?: NormalizedPropsOptions
__propsHandlers?: [ProxyHandler<any>, ProxyHandler<any>]
}
// Note: can't mark this whole interface internal because some public interfaces
// extend it.
interface ComponentInternalOptions {
/**
* @internal
*/
__scopeId?: string
/**
* @internal
*/
__cssModules?: Data
/**
* @internal
*/
__hmrId?: string
/**
* Compat build only, for bailing out of certain compatibility behavior
*/
__isBuiltIn?: boolean
/**
* This one should be exposed so that devtools can make use of it
*/
__file?: string
/**
* name inferred from filename
*/
__name?: string
}
export function createComponent(
component: Component,
rawProps?: RawProps,
isSingleRoot?: boolean,
): ComponentInstance {
// check if we are the single root of the parent
// if yes, inject parent attrs as dynamic props source
if (isSingleRoot && currentInstance && currentInstance.hasFallthrough) {
if (rawProps) {
;(rawProps.$ || (rawProps.$ = [])).push(currentInstance.attrs)
} else {
rawProps = { $: [currentInstance.attrs] }
}
}
const instance = new ComponentInstance(component, rawProps)
pauseTracking()
let prevInstance = currentInstance
currentInstance = instance
instance.scope.on()
const setupFn = isFunction(component) ? component : component.setup
const setupContext = setupFn!.length > 1 ? new SetupContext(instance) : null
instance.block = setupFn!(
instance.props,
// @ts-expect-error
setupContext,
) as Block // TODO handle return object
// single root, inherit attrs
if (
instance.hasFallthrough &&
component.inheritAttrs !== false &&
instance.block instanceof Element &&
Object.keys(instance.attrs).length
) {
renderEffect(() => {
for (const key in instance.attrs) {
setDynamicProp(instance.block as Element, key, instance.attrs[key])
}
})
}
instance.scope.off()
currentInstance = prevInstance
resetTracking()
return instance
}
let uid = 0
export let currentInstance: ComponentInstance | null = null
export class ComponentInstance {
type: Component
uid: number = uid++
scope: EffectScope = new EffectScope(true)
props: Record<string, any>
propsDefaults: Record<string, any> | null
attrs: Record<string, any>
block: Block
exposed?: Record<string, any>
hasFallthrough: boolean
constructor(comp: Component, rawProps?: RawProps) {
this.type = comp
this.block = null! // to be set
// init props
this.propsDefaults = null
this.hasFallthrough = false
if (comp.props && rawProps && rawProps.$) {
// has dynamic props, use proxy
const handlers = getDynamicPropsHandlers(comp, this)
this.props = new Proxy(rawProps, handlers[0])
this.attrs = new Proxy(rawProps, handlers[1])
this.hasFallthrough = true
} else {
this.props = {}
this.attrs = {}
this.hasFallthrough = initStaticProps(comp, rawProps, this)
}
// TODO validate props
// TODO init slots
}
}
export function isVaporComponent(value: unknown): value is ComponentInstance {
return value instanceof ComponentInstance
}
export class SetupContext<E = EmitsOptions> {
attrs: Record<string, any>
// emit: EmitFn<E>
// slots: Readonly<StaticSlots>
expose: (exposed?: Record<string, any>) => void
constructor(instance: ComponentInstance) {
this.attrs = instance.attrs
// this.emit = instance.emit as EmitFn<E>
// this.slots = instance.slots
this.expose = (exposed = {}) => {
instance.exposed = exposed
}
}
}

View File

@ -0,0 +1,214 @@
import { EMPTY_ARR, NO, camelize, hasOwn, isFunction } from '@vue/shared'
import type { Component, ComponentInstance } from './component'
import {
type NormalizedPropsOptions,
baseNormalizePropsOptions,
resolvePropValue,
} from '@vue/runtime-core'
export interface RawProps {
[key: string]: PropSource
$?: DynamicPropsSource[]
}
type PropSource<T = any> = T | (() => T)
type DynamicPropsSource = PropSource<Record<string, any>>
export function initStaticProps(
comp: Component,
rawProps: RawProps | undefined,
instance: ComponentInstance,
): boolean {
let hasAttrs = false
const { props, attrs } = instance
const [propsOptions, needCastKeys] = normalizePropsOptions(comp)
// TODO emits filtering
for (const key in rawProps) {
const normalizedKey = camelize(key)
const needCast = needCastKeys && needCastKeys.includes(normalizedKey)
const source = rawProps[key]
if (propsOptions && normalizedKey in propsOptions) {
if (isFunction(source)) {
Object.defineProperty(props, normalizedKey, {
enumerable: true,
get: needCast
? () =>
resolvePropValue(
propsOptions,
normalizedKey,
source(),
instance,
resolveDefault,
)
: source,
})
} else {
props[normalizedKey] = needCast
? resolvePropValue(
propsOptions,
normalizedKey,
source,
instance,
resolveDefault,
)
: source
}
} else {
if (isFunction(source)) {
Object.defineProperty(attrs, key, {
enumerable: true,
get: source,
})
} else {
attrs[normalizedKey] = source
}
hasAttrs = true
}
}
for (const key in propsOptions) {
if (!(key in props)) {
props[key] = resolvePropValue(
propsOptions,
key,
undefined,
instance,
resolveDefault,
true,
)
}
}
return hasAttrs
}
function resolveDefault(
factory: (props: Record<string, any>) => unknown,
instance: ComponentInstance,
) {
return factory.call(null, instance.props)
}
// TODO optimization: maybe convert functions into computeds
function resolveSource(source: PropSource): Record<string, any> {
return isFunction(source) ? source() : source
}
export function getDynamicPropsHandlers(
comp: Component,
instance: ComponentInstance,
): [ProxyHandler<RawProps>, ProxyHandler<RawProps>] {
if (comp.__propsHandlers) {
return comp.__propsHandlers
}
let normalizedKeys: string[] | undefined
const propsOptions = normalizePropsOptions(comp)[0]!
const isProp = (key: string | symbol) => hasOwn(propsOptions, key)
const getProp = (target: RawProps, key: string | symbol, asProp: boolean) => {
if (key !== '$' && (asProp ? isProp(key) : !isProp(key))) {
const castProp = (value: any, isAbsent = false) =>
asProp
? resolvePropValue(
propsOptions,
key as string,
value,
instance,
resolveDefault,
isAbsent,
)
: value
if (key in target) {
// TODO default value, casting, etc.
return castProp(resolveSource(target[key as string]))
}
if (target.$) {
let i = target.$.length
let source
while (i--) {
source = resolveSource(target.$[i])
if (hasOwn(source, key)) {
return castProp(source[key])
}
}
}
return castProp(undefined, true)
}
}
const propsHandlers = {
get: (target, key) => getProp(target, key, true),
has: (_, key) => isProp(key),
getOwnPropertyDescriptor(target, key) {
if (isProp(key)) {
return {
configurable: true,
enumerable: true,
get: () => getProp(target, key, true),
}
}
},
ownKeys: () =>
normalizedKeys || (normalizedKeys = Object.keys(propsOptions)),
set: NO,
deleteProperty: NO,
} satisfies ProxyHandler<RawProps>
const hasAttr = (target: RawProps, key: string | symbol) => {
if (key === '$' || isProp(key)) return false
if (hasOwn(target, key)) return true
if (target.$) {
let i = target.$.length
while (i--) {
if (hasOwn(resolveSource(target.$[i]), key)) {
return true
}
}
}
return false
}
const attrsHandlers = {
get: (target, key) => getProp(target, key, false),
has: hasAttr,
getOwnPropertyDescriptor(target, key) {
if (hasAttr(target, key)) {
return {
configurable: true,
enumerable: true,
get: () => getProp(target, key, false),
}
}
},
ownKeys(target) {
const staticKeys = Object.keys(target).filter(
key => key !== '$' && !isProp(key),
)
if (target.$) {
let i = target.$.length
while (i--) {
staticKeys.push(...Object.keys(resolveSource(target.$[i])))
}
}
return staticKeys
},
set: NO,
deleteProperty: NO,
} satisfies ProxyHandler<RawProps>
return (comp.__propsHandlers = [propsHandlers, attrsHandlers])
}
function normalizePropsOptions(comp: Component): NormalizedPropsOptions {
const cached = comp.__propsOptions
if (cached) return cached
const raw = comp.props
if (!raw) return EMPTY_ARR as []
const normalized: NormalizedPropsOptions[0] = {}
const needCastKeys: NormalizedPropsOptions[1] = []
baseNormalizePropsOptions(raw, normalized, needCastKeys)
return (comp.__propsOptions = [normalized, needCastKeys])
}

View File

@ -0,0 +1,3 @@
export { createComponent as createComponentSimple } from './component'
export { renderEffect as renderEffectSimple } from './renderEffect'
export { createVaporApp as createVaporAppSimple } from './apiCreateApp'

View File

@ -0,0 +1,22 @@
import { ReactiveEffect } from '@vue/reactivity'
import {
type SchedulerJob,
queueJob,
} from '../../../runtime-core/src/scheduler'
import { currentInstance } from './component'
export function renderEffect(fn: () => void): void {
const updateFn = () => {
fn()
}
const effect = new ReactiveEffect(updateFn)
const job: SchedulerJob = effect.runIfDirty.bind(effect)
job.i = currentInstance as any
job.id = currentInstance!.uid
effect.scheduler = () => queueJob(job)
effect.run()
// TODO lifecycle
// TODO recurse handling
// TODO measure
}

View File

@ -1,322 +0,0 @@
import {
EffectScope,
ReactiveEffect,
pauseTracking,
resetTracking,
} from '@vue/reactivity'
import type { Component } from './component'
import { NO, camelize, hasOwn, isFunction } from '@vue/shared'
import { type SchedulerJob, queueJob } from '../../runtime-core/src/scheduler'
import { insert } from './dom/element'
import { normalizeContainer } from './apiRender'
import { normalizePropsOptions, resolvePropValue } from './componentProps'
import type { Block } from './block'
import { EmitFn, type EmitsOptions } from './componentEmits'
import { StaticSlots } from './componentSlots'
import { setDynamicProp } from './dom/prop'
interface RawProps {
[key: string]: PropSource
$?: DynamicPropsSource[]
}
type PropSource<T = any> = T | (() => T)
type DynamicPropsSource = PropSource<Record<string, any>>
export function createComponentSimple(
component: Component,
rawProps?: RawProps,
isSingleRoot?: boolean,
): ComponentInstance {
// check if we are the single root of the parent
// if yes, inject parent attrs as dynamic props source
if (isSingleRoot && currentInstance && currentInstance.hasFallthrough) {
if (rawProps) {
;(rawProps.$ || (rawProps.$ = [])).push(currentInstance.attrs)
} else {
rawProps = { $: [currentInstance.attrs] }
}
}
const instance = new ComponentInstance(component, rawProps)
pauseTracking()
let prevInstance = currentInstance
currentInstance = instance
instance.scope.on()
const setupFn = isFunction(component) ? component : component.setup
const setupContext = setupFn!.length > 1 ? new SetupContext(instance) : null
instance.block = setupFn!(
instance.props,
// @ts-expect-error
setupContext,
) as Block // TODO handle return object
// single root, inherit attrs
if (
instance.hasFallthrough &&
component.inheritAttrs !== false &&
instance.block instanceof Element &&
Object.keys(instance.attrs).length
) {
renderEffectSimple(() => {
for (const key in instance.attrs) {
setDynamicProp(instance.block as Element, key, instance.attrs[key])
}
})
}
instance.scope.off()
currentInstance = prevInstance
resetTracking()
return instance
}
class SetupContext<E = EmitsOptions> {
attrs: Record<string, any>
// emit: EmitFn<E>
// slots: Readonly<StaticSlots>
expose: (exposed?: Record<string, any>) => void
constructor(instance: ComponentInstance) {
this.attrs = instance.attrs
// this.emit = instance.emit as EmitFn<E>
// this.slots = instance.slots
this.expose = (exposed = {}) => {
instance.exposed = exposed
}
}
}
let uid = 0
let currentInstance: ComponentInstance | null = null
export class ComponentInstance {
type: Component
uid: number = uid++
scope: EffectScope = new EffectScope(true)
props: Record<string, any>
attrs: Record<string, any>
block: Block
exposed?: Record<string, any>
hasFallthrough: boolean
constructor(comp: Component, rawProps?: RawProps) {
this.type = comp
this.block = null! // to be set
// init props
this.hasFallthrough = false
if (comp.props && rawProps && rawProps.$) {
// has dynamic props, use proxy
const handlers = getDynamicPropsHandlers(comp, this)
this.props = new Proxy(rawProps, handlers[0])
this.attrs = new Proxy(rawProps, handlers[1])
this.hasFallthrough = true
} else {
this.hasFallthrough = initStaticProps(
comp,
rawProps,
(this.props = {}),
(this.attrs = {}),
)
}
// TODO validate props
// TODO init slots
}
}
export function isVaporComponent(value: unknown): value is ComponentInstance {
return value instanceof ComponentInstance
}
function initStaticProps(
comp: Component,
rawProps: RawProps | undefined,
props: any,
attrs: any,
): boolean {
let hasAttrs = false
const [propsOptions, needCastKeys] = normalizePropsOptions(comp)
for (const key in rawProps) {
const normalizedKey = camelize(key)
const needCast = needCastKeys && needCastKeys.includes(normalizedKey)
const source = rawProps[key]
if (propsOptions && normalizedKey in propsOptions) {
if (isFunction(source)) {
Object.defineProperty(props, normalizedKey, {
enumerable: true,
get: needCast
? () =>
resolvePropValue(propsOptions, props, normalizedKey, source())
: source,
})
} else {
props[normalizedKey] = needCast
? resolvePropValue(propsOptions, props, normalizedKey, source)
: source
}
} else {
if (isFunction(source)) {
Object.defineProperty(attrs, key, {
enumerable: true,
get: source,
})
} else {
attrs[normalizedKey] = source
}
hasAttrs = true
}
}
for (const key in propsOptions) {
if (!(key in props)) {
props[key] = resolvePropValue(propsOptions, props, key, undefined, true)
}
}
return hasAttrs
}
// TODO optimization: maybe convert functions into computeds
function resolveSource(source: PropSource): Record<string, any> {
return isFunction(source) ? source() : source
}
function getDynamicPropsHandlers(
comp: Component,
instance: ComponentInstance,
): [ProxyHandler<RawProps>, ProxyHandler<RawProps>] {
if (comp.__propsHandlers) {
return comp.__propsHandlers
}
let normalizedKeys: string[] | undefined
const propsOptions = normalizePropsOptions(comp)[0]!
const isProp = (key: string | symbol) => hasOwn(propsOptions, key)
const getProp = (target: RawProps, key: string | symbol, asProp: boolean) => {
if (key !== '$' && (asProp ? isProp(key) : !isProp(key))) {
const castProp = (value: any, isAbsent?: boolean) =>
asProp
? resolvePropValue(
propsOptions,
instance.props,
key as string,
value,
isAbsent,
)
: value
if (key in target) {
// TODO default value, casting, etc.
return castProp(resolveSource(target[key as string]))
}
if (target.$) {
let i = target.$.length
let source
while (i--) {
source = resolveSource(target.$[i])
if (hasOwn(source, key)) {
return castProp(source[key])
}
}
}
return castProp(undefined, true)
}
}
const propsHandlers = {
get: (target, key) => getProp(target, key, true),
has: (_, key) => isProp(key),
getOwnPropertyDescriptor(target, key) {
if (isProp(key)) {
return {
configurable: true,
enumerable: true,
get: () => getProp(target, key, true),
}
}
},
ownKeys: () =>
normalizedKeys || (normalizedKeys = Object.keys(propsOptions)),
set: NO,
deleteProperty: NO,
} satisfies ProxyHandler<RawProps>
const hasAttr = (target: RawProps, key: string | symbol) => {
if (key === '$' || isProp(key)) return false
if (hasOwn(target, key)) return true
if (target.$) {
let i = target.$.length
while (i--) {
if (hasOwn(resolveSource(target.$[i]), key)) {
return true
}
}
}
return false
}
const attrsHandlers = {
get: (target, key) => getProp(target, key, false),
has: hasAttr,
getOwnPropertyDescriptor(target, key) {
if (hasAttr(target, key)) {
return {
configurable: true,
enumerable: true,
get: () => getProp(target, key, false),
}
}
},
ownKeys(target) {
const staticKeys = Object.keys(target).filter(
key => key !== '$' && !isProp(key),
)
if (target.$) {
let i = target.$.length
while (i--) {
staticKeys.push(...Object.keys(resolveSource(target.$[i])))
}
}
return staticKeys
},
set: NO,
deleteProperty: NO,
} satisfies ProxyHandler<RawProps>
return (comp.__propsHandlers = [propsHandlers, attrsHandlers])
}
export function renderEffectSimple(fn: () => void): void {
const updateFn = () => {
fn()
}
const effect = new ReactiveEffect(updateFn)
const job: SchedulerJob = effect.runIfDirty.bind(effect)
job.i = currentInstance as any
job.id = currentInstance!.uid
effect.scheduler = () => queueJob(job)
effect.run()
// TODO lifecycle
// TODO recurse handling
// TODO measure
}
// vapor app can be a subset of main app APIs
// TODO refactor core createApp for reuse
export function createVaporAppSimple(comp: Component): any {
return {
mount(container: string | ParentNode) {
container = normalizeContainer(container)
// clear content before mounting
if (container.nodeType === 1 /* Node.ELEMENT_NODE */) {
container.textContent = ''
}
const rootBlock = createComponentSimple(comp)
insert(rootBlock, container)
},
}
}

View File

@ -1,8 +1,5 @@
import { isArray } from '@vue/shared'
import {
type ComponentInstance,
isVaporComponent,
} from './apiCreateComponentSimple'
import { type ComponentInstance, isVaporComponent } from './_new/component'
export const fragmentKey: unique symbol = Symbol(__DEV__ ? `fragmentKey` : ``)

View File

@ -2,7 +2,7 @@ import { isArray } from '@vue/shared'
import { renderEffect } from '../renderEffect'
import { setText } from './prop'
import { type Block, normalizeBlock } from '../block'
import { isVaporComponent } from '../apiCreateComponentSimple'
import { isVaporComponent } from '../_new/component'
// export function insert(
// block: Block,

View File

@ -155,11 +155,6 @@ export {
export { createBranch, createIf } from './apiCreateIf'
export { createFor, createForSlots } from './apiCreateFor'
export { createComponent } from './apiCreateComponent'
export {
createComponentSimple,
renderEffectSimple,
createVaporAppSimple,
} from './apiCreateComponentSimple'
export { createSelector } from './apiCreateSelector'
export { setInheritAttrs } from './componentAttrs'
@ -195,3 +190,5 @@ export const devtools = (
export const setDevtoolsHook = (
__DEV__ || __ESM_BUNDLER__ ? _setDevtoolsHook : NOOP
) as typeof _setDevtoolsHook
export * from './_new'