Skip to content

Commit 9d651e2

Browse files
refactor(reactivity): ports alien-signals 1.0.0 (#12570)
1 parent f7d95ce commit 9d651e2

File tree

9 files changed

+372
-338
lines changed

9 files changed

+372
-338
lines changed

packages/reactivity/__tests__/computed.spec.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,8 +467,12 @@ describe('reactivity/computed', () => {
467467
const c2 = computed(() => c1.value) as unknown as ComputedRefImpl
468468

469469
c2.value
470-
expect(c1.flags & SubscriberFlags.Dirtys).toBe(0)
471-
expect(c2.flags & SubscriberFlags.Dirtys).toBe(0)
470+
expect(
471+
c1.flags & (SubscriberFlags.Dirty | SubscriberFlags.PendingComputed),
472+
).toBe(0)
473+
expect(
474+
c2.flags & (SubscriberFlags.Dirty | SubscriberFlags.PendingComputed),
475+
).toBe(0)
472476
})
473477

474478
it('should chained computeds dirtyLevel update with first computed effect', () => {

packages/reactivity/src/computed.ts

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,20 @@ import {
55
type DebuggerEvent,
66
type DebuggerOptions,
77
activeSub,
8-
activeTrackId,
9-
nextTrackId,
108
setActiveSub,
119
} from './effect'
1210
import { activeEffectScope } from './effectScope'
1311
import type { Ref } from './ref'
1412
import {
1513
type Dependency,
16-
type IComputed,
1714
type Link,
15+
type Subscriber,
1816
SubscriberFlags,
19-
checkDirty,
20-
endTrack,
17+
endTracking,
2118
link,
22-
startTrack,
19+
processComputedUpdate,
20+
startTracking,
21+
updateDirtyFlag,
2322
} from './system'
2423
import { warn } from './warning'
2524

@@ -54,22 +53,20 @@ export interface WritableComputedOptions<T, S = T> {
5453
* @private exported by @vue/reactivity for Vue core use, but not exported from
5554
* the main vue package
5655
*/
57-
export class ComputedRefImpl<T = any> implements IComputed {
56+
export class ComputedRefImpl<T = any> implements Dependency, Subscriber {
5857
/**
5958
* @internal
6059
*/
6160
_value: T | undefined = undefined
62-
version = 0
6361

6462
// Dependency
6563
subs: Link | undefined = undefined
6664
subsTail: Link | undefined = undefined
67-
lastTrackedId = 0
6865

6966
// Subscriber
7067
deps: Link | undefined = undefined
7168
depsTail: Link | undefined = undefined
72-
flags: SubscriberFlags = SubscriberFlags.Dirty
69+
flags: SubscriberFlags = SubscriberFlags.Computed | SubscriberFlags.Dirty
7370

7471
/**
7572
* @internal
@@ -93,24 +90,20 @@ export class ComputedRefImpl<T = any> implements IComputed {
9390
// for backwards compat
9491
get _dirty(): boolean {
9592
const flags = this.flags
96-
if (flags & SubscriberFlags.Dirty) {
93+
if (
94+
flags & SubscriberFlags.Dirty ||
95+
(flags & SubscriberFlags.PendingComputed &&
96+
updateDirtyFlag(this, this.flags))
97+
) {
9798
return true
98-
} else if (flags & SubscriberFlags.ToCheckDirty) {
99-
if (checkDirty(this.deps!)) {
100-
this.flags |= SubscriberFlags.Dirty
101-
return true
102-
} else {
103-
this.flags &= ~SubscriberFlags.ToCheckDirty
104-
return false
105-
}
10699
}
107100
return false
108101
}
109102
set _dirty(v: boolean) {
110103
if (v) {
111104
this.flags |= SubscriberFlags.Dirty
112105
} else {
113-
this.flags &= ~SubscriberFlags.Dirtys
106+
this.flags &= ~(SubscriberFlags.Dirty | SubscriberFlags.PendingComputed)
114107
}
115108
}
116109

@@ -133,23 +126,20 @@ export class ComputedRefImpl<T = any> implements IComputed {
133126
}
134127

135128
get value(): T {
136-
if (this._dirty) {
137-
this.update()
129+
const flags = this.flags
130+
if (flags & (SubscriberFlags.Dirty | SubscriberFlags.PendingComputed)) {
131+
processComputedUpdate(this, flags)
138132
}
139-
if (activeTrackId !== 0 && this.lastTrackedId !== activeTrackId) {
133+
if (activeSub !== undefined) {
140134
if (__DEV__) {
141135
onTrack(activeSub!, {
142136
target: this,
143137
type: TrackOpTypes.GET,
144138
key: 'value',
145139
})
146140
}
147-
this.lastTrackedId = activeTrackId
148-
link(this, activeSub!).version = this.version
149-
} else if (
150-
activeEffectScope !== undefined &&
151-
this.lastTrackedId !== activeEffectScope.trackId
152-
) {
141+
link(this, activeSub)
142+
} else if (activeEffectScope !== undefined) {
153143
link(this, activeEffectScope)
154144
}
155145
return this._value!
@@ -165,23 +155,20 @@ export class ComputedRefImpl<T = any> implements IComputed {
165155

166156
update(): boolean {
167157
const prevSub = activeSub
168-
const prevTrackId = activeTrackId
169-
setActiveSub(this, nextTrackId())
170-
startTrack(this)
171-
const oldValue = this._value
172-
let newValue: T
158+
setActiveSub(this)
159+
startTracking(this)
173160
try {
174-
newValue = this.fn(oldValue)
161+
const oldValue = this._value
162+
const newValue = this.fn(oldValue)
163+
if (hasChanged(oldValue, newValue)) {
164+
this._value = newValue
165+
return true
166+
}
167+
return false
175168
} finally {
176-
setActiveSub(prevSub, prevTrackId)
177-
endTrack(this)
169+
setActiveSub(prevSub)
170+
endTracking(this)
178171
}
179-
if (hasChanged(oldValue, newValue)) {
180-
this._value = newValue
181-
this.version++
182-
return true
183-
}
184-
return false
185172
}
186173
}
187174

packages/reactivity/src/debug.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,22 @@ export function setupOnTrigger(target: { new (...args: any[]): any }): void {
6262
}
6363

6464
function setupFlagsHandler(target: Subscriber): void {
65-
// @ts-expect-error
66-
target._flags = target.flags
65+
;(target as any)._flags = target.flags
6766
Object.defineProperty(target, 'flags', {
6867
get() {
69-
// @ts-expect-error
70-
return target._flags
68+
return (target as any)._flags
7169
},
7270
set(value) {
7371
if (
74-
// @ts-expect-error
75-
!(target._flags >> SubscriberFlags.DirtyFlagsIndex) &&
76-
!!(value >> SubscriberFlags.DirtyFlagsIndex)
72+
!(
73+
(target as any)._flags &
74+
(SubscriberFlags.PendingComputed | SubscriberFlags.Dirty)
75+
) &&
76+
!!(value & (SubscriberFlags.PendingComputed | SubscriberFlags.Dirty))
7777
) {
7878
onTrigger(this)
7979
}
80-
// @ts-expect-error
81-
target._flags = value
80+
;(target as any)._flags = value
8281
},
8382
})
8483
}

packages/reactivity/src/dep.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { isArray, isIntegerKey, isMap, isSymbol } from '@vue/shared'
22
import { type TrackOpTypes, TriggerOpTypes } from './constants'
33
import { onTrack, triggerEventInfos } from './debug'
4-
import { activeSub, activeTrackId } from './effect'
4+
import { activeSub } from './effect'
55
import {
66
type Dependency,
77
type Link,
@@ -14,7 +14,6 @@ import {
1414
class Dep implements Dependency {
1515
_subs: Link | undefined = undefined
1616
subsTail: Link | undefined = undefined
17-
lastTrackedId = 0
1817

1918
constructor(
2019
private map: KeyToDepMap,
@@ -62,7 +61,7 @@ export const ARRAY_ITERATE_KEY: unique symbol = Symbol(
6261
* @param key - Identifier of the reactive property to track.
6362
*/
6463
export function track(target: object, type: TrackOpTypes, key: unknown): void {
65-
if (activeTrackId > 0) {
64+
if (activeSub !== undefined) {
6665
let depsMap = targetMap.get(target)
6766
if (!depsMap) {
6867
targetMap.set(target, (depsMap = new Map()))
@@ -71,17 +70,14 @@ export function track(target: object, type: TrackOpTypes, key: unknown): void {
7170
if (!dep) {
7271
depsMap.set(key, (dep = new Dep(depsMap, key)))
7372
}
74-
if (dep.lastTrackedId !== activeTrackId) {
75-
if (__DEV__) {
76-
onTrack(activeSub!, {
77-
target,
78-
type,
79-
key,
80-
})
81-
}
82-
dep.lastTrackedId = activeTrackId
83-
link(dep, activeSub!)
73+
if (__DEV__) {
74+
onTrack(activeSub!, {
75+
target,
76+
type,
77+
key,
78+
})
8479
}
80+
link(dep, activeSub!)
8581
}
8682
}
8783

0 commit comments

Comments
 (0)