Skip to content

Commit 891bfa2

Browse files
committed
wip: save
1 parent 05844e4 commit 891bfa2

File tree

4 files changed

+85
-27
lines changed

4 files changed

+85
-27
lines changed

packages/runtime-vapor/__tests__/components/Suspense.spec.ts

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,12 @@ describe('vapor / vdom interop', () => {
3535
return { container }
3636
}
3737

38-
function asyncWrapper(code: string) {
38+
function withAsyncScript(code: string) {
3939
return {
4040
code: `
4141
<script vapor>
42-
const data = _data;
42+
const data = _data;
43+
const components = _components;
4344
const p = new Promise(r => setTimeout(r, 5))
4445
data.deps.push(p.then(() => Promise.resolve()))
4546
await p
@@ -60,20 +61,54 @@ describe('vapor / vdom interop', () => {
6061
<Suspense>
6162
<components.VaporChild/>
6263
<template #fallback>
63-
<span>loading</span>
64+
<span>fallback</span>
6465
</template>
6566
</Suspense>
6667
</template>`,
6768
{
68-
VaporChild: asyncWrapper(`<template><div>hi</div></template>`),
69+
VaporChild: withAsyncScript(`<template><div>hi</div></template>`),
6970
},
7071
data,
7172
)
7273

73-
expect(container.innerHTML).toBe(`<span>loading</span>`)
74+
expect(container.innerHTML).toBe(`<span>fallback</span>`)
7475
expect(data.deps.length).toBe(1)
7576
await Promise.all(data.deps)
7677
await nextTick()
7778
expect(container.innerHTML).toBe(`<div>hi</div>`)
7879
})
80+
81+
test('vdom suspense: nested async vapor components', async () => {
82+
const data = { deps: [] }
83+
const { container } = await testSuspense(
84+
`<script setup>
85+
const components = _components;
86+
</script>
87+
<template>
88+
<Suspense>
89+
<components.AsyncOuter/>
90+
<template #fallback>
91+
<span>fallback</span>
92+
</template>
93+
</Suspense>
94+
</template>`,
95+
{
96+
AsyncOuter: withAsyncScript(
97+
`<template><components.AsyncInner/></template>`,
98+
),
99+
AsyncInner: withAsyncScript(`<template><div>inner</div></template>`),
100+
},
101+
data,
102+
)
103+
104+
expect(container.innerHTML).toBe(`<span>fallback</span>`)
105+
106+
await data.deps[0]
107+
await nextTick()
108+
expect(container.innerHTML).toBe(`<span>fallback</span>`)
109+
110+
await Promise.all(data.deps)
111+
await nextTick()
112+
expect(container.innerHTML).toBe(`<div>inner</div>`)
113+
})
79114
})

packages/runtime-vapor/src/component.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import {
6767
import { hmrReload, hmrRerender } from './hmr'
6868
import { isHydrating, locateHydrationNode } from './dom/hydration'
6969
import { insertionAnchor, insertionParent } from './insertionState'
70+
import { currentSuspense } from './components/Suspense'
7071

7172
export { currentInstance } from '@vue/runtime-dom'
7273

@@ -144,7 +145,6 @@ export function createComponent(
144145
appContext: GenericAppContext = (currentInstance &&
145146
currentInstance.appContext) ||
146147
emptyContext,
147-
parentSuspense?: SuspenseBoundary | null,
148148
): VaporComponentInstance {
149149
const _insertionParent = insertionParent
150150
const _insertionAnchor = insertionAnchor
@@ -188,7 +188,7 @@ export function createComponent(
188188
rawProps as RawProps,
189189
rawSlots as RawSlots,
190190
appContext,
191-
parentSuspense,
191+
currentSuspense,
192192
)
193193

194194
if (__DEV__) {
@@ -483,6 +483,30 @@ export function mountComponent(
483483
parent: ParentNode,
484484
anchor?: Node | null | 0,
485485
): void {
486+
if (
487+
__FEATURE_SUSPENSE__ &&
488+
instance.suspense &&
489+
instance.asyncDep &&
490+
!instance.asyncResolved
491+
) {
492+
const component = instance.type as any
493+
instance.suspense.registerDep(
494+
instance as any,
495+
(setupResult: any) => {
496+
handleSetupResult(
497+
setupResult,
498+
component,
499+
instance,
500+
undefined,
501+
isFunction(component) ? component : component.setup,
502+
)
503+
mountComponent(instance, parent, anchor)
504+
},
505+
false,
506+
)
507+
return
508+
}
509+
486510
if (__DEV__) {
487511
startMeasure(instance, `mount`)
488512
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import type { SuspenseBoundary } from '@vue/runtime-dom'
2+
3+
export let currentSuspense: SuspenseBoundary | null = null
4+
export function setCurrentSuspense(suspense: SuspenseBoundary | null): void {
5+
currentSuspense = suspense
6+
}
7+
8+
// TODO
9+
export const VaporSuspenseImpl = {
10+
name: 'VaporSuspense',
11+
__isSuspense: true,
12+
process(): void {},
13+
}

packages/runtime-vapor/src/vdomInterop.ts

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import {
2323
type VaporComponent,
2424
VaporComponentInstance,
2525
createComponent,
26-
handleSetupResult,
2726
mountComponent,
2827
unmountComponent,
2928
} from './component'
@@ -34,6 +33,7 @@ import type { RawSlots, VaporSlot } from './componentSlots'
3433
import { renderEffect } from './renderEffect'
3534
import { createTextNode } from './dom/node'
3635
import { optimizePropertyLookup } from './dom/prop'
36+
import { setCurrentSuspense } from './components/Suspense'
3737

3838
// mounting vapor components and slots in vdom
3939
const vaporInteropImpl: Omit<
@@ -49,6 +49,10 @@ const vaporInteropImpl: Omit<
4949
const propsRef = shallowRef(vnode.props)
5050
const slotsRef = shallowRef(vnode.children)
5151

52+
if (__FEATURE_SUSPENSE__) {
53+
setCurrentSuspense(parentSuspense)
54+
}
55+
5256
const component = vnode.type as any as VaporComponent
5357
// @ts-expect-error
5458
const instance = (vnode.component = createComponent(
@@ -61,28 +65,10 @@ const vaporInteropImpl: Omit<
6165
} as any as RawSlots,
6266
undefined,
6367
undefined,
64-
parentSuspense,
6568
))
6669
instance.rawPropsRef = propsRef
6770
instance.rawSlotsRef = slotsRef
68-
if (__FEATURE_SUSPENSE__ && parentSuspense && instance.asyncDep) {
69-
parentSuspense.registerDep(
70-
instance as any,
71-
(setupResult: any) => {
72-
handleSetupResult(
73-
setupResult,
74-
component,
75-
instance,
76-
undefined,
77-
isFunction(component) ? component : component.setup,
78-
)
79-
mountComponent(instance, container, selfAnchor)
80-
},
81-
false,
82-
)
83-
} else {
84-
mountComponent(instance, container, selfAnchor)
85-
}
71+
mountComponent(instance, container, selfAnchor)
8672
simpleSetCurrentInstance(prev)
8773
return instance
8874
},

0 commit comments

Comments
 (0)