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'
|
} from '../../../packages/vue/__tests__/e2e/e2eUtils'
|
||||||
import connect from 'connect'
|
import connect from 'connect'
|
||||||
import sirv from 'sirv'
|
import sirv from 'sirv'
|
||||||
|
import { ports } from '../utils'
|
||||||
|
|
||||||
describe('e2e: todomvc', () => {
|
describe('e2e: todomvc', () => {
|
||||||
const {
|
const {
|
||||||
|
@ -23,7 +24,7 @@ describe('e2e: todomvc', () => {
|
||||||
} = setupPuppeteer()
|
} = setupPuppeteer()
|
||||||
|
|
||||||
let server: any
|
let server: any
|
||||||
const port = '8194'
|
const port = ports.todomvc
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
server = connect()
|
server = connect()
|
||||||
.use(sirv(path.resolve(import.meta.dirname, '../dist')))
|
.use(sirv(path.resolve(import.meta.dirname, '../dist')))
|
||||||
|
|
|
@ -7,6 +7,7 @@ import connect from 'connect'
|
||||||
import sirv from 'sirv'
|
import sirv from 'sirv'
|
||||||
import { expect } from 'vitest'
|
import { expect } from 'vitest'
|
||||||
const { page, nextFrame, timeout, html, transitionStart } = setupPuppeteer()
|
const { page, nextFrame, timeout, html, transitionStart } = setupPuppeteer()
|
||||||
|
import { ports } from '../utils'
|
||||||
|
|
||||||
const duration = process.env.CI ? 200 : 50
|
const duration = process.env.CI ? 200 : 50
|
||||||
const buffer = process.env.CI ? 50 : 20
|
const buffer = process.env.CI ? 50 : 20
|
||||||
|
@ -14,7 +15,7 @@ const transitionFinish = (time = duration) => timeout(time + buffer)
|
||||||
|
|
||||||
describe('vapor transition-group', () => {
|
describe('vapor transition-group', () => {
|
||||||
let server: any
|
let server: any
|
||||||
const port = '8196'
|
const port = ports.transitionGroup
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
server = connect()
|
server = connect()
|
||||||
.use(sirv(path.resolve(import.meta.dirname, '../dist')))
|
.use(sirv(path.resolve(import.meta.dirname, '../dist')))
|
||||||
|
|
|
@ -19,6 +19,7 @@ const {
|
||||||
waitForElement,
|
waitForElement,
|
||||||
click,
|
click,
|
||||||
} = setupPuppeteer()
|
} = setupPuppeteer()
|
||||||
|
import { ports } from '../utils'
|
||||||
|
|
||||||
const duration = process.env.CI ? 200 : 50
|
const duration = process.env.CI ? 200 : 50
|
||||||
const buffer = process.env.CI ? 50 : 20
|
const buffer = process.env.CI ? 50 : 20
|
||||||
|
@ -26,7 +27,7 @@ const transitionFinish = (time = duration) => timeout(time + buffer)
|
||||||
|
|
||||||
describe('vapor transition', () => {
|
describe('vapor transition', () => {
|
||||||
let server: any
|
let server: any
|
||||||
const port = '8195'
|
const port = ports.transition
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
server = connect()
|
server = connect()
|
||||||
.use(sirv(path.resolve(import.meta.dirname, '../dist')))
|
.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 buffer = process.env.CI ? 50 : 20
|
||||||
const transitionFinish = (time = duration) => timeout(time + buffer)
|
const transitionFinish = (time = duration) => timeout(time + buffer)
|
||||||
|
|
||||||
|
import { ports } from '../utils'
|
||||||
|
import { nextTick } from 'vue'
|
||||||
|
|
||||||
describe('vdom / vapor interop', () => {
|
describe('vdom / vapor interop', () => {
|
||||||
let server: any
|
let server: any
|
||||||
const port = '8193'
|
const port = ports.vdomInterop
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
server = connect()
|
server = connect()
|
||||||
.use(sirv(path.resolve(import.meta.dirname, '../dist')))
|
.use(sirv(path.resolve(import.meta.dirname, '../dist')))
|
||||||
|
@ -31,6 +34,12 @@ describe('vdom / vapor interop', () => {
|
||||||
process.on('SIGTERM', () => server && server.close())
|
process.on('SIGTERM', () => server && server.close())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const baseUrl = `http://localhost:${port}/interop/`
|
||||||
|
await page().goto(baseUrl)
|
||||||
|
await page().waitForSelector('#app')
|
||||||
|
})
|
||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
server.close()
|
server.close()
|
||||||
})
|
})
|
||||||
|
@ -255,5 +264,33 @@ describe('vdom / vapor interop', () => {
|
||||||
},
|
},
|
||||||
E2E_TIMEOUT,
|
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="/todomvc/">Vapor TodoMVC</a>
|
||||||
<a href="/transition/">Vapor Transition</a>
|
<a href="/transition/">Vapor Transition</a>
|
||||||
<a href="/transition-group/">Vapor TransitionGroup</a>
|
<a href="/transition-group/">Vapor TransitionGroup</a>
|
||||||
|
<a href="/teleport/">Vapor Teleport</a>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
a {
|
a {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, shallowRef } from 'vue'
|
import { ref, shallowRef } from 'vue'
|
||||||
import VaporComp from './VaporComp.vue'
|
import VaporComp from './components/VaporComp.vue'
|
||||||
import VaporCompA from '../transition/components/VaporCompA.vue'
|
import VaporCompA from '../transition/components/VaporCompA.vue'
|
||||||
import VdomComp from '../transition/components/VdomComp.vue'
|
import VdomComp from '../transition/components/VdomComp.vue'
|
||||||
import VaporSlot from '../transition/components/VaporSlot.vue'
|
import VaporSlot from '../transition/components/VaporSlot.vue'
|
||||||
|
@ -17,6 +17,9 @@ function toggleInteropComponent() {
|
||||||
|
|
||||||
const items = ref(['a', 'b', 'c'])
|
const items = ref(['a', 'b', 'c'])
|
||||||
const enterClick = () => items.value.push('d', 'e')
|
const enterClick = () => items.value.push('d', 'e')
|
||||||
|
import SimpleVaporComp from './components/SimpleVaporComp.vue'
|
||||||
|
|
||||||
|
const disabled = ref(true)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -69,4 +72,15 @@ const enterClick = () => items.value.push('d', 'e')
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</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>
|
</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: {
|
input: {
|
||||||
interop: resolve(import.meta.dirname, 'interop/index.html'),
|
interop: resolve(import.meta.dirname, 'interop/index.html'),
|
||||||
todomvc: resolve(import.meta.dirname, 'todomvc/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'),
|
transition: resolve(import.meta.dirname, 'transition/index.html'),
|
||||||
transitionGroup: resolve(
|
transitionGroup: resolve(
|
||||||
import.meta.dirname,
|
import.meta.dirname,
|
||||||
|
|
|
@ -39,7 +39,6 @@ import { genEventHandler } from './event'
|
||||||
import { genDirectiveModifiers, genDirectivesForElement } from './directive'
|
import { genDirectiveModifiers, genDirectivesForElement } from './directive'
|
||||||
import { genBlock } from './block'
|
import { genBlock } from './block'
|
||||||
import { genModelHandler } from './vModel'
|
import { genModelHandler } from './vModel'
|
||||||
|
|
||||||
import { isBuiltInComponent } from '../utils'
|
import { isBuiltInComponent } from '../utils'
|
||||||
|
|
||||||
export function genCreateComponent(
|
export function genCreateComponent(
|
||||||
|
|
|
@ -115,10 +115,17 @@ export function isTransitionGroupTag(tag: string): boolean {
|
||||||
return tag === 'transitiongroup' || tag === 'vaportransitiongroup'
|
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 {
|
export function isBuiltInComponent(tag: string): string | undefined {
|
||||||
if (isTransitionTag(tag)) {
|
if (isTransitionTag(tag)) {
|
||||||
return 'VaporTransition'
|
return 'VaporTransition'
|
||||||
} else if (isTransitionGroupTag(tag)) {
|
} else if (isTransitionGroupTag(tag)) {
|
||||||
return 'VaporTransitionGroup'
|
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
|
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 === '')
|
props && (props.disabled || props.disabled === '')
|
||||||
|
|
||||||
const isTeleportDeferred = (props: VNode['props']): boolean =>
|
export const isTeleportDeferred = (props: VNode['props']): boolean =>
|
||||||
props && (props.defer || props.defer === '')
|
props && (props.defer || props.defer === '')
|
||||||
|
|
||||||
const isTargetSVG = (target: RendererElement): boolean =>
|
const isTargetSVG = (target: RendererElement): boolean =>
|
||||||
|
@ -39,7 +39,7 @@ const isTargetSVG = (target: RendererElement): boolean =>
|
||||||
const isTargetMathML = (target: RendererElement): boolean =>
|
const isTargetMathML = (target: RendererElement): boolean =>
|
||||||
typeof MathMLElement === 'function' && target instanceof MathMLElement
|
typeof MathMLElement === 'function' && target instanceof MathMLElement
|
||||||
|
|
||||||
const resolveTarget = <T = RendererElement>(
|
export const resolveTarget = <T = RendererElement>(
|
||||||
props: TeleportProps | null,
|
props: TeleportProps | null,
|
||||||
select: RendererOptions['querySelector'],
|
select: RendererOptions['querySelector'],
|
||||||
): T | null => {
|
): T | null => {
|
||||||
|
|
|
@ -119,7 +119,7 @@ function reload(id: string, newComp: HMRComponent): void {
|
||||||
// create a snapshot which avoids the set being mutated during updates
|
// create a snapshot which avoids the set being mutated during updates
|
||||||
const instances = [...record.instances]
|
const instances = [...record.instances]
|
||||||
|
|
||||||
if (newComp.vapor) {
|
if (newComp.__vapor) {
|
||||||
for (const instance of instances) {
|
for (const instance of instances) {
|
||||||
instance.hmrReload!(newComp)
|
instance.hmrReload!(newComp)
|
||||||
}
|
}
|
||||||
|
|
|
@ -574,6 +574,14 @@ export { performTransitionEnter, performTransitionLeave } from './renderer'
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export { ensureVaporSlotFallback } from './helpers/renderSlot'
|
export { ensureVaporSlotFallback } from './helpers/renderSlot'
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export {
|
||||||
|
resolveTarget as resolveTeleportTarget,
|
||||||
|
isTeleportDisabled,
|
||||||
|
isTeleportDeferred,
|
||||||
|
} from './components/Teleport'
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
import {
|
import { insert, normalizeBlock, prepend, remove } from '../src/block'
|
||||||
VaporFragment,
|
import { VaporFragment } from '../src/fragment'
|
||||||
insert,
|
|
||||||
normalizeBlock,
|
|
||||||
prepend,
|
|
||||||
remove,
|
|
||||||
} from '../src/block'
|
|
||||||
|
|
||||||
const node1 = document.createTextNode('node1')
|
const node1 = document.createTextNode('node1')
|
||||||
const node2 = document.createTextNode('node2')
|
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 { currentInstance, resolveDynamicComponent } from '@vue/runtime-dom'
|
||||||
import { DynamicFragment, type VaporFragment, insert } from './block'
|
import { insert } from './block'
|
||||||
import { createComponentWithFallback, emptyContext } from './component'
|
import { createComponentWithFallback, emptyContext } from './component'
|
||||||
import { renderEffect } from './renderEffect'
|
import { renderEffect } from './renderEffect'
|
||||||
import type { RawProps } from './componentProps'
|
import type { RawProps } from './componentProps'
|
||||||
|
@ -11,6 +11,7 @@ import {
|
||||||
} from './insertionState'
|
} from './insertionState'
|
||||||
import { DYNAMIC_COMPONENT_ANCHOR_LABEL } from '@vue/shared'
|
import { DYNAMIC_COMPONENT_ANCHOR_LABEL } from '@vue/shared'
|
||||||
import { isHydrating, locateHydrationNode } from './dom/hydration'
|
import { isHydrating, locateHydrationNode } from './dom/hydration'
|
||||||
|
import { DynamicFragment, type VaporFragment } from './fragment'
|
||||||
|
|
||||||
export function createDynamicComponent(
|
export function createDynamicComponent(
|
||||||
getter: () => any,
|
getter: () => any,
|
||||||
|
|
|
@ -19,12 +19,7 @@ import {
|
||||||
isString,
|
isString,
|
||||||
} from '@vue/shared'
|
} from '@vue/shared'
|
||||||
import { createComment, createTextNode } from './dom/node'
|
import { createComment, createTextNode } from './dom/node'
|
||||||
import {
|
import { type Block, insert, remove as removeBlock } from './block'
|
||||||
type Block,
|
|
||||||
VaporFragment,
|
|
||||||
insert,
|
|
||||||
remove as removeBlock,
|
|
||||||
} from './block'
|
|
||||||
import { warn } from '@vue/runtime-dom'
|
import { warn } from '@vue/runtime-dom'
|
||||||
import { currentInstance, isVaporComponent } from './component'
|
import { currentInstance, isVaporComponent } from './component'
|
||||||
import type { DynamicSlot } from './componentSlots'
|
import type { DynamicSlot } from './componentSlots'
|
||||||
|
@ -37,6 +32,7 @@ import {
|
||||||
locateHydrationNode,
|
locateHydrationNode,
|
||||||
locateVaporFragmentAnchor,
|
locateVaporFragmentAnchor,
|
||||||
} from './dom/hydration'
|
} from './dom/hydration'
|
||||||
|
import { VaporFragment } from './fragment'
|
||||||
import {
|
import {
|
||||||
insertionAnchor,
|
insertionAnchor,
|
||||||
insertionParent,
|
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'
|
import { renderEffect } from './renderEffect'
|
||||||
|
|
||||||
export function createKeyedFragment(key: () => any, render: BlockFn): Block {
|
export function createKeyedFragment(key: () => any, render: BlockFn): Block {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { IF_ANCHOR_LABEL } from '@vue/shared'
|
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 { isHydrating, locateHydrationNode } from './dom/hydration'
|
||||||
import {
|
import {
|
||||||
insertionAnchor,
|
insertionAnchor,
|
||||||
|
@ -7,6 +7,7 @@ import {
|
||||||
resetInsertionState,
|
resetInsertionState,
|
||||||
} from './insertionState'
|
} from './insertionState'
|
||||||
import { renderEffect } from './renderEffect'
|
import { renderEffect } from './renderEffect'
|
||||||
|
import { DynamicFragment } from './fragment'
|
||||||
|
|
||||||
export function createIf(
|
export function createIf(
|
||||||
condition: () => any,
|
condition: () => any,
|
||||||
|
|
|
@ -20,7 +20,7 @@ import {
|
||||||
isString,
|
isString,
|
||||||
remove,
|
remove,
|
||||||
} from '@vue/shared'
|
} from '@vue/shared'
|
||||||
import { DynamicFragment } from './block'
|
import { DynamicFragment } from './fragment'
|
||||||
|
|
||||||
export type NodeRef = string | Ref | ((ref: Element) => void)
|
export type NodeRef = string | Ref | ((ref: Element) => void)
|
||||||
export type RefEl = Element | VaporComponentInstance
|
export type RefEl = Element | VaporComponentInstance
|
||||||
|
|
|
@ -5,14 +5,6 @@ import {
|
||||||
mountComponent,
|
mountComponent,
|
||||||
unmountComponent,
|
unmountComponent,
|
||||||
} from './component'
|
} from './component'
|
||||||
import { createComment, createTextNode } from './dom/node'
|
|
||||||
import { EffectScope, pauseTracking, resetTracking } from '@vue/reactivity'
|
|
||||||
import {
|
|
||||||
currentHydrationNode,
|
|
||||||
isComment,
|
|
||||||
locateHydrationNode,
|
|
||||||
locateVaporFragmentAnchor,
|
|
||||||
} from './dom/hydration'
|
|
||||||
import {
|
import {
|
||||||
type TransitionHooks,
|
type TransitionHooks,
|
||||||
type TransitionProps,
|
type TransitionProps,
|
||||||
|
@ -20,17 +12,18 @@ import {
|
||||||
performTransitionEnter,
|
performTransitionEnter,
|
||||||
performTransitionLeave,
|
performTransitionLeave,
|
||||||
} from '@vue/runtime-dom'
|
} from '@vue/runtime-dom'
|
||||||
|
import { isHydrating } from './dom/hydration'
|
||||||
|
import { getInheritedScopeIds } from '@vue/runtime-dom'
|
||||||
import {
|
import {
|
||||||
applyTransitionHooks,
|
type DynamicFragment,
|
||||||
applyTransitionLeaveHooks,
|
type VaporFragment,
|
||||||
} from './components/Transition'
|
isFragment,
|
||||||
|
} from './fragment'
|
||||||
|
|
||||||
export interface TransitionOptions {
|
export interface TransitionOptions {
|
||||||
$key?: any
|
$key?: any
|
||||||
$transition?: VaporTransitionHooks
|
$transition?: VaporTransitionHooks
|
||||||
}
|
}
|
||||||
import { isHydrating } from './dom/hydration'
|
|
||||||
import { getInheritedScopeIds } from '@vue/runtime-dom'
|
|
||||||
|
|
||||||
export interface VaporTransitionHooks extends TransitionHooks {
|
export interface VaporTransitionHooks extends TransitionHooks {
|
||||||
state: TransitionState
|
state: TransitionState
|
||||||
|
@ -50,119 +43,6 @@ export type Block = TransitionBlock | VaporComponentInstance | Block[]
|
||||||
|
|
||||||
export type BlockFn = (...args: any[]) => 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 {
|
export function isBlock(val: NonNullable<unknown>): val is Block {
|
||||||
return (
|
return (
|
||||||
val instanceof Node ||
|
val instanceof Node ||
|
||||||
|
@ -229,7 +109,12 @@ export function insert(
|
||||||
if (block.insert) {
|
if (block.insert) {
|
||||||
block.insert(parent, anchor, (block as TransitionBlock).$transition)
|
block.insert(parent, anchor, (block as TransitionBlock).$transition)
|
||||||
} else {
|
} 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)))
|
block.forEach(child => nodes.push(...normalizeBlock(child)))
|
||||||
} else if (isVaporComponent(block)) {
|
} else if (isVaporComponent(block)) {
|
||||||
nodes.push(...normalizeBlock(block.block!))
|
nodes.push(...normalizeBlock(block.block!))
|
||||||
|
} else {
|
||||||
|
if (block.getNodes) {
|
||||||
|
nodes.push(...normalizeBlock(block.getNodes()))
|
||||||
} else {
|
} else {
|
||||||
nodes.push(...normalizeBlock(block.nodes))
|
nodes.push(...normalizeBlock(block.nodes))
|
||||||
|
}
|
||||||
block.anchor && nodes.push(block.anchor)
|
block.anchor && nodes.push(block.anchor)
|
||||||
}
|
}
|
||||||
return nodes
|
return nodes
|
||||||
|
|
|
@ -27,7 +27,6 @@ import {
|
||||||
} from '@vue/runtime-dom'
|
} from '@vue/runtime-dom'
|
||||||
import {
|
import {
|
||||||
type Block,
|
type Block,
|
||||||
DynamicFragment,
|
|
||||||
insert,
|
insert,
|
||||||
isBlock,
|
isBlock,
|
||||||
remove,
|
remove,
|
||||||
|
@ -68,11 +67,13 @@ import {
|
||||||
import { hmrReload, hmrRerender } from './hmr'
|
import { hmrReload, hmrRerender } from './hmr'
|
||||||
import { createElement } from './dom/node'
|
import { createElement } from './dom/node'
|
||||||
import { isHydrating, locateHydrationNode } from './dom/hydration'
|
import { isHydrating, locateHydrationNode } from './dom/hydration'
|
||||||
|
import { isVaporTeleport } from './components/Teleport'
|
||||||
import {
|
import {
|
||||||
insertionAnchor,
|
insertionAnchor,
|
||||||
insertionParent,
|
insertionParent,
|
||||||
resetInsertionState,
|
resetInsertionState,
|
||||||
} from './insertionState'
|
} from './insertionState'
|
||||||
|
import { DynamicFragment } from './fragment'
|
||||||
|
|
||||||
export { currentInstance } from '@vue/runtime-dom'
|
export { currentInstance } from '@vue/runtime-dom'
|
||||||
|
|
||||||
|
@ -177,6 +178,18 @@ export function createComponent(
|
||||||
return frag
|
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 (
|
if (
|
||||||
isSingleRoot &&
|
isSingleRoot &&
|
||||||
component.inheritAttrs !== false &&
|
component.inheritAttrs !== false &&
|
||||||
|
@ -398,6 +411,7 @@ export class VaporComponentInstance implements GenericComponentInstance {
|
||||||
setupState?: Record<string, any>
|
setupState?: Record<string, any>
|
||||||
devtoolsRawSetupState?: any
|
devtoolsRawSetupState?: any
|
||||||
hmrRerender?: () => void
|
hmrRerender?: () => void
|
||||||
|
hmrRerenderEffects?: (() => void)[]
|
||||||
hmrReload?: (newComp: VaporComponent) => void
|
hmrReload?: (newComp: VaporComponent) => void
|
||||||
propsOptions?: NormalizedPropsOptions
|
propsOptions?: NormalizedPropsOptions
|
||||||
emitsOptions?: ObjectEmitsOptions | null
|
emitsOptions?: ObjectEmitsOptions | null
|
||||||
|
|
|
@ -6,15 +6,7 @@ import {
|
||||||
isArray,
|
isArray,
|
||||||
isFunction,
|
isFunction,
|
||||||
} from '@vue/shared'
|
} from '@vue/shared'
|
||||||
import {
|
import { type Block, type BlockFn, insert, setScopeId } from './block'
|
||||||
type Block,
|
|
||||||
type BlockFn,
|
|
||||||
DynamicFragment,
|
|
||||||
type VaporFragment,
|
|
||||||
insert,
|
|
||||||
isFragment,
|
|
||||||
setScopeId,
|
|
||||||
} from './block'
|
|
||||||
import { rawPropsProxyHandlers } from './componentProps'
|
import { rawPropsProxyHandlers } from './componentProps'
|
||||||
import { currentInstance, isRef } from '@vue/runtime-dom'
|
import { currentInstance, isRef } from '@vue/runtime-dom'
|
||||||
import type { LooseRawProps, VaporComponentInstance } from './component'
|
import type { LooseRawProps, VaporComponentInstance } from './component'
|
||||||
|
@ -25,6 +17,7 @@ import {
|
||||||
resetInsertionState,
|
resetInsertionState,
|
||||||
} from './insertionState'
|
} from './insertionState'
|
||||||
import { isHydrating, locateHydrationNode } from './dom/hydration'
|
import { isHydrating, locateHydrationNode } from './dom/hydration'
|
||||||
|
import { DynamicFragment, type VaporFragment, isFragment } from './fragment'
|
||||||
|
|
||||||
export type RawSlots = Record<string, VaporSlot> & {
|
export type RawSlots = Record<string, VaporSlot> & {
|
||||||
$?: DynamicSlotSource[]
|
$?: 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,
|
useTransitionState,
|
||||||
warn,
|
warn,
|
||||||
} from '@vue/runtime-dom'
|
} from '@vue/runtime-dom'
|
||||||
import {
|
import type { Block, TransitionBlock, VaporTransitionHooks } from '../block'
|
||||||
type Block,
|
|
||||||
type TransitionBlock,
|
|
||||||
type VaporTransitionHooks,
|
|
||||||
isFragment,
|
|
||||||
} from '../block'
|
|
||||||
import {
|
import {
|
||||||
type FunctionalVaporComponent,
|
type FunctionalVaporComponent,
|
||||||
type VaporComponentInstance,
|
type VaporComponentInstance,
|
||||||
|
@ -28,6 +23,7 @@ import {
|
||||||
} from '../component'
|
} from '../component'
|
||||||
import { extend, isArray } from '@vue/shared'
|
import { extend, isArray } from '@vue/shared'
|
||||||
import { renderEffect } from '../renderEffect'
|
import { renderEffect } from '../renderEffect'
|
||||||
|
import { isFragment } from '../fragment'
|
||||||
|
|
||||||
const decorate = (t: typeof VaporTransition) => {
|
const decorate = (t: typeof VaporTransition) => {
|
||||||
t.displayName = 'VaporTransition'
|
t.displayName = 'VaporTransition'
|
||||||
|
|
|
@ -17,11 +17,9 @@ import {
|
||||||
import { extend, isArray } from '@vue/shared'
|
import { extend, isArray } from '@vue/shared'
|
||||||
import {
|
import {
|
||||||
type Block,
|
type Block,
|
||||||
DynamicFragment,
|
|
||||||
type TransitionBlock,
|
type TransitionBlock,
|
||||||
type VaporTransitionHooks,
|
type VaporTransitionHooks,
|
||||||
insert,
|
insert,
|
||||||
isFragment,
|
|
||||||
} from '../block'
|
} from '../block'
|
||||||
import {
|
import {
|
||||||
resolveTransitionHooks,
|
resolveTransitionHooks,
|
||||||
|
@ -37,6 +35,7 @@ import {
|
||||||
import { isForBlock } from '../apiCreateFor'
|
import { isForBlock } from '../apiCreateFor'
|
||||||
import { renderEffect } from '../renderEffect'
|
import { renderEffect } from '../renderEffect'
|
||||||
import { createElement } from '../dom/node'
|
import { createElement } from '../dom/node'
|
||||||
|
import { DynamicFragment, isFragment } from '../fragment'
|
||||||
|
|
||||||
const positionMap = new WeakMap<TransitionBlock, DOMRect>()
|
const positionMap = new WeakMap<TransitionBlock, DOMRect>()
|
||||||
const newPositionMap = new WeakMap<TransitionBlock, DOMRect>()
|
const newPositionMap = new WeakMap<TransitionBlock, DOMRect>()
|
||||||
|
|
|
@ -6,8 +6,9 @@ import {
|
||||||
} from '@vue/runtime-dom'
|
} from '@vue/runtime-dom'
|
||||||
import { renderEffect } from '../renderEffect'
|
import { renderEffect } from '../renderEffect'
|
||||||
import { isVaporComponent } from '../component'
|
import { isVaporComponent } from '../component'
|
||||||
import { type Block, DynamicFragment, type TransitionBlock } from '../block'
|
import type { Block, TransitionBlock } from '../block'
|
||||||
import { isArray } from '@vue/shared'
|
import { isArray } from '@vue/shared'
|
||||||
|
import { DynamicFragment } from '../fragment'
|
||||||
|
|
||||||
export function applyVShow(target: Block, source: () => any): void {
|
export function applyVShow(target: Block, source: () => any): void {
|
||||||
if (isVaporComponent(target)) {
|
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,
|
mountComponent,
|
||||||
unmountComponent,
|
unmountComponent,
|
||||||
} from './component'
|
} from './component'
|
||||||
|
import { handleTeleportRootComponentHmrReload } from './components/Teleport'
|
||||||
|
|
||||||
export function hmrRerender(instance: VaporComponentInstance): void {
|
export function hmrRerender(instance: VaporComponentInstance): void {
|
||||||
const normalized = normalizeBlock(instance.block)
|
const normalized = normalizeBlock(instance.block)
|
||||||
const parent = normalized[0].parentNode!
|
const parent = normalized[0].parentNode!
|
||||||
const anchor = normalized[normalized.length - 1].nextSibling
|
const anchor = normalized[normalized.length - 1].nextSibling
|
||||||
remove(instance.block, parent)
|
remove(instance.block, parent)
|
||||||
|
if (instance.hmrRerenderEffects) {
|
||||||
|
instance.hmrRerenderEffects.forEach(e => e())
|
||||||
|
instance.hmrRerenderEffects.length = 0
|
||||||
|
}
|
||||||
const prev = currentInstance
|
const prev = currentInstance
|
||||||
simpleSetCurrentInstance(instance)
|
simpleSetCurrentInstance(instance)
|
||||||
pushWarningContext(instance)
|
pushWarningContext(instance)
|
||||||
|
@ -46,4 +51,5 @@ export function hmrReload(
|
||||||
)
|
)
|
||||||
simpleSetCurrentInstance(prev, instance.parent)
|
simpleSetCurrentInstance(prev, instance.parent)
|
||||||
mountComponent(newInstance, parent, anchor)
|
mountComponent(newInstance, parent, anchor)
|
||||||
|
handleTeleportRootComponentHmrReload(instance, newInstance)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,10 @@ export { createVaporApp, createVaporSSRApp } from './apiCreateApp'
|
||||||
export { defineVaporComponent } from './apiDefineComponent'
|
export { defineVaporComponent } from './apiDefineComponent'
|
||||||
export { vaporInteropPlugin } from './vdomInterop'
|
export { vaporInteropPlugin } from './vdomInterop'
|
||||||
export type { VaporDirective } from './directives/custom'
|
export type { VaporDirective } from './directives/custom'
|
||||||
|
export { VaporTeleportImpl as VaporTeleport } from './components/Teleport'
|
||||||
|
|
||||||
// compiler-use only
|
// compiler-use only
|
||||||
export { insert, prepend, remove, isFragment, VaporFragment } from './block'
|
export { insert, prepend, remove } from './block'
|
||||||
export { setInsertionState } from './insertionState'
|
export { setInsertionState } from './insertionState'
|
||||||
export { createComponent, createComponentWithFallback } from './component'
|
export { createComponent, createComponentWithFallback } from './component'
|
||||||
export { renderEffect } from './renderEffect'
|
export { renderEffect } from './renderEffect'
|
||||||
|
@ -46,3 +47,4 @@ export {
|
||||||
export { withVaporDirectives } from './directives/custom'
|
export { withVaporDirectives } from './directives/custom'
|
||||||
export { VaporTransition } from './components/Transition'
|
export { VaporTransition } from './components/Transition'
|
||||||
export { VaporTransitionGroup } from './components/TransitionGroup'
|
export { VaporTransitionGroup } from './components/TransitionGroup'
|
||||||
|
export { isFragment, VaporFragment } from './fragment'
|
||||||
|
|
|
@ -11,7 +11,10 @@ import {
|
||||||
import { type VaporComponentInstance, isVaporComponent } from './component'
|
import { type VaporComponentInstance, isVaporComponent } from './component'
|
||||||
import { invokeArrayFns } from '@vue/shared'
|
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 instance = currentInstance as VaporComponentInstance | null
|
||||||
const scope = getCurrentScope()
|
const scope = getCurrentScope()
|
||||||
if (__DEV__ && !__TEST__ && !scope && !isVaporComponent(instance)) {
|
if (__DEV__ && !__TEST__ && !scope && !isVaporComponent(instance)) {
|
||||||
|
@ -66,5 +69,6 @@ export function renderEffect(fn: () => void, noLifecycle = false): void {
|
||||||
effect.scheduler = () => queueJob(job)
|
effect.scheduler = () => queueJob(job)
|
||||||
effect.run()
|
effect.run()
|
||||||
|
|
||||||
|
return effect
|
||||||
// TODO recurse handling
|
// TODO recurse handling
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,15 +37,7 @@ import {
|
||||||
mountComponent,
|
mountComponent,
|
||||||
unmountComponent,
|
unmountComponent,
|
||||||
} from './component'
|
} from './component'
|
||||||
import {
|
import { type Block, type VaporTransitionHooks, insert, remove } from './block'
|
||||||
type Block,
|
|
||||||
DynamicFragment,
|
|
||||||
VaporFragment,
|
|
||||||
type VaporTransitionHooks,
|
|
||||||
insert,
|
|
||||||
isFragment,
|
|
||||||
remove,
|
|
||||||
} from './block'
|
|
||||||
import {
|
import {
|
||||||
EMPTY_OBJ,
|
EMPTY_OBJ,
|
||||||
extend,
|
extend,
|
||||||
|
@ -65,6 +57,7 @@ import {
|
||||||
locateHydrationNode,
|
locateHydrationNode,
|
||||||
hydrateNode as vaporHydrateNode,
|
hydrateNode as vaporHydrateNode,
|
||||||
} from './dom/hydration'
|
} from './dom/hydration'
|
||||||
|
import { DynamicFragment, VaporFragment, isFragment } from './fragment'
|
||||||
|
|
||||||
// mounting vapor components and slots in vdom
|
// mounting vapor components and slots in vdom
|
||||||
const vaporInteropImpl: Omit<
|
const vaporInteropImpl: Omit<
|
||||||
|
|
|
@ -55,7 +55,7 @@ importers:
|
||||||
version: 5.0.4(rollup@4.44.0)
|
version: 5.0.4(rollup@4.44.0)
|
||||||
'@swc/core':
|
'@swc/core':
|
||||||
specifier: ^1.11.24
|
specifier: ^1.11.24
|
||||||
version: 1.12.3
|
version: 1.12.4
|
||||||
'@types/hash-sum':
|
'@types/hash-sum':
|
||||||
specifier: ^1.0.2
|
specifier: ^1.0.2
|
||||||
version: 1.0.2
|
version: 1.0.2
|
||||||
|
@ -1288,68 +1288,68 @@ packages:
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@swc/core-darwin-arm64@1.12.3':
|
'@swc/core-darwin-arm64@1.12.4':
|
||||||
resolution: {integrity: sha512-QCV9vQ/s27AMxm8j8MTDL/nDoiEMrANiENRrWnb0Fxvz/O39CajPVShp/W7HlOkzt1GYtUXPdQJpSKylugfrWw==}
|
resolution: {integrity: sha512-HihKfeitjZU2ab94Zf893sxzFryLKX0TweGsNXXOLNtkSMLw50auuYfpRM0BOL9/uXXtuCWgRIF6P030SAX5xQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
'@swc/core-darwin-x64@1.12.3':
|
'@swc/core-darwin-x64@1.12.4':
|
||||||
resolution: {integrity: sha512-LylCMfzGhdvl5tyKaTT9ePetHUX7wSsST7hxWiHzS+cUMj7FnhcfdEr6kcNVT7y1RJn3fCvuv7T98ZB+T2q3HA==}
|
resolution: {integrity: sha512-meYCXHyYb6RDdu2N5PNAf0EelyxPBFhRcVo4kBFLuvuNb0m6EUg///VWy8MUMXq9/s9uzGS9kJVXXdRdr/d6FA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
'@swc/core-linux-arm-gnueabihf@1.12.3':
|
'@swc/core-linux-arm-gnueabihf@1.12.4':
|
||||||
resolution: {integrity: sha512-DQODb7S+q+pwQY41Azcavwb2rb4rGxP70niScRDxB9X68hHOM9D0w9fxzC+Nr3AHcPSmVJUYUIiq5h38O5hVgQ==}
|
resolution: {integrity: sha512-szfDbf7mE8V64of0q/LSqbk+em+T+TD3uqnH40Z7Qu/aL8vi5CHgyLjWG2SLkLLpyjgkAUF6AKrupgnBYcC2NA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@swc/core-linux-arm64-gnu@1.12.3':
|
'@swc/core-linux-arm64-gnu@1.12.4':
|
||||||
resolution: {integrity: sha512-nTxtJSq78AjeaQBueYImoFBs5j7qXbgOxtirpyt8jE29NQBd0VFzDzRBhkr6I9jq0hNiChgMkqBN4eUkEQjytg==}
|
resolution: {integrity: sha512-n0IY76w+Scx8m3HIVRvLkoResuwsQgjDfAk9bxn99dq4leQO+mE0fkPl0Yw/1BIsPh+kxGfopIJH9zsZ1Z2YrA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@swc/core-linux-arm64-musl@1.12.3':
|
'@swc/core-linux-arm64-musl@1.12.4':
|
||||||
resolution: {integrity: sha512-lBGvC5UgPSxqLr/y1NZxQhyRQ7nXy3/Ec1Z47YNXtqtpKiG1EcOGPyS0UZgwiYQkXqq8NBFMHnyHmpKnXTvRDA==}
|
resolution: {integrity: sha512-wE5jmFi5cEQyLy8WmCWmNwfKETrnzy2D8YNi/xpYWpLPWqPhcelpa6tswkfYlbsMmmOh7hQNoTba1QdGu0jvHQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@swc/core-linux-x64-gnu@1.12.3':
|
'@swc/core-linux-x64-gnu@1.12.4':
|
||||||
resolution: {integrity: sha512-61wZ8hwxNYzBY9MCWB50v90ICzdIhOuPk1O1qXswz9AXw5O6iQStEBHQ1rozPkfQ/rmhepk0pOf/6LCwssJOwg==}
|
resolution: {integrity: sha512-6S50Xd/7ePjEwrXyHMxpKTZ+KBrgUwMA8hQPbArUOwH4S5vHBr51heL0iXbUkppn1bkSr0J0IbOove5hzn+iqQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@swc/core-linux-x64-musl@1.12.3':
|
'@swc/core-linux-x64-musl@1.12.4':
|
||||||
resolution: {integrity: sha512-NNeBiTpCgWt80vumTKVoaj6Fa/ZjUcaNQNM7np3PIgB8EbuXfyztboV7vUxpkmD/lUgsk8GlEFYViHvo6VMefQ==}
|
resolution: {integrity: sha512-hbYRyaHhC13vYKuGG5BrAG5fjjWEQFfQetuFp/4QKEoXDzdnabJoixxWTQACDL3m0JW32nJ+gUzsYIPtFYkwXg==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@swc/core-win32-arm64-msvc@1.12.3':
|
'@swc/core-win32-arm64-msvc@1.12.4':
|
||||||
resolution: {integrity: sha512-fxraM7exaPb1/W0CoHW45EFNOQUQh0nonBEcNFm2iv095mziBwttyxZyQBoDkQocpkd5NtsZw3xW5FTBPnn+Vw==}
|
resolution: {integrity: sha512-e6EbfjPL8GA/bb1lc9Omtxjlz+1ThTsAuBsy4Q3Kpbuh6B3jclg8KzxU/6t91v23wG593mieTyR5f3Pr7X3AWw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@swc/core-win32-ia32-msvc@1.12.3':
|
'@swc/core-win32-ia32-msvc@1.12.4':
|
||||||
resolution: {integrity: sha512-FFIhMPXIDjRcewomwbYGPvem7Fj76AsuzbRahnAyp+OzJwrrtxVmra/kyUCfj4kix7vdGByY0WvVfiVCf5b7Mg==}
|
resolution: {integrity: sha512-RG2FzmllBTUf4EksANlIvLckcBrLZEA0t13LIa6L213UZKQfEuDNHezqESgoVhJMg2S/tWauitATOCFgZNSmjg==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [ia32]
|
cpu: [ia32]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@swc/core-win32-x64-msvc@1.12.3':
|
'@swc/core-win32-x64-msvc@1.12.4':
|
||||||
resolution: {integrity: sha512-Sf4iSg+IYT5AzFSDDmii08DfeKcvtkVxIuo+uS8BJMbiLjFNjgMkkVlBthknGyJcSK15ncg9248XjnM4jU8DZA==}
|
resolution: {integrity: sha512-oRHKnZlR83zaMeVUCmHENa4j5uNRAWbmEpjYbzRcfC45LPFNWKGWGAGERLx0u87XMUtTGqnVYxnBTHN/rzDHOw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@swc/core@1.12.3':
|
'@swc/core@1.12.4':
|
||||||
resolution: {integrity: sha512-c4NeXW8P3gPqcFwtm+4aH+F2Cj5KJLMiLaKhSj3mpv19glq+jmekomdktAw/VHyjsXlsmouOeNWrk8rVlkCRsg==}
|
resolution: {integrity: sha512-hn30ebV4njAn0NAUM+3a0qCF+MJgqTNSrfA/hUAbC6TVjOQy2OYGQwkUvCu/V7S2+rZxrUsTpKOnZ7qqECZV9Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@swc/helpers': '>=0.5.17'
|
'@swc/helpers': '>=0.5.17'
|
||||||
|
@ -4482,51 +4482,51 @@ snapshots:
|
||||||
'@rollup/rollup-win32-x64-msvc@4.44.0':
|
'@rollup/rollup-win32-x64-msvc@4.44.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@swc/core-darwin-arm64@1.12.3':
|
'@swc/core-darwin-arm64@1.12.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@swc/core-darwin-x64@1.12.3':
|
'@swc/core-darwin-x64@1.12.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@swc/core-linux-arm-gnueabihf@1.12.3':
|
'@swc/core-linux-arm-gnueabihf@1.12.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@swc/core-linux-arm64-gnu@1.12.3':
|
'@swc/core-linux-arm64-gnu@1.12.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@swc/core-linux-arm64-musl@1.12.3':
|
'@swc/core-linux-arm64-musl@1.12.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@swc/core-linux-x64-gnu@1.12.3':
|
'@swc/core-linux-x64-gnu@1.12.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@swc/core-linux-x64-musl@1.12.3':
|
'@swc/core-linux-x64-musl@1.12.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@swc/core-win32-arm64-msvc@1.12.3':
|
'@swc/core-win32-arm64-msvc@1.12.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@swc/core-win32-ia32-msvc@1.12.3':
|
'@swc/core-win32-ia32-msvc@1.12.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@swc/core-win32-x64-msvc@1.12.3':
|
'@swc/core-win32-x64-msvc@1.12.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@swc/core@1.12.3':
|
'@swc/core@1.12.4':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@swc/counter': 0.1.3
|
'@swc/counter': 0.1.3
|
||||||
'@swc/types': 0.1.23
|
'@swc/types': 0.1.23
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@swc/core-darwin-arm64': 1.12.3
|
'@swc/core-darwin-arm64': 1.12.4
|
||||||
'@swc/core-darwin-x64': 1.12.3
|
'@swc/core-darwin-x64': 1.12.4
|
||||||
'@swc/core-linux-arm-gnueabihf': 1.12.3
|
'@swc/core-linux-arm-gnueabihf': 1.12.4
|
||||||
'@swc/core-linux-arm64-gnu': 1.12.3
|
'@swc/core-linux-arm64-gnu': 1.12.4
|
||||||
'@swc/core-linux-arm64-musl': 1.12.3
|
'@swc/core-linux-arm64-musl': 1.12.4
|
||||||
'@swc/core-linux-x64-gnu': 1.12.3
|
'@swc/core-linux-x64-gnu': 1.12.4
|
||||||
'@swc/core-linux-x64-musl': 1.12.3
|
'@swc/core-linux-x64-musl': 1.12.4
|
||||||
'@swc/core-win32-arm64-msvc': 1.12.3
|
'@swc/core-win32-arm64-msvc': 1.12.4
|
||||||
'@swc/core-win32-ia32-msvc': 1.12.3
|
'@swc/core-win32-ia32-msvc': 1.12.4
|
||||||
'@swc/core-win32-x64-msvc': 1.12.3
|
'@swc/core-win32-x64-msvc': 1.12.4
|
||||||
|
|
||||||
'@swc/counter@0.1.3': {}
|
'@swc/counter@0.1.3': {}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue