Skip to content

Commit e3a33e6

Browse files
committed
wip(vapor): component hydration
1 parent a2415de commit e3a33e6

File tree

14 files changed

+333
-118
lines changed

14 files changed

+333
-118
lines changed

packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function render(_ctx) {
2626
`;
2727

2828
exports[`compile > custom directive > component 1`] = `
29-
"import { resolveComponent as _resolveComponent, resolveDirective as _resolveDirective, createComponentWithFallback as _createComponentWithFallback, withVaporDirectives as _withVaporDirectives, insert as _insert, createIf as _createIf, template as _template } from 'vue';
29+
"import { resolveComponent as _resolveComponent, resolveDirective as _resolveDirective, setInsertionState as _setInsertionState, createComponentWithFallback as _createComponentWithFallback, withVaporDirectives as _withVaporDirectives, createIf as _createIf, template as _template } from 'vue';
3030
const t0 = _template("<div></div>")
3131
3232
export function render(_ctx) {
@@ -38,9 +38,9 @@ export function render(_ctx) {
3838
"default": () => {
3939
const n0 = _createIf(() => (true), () => {
4040
const n3 = t0()
41+
_setInsertionState(n3)
4142
const n2 = _createComponentWithFallback(_component_Bar)
4243
_withVaporDirectives(n2, [[_directive_hello, void 0, void 0, { world: true }]])
43-
_insert(n2, n3)
4444
return n3
4545
})
4646
return n0
@@ -149,7 +149,7 @@ export function render(_ctx, $props, $emit, $attrs, $slots) {
149149
`;
150150
151151
exports[`compile > directives > v-pre > should not affect siblings after it 1`] = `
152-
"import { resolveComponent as _resolveComponent, child as _child, createComponentWithFallback as _createComponentWithFallback, prepend as _prepend, toDisplayString as _toDisplayString, setText as _setText, setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue';
152+
"import { resolveComponent as _resolveComponent, child as _child, setInsertionState as _setInsertionState, createComponentWithFallback as _createComponentWithFallback, toDisplayString as _toDisplayString, setText as _setText, setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue';
153153
const t0 = _template("<div :id=\\"foo\\"><Comp></Comp>{{ bar }}</div>")
154154
const t1 = _template("<div> </div>")
155155
@@ -158,8 +158,8 @@ export function render(_ctx, $props, $emit, $attrs, $slots) {
158158
const n0 = t0()
159159
const n3 = t1()
160160
const n2 = _child(n3)
161+
_setInsertionState(n3, 0)
161162
const n1 = _createComponentWithFallback(_component_Comp)
162-
_prepend(n3, n1)
163163
_renderEffect(() => {
164164
_setText(n2, _toDisplayString(_ctx.bar))
165165
_setProp(n3, "id", _ctx.foo)

packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,20 +65,20 @@ export function render(_ctx) {
6565
`;
6666

6767
exports[`compiler: v-for > nested v-for 1`] = `
68-
"import { child as _child, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, insert as _insert, template as _template } from 'vue';
68+
"import { setInsertionState as _setInsertionState, child as _child, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue';
6969
const t0 = _template("<span> </span>")
7070
const t1 = _template("<div></div>", true)
7171
7272
export function render(_ctx) {
7373
const n0 = _createFor(() => (_ctx.list), (_for_item0) => {
7474
const n5 = t1()
75+
_setInsertionState(n5)
7576
const n2 = _createFor(() => (_for_item0.value), (_for_item1) => {
7677
const n4 = t0()
7778
const x4 = _child(n4)
7879
_renderEffect(() => _setText(x4, _toDisplayString(_for_item1.value+_for_item0.value)))
7980
return n4
8081
}, null, 1)
81-
_insert(n2, n5)
8282
return n5
8383
})
8484
return n0

packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ export function render(_ctx) {
3636
`;
3737

3838
exports[`compiler: v-once > on component 1`] = `
39-
"import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback, insert as _insert, template as _template } from 'vue';
39+
"import { resolveComponent as _resolveComponent, setInsertionState as _setInsertionState, createComponentWithFallback as _createComponentWithFallback, template as _template } from 'vue';
4040
const t0 = _template("<div></div>", true)
4141
4242
export function render(_ctx) {
4343
const _component_Comp = _resolveComponent("Comp")
4444
const n1 = t0()
45+
_setInsertionState(n1)
4546
const n0 = _createComponentWithFallback(_component_Comp, { id: () => (_ctx.foo) }, null, null, true)
46-
_insert(n0, n1)
4747
return n1
4848
}"
4949
`;

packages/compiler-vapor/__tests__/transforms/vOnce.spec.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,6 @@ describe('compiler: v-once', () => {
132132
id: 0,
133133
tag: 'Comp',
134134
once: true,
135-
},
136-
{
137-
type: IRNodeTypes.INSERT_NODE,
138-
elements: [0],
139135
parent: 1,
140136
},
141137
])

packages/compiler-vapor/src/generators/component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export function genCreateComponent(
5151
const rawSlots = genRawSlots(slots, context)
5252
const [ids, handlers] = processInlineHandlers(props, context)
5353
const rawProps = context.withId(() => genRawProps(props, context), ids)
54+
5455
const inlineHandlers: CodeFragment[] = handlers.reduce<CodeFragment[]>(
5556
(acc, { name, value }) => {
5657
const handler = genEventHandler(context, value, undefined, false)

packages/compiler-vapor/src/generators/operation.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { type IREffect, IRNodeTypes, type OperationNode } from '../ir'
1+
import {
2+
type IREffect,
3+
IRNodeTypes,
4+
type InsertionStateTypes,
5+
type OperationNode,
6+
isTypeThatNeedsInsertionState,
7+
} from '../ir'
28
import type { CodegenContext } from '../generate'
39
import { genInsertNode, genPrependNode } from './dom'
410
import { genSetDynamicEvents, genSetEvent } from './event'
@@ -14,6 +20,7 @@ import {
1420
INDENT_START,
1521
NEWLINE,
1622
buildCodeFragment,
23+
genCall,
1724
} from './utils'
1825
import { genCreateComponent } from './component'
1926
import { genSlotOutlet } from './slotOutlet'
@@ -26,6 +33,9 @@ export function genOperations(
2633
): CodeFragment[] {
2734
const [frag, push] = buildCodeFragment()
2835
for (const operation of opers) {
36+
if (isTypeThatNeedsInsertionState(operation) && operation.parent) {
37+
push(...genInsertionstate(operation, context))
38+
}
2939
push(...genOperation(operation, context))
3040
}
3141
return frag
@@ -134,3 +144,21 @@ export function genEffect(
134144

135145
return frag
136146
}
147+
148+
function genInsertionstate(
149+
operation: InsertionStateTypes,
150+
context: CodegenContext,
151+
): CodeFragment[] {
152+
return [
153+
NEWLINE,
154+
...genCall(
155+
context.helper('setInsertionState'),
156+
`n${operation.parent}`,
157+
operation.anchor == null
158+
? undefined
159+
: operation.anchor === -1 // -1 indicates prepend
160+
? `0` // runtime anchor value for prepend
161+
: `n${operation.anchor}`,
162+
),
163+
]
164+
}

packages/compiler-vapor/src/ir/index.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ export interface IfIRNode extends BaseIRNode {
7676
positive: BlockIRNode
7777
negative?: BlockIRNode | IfIRNode
7878
once?: boolean
79+
parent?: number
80+
anchor?: number
7981
}
8082

8183
export interface IRFor {
@@ -93,6 +95,8 @@ export interface ForIRNode extends BaseIRNode, IRFor {
9395
once: boolean
9496
component: boolean
9597
onlyChild: boolean
98+
parent?: number
99+
anchor?: number
96100
}
97101

98102
export interface SetPropIRNode extends BaseIRNode {
@@ -158,6 +162,7 @@ export interface SetTemplateRefIRNode extends BaseIRNode {
158162
effect: boolean
159163
}
160164

165+
// TODO remove, no longer needed
161166
export interface CreateTextNodeIRNode extends BaseIRNode {
162167
type: IRNodeTypes.CREATE_TEXT_NODE
163168
id: number
@@ -198,6 +203,8 @@ export interface CreateComponentIRNode extends BaseIRNode {
198203
root: boolean
199204
once: boolean
200205
dynamic?: SimpleExpressionNode
206+
parent?: number
207+
anchor?: number
201208
}
202209

203210
export interface DeclareOldRefIRNode extends BaseIRNode {
@@ -211,6 +218,8 @@ export interface SlotOutletIRNode extends BaseIRNode {
211218
name: SimpleExpressionNode
212219
props: IRProps[]
213220
fallback?: BlockIRNode
221+
parent?: number
222+
anchor?: number
214223
}
215224

216225
export interface GetTextChildIRNode extends BaseIRNode {
@@ -288,3 +297,21 @@ export type VaporDirectiveNode = Overwrite<
288297
arg: Exclude<DirectiveNode['arg'], CompoundExpressionNode>
289298
}
290299
>
300+
301+
export type InsertionStateTypes =
302+
| IfIRNode
303+
| ForIRNode
304+
| SlotOutletIRNode
305+
| CreateComponentIRNode
306+
307+
export function isTypeThatNeedsInsertionState(
308+
op: OperationNode,
309+
): op is InsertionStateTypes {
310+
const type = op.type
311+
return (
312+
type === IRNodeTypes.CREATE_COMPONENT_NODE ||
313+
type === IRNodeTypes.SLOT_OUTLET_NODE ||
314+
type === IRNodeTypes.IF ||
315+
type === IRNodeTypes.FOR
316+
)
317+
}

packages/compiler-vapor/src/transforms/transformChildren.ts

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ import {
44
type TransformContext,
55
transformNode,
66
} from '../transform'
7-
import { DynamicFlag, type IRDynamicInfo, IRNodeTypes } from '../ir'
7+
import {
8+
DynamicFlag,
9+
type IRDynamicInfo,
10+
IRNodeTypes,
11+
isTypeThatNeedsInsertionState as isBlockOperation,
12+
} from '../ir'
813

914
export const transformChildren: NodeTransform = (node, context) => {
1015
const isFragment =
@@ -66,21 +71,11 @@ function processDynamicChildren(context: TransformContext<ElementNode>) {
6671
if (prevDynamics.length) {
6772
if (hasStaticTemplate) {
6873
context.childrenTemplate[index - prevDynamics.length] = `<!>`
69-
7074
prevDynamics[0].flags -= DynamicFlag.NON_TEMPLATE
7175
const anchor = (prevDynamics[0].anchor = context.increaseId())
72-
context.registerOperation({
73-
type: IRNodeTypes.INSERT_NODE,
74-
elements: prevDynamics.map(child => child.id!),
75-
parent: context.reference(),
76-
anchor,
77-
})
76+
registerInsertion(prevDynamics, context, anchor)
7877
} else {
79-
context.registerOperation({
80-
type: IRNodeTypes.PREPEND_NODE,
81-
elements: prevDynamics.map(child => child.id!),
82-
parent: context.reference(),
83-
})
78+
registerInsertion(prevDynamics, context, -1 /* prepend */)
8479
}
8580
prevDynamics = []
8681
}
@@ -89,10 +84,32 @@ function processDynamicChildren(context: TransformContext<ElementNode>) {
8984
}
9085

9186
if (prevDynamics.length) {
92-
context.registerOperation({
93-
type: IRNodeTypes.INSERT_NODE,
94-
elements: prevDynamics.map(child => child.id!),
95-
parent: context.reference(),
96-
})
87+
registerInsertion(prevDynamics, context)
88+
}
89+
}
90+
91+
function registerInsertion(
92+
dynamics: IRDynamicInfo[],
93+
context: TransformContext,
94+
anchor?: number,
95+
) {
96+
for (const child of dynamics) {
97+
if (child.template != null) {
98+
// template node due to invalid nesting - generate actual insertion
99+
context.registerOperation({
100+
type: IRNodeTypes.INSERT_NODE,
101+
elements: dynamics.map(child => child.id!),
102+
parent: context.reference(),
103+
anchor,
104+
})
105+
} else {
106+
// block types
107+
for (const op of context.block.operation) {
108+
if (isBlockOperation(op) && op.id === child.id) {
109+
op.parent = context.reference()
110+
op.anchor = anchor
111+
}
112+
}
113+
}
97114
}
98115
}

0 commit comments

Comments
 (0)