1- import { ReactiveEffect , getCurrentScope } from '@vue/reactivity'
1+ import {
2+ type EffectScope ,
3+ ReactiveEffect ,
4+ getCurrentScope ,
5+ } from '@vue/reactivity'
26import {
37 type SchedulerJob ,
48 currentInstance ,
@@ -11,60 +15,94 @@ import {
1115import { type VaporComponentInstance , isVaporComponent } from './component'
1216import { invokeArrayFns } from '@vue/shared'
1317
14- export function renderEffect ( fn : ( ) => void , noLifecycle = false ) : void {
15- const instance = currentInstance as VaporComponentInstance | null
16- const scope = getCurrentScope ( )
17- if ( __DEV__ && ! __TEST__ && ! scope && ! isVaporComponent ( instance ) ) {
18- warn ( 'renderEffect called without active EffectScope or Vapor instance.' )
19- }
18+ class RenderEffect extends ReactiveEffect {
19+ i : VaporComponentInstance | null
20+ scope : EffectScope | undefined
21+ baseJob : SchedulerJob
22+ postJob : SchedulerJob
23+
24+ constructor ( public render : ( ) => void ) {
25+ super ( )
26+ const instance = currentInstance as VaporComponentInstance | null
27+ const scope = getCurrentScope ( )
28+ if ( __DEV__ && ! __TEST__ && ! scope && ! isVaporComponent ( instance ) ) {
29+ warn ( 'renderEffect called without active EffectScope or Vapor instance.' )
30+ }
31+
32+ this . baseJob = ( ) => {
33+ if ( this . dirty ) {
34+ this . run ( )
35+ }
36+ }
37+ this . postJob = ( ) => {
38+ instance ! . isUpdating = false
39+ instance ! . u && invokeArrayFns ( instance ! . u )
40+ }
2041
21- // renderEffect is always called after user has registered all hooks
22- const hasUpdateHooks = instance && ( instance . bu || instance . u )
23- const renderEffectFn = noLifecycle
24- ? fn
25- : ( ) => {
26- if ( __DEV__ && instance ) {
27- startMeasure ( instance , `renderEffect` )
28- }
29- const prev = currentInstance
30- simpleSetCurrentInstance ( instance )
31- if ( scope ) scope . on ( )
32- if ( hasUpdateHooks && instance . isMounted && ! instance . isUpdating ) {
33- instance . isUpdating = true
34- instance . bu && invokeArrayFns ( instance . bu )
35- fn ( )
36- queuePostFlushCb ( ( ) => {
37- instance . isUpdating = false
38- instance . u && invokeArrayFns ( instance . u )
39- } )
40- } else {
41- fn ( )
42- }
43- if ( scope ) scope . off ( )
44- simpleSetCurrentInstance ( prev , instance )
45- if ( __DEV__ && instance ) {
46- startMeasure ( instance , `renderEffect` )
47- }
42+ if ( instance ) {
43+ if ( __DEV__ ) {
44+ this . onTrack = instance . rtc
45+ ? e => invokeArrayFns ( instance . rtc ! , e )
46+ : void 0
47+ this . onTrigger = instance . rtg
48+ ? e => invokeArrayFns ( instance . rtg ! , e )
49+ : void 0
4850 }
51+ this . baseJob . i = instance
52+ this . baseJob . id = instance . uid
53+ }
54+
55+ this . i = instance
56+ this . scope = scope
4957
50- const effect = new ReactiveEffect ( renderEffectFn )
51- const job : SchedulerJob = ( ) => effect . dirty && effect . run ( )
58+ // TODO recurse handling
59+ }
5260
53- if ( instance ) {
54- if ( __DEV__ ) {
55- effect . onTrack = instance . rtc
56- ? e => invokeArrayFns ( instance . rtc ! , e )
57- : void 0
58- effect . onTrigger = instance . rtg
59- ? e => invokeArrayFns ( instance . rtg ! , e )
60- : void 0
61+ callback ( ) {
62+ const instance = this . i !
63+ const scope = this . scope
64+ // renderEffect is always called after user has registered all hooks
65+ const hasUpdateHooks = instance && ( instance . bu || instance . u )
66+ if ( __DEV__ && instance ) {
67+ startMeasure ( instance , `renderEffect` )
6168 }
62- job . i = instance
63- job . id = instance . uid
69+ const prev = currentInstance
70+ simpleSetCurrentInstance ( instance )
71+ if ( scope ) scope . on ( )
72+ if ( hasUpdateHooks && instance . isMounted && ! instance . isUpdating ) {
73+ instance . isUpdating = true
74+ instance . bu && invokeArrayFns ( instance . bu )
75+ this . render ( )
76+ queuePostFlushCb ( this . postJob )
77+ } else {
78+ this . render ( )
79+ }
80+ if ( scope ) scope . off ( )
81+ simpleSetCurrentInstance ( prev , instance )
82+ if ( __DEV__ && instance ) {
83+ startMeasure ( instance , `renderEffect` )
84+ }
85+ }
86+
87+ scheduler ( ) {
88+ queueJob ( this . baseJob )
6489 }
90+ }
6591
66- effect . scheduler = ( ) => queueJob ( job )
67- effect . run ( )
92+ class RenderEffect_NoLifecycle extends RenderEffect {
93+ constructor ( render : ( ) => void ) {
94+ super ( render )
95+ }
6896
69- // TODO recurse handling
97+ callback ( ) {
98+ this . render ( )
99+ }
100+ }
101+
102+ export function renderEffect ( fn : ( ) => void , noLifecycle = false ) : void {
103+ if ( noLifecycle ) {
104+ new RenderEffect_NoLifecycle ( fn ) . run ( )
105+ } else {
106+ new RenderEffect ( fn ) . run ( )
107+ }
70108}
0 commit comments