| 
									
										
										
										
											2023-12-10 01:33:18 +08:00
										 |  |  | import { | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   type ComponentInternalOptions, | 
					
						
							| 
									
										
										
										
											2023-12-10 01:33:18 +08:00
										 |  |  |   type ComponentPropsOptions, | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   EffectScope, | 
					
						
							| 
									
										
										
										
											2024-12-04 15:07:40 +08:00
										 |  |  |   type EmitFn, | 
					
						
							| 
									
										
										
										
											2024-02-04 21:18:57 +08:00
										 |  |  |   type EmitsOptions, | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   type GenericAppContext, | 
					
						
							|  |  |  |   type GenericComponentInstance, | 
					
						
							|  |  |  |   type LifecycleHook, | 
					
						
							|  |  |  |   type NormalizedPropsOptions, | 
					
						
							| 
									
										
										
										
											2024-02-04 21:18:57 +08:00
										 |  |  |   type ObjectEmitsOptions, | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   nextUid, | 
					
						
							|  |  |  |   popWarningContext, | 
					
						
							|  |  |  |   pushWarningContext, | 
					
						
							| 
									
										
										
										
											2024-12-04 15:07:40 +08:00
										 |  |  |   warn, | 
					
						
							| 
									
										
										
										
											2024-12-04 14:22:26 +08:00
										 |  |  | } from '@vue/runtime-dom' | 
					
						
							| 
									
										
										
										
											2024-12-04 15:07:40 +08:00
										 |  |  | import { type Block, isBlock } from './block' | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  | import { pauseTracking, resetTracking } from '@vue/reactivity' | 
					
						
							| 
									
										
										
										
											2024-12-05 16:14:24 +08:00
										 |  |  | import { EMPTY_OBJ, isFunction } from '@vue/shared' | 
					
						
							| 
									
										
										
										
											2024-05-29 01:43:47 +08:00
										 |  |  | import { | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   type RawProps, | 
					
						
							| 
									
										
										
										
											2024-12-04 23:02:15 +08:00
										 |  |  |   getPropsProxyHandlers, | 
					
						
							| 
									
										
										
										
											2024-12-05 16:14:24 +08:00
										 |  |  |   hasFallthroughAttrs, | 
					
						
							| 
									
										
										
										
											2024-12-04 23:02:15 +08:00
										 |  |  |   normalizePropsOptions, | 
					
						
							| 
									
										
										
										
											2024-12-05 16:14:24 +08:00
										 |  |  |   setupPropsValidation, | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  | } from './componentProps' | 
					
						
							|  |  |  | import { setDynamicProp } from './dom/prop' | 
					
						
							|  |  |  | import { renderEffect } from './renderEffect' | 
					
						
							| 
									
										
										
										
											2024-12-04 23:50:59 +08:00
										 |  |  | import { emit, normalizeEmitsOptions } from './componentEmits' | 
					
						
							| 
									
										
										
										
											2023-12-10 01:33:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  | export type VaporComponent = FunctionalVaporComponent | ObjectVaporComponent | 
					
						
							| 
									
										
										
										
											2024-12-02 20:35:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  | export type VaporSetupFn = ( | 
					
						
							| 
									
										
										
										
											2024-12-02 09:36:49 +08:00
										 |  |  |   props: any, | 
					
						
							|  |  |  |   ctx: SetupContext, | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  | ) => Block | Record<string, any> | undefined | 
					
						
							| 
									
										
										
										
											2024-12-02 20:35:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  | export type FunctionalVaporComponent = VaporSetupFn & | 
					
						
							|  |  |  |   Omit<ObjectVaporComponent, 'setup'> & { | 
					
						
							| 
									
										
										
										
											2024-04-28 18:43:16 +08:00
										 |  |  |     displayName?: string | 
					
						
							| 
									
										
										
										
											2024-12-02 20:35:45 +08:00
										 |  |  |   } & SharedInternalOptions | 
					
						
							| 
									
										
										
										
											2024-02-14 14:43:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  | export interface ObjectVaporComponent | 
					
						
							| 
									
										
										
										
											2024-12-02 20:35:45 +08:00
										 |  |  |   extends ComponentInternalOptions, | 
					
						
							|  |  |  |     SharedInternalOptions { | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   setup?: VaporSetupFn | 
					
						
							| 
									
										
										
										
											2024-03-19 00:24:58 +08:00
										 |  |  |   inheritAttrs?: boolean | 
					
						
							| 
									
										
										
										
											2024-04-28 18:43:16 +08:00
										 |  |  |   props?: ComponentPropsOptions | 
					
						
							| 
									
										
										
										
											2024-02-14 14:43:18 +08:00
										 |  |  |   emits?: EmitsOptions | 
					
						
							|  |  |  |   render?(ctx: any): Block | 
					
						
							| 
									
										
										
										
											2024-04-28 18:43:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   name?: string | 
					
						
							| 
									
										
										
										
											2024-02-14 14:43:18 +08:00
										 |  |  |   vapor?: boolean | 
					
						
							| 
									
										
										
										
											2023-12-06 14:59:11 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  | interface SharedInternalOptions { | 
					
						
							| 
									
										
										
										
											2024-04-28 18:43:16 +08:00
										 |  |  |   /** | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |    * Cached normalized props options. | 
					
						
							|  |  |  |    * In vapor mode there are no mixins so normalized options can be cached | 
					
						
							|  |  |  |    * directly on the component | 
					
						
							| 
									
										
										
										
											2024-04-28 18:43:16 +08:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   __propsOptions?: NormalizedPropsOptions | 
					
						
							| 
									
										
										
										
											2024-04-28 18:43:16 +08:00
										 |  |  |   /** | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |    * Cached normalized props proxy handlers. | 
					
						
							| 
									
										
										
										
											2024-04-28 18:43:16 +08:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   __propsHandlers?: [ProxyHandler<any> | null, ProxyHandler<any>] | 
					
						
							| 
									
										
										
										
											2024-04-28 18:43:16 +08:00
										 |  |  |   /** | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |    * Cached normalized emits options. | 
					
						
							| 
									
										
										
										
											2024-04-28 18:43:16 +08:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   __emitsOptions?: ObjectEmitsOptions | 
					
						
							| 
									
										
										
										
											2024-04-28 18:43:16 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  | export function createComponent( | 
					
						
							|  |  |  |   component: VaporComponent, | 
					
						
							|  |  |  |   rawProps?: RawProps, | 
					
						
							|  |  |  |   isSingleRoot?: boolean, | 
					
						
							|  |  |  | ): VaporComponentInstance { | 
					
						
							|  |  |  |   // check if we are the single root of the parent
 | 
					
						
							|  |  |  |   // if yes, inject parent attrs as dynamic props source
 | 
					
						
							|  |  |  |   if (isSingleRoot && currentInstance && currentInstance.hasFallthrough) { | 
					
						
							| 
									
										
										
										
											2024-12-04 20:55:10 +08:00
										 |  |  |     const attrs = currentInstance.attrs | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |     if (rawProps) { | 
					
						
							| 
									
										
										
										
											2024-12-04 20:55:10 +08:00
										 |  |  |       ;(rawProps.$ || (rawProps.$ = [])).push(() => attrs) | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2024-12-04 20:55:10 +08:00
										 |  |  |       rawProps = { $: [() => attrs] } as RawProps | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-12-01 16:41:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   const instance = new VaporComponentInstance(component, rawProps) | 
					
						
							| 
									
										
										
										
											2024-12-01 16:41:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   pauseTracking() | 
					
						
							|  |  |  |   let prevInstance = currentInstance | 
					
						
							| 
									
										
										
										
											2024-12-01 16:41:51 +08:00
										 |  |  |   currentInstance = instance | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   instance.scope.on() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (__DEV__) { | 
					
						
							|  |  |  |     pushWarningContext(instance) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const setupFn = isFunction(component) ? component : component.setup | 
					
						
							|  |  |  |   const setupContext = setupFn!.length > 1 ? new SetupContext(instance) : null | 
					
						
							| 
									
										
										
										
											2024-12-04 15:07:40 +08:00
										 |  |  |   const setupResult = | 
					
						
							|  |  |  |     setupFn!( | 
					
						
							|  |  |  |       instance.props, | 
					
						
							|  |  |  |       // @ts-expect-error
 | 
					
						
							|  |  |  |       setupContext, | 
					
						
							|  |  |  |     ) || EMPTY_OBJ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (__DEV__ && !isBlock(setupResult)) { | 
					
						
							|  |  |  |     if (isFunction(component)) { | 
					
						
							|  |  |  |       warn(`Functional vapor component must return a block directly.`) | 
					
						
							|  |  |  |       instance.block = [] | 
					
						
							|  |  |  |     } else if (!component.render) { | 
					
						
							|  |  |  |       warn( | 
					
						
							|  |  |  |         `Vapor component setup() returned non-block value, and has no render function.`, | 
					
						
							|  |  |  |       ) | 
					
						
							|  |  |  |       instance.block = [] | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       instance.block = component.render.call(null, setupResult) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     // in prod result can only be block
 | 
					
						
							|  |  |  |     instance.block = setupResult as Block | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // 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]) | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }) | 
					
						
							| 
									
										
										
										
											2024-12-01 16:41:51 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   if (__DEV__) { | 
					
						
							|  |  |  |     popWarningContext() | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   instance.scope.off() | 
					
						
							|  |  |  |   currentInstance = prevInstance | 
					
						
							|  |  |  |   resetTracking() | 
					
						
							|  |  |  |   return instance | 
					
						
							| 
									
										
										
										
											2024-12-01 16:41:51 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  | export let currentInstance: VaporComponentInstance | null = null | 
					
						
							| 
									
										
										
										
											2024-12-01 16:41:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  | const emptyContext: GenericAppContext = { | 
					
						
							|  |  |  |   app: null as any, | 
					
						
							|  |  |  |   config: {}, | 
					
						
							|  |  |  |   provides: /*@__PURE__*/ Object.create(null), | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-03-19 00:24:58 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  | export class VaporComponentInstance implements GenericComponentInstance { | 
					
						
							| 
									
										
										
										
											2023-11-30 02:11:21 +08:00
										 |  |  |   uid: number | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   type: VaporComponent | 
					
						
							|  |  |  |   parent: GenericComponentInstance | null | 
					
						
							|  |  |  |   appContext: GenericAppContext | 
					
						
							| 
									
										
										
										
											2024-03-16 18:54:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   block: Block | 
					
						
							| 
									
										
										
										
											2024-09-19 01:15:17 +08:00
										 |  |  |   scope: EffectScope | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   rawProps: RawProps | undefined | 
					
						
							|  |  |  |   props: Record<string, any> | 
					
						
							|  |  |  |   attrs: Record<string, any> | 
					
						
							|  |  |  |   exposed: Record<string, any> | null | 
					
						
							| 
									
										
										
										
											2023-12-10 01:33:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-04 21:18:57 +08:00
										 |  |  |   emitted: Record<string, boolean> | null | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   propsDefaults: Record<string, any> | null | 
					
						
							| 
									
										
										
										
											2023-11-30 02:11:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   // for useTemplateRef()
 | 
					
						
							|  |  |  |   refs: Record<string, any> | 
					
						
							|  |  |  |   // for provide / inject
 | 
					
						
							|  |  |  |   provides: Record<string, any> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   hasFallthrough: boolean | 
					
						
							| 
									
										
										
										
											2024-03-22 23:28:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-20 20:46:41 +08:00
										 |  |  |   isMounted: boolean | 
					
						
							|  |  |  |   isUnmounted: boolean | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   isDeactivated: boolean | 
					
						
							|  |  |  |   // LifecycleHooks.ERROR_CAPTURED
 | 
					
						
							| 
									
										
										
										
											2024-12-01 16:41:51 +08:00
										 |  |  |   ec: LifecycleHook | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   // dev only
 | 
					
						
							| 
									
										
										
										
											2024-12-04 15:07:40 +08:00
										 |  |  |   setupState?: Record<string, any> | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   propsOptions?: NormalizedPropsOptions | 
					
						
							|  |  |  |   emitsOptions?: ObjectEmitsOptions | null | 
					
						
							| 
									
										
										
										
											2023-12-10 01:33:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   constructor(comp: VaporComponent, rawProps?: RawProps) { | 
					
						
							|  |  |  |     this.uid = nextUid() | 
					
						
							|  |  |  |     this.type = comp | 
					
						
							|  |  |  |     this.parent = currentInstance | 
					
						
							|  |  |  |     this.appContext = currentInstance | 
					
						
							|  |  |  |       ? currentInstance.appContext | 
					
						
							|  |  |  |       : emptyContext | 
					
						
							| 
									
										
										
										
											2024-12-01 16:41:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |     this.block = null! // to be set
 | 
					
						
							|  |  |  |     this.scope = new EffectScope(true) | 
					
						
							| 
									
										
										
										
											2024-03-22 23:28:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |     this.rawProps = rawProps | 
					
						
							|  |  |  |     this.provides = this.refs = EMPTY_OBJ | 
					
						
							| 
									
										
										
										
											2024-12-04 23:02:15 +08:00
										 |  |  |     this.emitted = this.ec = this.exposed = this.propsDefaults = null | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |     this.isMounted = this.isUnmounted = this.isDeactivated = false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // init props
 | 
					
						
							| 
									
										
										
										
											2024-12-04 23:02:15 +08:00
										 |  |  |     const target = rawProps || EMPTY_OBJ | 
					
						
							|  |  |  |     const handlers = getPropsProxyHandlers(comp, this) | 
					
						
							|  |  |  |     this.props = comp.props ? new Proxy(target, handlers[0]!) : {} | 
					
						
							|  |  |  |     this.attrs = new Proxy(target, handlers[1]) | 
					
						
							| 
									
										
										
										
											2024-12-05 16:14:24 +08:00
										 |  |  |     this.hasFallthrough = hasFallthroughAttrs(comp, rawProps) | 
					
						
							| 
									
										
										
										
											2024-12-04 23:02:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 23:50:59 +08:00
										 |  |  |     if (__DEV__) { | 
					
						
							| 
									
										
										
										
											2024-12-05 16:14:24 +08:00
										 |  |  |       // validate props
 | 
					
						
							|  |  |  |       if (rawProps) setupPropsValidation(this) | 
					
						
							| 
									
										
										
										
											2024-12-04 23:50:59 +08:00
										 |  |  |       // cache normalized options for dev only emit check
 | 
					
						
							|  |  |  |       this.propsOptions = normalizePropsOptions(comp) | 
					
						
							|  |  |  |       this.emitsOptions = normalizeEmitsOptions(comp) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |     // TODO init slots
 | 
					
						
							| 
									
										
										
										
											2024-05-29 01:43:47 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  | export function isVaporComponent( | 
					
						
							|  |  |  |   value: unknown, | 
					
						
							|  |  |  | ): value is VaporComponentInstance { | 
					
						
							|  |  |  |   return value instanceof VaporComponentInstance | 
					
						
							| 
									
										
										
										
											2024-06-16 16:50:36 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  | export class SetupContext<E = EmitsOptions> { | 
					
						
							|  |  |  |   attrs: Record<string, any> | 
					
						
							| 
									
										
										
										
											2024-12-04 15:07:40 +08:00
										 |  |  |   emit: EmitFn<E> | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   // slots: Readonly<StaticSlots>
 | 
					
						
							|  |  |  |   expose: (exposed?: Record<string, any>) => void | 
					
						
							| 
									
										
										
										
											2024-06-16 16:50:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |   constructor(instance: VaporComponentInstance) { | 
					
						
							|  |  |  |     this.attrs = instance.attrs | 
					
						
							| 
									
										
										
										
											2024-12-04 15:07:40 +08:00
										 |  |  |     this.emit = emit.bind(null, instance) as EmitFn<E> | 
					
						
							| 
									
										
										
										
											2024-12-04 13:50:54 +08:00
										 |  |  |     // this.slots = instance.slots
 | 
					
						
							|  |  |  |     this.expose = (exposed = {}) => { | 
					
						
							|  |  |  |       instance.exposed = exposed | 
					
						
							| 
									
										
										
										
											2024-06-16 16:50:36 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |