"packageManager": "pnpm@9.12.3",
"type": "module",
"scripts": {
- "dev": "node scripts/dev.js vue vue-vapor",
+ "dev": "node scripts/dev.js vue runtime-vapor",
"build": "node scripts/build.js",
"build-dts": "tsc -p tsconfig.build.json --noCheck && rollup -c rollup.dts.config.js",
"clean": "rimraf --glob packages/*/dist temp .eslintcache",
"size": "run-s \"size-*\" && node scripts/usage-size.js",
- "size-global": "node scripts/build.js vue vue-vapor runtime-dom runtime-vapor compiler-dom -f global -p --size",
+ "size-global": "node scripts/build.js vue runtime-vapor runtime-dom runtime-vapor compiler-dom -f global -p --size",
"size-esm-runtime": "node scripts/build.js vue -f esm-bundler-runtime",
- "size-esm": "node scripts/build.js runtime-shared runtime-dom runtime-vapor runtime-core reactivity shared vue-vapor -f esm-bundler",
+ "size-esm": "node scripts/build.js runtime-shared runtime-dom runtime-vapor runtime-core reactivity shared runtime-vapor -f esm-bundler",
"check": "tsc --incremental --noEmit",
"lint": "eslint --cache .",
"format": "prettier --write --cache .",
"format-check": "prettier --check --cache .",
"test": "vitest",
"test-unit": "vitest --project unit",
- "test-e2e": "node scripts/build.js vue vue-vapor -f global -d && vitest --project e2e",
+ "test-e2e": "node scripts/build.js vue runtime-vapor -f global -d && vitest --project e2e",
"test-dts": "run-s build-dts test-dts-only",
"test-dts-only": "tsc -p packages-private/dts-built-test/tsconfig.json && tsc -p ./packages-private/dts-test/tsconfig.test.json",
"test-coverage": "vitest run --project unit --coverage",
"build-all-cjs": "node scripts/build.js vue runtime compiler reactivity shared -af cjs",
"build-runtime-esm": "node scripts/build.js runtime reactivity shared -af esm-bundler && node scripts/build.js vue -f esm-bundler-runtime && node scripts/build.js vue -f esm-browser-runtime",
"build-browser-esm": "node scripts/build.js runtime reactivity shared -af esm-bundler && node scripts/build.js vue -f esm-bundler && node scripts/build.js vue -f esm-browser",
- "build-ssr-esm": "node scripts/build.js compiler-sfc server-renderer vue-vapor -f esm-browser",
+ "build-ssr-esm": "node scripts/build.js compiler-sfc server-renderer runtime-vapor -f esm-browser",
"build-sfc-playground-self": "cd packages-private/sfc-playground && npm run build",
"preinstall": "npx only-allow pnpm",
"postinstall": "simple-git-hooks"
'vue/vapor': vapor,
},
}
- if (useVaporMode.value) vaporImportMap.imports!.vue = vapor
return mergeImportMap(vueImportMap.value, vaporImportMap)
})
--- /dev/null
+import type { VaporComponent } from './component'
+
+/*! #__NO_SIDE_EFFECTS__ */
+export function defineComponent(comp: VaporComponent): VaporComponent {
+ // TODO type inference
+ return comp
+}
[fragmentKey]: true
}
+export function isFragment(val: NonNullable<unknown>): val is Fragment {
+ return fragmentKey in val
+}
+
+export function isBlock(val: NonNullable<unknown>): val is Block {
+ return (
+ val instanceof Node ||
+ isArray(val) ||
+ isVaporComponent(val) ||
+ isFragment(val)
+ )
+}
+
/*! #__NO_SIDE_EFFECTS__ */
export function normalizeBlock(block: Block): Node[] {
const nodes: Node[] = []
type ComponentInternalOptions,
type ComponentPropsOptions,
EffectScope,
+ type EmitFn,
type EmitsOptions,
type GenericAppContext,
type GenericComponentInstance,
nextUid,
popWarningContext,
pushWarningContext,
+ warn,
} from '@vue/runtime-dom'
-import type { Block } from './block'
+import { type Block, isBlock } from './block'
import { pauseTracking, resetTracking } from '@vue/reactivity'
import { EMPTY_OBJ, isFunction } from '@vue/shared'
import {
} from './componentProps'
import { setDynamicProp } from './dom/prop'
import { renderEffect } from './renderEffect'
+import { emit } from './componentEmits'
export type VaporComponent = FunctionalVaporComponent | ObjectVaporComponent
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
+ 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
+ }
// single root, inherit attrs
if (
ec: LifecycleHook
// dev only
+ setupState?: Record<string, any>
propsOptions?: NormalizedPropsOptions
emitsOptions?: ObjectEmitsOptions | null
export class SetupContext<E = EmitsOptions> {
attrs: Record<string, any>
- // emit: EmitFn<E>
+ emit: EmitFn<E>
// slots: Readonly<StaticSlots>
expose: (exposed?: Record<string, any>) => void
constructor(instance: VaporComponentInstance) {
this.attrs = instance.attrs
- // this.emit = instance.emit as EmitFn<E>
+ this.emit = emit.bind(null, instance) as EmitFn<E>
// this.slots = instance.slots
this.expose = (exposed = {}) => {
instance.exposed = exposed
-import {
- type EmitFn,
- type ObjectEmitsOptions,
- baseEmit,
-} from '@vue/runtime-dom'
-import {
- type VaporComponent,
- type VaporComponentInstance,
- currentInstance,
-} from './component'
-import { EMPTY_OBJ, NOOP, hasOwn, isArray } from '@vue/shared'
+import { type ObjectEmitsOptions, baseEmit } from '@vue/runtime-dom'
+import type { VaporComponent, VaporComponentInstance } from './component'
+import { EMPTY_OBJ, hasOwn, isArray } from '@vue/shared'
import { resolveSource } from './componentProps'
/**
return (comp.__emitsOptions = normalized)
}
-export function useEmit(): EmitFn {
- if (!currentInstance) {
- // TODO warn
- return NOOP
- } else {
- return emit.bind(null, currentInstance)
- }
-}
-
export function emit(
instance: VaporComponentInstance,
event: string,
export { createComponent } from './component'
export { renderEffect } from './renderEffect'
export { createVaporApp } from './apiCreateApp'
-export { useEmit } from './componentEmits'
+export { defineComponent } from './apiDefineComponent'
// DOM
export { template, children, next } from './dom/template'