mirror of https://github.com/vuejs/core.git
chore: Merge branch 'edison/feat/vaporTeleport' into edison/testVapor
This commit is contained in:
commit
fd2e46bf64
|
@ -0,0 +1,62 @@
|
|||
import path from 'node:path'
|
||||
import {
|
||||
E2E_TIMEOUT,
|
||||
setupPuppeteer,
|
||||
} from '../../../packages/vue/__tests__/e2e/e2eUtils'
|
||||
import connect from 'connect'
|
||||
import sirv from 'sirv'
|
||||
import { nextTick } from 'vue'
|
||||
import { ports } from '../utils'
|
||||
const { page, click, html } = setupPuppeteer()
|
||||
|
||||
describe('vapor teleport', () => {
|
||||
let server: any
|
||||
const port = ports.teleport
|
||||
beforeAll(() => {
|
||||
server = connect()
|
||||
.use(sirv(path.resolve(import.meta.dirname, '../dist')))
|
||||
.listen(port)
|
||||
process.on('SIGTERM', () => server && server.close())
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
server.close()
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
const baseUrl = `http://localhost:${port}/teleport/`
|
||||
await page().goto(baseUrl)
|
||||
await page().waitForSelector('#app')
|
||||
})
|
||||
|
||||
test(
|
||||
'render vdom component',
|
||||
async () => {
|
||||
const targetSelector = '.target'
|
||||
const testSelector = '.interop-render-vdom-comp'
|
||||
const containerSelector = `${testSelector} > div`
|
||||
const btnSelector = `${testSelector} > button`
|
||||
|
||||
const tt = await html('#app')
|
||||
console.log(tt)
|
||||
|
||||
// teleport is disabled
|
||||
expect(await html(containerSelector)).toBe('<h1>vdom comp</h1>')
|
||||
expect(await html(targetSelector)).toBe('')
|
||||
|
||||
// enable teleport
|
||||
await click(btnSelector)
|
||||
await nextTick()
|
||||
|
||||
expect(await html(containerSelector)).toBe('')
|
||||
expect(await html(targetSelector)).toBe('<h1>vdom comp</h1>')
|
||||
|
||||
// disable teleport
|
||||
await click(btnSelector)
|
||||
await nextTick()
|
||||
expect(await html(containerSelector)).toBe('<h1>vdom comp</h1>')
|
||||
expect(await html(targetSelector)).toBe('')
|
||||
},
|
||||
E2E_TIMEOUT,
|
||||
)
|
||||
})
|
|
@ -5,6 +5,7 @@ import {
|
|||
} from '../../../packages/vue/__tests__/e2e/e2eUtils'
|
||||
import connect from 'connect'
|
||||
import sirv from 'sirv'
|
||||
import { ports } from '../utils'
|
||||
|
||||
describe('e2e: todomvc', () => {
|
||||
const {
|
||||
|
@ -23,7 +24,7 @@ describe('e2e: todomvc', () => {
|
|||
} = setupPuppeteer()
|
||||
|
||||
let server: any
|
||||
const port = '8194'
|
||||
const port = ports.todomvc
|
||||
beforeAll(() => {
|
||||
server = connect()
|
||||
.use(sirv(path.resolve(import.meta.dirname, '../dist')))
|
||||
|
|
|
@ -7,6 +7,7 @@ import connect from 'connect'
|
|||
import sirv from 'sirv'
|
||||
import { expect } from 'vitest'
|
||||
const { page, nextFrame, timeout, html, transitionStart } = setupPuppeteer()
|
||||
import { ports } from '../utils'
|
||||
|
||||
const duration = process.env.CI ? 200 : 50
|
||||
const buffer = process.env.CI ? 50 : 20
|
||||
|
@ -14,7 +15,7 @@ const transitionFinish = (time = duration) => timeout(time + buffer)
|
|||
|
||||
describe('vapor transition-group', () => {
|
||||
let server: any
|
||||
const port = '8196'
|
||||
const port = ports.transitionGroup
|
||||
beforeAll(() => {
|
||||
server = connect()
|
||||
.use(sirv(path.resolve(import.meta.dirname, '../dist')))
|
||||
|
|
|
@ -19,6 +19,7 @@ const {
|
|||
waitForElement,
|
||||
click,
|
||||
} = setupPuppeteer()
|
||||
import { ports } from '../utils'
|
||||
|
||||
const duration = process.env.CI ? 200 : 50
|
||||
const buffer = process.env.CI ? 50 : 20
|
||||
|
@ -26,7 +27,7 @@ const transitionFinish = (time = duration) => timeout(time + buffer)
|
|||
|
||||
describe('vapor transition', () => {
|
||||
let server: any
|
||||
const port = '8195'
|
||||
const port = ports.transition
|
||||
beforeAll(() => {
|
||||
server = connect()
|
||||
.use(sirv(path.resolve(import.meta.dirname, '../dist')))
|
||||
|
|
|
@ -21,9 +21,12 @@ const duration = process.env.CI ? 200 : 50
|
|||
const buffer = process.env.CI ? 50 : 20
|
||||
const transitionFinish = (time = duration) => timeout(time + buffer)
|
||||
|
||||
import { ports } from '../utils'
|
||||
import { nextTick } from 'vue'
|
||||
|
||||
describe('vdom / vapor interop', () => {
|
||||
let server: any
|
||||
const port = '8193'
|
||||
const port = ports.vdomInterop
|
||||
beforeAll(() => {
|
||||
server = connect()
|
||||
.use(sirv(path.resolve(import.meta.dirname, '../dist')))
|
||||
|
@ -31,6 +34,12 @@ describe('vdom / vapor interop', () => {
|
|||
process.on('SIGTERM', () => server && server.close())
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
const baseUrl = `http://localhost:${port}/interop/`
|
||||
await page().goto(baseUrl)
|
||||
await page().waitForSelector('#app')
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
server.close()
|
||||
})
|
||||
|
@ -255,5 +264,33 @@ describe('vdom / vapor interop', () => {
|
|||
},
|
||||
E2E_TIMEOUT,
|
||||
)
|
||||
describe('teleport', () => {
|
||||
const testSelector = '.teleport'
|
||||
test('render vapor component', async () => {
|
||||
const targetSelector = `${testSelector} .teleport-target`
|
||||
const containerSelector = `${testSelector} .render-vapor-comp`
|
||||
const buttonSelector = `${containerSelector} button`
|
||||
|
||||
// teleport is disabled by default
|
||||
expect(await html(containerSelector)).toBe(
|
||||
`<button>toggle</button><div>vapor comp</div>`,
|
||||
)
|
||||
expect(await html(targetSelector)).toBe('')
|
||||
|
||||
// disabled -> enabled
|
||||
await click(buttonSelector)
|
||||
await nextTick()
|
||||
expect(await html(containerSelector)).toBe(`<button>toggle</button>`)
|
||||
expect(await html(targetSelector)).toBe('<div>vapor comp</div>')
|
||||
|
||||
// enabled -> disabled
|
||||
await click(buttonSelector)
|
||||
await nextTick()
|
||||
expect(await html(containerSelector)).toBe(
|
||||
`<button>toggle</button><div>vapor comp</div>`,
|
||||
)
|
||||
expect(await html(targetSelector)).toBe('')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<a href="/todomvc/">Vapor TodoMVC</a>
|
||||
<a href="/transition/">Vapor Transition</a>
|
||||
<a href="/transition-group/">Vapor TransitionGroup</a>
|
||||
<a href="/teleport/">Vapor Teleport</a>
|
||||
|
||||
<style>
|
||||
a {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, shallowRef } from 'vue'
|
||||
import VaporComp from './VaporComp.vue'
|
||||
import VaporComp from './components/VaporComp.vue'
|
||||
import VaporCompA from '../transition/components/VaporCompA.vue'
|
||||
import VdomComp from '../transition/components/VdomComp.vue'
|
||||
import VaporSlot from '../transition/components/VaporSlot.vue'
|
||||
|
@ -17,6 +17,9 @@ function toggleInteropComponent() {
|
|||
|
||||
const items = ref(['a', 'b', 'c'])
|
||||
const enterClick = () => items.value.push('d', 'e')
|
||||
import SimpleVaporComp from './components/SimpleVaporComp.vue'
|
||||
|
||||
const disabled = ref(true)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -69,4 +72,15 @@ const enterClick = () => items.value.push('d', 'e')
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- teleport -->
|
||||
<div class="teleport">
|
||||
<div class="teleport-target"></div>
|
||||
<div class="render-vapor-comp">
|
||||
<button @click="disabled = !disabled">toggle</button>
|
||||
<Teleport to=".teleport-target" defer :disabled="disabled">
|
||||
<SimpleVaporComp />
|
||||
</Teleport>
|
||||
</div>
|
||||
</div>
|
||||
<!-- teleport end-->
|
||||
</template>
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<script setup vapor lang="ts">
|
||||
const msg = 'vapor comp'
|
||||
</script>
|
||||
<template>
|
||||
<div>{{ msg }}</div>
|
||||
</template>
|
|
@ -0,0 +1,17 @@
|
|||
<script setup vapor>
|
||||
import { ref, Teleport } from 'vue'
|
||||
import VdomComp from './components/VdomComp.vue'
|
||||
const disabled = ref(true)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="target"></div>
|
||||
<div class="interop-render-vdom-comp">
|
||||
<button @click="disabled = !disabled">toggle</button>
|
||||
<div>
|
||||
<Teleport to=".target" defer :disabled>
|
||||
<VdomComp />
|
||||
</Teleport>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
const msg = 'vdom comp'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>{{ msg }}</h1>
|
||||
</template>
|
|
@ -0,0 +1,2 @@
|
|||
<script type="module" src="./main.ts"></script>
|
||||
<div id="app"></div>
|
|
@ -0,0 +1,5 @@
|
|||
import { createVaporApp, vaporInteropPlugin } from 'vue'
|
||||
import App from './App.vue'
|
||||
import 'todomvc-app-css/index.css'
|
||||
|
||||
createVaporApp(App).use(vaporInteropPlugin).mount('#app')
|
|
@ -0,0 +1,8 @@
|
|||
// make sure these ports are unique
|
||||
export const ports = {
|
||||
vdomInterop: 8193,
|
||||
todomvc: 8194,
|
||||
transition: 8195,
|
||||
transitionGroup: 8196,
|
||||
teleport: 8197,
|
||||
}
|
|
@ -14,6 +14,7 @@ export default defineConfig({
|
|||
input: {
|
||||
interop: resolve(import.meta.dirname, 'interop/index.html'),
|
||||
todomvc: resolve(import.meta.dirname, 'todomvc/index.html'),
|
||||
teleport: resolve(import.meta.dirname, 'teleport/index.html'),
|
||||
transition: resolve(import.meta.dirname, 'transition/index.html'),
|
||||
transitionGroup: resolve(
|
||||
import.meta.dirname,
|
||||
|
|
|
@ -39,7 +39,6 @@ import { genEventHandler } from './event'
|
|||
import { genDirectiveModifiers, genDirectivesForElement } from './directive'
|
||||
import { genBlock } from './block'
|
||||
import { genModelHandler } from './vModel'
|
||||
|
||||
import { isBuiltInComponent } from '../utils'
|
||||
|
||||
export function genCreateComponent(
|
||||
|
|
|
@ -115,10 +115,17 @@ export function isTransitionGroupTag(tag: string): boolean {
|
|||
return tag === 'transitiongroup' || tag === 'vaportransitiongroup'
|
||||
}
|
||||
|
||||
export function isTeleportTag(tag: string): boolean {
|
||||
tag = tag.toLowerCase()
|
||||
return tag === 'teleport' || tag === 'vaporteleport'
|
||||
}
|
||||
|
||||
export function isBuiltInComponent(tag: string): string | undefined {
|
||||
if (isTransitionTag(tag)) {
|
||||
return 'VaporTransition'
|
||||
} else if (isTransitionGroupTag(tag)) {
|
||||
return 'VaporTransitionGroup'
|
||||
} else if (isTeleportTag(tag)) {
|
||||
return 'VaporTeleport'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,10 @@ export const TeleportEndKey: unique symbol = Symbol('_vte')
|
|||
|
||||
export const isTeleport = (type: any): boolean => type.__isTeleport
|
||||
|
||||
const isTeleportDisabled = (props: VNode['props']): boolean =>
|
||||
export const isTeleportDisabled = (props: VNode['props']): boolean =>
|
||||
props && (props.disabled || props.disabled === '')
|
||||
|
||||
const isTeleportDeferred = (props: VNode['props']): boolean =>
|
||||
export const isTeleportDeferred = (props: VNode['props']): boolean =>
|
||||
props && (props.defer || props.defer === '')
|
||||
|
||||
const isTargetSVG = (target: RendererElement): boolean =>
|
||||
|
@ -39,7 +39,7 @@ const isTargetSVG = (target: RendererElement): boolean =>
|
|||
const isTargetMathML = (target: RendererElement): boolean =>
|
||||
typeof MathMLElement === 'function' && target instanceof MathMLElement
|
||||
|
||||
const resolveTarget = <T = RendererElement>(
|
||||
export const resolveTarget = <T = RendererElement>(
|
||||
props: TeleportProps | null,
|
||||
select: RendererOptions['querySelector'],
|
||||
): T | null => {
|
||||
|
|
|
@ -119,7 +119,7 @@ function reload(id: string, newComp: HMRComponent): void {
|
|||
// create a snapshot which avoids the set being mutated during updates
|
||||
const instances = [...record.instances]
|
||||
|
||||
if (newComp.vapor) {
|
||||
if (newComp.__vapor) {
|
||||
for (const instance of instances) {
|
||||
instance.hmrReload!(newComp)
|
||||
}
|
||||
|
|
|
@ -574,6 +574,14 @@ export { performTransitionEnter, performTransitionLeave } from './renderer'
|
|||
* @internal
|
||||
*/
|
||||
export { ensureVaporSlotFallback } from './helpers/renderSlot'
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export {
|
||||
resolveTarget as resolveTeleportTarget,
|
||||
isTeleportDisabled,
|
||||
isTeleportDeferred,
|
||||
} from './components/Teleport'
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
import {
|
||||
VaporFragment,
|
||||
insert,
|
||||
normalizeBlock,
|
||||
prepend,
|
||||
remove,
|
||||
} from '../src/block'
|
||||
import { insert, normalizeBlock, prepend, remove } from '../src/block'
|
||||
import { VaporFragment } from '../src/fragment'
|
||||
|
||||
const node1 = document.createTextNode('node1')
|
||||
const node2 = document.createTextNode('node2')
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
import { currentInstance, resolveDynamicComponent } from '@vue/runtime-dom'
|
||||
import { DynamicFragment, type VaporFragment, insert } from './block'
|
||||
import { insert } from './block'
|
||||
import { createComponentWithFallback, emptyContext } from './component'
|
||||
import { renderEffect } from './renderEffect'
|
||||
import type { RawProps } from './componentProps'
|
||||
|
@ -11,6 +11,7 @@ import {
|
|||
} from './insertionState'
|
||||
import { DYNAMIC_COMPONENT_ANCHOR_LABEL } from '@vue/shared'
|
||||
import { isHydrating, locateHydrationNode } from './dom/hydration'
|
||||
import { DynamicFragment, type VaporFragment } from './fragment'
|
||||
|
||||
export function createDynamicComponent(
|
||||
getter: () => any,
|
||||
|
|
|
@ -19,12 +19,7 @@ import {
|
|||
isString,
|
||||
} from '@vue/shared'
|
||||
import { createComment, createTextNode } from './dom/node'
|
||||
import {
|
||||
type Block,
|
||||
VaporFragment,
|
||||
insert,
|
||||
remove as removeBlock,
|
||||
} from './block'
|
||||
import { type Block, insert, remove as removeBlock } from './block'
|
||||
import { warn } from '@vue/runtime-dom'
|
||||
import { currentInstance, isVaporComponent } from './component'
|
||||
import type { DynamicSlot } from './componentSlots'
|
||||
|
@ -37,6 +32,7 @@ import {
|
|||
locateHydrationNode,
|
||||
locateVaporFragmentAnchor,
|
||||
} from './dom/hydration'
|
||||
import { VaporFragment } from './fragment'
|
||||
import {
|
||||
insertionAnchor,
|
||||
insertionParent,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { type Block, type BlockFn, DynamicFragment } from './block'
|
||||
import type { Block, BlockFn } from './block'
|
||||
import { DynamicFragment } from './fragment'
|
||||
import { renderEffect } from './renderEffect'
|
||||
|
||||
export function createKeyedFragment(key: () => any, render: BlockFn): Block {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { IF_ANCHOR_LABEL } from '@vue/shared'
|
||||
import { type Block, type BlockFn, DynamicFragment, insert } from './block'
|
||||
import { type Block, type BlockFn, insert } from './block'
|
||||
import { isHydrating, locateHydrationNode } from './dom/hydration'
|
||||
import {
|
||||
insertionAnchor,
|
||||
|
@ -7,6 +7,7 @@ import {
|
|||
resetInsertionState,
|
||||
} from './insertionState'
|
||||
import { renderEffect } from './renderEffect'
|
||||
import { DynamicFragment } from './fragment'
|
||||
|
||||
export function createIf(
|
||||
condition: () => any,
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
isString,
|
||||
remove,
|
||||
} from '@vue/shared'
|
||||
import { DynamicFragment } from './block'
|
||||
import { DynamicFragment } from './fragment'
|
||||
|
||||
export type NodeRef = string | Ref | ((ref: Element) => void)
|
||||
export type RefEl = Element | VaporComponentInstance
|
||||
|
|
|
@ -5,14 +5,6 @@ import {
|
|||
mountComponent,
|
||||
unmountComponent,
|
||||
} from './component'
|
||||
import { createComment, createTextNode } from './dom/node'
|
||||
import { EffectScope, pauseTracking, resetTracking } from '@vue/reactivity'
|
||||
import {
|
||||
currentHydrationNode,
|
||||
isComment,
|
||||
locateHydrationNode,
|
||||
locateVaporFragmentAnchor,
|
||||
} from './dom/hydration'
|
||||
import {
|
||||
type TransitionHooks,
|
||||
type TransitionProps,
|
||||
|
@ -20,17 +12,18 @@ import {
|
|||
performTransitionEnter,
|
||||
performTransitionLeave,
|
||||
} from '@vue/runtime-dom'
|
||||
import { isHydrating } from './dom/hydration'
|
||||
import { getInheritedScopeIds } from '@vue/runtime-dom'
|
||||
import {
|
||||
applyTransitionHooks,
|
||||
applyTransitionLeaveHooks,
|
||||
} from './components/Transition'
|
||||
type DynamicFragment,
|
||||
type VaporFragment,
|
||||
isFragment,
|
||||
} from './fragment'
|
||||
|
||||
export interface TransitionOptions {
|
||||
$key?: any
|
||||
$transition?: VaporTransitionHooks
|
||||
}
|
||||
import { isHydrating } from './dom/hydration'
|
||||
import { getInheritedScopeIds } from '@vue/runtime-dom'
|
||||
|
||||
export interface VaporTransitionHooks extends TransitionHooks {
|
||||
state: TransitionState
|
||||
|
@ -50,119 +43,6 @@ export type Block = TransitionBlock | VaporComponentInstance | Block[]
|
|||
|
||||
export type BlockFn = (...args: any[]) => Block
|
||||
|
||||
export class VaporFragment implements TransitionOptions {
|
||||
$key?: any
|
||||
$transition?: VaporTransitionHooks | undefined
|
||||
nodes: Block
|
||||
anchor?: Node
|
||||
insert?: (
|
||||
parent: ParentNode,
|
||||
anchor: Node | null,
|
||||
transitionHooks?: TransitionHooks,
|
||||
) => void
|
||||
remove?: (parent?: ParentNode, transitionHooks?: TransitionHooks) => void
|
||||
fallback?: BlockFn
|
||||
|
||||
constructor(nodes: Block) {
|
||||
this.nodes = nodes
|
||||
}
|
||||
}
|
||||
|
||||
export class DynamicFragment extends VaporFragment {
|
||||
anchor!: Node
|
||||
scope: EffectScope | undefined
|
||||
current?: BlockFn
|
||||
fallback?: BlockFn
|
||||
/**
|
||||
* slot only
|
||||
* indicates forwarded slot
|
||||
*/
|
||||
forwarded?: boolean
|
||||
|
||||
constructor(anchorLabel?: string) {
|
||||
super([])
|
||||
if (isHydrating) {
|
||||
locateHydrationNode(true)
|
||||
this.hydrate(anchorLabel!)
|
||||
} else {
|
||||
this.anchor =
|
||||
__DEV__ && anchorLabel ? createComment(anchorLabel) : createTextNode()
|
||||
}
|
||||
}
|
||||
|
||||
update(render?: BlockFn, key: any = render): void {
|
||||
if (key === this.current) {
|
||||
return
|
||||
}
|
||||
this.current = key
|
||||
|
||||
pauseTracking()
|
||||
const parent = this.anchor.parentNode
|
||||
const transition = this.$transition
|
||||
const renderBranch = () => {
|
||||
if (render) {
|
||||
this.scope = new EffectScope()
|
||||
this.nodes = this.scope.run(render) || []
|
||||
if (transition) {
|
||||
this.$transition = applyTransitionHooks(this.nodes, transition)
|
||||
}
|
||||
if (parent) insert(this.nodes, parent, this.anchor)
|
||||
} else {
|
||||
this.scope = undefined
|
||||
this.nodes = []
|
||||
}
|
||||
}
|
||||
|
||||
// teardown previous branch
|
||||
if (this.scope) {
|
||||
this.scope.stop()
|
||||
const mode = transition && transition.mode
|
||||
if (mode) {
|
||||
applyTransitionLeaveHooks(this.nodes, transition, renderBranch)
|
||||
parent && remove(this.nodes, parent)
|
||||
if (mode === 'out-in') {
|
||||
resetTracking()
|
||||
return
|
||||
}
|
||||
} else {
|
||||
parent && remove(this.nodes, parent)
|
||||
}
|
||||
}
|
||||
|
||||
renderBranch()
|
||||
|
||||
if (this.fallback && !isValidBlock(this.nodes)) {
|
||||
parent && remove(this.nodes, parent)
|
||||
this.nodes =
|
||||
(this.scope || (this.scope = new EffectScope())).run(this.fallback) ||
|
||||
[]
|
||||
parent && insert(this.nodes, parent, this.anchor)
|
||||
}
|
||||
|
||||
resetTracking()
|
||||
}
|
||||
|
||||
hydrate(label: string): void {
|
||||
// for `v-if="false"` the node will be an empty comment, use it as the anchor.
|
||||
// otherwise, find next sibling vapor fragment anchor
|
||||
if (isComment(currentHydrationNode!, '')) {
|
||||
this.anchor = currentHydrationNode
|
||||
} else {
|
||||
const anchor = locateVaporFragmentAnchor(currentHydrationNode!, label)!
|
||||
if (anchor) {
|
||||
this.anchor = anchor
|
||||
} else if (__DEV__) {
|
||||
// this should not happen
|
||||
throw new Error(`${label} fragment anchor node was not found.`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function isFragment(val: NonNullable<unknown>): val is VaporFragment {
|
||||
return val instanceof VaporFragment
|
||||
}
|
||||
|
||||
export function isBlock(val: NonNullable<unknown>): val is Block {
|
||||
return (
|
||||
val instanceof Node ||
|
||||
|
@ -229,7 +109,12 @@ export function insert(
|
|||
if (block.insert) {
|
||||
block.insert(parent, anchor, (block as TransitionBlock).$transition)
|
||||
} else {
|
||||
insert(block.nodes, parent, anchor, parentSuspense)
|
||||
insert(
|
||||
block.nodes,
|
||||
block.target || parent,
|
||||
block.targetAnchor || anchor,
|
||||
parentSuspense,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -288,8 +173,12 @@ export function normalizeBlock(block: Block): Node[] {
|
|||
block.forEach(child => nodes.push(...normalizeBlock(child)))
|
||||
} else if (isVaporComponent(block)) {
|
||||
nodes.push(...normalizeBlock(block.block!))
|
||||
} else {
|
||||
if (block.getNodes) {
|
||||
nodes.push(...normalizeBlock(block.getNodes()))
|
||||
} else {
|
||||
nodes.push(...normalizeBlock(block.nodes))
|
||||
}
|
||||
block.anchor && nodes.push(block.anchor)
|
||||
}
|
||||
return nodes
|
||||
|
|
|
@ -27,7 +27,6 @@ import {
|
|||
} from '@vue/runtime-dom'
|
||||
import {
|
||||
type Block,
|
||||
DynamicFragment,
|
||||
insert,
|
||||
isBlock,
|
||||
remove,
|
||||
|
@ -68,11 +67,13 @@ import {
|
|||
import { hmrReload, hmrRerender } from './hmr'
|
||||
import { createElement } from './dom/node'
|
||||
import { isHydrating, locateHydrationNode } from './dom/hydration'
|
||||
import { isVaporTeleport } from './components/Teleport'
|
||||
import {
|
||||
insertionAnchor,
|
||||
insertionParent,
|
||||
resetInsertionState,
|
||||
} from './insertionState'
|
||||
import { DynamicFragment } from './fragment'
|
||||
|
||||
export { currentInstance } from '@vue/runtime-dom'
|
||||
|
||||
|
@ -177,6 +178,18 @@ export function createComponent(
|
|||
return frag
|
||||
}
|
||||
|
||||
// teleport
|
||||
if (isVaporTeleport(component)) {
|
||||
const frag = component.process(rawProps!, rawSlots!)
|
||||
if (!isHydrating && _insertionParent) {
|
||||
insert(frag, _insertionParent, _insertionAnchor)
|
||||
} else {
|
||||
frag.hydrate()
|
||||
}
|
||||
|
||||
return frag as any
|
||||
}
|
||||
|
||||
if (
|
||||
isSingleRoot &&
|
||||
component.inheritAttrs !== false &&
|
||||
|
@ -398,6 +411,7 @@ export class VaporComponentInstance implements GenericComponentInstance {
|
|||
setupState?: Record<string, any>
|
||||
devtoolsRawSetupState?: any
|
||||
hmrRerender?: () => void
|
||||
hmrRerenderEffects?: (() => void)[]
|
||||
hmrReload?: (newComp: VaporComponent) => void
|
||||
propsOptions?: NormalizedPropsOptions
|
||||
emitsOptions?: ObjectEmitsOptions | null
|
||||
|
|
|
@ -6,15 +6,7 @@ import {
|
|||
isArray,
|
||||
isFunction,
|
||||
} from '@vue/shared'
|
||||
import {
|
||||
type Block,
|
||||
type BlockFn,
|
||||
DynamicFragment,
|
||||
type VaporFragment,
|
||||
insert,
|
||||
isFragment,
|
||||
setScopeId,
|
||||
} from './block'
|
||||
import { type Block, type BlockFn, insert, setScopeId } from './block'
|
||||
import { rawPropsProxyHandlers } from './componentProps'
|
||||
import { currentInstance, isRef } from '@vue/runtime-dom'
|
||||
import type { LooseRawProps, VaporComponentInstance } from './component'
|
||||
|
@ -25,6 +17,7 @@ import {
|
|||
resetInsertionState,
|
||||
} from './insertionState'
|
||||
import { isHydrating, locateHydrationNode } from './dom/hydration'
|
||||
import { DynamicFragment, type VaporFragment, isFragment } from './fragment'
|
||||
|
||||
export type RawSlots = Record<string, VaporSlot> & {
|
||||
$?: DynamicSlotSource[]
|
||||
|
|
|
@ -0,0 +1,243 @@
|
|||
import {
|
||||
type TeleportProps,
|
||||
currentInstance,
|
||||
isTeleportDeferred,
|
||||
isTeleportDisabled,
|
||||
queuePostFlushCb,
|
||||
resolveTeleportTarget,
|
||||
warn,
|
||||
} from '@vue/runtime-dom'
|
||||
import { type Block, type BlockFn, insert, remove } from '../block'
|
||||
import { createComment, createTextNode, querySelector } from '../dom/node'
|
||||
import {
|
||||
type LooseRawProps,
|
||||
type LooseRawSlots,
|
||||
type VaporComponentInstance,
|
||||
isVaporComponent,
|
||||
} from '../component'
|
||||
import { rawPropsProxyHandlers } from '../componentProps'
|
||||
import { renderEffect } from '../renderEffect'
|
||||
import { extend, isArray } from '@vue/shared'
|
||||
import { VaporFragment } from '../fragment'
|
||||
|
||||
const instanceToTeleportMap: WeakMap<VaporComponentInstance, TeleportFragment> =
|
||||
__DEV__ ? new WeakMap() : (undefined as any)
|
||||
|
||||
export const VaporTeleportImpl = {
|
||||
name: 'VaporTeleport',
|
||||
__isTeleport: true,
|
||||
__vapor: true,
|
||||
|
||||
process(props: LooseRawProps, slots: LooseRawSlots): TeleportFragment {
|
||||
const frag = new TeleportFragment()
|
||||
const updateChildrenEffect = renderEffect(() =>
|
||||
frag.updateChildren(slots.default && (slots.default as BlockFn)()),
|
||||
)
|
||||
|
||||
const updateEffect = renderEffect(() => {
|
||||
frag.update(
|
||||
// access the props to trigger tracking
|
||||
extend(
|
||||
{},
|
||||
new Proxy(props, rawPropsProxyHandlers) as any as TeleportProps,
|
||||
),
|
||||
)
|
||||
})
|
||||
|
||||
if (__DEV__) {
|
||||
// used in `normalizeBlock` to get nodes of TeleportFragment during
|
||||
// HMR updates. returns empty array if content is mounted in target
|
||||
// container to prevent incorrect parent node lookup.
|
||||
frag.getNodes = () => {
|
||||
return frag.parent !== frag.currentParent ? [] : frag.nodes
|
||||
}
|
||||
|
||||
// for HMR rerender
|
||||
const instance = currentInstance as VaporComponentInstance
|
||||
;(
|
||||
instance!.hmrRerenderEffects || (instance!.hmrRerenderEffects = [])
|
||||
).push(() => {
|
||||
// remove the teleport content
|
||||
frag.remove()
|
||||
|
||||
// stop effects
|
||||
updateChildrenEffect.stop()
|
||||
updateEffect.stop()
|
||||
})
|
||||
|
||||
// for HMR reload
|
||||
const nodes = frag.nodes
|
||||
if (isVaporComponent(nodes)) {
|
||||
instanceToTeleportMap.set(nodes, frag)
|
||||
} else if (isArray(nodes)) {
|
||||
nodes.forEach(
|
||||
node =>
|
||||
isVaporComponent(node) && instanceToTeleportMap.set(node, frag),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return frag
|
||||
},
|
||||
}
|
||||
|
||||
export class TeleportFragment extends VaporFragment {
|
||||
anchor: Node
|
||||
|
||||
private targetStart?: Node
|
||||
private mainAnchor?: Node
|
||||
private placeholder?: Node
|
||||
private mountContainer?: ParentNode | null
|
||||
private mountAnchor?: Node | null
|
||||
|
||||
constructor() {
|
||||
super([])
|
||||
this.anchor = __DEV__ ? createComment('teleport') : createTextNode()
|
||||
}
|
||||
|
||||
get currentParent(): ParentNode {
|
||||
return (this.mountContainer || this.parent)!
|
||||
}
|
||||
|
||||
get currentAnchor(): Node | null {
|
||||
return this.mountAnchor || this.anchor
|
||||
}
|
||||
|
||||
get parent(): ParentNode | null {
|
||||
return this.anchor.parentNode
|
||||
}
|
||||
|
||||
updateChildren(children: Block): void {
|
||||
// not mounted yet
|
||||
if (!this.parent) {
|
||||
this.nodes = children
|
||||
return
|
||||
}
|
||||
|
||||
// teardown previous nodes
|
||||
remove(this.nodes, this.currentParent)
|
||||
// mount new nodes
|
||||
insert((this.nodes = children), this.currentParent, this.currentAnchor)
|
||||
}
|
||||
|
||||
update(props: TeleportProps): void {
|
||||
const mount = (parent: ParentNode, anchor: Node | null) => {
|
||||
insert(
|
||||
this.nodes,
|
||||
(this.mountContainer = parent),
|
||||
(this.mountAnchor = anchor),
|
||||
)
|
||||
}
|
||||
|
||||
const mountToTarget = () => {
|
||||
const target = (this.target = resolveTeleportTarget(props, querySelector))
|
||||
if (target) {
|
||||
if (
|
||||
// initial mount into target
|
||||
!this.targetAnchor ||
|
||||
// target changed
|
||||
this.targetAnchor.parentNode !== target
|
||||
) {
|
||||
insert((this.targetStart = createTextNode('')), target)
|
||||
insert((this.targetAnchor = createTextNode('')), target)
|
||||
}
|
||||
|
||||
mount(target, this.targetAnchor!)
|
||||
} else if (__DEV__) {
|
||||
warn(
|
||||
`Invalid Teleport target on ${this.targetAnchor ? 'update' : 'mount'}:`,
|
||||
target,
|
||||
`(${typeof target})`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// mount into main container
|
||||
if (isTeleportDisabled(props)) {
|
||||
if (this.parent) {
|
||||
if (!this.mainAnchor) {
|
||||
this.mainAnchor = __DEV__
|
||||
? createComment('teleport end')
|
||||
: createTextNode()
|
||||
}
|
||||
if (!this.placeholder) {
|
||||
this.placeholder = __DEV__
|
||||
? createComment('teleport start')
|
||||
: createTextNode()
|
||||
}
|
||||
if (!this.mainAnchor.isConnected) {
|
||||
insert(this.placeholder, this.parent, this.anchor)
|
||||
insert(this.mainAnchor, this.parent, this.anchor)
|
||||
}
|
||||
|
||||
mount(this.parent, this.mainAnchor)
|
||||
}
|
||||
}
|
||||
// mount into target container
|
||||
else {
|
||||
if (isTeleportDeferred(props)) {
|
||||
queuePostFlushCb(mountToTarget)
|
||||
} else {
|
||||
mountToTarget()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
remove = (parent: ParentNode | undefined = this.parent!): void => {
|
||||
// remove nodes
|
||||
if (this.nodes) {
|
||||
remove(this.nodes, this.currentParent)
|
||||
this.nodes = []
|
||||
}
|
||||
|
||||
// remove anchors
|
||||
if (this.targetStart) {
|
||||
remove(this.targetStart!, this.target!)
|
||||
this.targetStart = undefined
|
||||
remove(this.targetAnchor!, this.target!)
|
||||
this.targetAnchor = undefined
|
||||
}
|
||||
|
||||
if (this.placeholder) {
|
||||
remove(this.placeholder!, parent)
|
||||
this.placeholder = undefined
|
||||
remove(this.mainAnchor!, parent)
|
||||
this.mainAnchor = undefined
|
||||
}
|
||||
|
||||
this.mountContainer = undefined
|
||||
this.mountAnchor = undefined
|
||||
}
|
||||
|
||||
hydrate(): void {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
export function isVaporTeleport(
|
||||
value: unknown,
|
||||
): value is typeof VaporTeleportImpl {
|
||||
return value === VaporTeleportImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* dev only
|
||||
* during root component HMR reload, since the old component will be unmounted
|
||||
* and a new one will be mounted, we need to update the teleport's nodes
|
||||
* to ensure they are up to date.
|
||||
*/
|
||||
export function handleTeleportRootComponentHmrReload(
|
||||
instance: VaporComponentInstance,
|
||||
newInstance: VaporComponentInstance,
|
||||
): void {
|
||||
const teleport = instanceToTeleportMap.get(instance)
|
||||
if (teleport) {
|
||||
instanceToTeleportMap.set(newInstance, teleport)
|
||||
if (teleport.nodes === instance) {
|
||||
teleport.nodes = newInstance
|
||||
} else if (isArray(teleport.nodes)) {
|
||||
const i = teleport.nodes.indexOf(instance)
|
||||
if (i !== -1) teleport.nodes[i] = newInstance
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,12 +14,7 @@ import {
|
|||
useTransitionState,
|
||||
warn,
|
||||
} from '@vue/runtime-dom'
|
||||
import {
|
||||
type Block,
|
||||
type TransitionBlock,
|
||||
type VaporTransitionHooks,
|
||||
isFragment,
|
||||
} from '../block'
|
||||
import type { Block, TransitionBlock, VaporTransitionHooks } from '../block'
|
||||
import {
|
||||
type FunctionalVaporComponent,
|
||||
type VaporComponentInstance,
|
||||
|
@ -28,6 +23,7 @@ import {
|
|||
} from '../component'
|
||||
import { extend, isArray } from '@vue/shared'
|
||||
import { renderEffect } from '../renderEffect'
|
||||
import { isFragment } from '../fragment'
|
||||
|
||||
const decorate = (t: typeof VaporTransition) => {
|
||||
t.displayName = 'VaporTransition'
|
||||
|
|
|
@ -17,11 +17,9 @@ import {
|
|||
import { extend, isArray } from '@vue/shared'
|
||||
import {
|
||||
type Block,
|
||||
DynamicFragment,
|
||||
type TransitionBlock,
|
||||
type VaporTransitionHooks,
|
||||
insert,
|
||||
isFragment,
|
||||
} from '../block'
|
||||
import {
|
||||
resolveTransitionHooks,
|
||||
|
@ -37,6 +35,7 @@ import {
|
|||
import { isForBlock } from '../apiCreateFor'
|
||||
import { renderEffect } from '../renderEffect'
|
||||
import { createElement } from '../dom/node'
|
||||
import { DynamicFragment, isFragment } from '../fragment'
|
||||
|
||||
const positionMap = new WeakMap<TransitionBlock, DOMRect>()
|
||||
const newPositionMap = new WeakMap<TransitionBlock, DOMRect>()
|
||||
|
|
|
@ -6,8 +6,9 @@ import {
|
|||
} from '@vue/runtime-dom'
|
||||
import { renderEffect } from '../renderEffect'
|
||||
import { isVaporComponent } from '../component'
|
||||
import { type Block, DynamicFragment, type TransitionBlock } from '../block'
|
||||
import type { Block, TransitionBlock } from '../block'
|
||||
import { isArray } from '@vue/shared'
|
||||
import { DynamicFragment } from '../fragment'
|
||||
|
||||
export function applyVShow(target: Block, source: () => any): void {
|
||||
if (isVaporComponent(target)) {
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
import { EffectScope, pauseTracking, resetTracking } from '@vue/reactivity'
|
||||
import { createComment, createTextNode } from './dom/node'
|
||||
import {
|
||||
type Block,
|
||||
type BlockFn,
|
||||
type TransitionOptions,
|
||||
type VaporTransitionHooks,
|
||||
insert,
|
||||
isValidBlock,
|
||||
remove,
|
||||
} from './block'
|
||||
import type { TransitionHooks } from '@vue/runtime-dom'
|
||||
import {
|
||||
currentHydrationNode,
|
||||
isComment,
|
||||
isHydrating,
|
||||
locateHydrationNode,
|
||||
locateVaporFragmentAnchor,
|
||||
} from './dom/hydration'
|
||||
import {
|
||||
applyTransitionHooks,
|
||||
applyTransitionLeaveHooks,
|
||||
} from './components/Transition'
|
||||
|
||||
export class VaporFragment implements TransitionOptions {
|
||||
$key?: any
|
||||
$transition?: VaporTransitionHooks | undefined
|
||||
nodes: Block
|
||||
anchor?: Node
|
||||
insert?: (
|
||||
parent: ParentNode,
|
||||
anchor: Node | null,
|
||||
transitionHooks?: TransitionHooks,
|
||||
) => void
|
||||
remove?: (parent?: ParentNode, transitionHooks?: TransitionHooks) => void
|
||||
fallback?: BlockFn
|
||||
|
||||
target?: ParentNode | null
|
||||
targetAnchor?: Node | null
|
||||
getNodes?: () => Block
|
||||
|
||||
constructor(nodes: Block) {
|
||||
this.nodes = nodes
|
||||
}
|
||||
}
|
||||
|
||||
export class DynamicFragment extends VaporFragment {
|
||||
anchor!: Node
|
||||
scope: EffectScope | undefined
|
||||
current?: BlockFn
|
||||
fallback?: BlockFn
|
||||
/**
|
||||
* slot only
|
||||
* indicates forwarded slot
|
||||
*/
|
||||
forwarded?: boolean
|
||||
|
||||
constructor(anchorLabel?: string) {
|
||||
super([])
|
||||
if (isHydrating) {
|
||||
locateHydrationNode(true)
|
||||
this.hydrate(anchorLabel!)
|
||||
} else {
|
||||
this.anchor =
|
||||
__DEV__ && anchorLabel ? createComment(anchorLabel) : createTextNode()
|
||||
}
|
||||
}
|
||||
|
||||
update(render?: BlockFn, key: any = render): void {
|
||||
if (key === this.current) {
|
||||
return
|
||||
}
|
||||
this.current = key
|
||||
|
||||
pauseTracking()
|
||||
const parent = this.anchor.parentNode
|
||||
const transition = this.$transition
|
||||
const renderBranch = () => {
|
||||
if (render) {
|
||||
this.scope = new EffectScope()
|
||||
this.nodes = this.scope.run(render) || []
|
||||
if (transition) {
|
||||
this.$transition = applyTransitionHooks(this.nodes, transition)
|
||||
}
|
||||
if (parent) insert(this.nodes, parent, this.anchor)
|
||||
} else {
|
||||
this.scope = undefined
|
||||
this.nodes = []
|
||||
}
|
||||
}
|
||||
|
||||
// teardown previous branch
|
||||
if (this.scope) {
|
||||
this.scope.stop()
|
||||
const mode = transition && transition.mode
|
||||
if (mode) {
|
||||
applyTransitionLeaveHooks(this.nodes, transition, renderBranch)
|
||||
parent && remove(this.nodes, parent)
|
||||
if (mode === 'out-in') {
|
||||
resetTracking()
|
||||
return
|
||||
}
|
||||
} else {
|
||||
parent && remove(this.nodes, parent)
|
||||
}
|
||||
}
|
||||
|
||||
renderBranch()
|
||||
|
||||
if (this.fallback && !isValidBlock(this.nodes)) {
|
||||
parent && remove(this.nodes, parent)
|
||||
this.nodes =
|
||||
(this.scope || (this.scope = new EffectScope())).run(this.fallback) ||
|
||||
[]
|
||||
parent && insert(this.nodes, parent, this.anchor)
|
||||
}
|
||||
|
||||
resetTracking()
|
||||
}
|
||||
|
||||
hydrate(label: string): void {
|
||||
// for `v-if="false"` the node will be an empty comment, use it as the anchor.
|
||||
// otherwise, find next sibling vapor fragment anchor
|
||||
if (isComment(currentHydrationNode!, '')) {
|
||||
this.anchor = currentHydrationNode
|
||||
} else {
|
||||
const anchor = locateVaporFragmentAnchor(currentHydrationNode!, label)!
|
||||
if (anchor) {
|
||||
this.anchor = anchor
|
||||
} else if (__DEV__) {
|
||||
// this should not happen
|
||||
throw new Error(`${label} fragment anchor node was not found.`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function isFragment(val: NonNullable<unknown>): val is VaporFragment {
|
||||
return val instanceof VaporFragment
|
||||
}
|
|
@ -13,12 +13,17 @@ import {
|
|||
mountComponent,
|
||||
unmountComponent,
|
||||
} from './component'
|
||||
import { handleTeleportRootComponentHmrReload } from './components/Teleport'
|
||||
|
||||
export function hmrRerender(instance: VaporComponentInstance): void {
|
||||
const normalized = normalizeBlock(instance.block)
|
||||
const parent = normalized[0].parentNode!
|
||||
const anchor = normalized[normalized.length - 1].nextSibling
|
||||
remove(instance.block, parent)
|
||||
if (instance.hmrRerenderEffects) {
|
||||
instance.hmrRerenderEffects.forEach(e => e())
|
||||
instance.hmrRerenderEffects.length = 0
|
||||
}
|
||||
const prev = currentInstance
|
||||
simpleSetCurrentInstance(instance)
|
||||
pushWarningContext(instance)
|
||||
|
@ -46,4 +51,5 @@ export function hmrReload(
|
|||
)
|
||||
simpleSetCurrentInstance(prev, instance.parent)
|
||||
mountComponent(newInstance, parent, anchor)
|
||||
handleTeleportRootComponentHmrReload(instance, newInstance)
|
||||
}
|
||||
|
|
|
@ -3,9 +3,10 @@ export { createVaporApp, createVaporSSRApp } from './apiCreateApp'
|
|||
export { defineVaporComponent } from './apiDefineComponent'
|
||||
export { vaporInteropPlugin } from './vdomInterop'
|
||||
export type { VaporDirective } from './directives/custom'
|
||||
export { VaporTeleportImpl as VaporTeleport } from './components/Teleport'
|
||||
|
||||
// compiler-use only
|
||||
export { insert, prepend, remove, isFragment, VaporFragment } from './block'
|
||||
export { insert, prepend, remove } from './block'
|
||||
export { setInsertionState } from './insertionState'
|
||||
export { createComponent, createComponentWithFallback } from './component'
|
||||
export { renderEffect } from './renderEffect'
|
||||
|
@ -46,3 +47,4 @@ export {
|
|||
export { withVaporDirectives } from './directives/custom'
|
||||
export { VaporTransition } from './components/Transition'
|
||||
export { VaporTransitionGroup } from './components/TransitionGroup'
|
||||
export { isFragment, VaporFragment } from './fragment'
|
||||
|
|
|
@ -11,7 +11,10 @@ import {
|
|||
import { type VaporComponentInstance, isVaporComponent } from './component'
|
||||
import { invokeArrayFns } from '@vue/shared'
|
||||
|
||||
export function renderEffect(fn: () => void, noLifecycle = false): void {
|
||||
export function renderEffect(
|
||||
fn: () => void,
|
||||
noLifecycle = false,
|
||||
): ReactiveEffect<void> {
|
||||
const instance = currentInstance as VaporComponentInstance | null
|
||||
const scope = getCurrentScope()
|
||||
if (__DEV__ && !__TEST__ && !scope && !isVaporComponent(instance)) {
|
||||
|
@ -66,5 +69,6 @@ export function renderEffect(fn: () => void, noLifecycle = false): void {
|
|||
effect.scheduler = () => queueJob(job)
|
||||
effect.run()
|
||||
|
||||
return effect
|
||||
// TODO recurse handling
|
||||
}
|
||||
|
|
|
@ -37,15 +37,7 @@ import {
|
|||
mountComponent,
|
||||
unmountComponent,
|
||||
} from './component'
|
||||
import {
|
||||
type Block,
|
||||
DynamicFragment,
|
||||
VaporFragment,
|
||||
type VaporTransitionHooks,
|
||||
insert,
|
||||
isFragment,
|
||||
remove,
|
||||
} from './block'
|
||||
import { type Block, type VaporTransitionHooks, insert, remove } from './block'
|
||||
import {
|
||||
EMPTY_OBJ,
|
||||
extend,
|
||||
|
@ -65,6 +57,7 @@ import {
|
|||
locateHydrationNode,
|
||||
hydrateNode as vaporHydrateNode,
|
||||
} from './dom/hydration'
|
||||
import { DynamicFragment, VaporFragment, isFragment } from './fragment'
|
||||
|
||||
// mounting vapor components and slots in vdom
|
||||
const vaporInteropImpl: Omit<
|
||||
|
|
|
@ -55,7 +55,7 @@ importers:
|
|||
version: 5.0.4(rollup@4.44.0)
|
||||
'@swc/core':
|
||||
specifier: ^1.11.24
|
||||
version: 1.12.3
|
||||
version: 1.12.4
|
||||
'@types/hash-sum':
|
||||
specifier: ^1.0.2
|
||||
version: 1.0.2
|
||||
|
@ -1288,68 +1288,68 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@swc/core-darwin-arm64@1.12.3':
|
||||
resolution: {integrity: sha512-QCV9vQ/s27AMxm8j8MTDL/nDoiEMrANiENRrWnb0Fxvz/O39CajPVShp/W7HlOkzt1GYtUXPdQJpSKylugfrWw==}
|
||||
'@swc/core-darwin-arm64@1.12.4':
|
||||
resolution: {integrity: sha512-HihKfeitjZU2ab94Zf893sxzFryLKX0TweGsNXXOLNtkSMLw50auuYfpRM0BOL9/uXXtuCWgRIF6P030SAX5xQ==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@swc/core-darwin-x64@1.12.3':
|
||||
resolution: {integrity: sha512-LylCMfzGhdvl5tyKaTT9ePetHUX7wSsST7hxWiHzS+cUMj7FnhcfdEr6kcNVT7y1RJn3fCvuv7T98ZB+T2q3HA==}
|
||||
'@swc/core-darwin-x64@1.12.4':
|
||||
resolution: {integrity: sha512-meYCXHyYb6RDdu2N5PNAf0EelyxPBFhRcVo4kBFLuvuNb0m6EUg///VWy8MUMXq9/s9uzGS9kJVXXdRdr/d6FA==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@swc/core-linux-arm-gnueabihf@1.12.3':
|
||||
resolution: {integrity: sha512-DQODb7S+q+pwQY41Azcavwb2rb4rGxP70niScRDxB9X68hHOM9D0w9fxzC+Nr3AHcPSmVJUYUIiq5h38O5hVgQ==}
|
||||
'@swc/core-linux-arm-gnueabihf@1.12.4':
|
||||
resolution: {integrity: sha512-szfDbf7mE8V64of0q/LSqbk+em+T+TD3uqnH40Z7Qu/aL8vi5CHgyLjWG2SLkLLpyjgkAUF6AKrupgnBYcC2NA==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@swc/core-linux-arm64-gnu@1.12.3':
|
||||
resolution: {integrity: sha512-nTxtJSq78AjeaQBueYImoFBs5j7qXbgOxtirpyt8jE29NQBd0VFzDzRBhkr6I9jq0hNiChgMkqBN4eUkEQjytg==}
|
||||
'@swc/core-linux-arm64-gnu@1.12.4':
|
||||
resolution: {integrity: sha512-n0IY76w+Scx8m3HIVRvLkoResuwsQgjDfAk9bxn99dq4leQO+mE0fkPl0Yw/1BIsPh+kxGfopIJH9zsZ1Z2YrA==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@swc/core-linux-arm64-musl@1.12.3':
|
||||
resolution: {integrity: sha512-lBGvC5UgPSxqLr/y1NZxQhyRQ7nXy3/Ec1Z47YNXtqtpKiG1EcOGPyS0UZgwiYQkXqq8NBFMHnyHmpKnXTvRDA==}
|
||||
'@swc/core-linux-arm64-musl@1.12.4':
|
||||
resolution: {integrity: sha512-wE5jmFi5cEQyLy8WmCWmNwfKETrnzy2D8YNi/xpYWpLPWqPhcelpa6tswkfYlbsMmmOh7hQNoTba1QdGu0jvHQ==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@swc/core-linux-x64-gnu@1.12.3':
|
||||
resolution: {integrity: sha512-61wZ8hwxNYzBY9MCWB50v90ICzdIhOuPk1O1qXswz9AXw5O6iQStEBHQ1rozPkfQ/rmhepk0pOf/6LCwssJOwg==}
|
||||
'@swc/core-linux-x64-gnu@1.12.4':
|
||||
resolution: {integrity: sha512-6S50Xd/7ePjEwrXyHMxpKTZ+KBrgUwMA8hQPbArUOwH4S5vHBr51heL0iXbUkppn1bkSr0J0IbOove5hzn+iqQ==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@swc/core-linux-x64-musl@1.12.3':
|
||||
resolution: {integrity: sha512-NNeBiTpCgWt80vumTKVoaj6Fa/ZjUcaNQNM7np3PIgB8EbuXfyztboV7vUxpkmD/lUgsk8GlEFYViHvo6VMefQ==}
|
||||
'@swc/core-linux-x64-musl@1.12.4':
|
||||
resolution: {integrity: sha512-hbYRyaHhC13vYKuGG5BrAG5fjjWEQFfQetuFp/4QKEoXDzdnabJoixxWTQACDL3m0JW32nJ+gUzsYIPtFYkwXg==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@swc/core-win32-arm64-msvc@1.12.3':
|
||||
resolution: {integrity: sha512-fxraM7exaPb1/W0CoHW45EFNOQUQh0nonBEcNFm2iv095mziBwttyxZyQBoDkQocpkd5NtsZw3xW5FTBPnn+Vw==}
|
||||
'@swc/core-win32-arm64-msvc@1.12.4':
|
||||
resolution: {integrity: sha512-e6EbfjPL8GA/bb1lc9Omtxjlz+1ThTsAuBsy4Q3Kpbuh6B3jclg8KzxU/6t91v23wG593mieTyR5f3Pr7X3AWw==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@swc/core-win32-ia32-msvc@1.12.3':
|
||||
resolution: {integrity: sha512-FFIhMPXIDjRcewomwbYGPvem7Fj76AsuzbRahnAyp+OzJwrrtxVmra/kyUCfj4kix7vdGByY0WvVfiVCf5b7Mg==}
|
||||
'@swc/core-win32-ia32-msvc@1.12.4':
|
||||
resolution: {integrity: sha512-RG2FzmllBTUf4EksANlIvLckcBrLZEA0t13LIa6L213UZKQfEuDNHezqESgoVhJMg2S/tWauitATOCFgZNSmjg==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@swc/core-win32-x64-msvc@1.12.3':
|
||||
resolution: {integrity: sha512-Sf4iSg+IYT5AzFSDDmii08DfeKcvtkVxIuo+uS8BJMbiLjFNjgMkkVlBthknGyJcSK15ncg9248XjnM4jU8DZA==}
|
||||
'@swc/core-win32-x64-msvc@1.12.4':
|
||||
resolution: {integrity: sha512-oRHKnZlR83zaMeVUCmHENa4j5uNRAWbmEpjYbzRcfC45LPFNWKGWGAGERLx0u87XMUtTGqnVYxnBTHN/rzDHOw==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@swc/core@1.12.3':
|
||||
resolution: {integrity: sha512-c4NeXW8P3gPqcFwtm+4aH+F2Cj5KJLMiLaKhSj3mpv19glq+jmekomdktAw/VHyjsXlsmouOeNWrk8rVlkCRsg==}
|
||||
'@swc/core@1.12.4':
|
||||
resolution: {integrity: sha512-hn30ebV4njAn0NAUM+3a0qCF+MJgqTNSrfA/hUAbC6TVjOQy2OYGQwkUvCu/V7S2+rZxrUsTpKOnZ7qqECZV9Q==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
'@swc/helpers': '>=0.5.17'
|
||||
|
@ -4482,51 +4482,51 @@ snapshots:
|
|||
'@rollup/rollup-win32-x64-msvc@4.44.0':
|
||||
optional: true
|
||||
|
||||
'@swc/core-darwin-arm64@1.12.3':
|
||||
'@swc/core-darwin-arm64@1.12.4':
|
||||
optional: true
|
||||
|
||||
'@swc/core-darwin-x64@1.12.3':
|
||||
'@swc/core-darwin-x64@1.12.4':
|
||||
optional: true
|
||||
|
||||
'@swc/core-linux-arm-gnueabihf@1.12.3':
|
||||
'@swc/core-linux-arm-gnueabihf@1.12.4':
|
||||
optional: true
|
||||
|
||||
'@swc/core-linux-arm64-gnu@1.12.3':
|
||||
'@swc/core-linux-arm64-gnu@1.12.4':
|
||||
optional: true
|
||||
|
||||
'@swc/core-linux-arm64-musl@1.12.3':
|
||||
'@swc/core-linux-arm64-musl@1.12.4':
|
||||
optional: true
|
||||
|
||||
'@swc/core-linux-x64-gnu@1.12.3':
|
||||
'@swc/core-linux-x64-gnu@1.12.4':
|
||||
optional: true
|
||||
|
||||
'@swc/core-linux-x64-musl@1.12.3':
|
||||
'@swc/core-linux-x64-musl@1.12.4':
|
||||
optional: true
|
||||
|
||||
'@swc/core-win32-arm64-msvc@1.12.3':
|
||||
'@swc/core-win32-arm64-msvc@1.12.4':
|
||||
optional: true
|
||||
|
||||
'@swc/core-win32-ia32-msvc@1.12.3':
|
||||
'@swc/core-win32-ia32-msvc@1.12.4':
|
||||
optional: true
|
||||
|
||||
'@swc/core-win32-x64-msvc@1.12.3':
|
||||
'@swc/core-win32-x64-msvc@1.12.4':
|
||||
optional: true
|
||||
|
||||
'@swc/core@1.12.3':
|
||||
'@swc/core@1.12.4':
|
||||
dependencies:
|
||||
'@swc/counter': 0.1.3
|
||||
'@swc/types': 0.1.23
|
||||
optionalDependencies:
|
||||
'@swc/core-darwin-arm64': 1.12.3
|
||||
'@swc/core-darwin-x64': 1.12.3
|
||||
'@swc/core-linux-arm-gnueabihf': 1.12.3
|
||||
'@swc/core-linux-arm64-gnu': 1.12.3
|
||||
'@swc/core-linux-arm64-musl': 1.12.3
|
||||
'@swc/core-linux-x64-gnu': 1.12.3
|
||||
'@swc/core-linux-x64-musl': 1.12.3
|
||||
'@swc/core-win32-arm64-msvc': 1.12.3
|
||||
'@swc/core-win32-ia32-msvc': 1.12.3
|
||||
'@swc/core-win32-x64-msvc': 1.12.3
|
||||
'@swc/core-darwin-arm64': 1.12.4
|
||||
'@swc/core-darwin-x64': 1.12.4
|
||||
'@swc/core-linux-arm-gnueabihf': 1.12.4
|
||||
'@swc/core-linux-arm64-gnu': 1.12.4
|
||||
'@swc/core-linux-arm64-musl': 1.12.4
|
||||
'@swc/core-linux-x64-gnu': 1.12.4
|
||||
'@swc/core-linux-x64-musl': 1.12.4
|
||||
'@swc/core-win32-arm64-msvc': 1.12.4
|
||||
'@swc/core-win32-ia32-msvc': 1.12.4
|
||||
'@swc/core-win32-x64-msvc': 1.12.4
|
||||
|
||||
'@swc/counter@0.1.3': {}
|
||||
|
||||
|
|
Loading…
Reference in New Issue