Skip to content

Commit 4765af3

Browse files
committed
refactor(reactivity): alien-signals 2.0.1
1 parent b4c4fef commit 4765af3

File tree

9 files changed

+266
-259
lines changed

9 files changed

+266
-259
lines changed

packages/reactivity/__tests__/computed.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import {
2727
} from '../src'
2828
import type { ComputedRef, ComputedRefImpl } from '../src/computed'
2929
import { pauseTracking, resetTracking } from '../src/effect'
30-
import { SubscriberFlags } from '../src/system'
30+
import { ReactiveFlags } from '../src/system'
3131

3232
describe('reactivity/computed', () => {
3333
it('should return updated value', () => {
@@ -467,8 +467,8 @@ describe('reactivity/computed', () => {
467467
const c2 = computed(() => c1.value) as unknown as ComputedRefImpl
468468

469469
c2.value
470-
expect(c1.flags & (SubscriberFlags.Dirty | SubscriberFlags.Pending)).toBe(0)
471-
expect(c2.flags & (SubscriberFlags.Dirty | SubscriberFlags.Pending)).toBe(0)
470+
expect(c1.flags & (ReactiveFlags.Dirty | ReactiveFlags.Pending)).toBe(0)
471+
expect(c2.flags & (ReactiveFlags.Dirty | ReactiveFlags.Pending)).toBe(0)
472472
})
473473

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

packages/reactivity/__tests__/effect.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
stop,
2323
toRaw,
2424
} from '../src/index'
25-
import { type Dependency, endBatch, startBatch } from '../src/system'
25+
import { type ReactiveNode, endBatch, startBatch } from '../src/system'
2626

2727
describe('reactivity/effect', () => {
2828
it('should run the passed function once (wrapped by a effect)', () => {
@@ -1178,7 +1178,7 @@ describe('reactivity/effect', () => {
11781178
})
11791179

11801180
describe('dep unsubscribe', () => {
1181-
function getSubCount(dep: Dependency | undefined) {
1181+
function getSubCount(dep: ReactiveNode | undefined) {
11821182
let count = 0
11831183
let sub = dep!.subs
11841184
while (sub) {

packages/reactivity/src/computed.ts

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ import {
1010
import { activeEffectScope } from './effectScope'
1111
import type { Ref } from './ref'
1212
import {
13-
type Dependency,
1413
type Link,
15-
type Subscriber,
16-
SubscriberFlags,
14+
type ReactiveNode,
15+
ReactiveFlags as _ReactiveFlags,
1716
checkDirty,
1817
endTracking,
1918
link,
@@ -53,20 +52,17 @@ export interface WritableComputedOptions<T, S = T> {
5352
* @private exported by @vue/reactivity for Vue core use, but not exported from
5453
* the main vue package
5554
*/
56-
export class ComputedRefImpl<T = any> implements Dependency, Subscriber {
55+
export class ComputedRefImpl<T = any> implements ReactiveNode {
5756
/**
5857
* @internal
5958
*/
6059
_value: T | undefined = undefined
6160

62-
// Dependency
6361
subs: Link | undefined = undefined
6462
subsTail: Link | undefined = undefined
65-
66-
// Subscriber
6763
deps: Link | undefined = undefined
6864
depsTail: Link | undefined = undefined
69-
flags: SubscriberFlags = SubscriberFlags.Dirty
65+
flags: _ReactiveFlags = _ReactiveFlags.Mutable | _ReactiveFlags.Dirty
7066

7167
/**
7268
* @internal
@@ -84,7 +80,7 @@ export class ComputedRefImpl<T = any> implements Dependency, Subscriber {
8480
return this
8581
}
8682
// for backwards compat
87-
get dep(): Dependency {
83+
get dep(): ReactiveNode {
8884
return this
8985
}
9086
/**
@@ -93,15 +89,15 @@ export class ComputedRefImpl<T = any> implements Dependency, Subscriber {
9389
*/
9490
get _dirty(): boolean {
9591
const flags = this.flags
96-
if (flags & SubscriberFlags.Dirty) {
92+
if (flags & _ReactiveFlags.Dirty) {
9793
return true
9894
}
99-
if (flags & SubscriberFlags.Pending) {
100-
if (checkDirty(this.deps!)) {
101-
this.flags = flags | SubscriberFlags.Dirty
95+
if (flags & _ReactiveFlags.Pending) {
96+
if (checkDirty(this.deps!, this)) {
97+
this.flags = flags | _ReactiveFlags.Dirty
10298
return true
10399
} else {
104-
this.flags = flags & ~SubscriberFlags.Pending
100+
this.flags = flags & ~_ReactiveFlags.Pending
105101
}
106102
}
107103
return false
@@ -112,9 +108,9 @@ export class ComputedRefImpl<T = any> implements Dependency, Subscriber {
112108
*/
113109
set _dirty(v: boolean) {
114110
if (v) {
115-
this.flags |= SubscriberFlags.Dirty
111+
this.flags |= _ReactiveFlags.Dirty
116112
} else {
117-
this.flags &= ~(SubscriberFlags.Dirty | SubscriberFlags.Pending)
113+
this.flags &= ~(_ReactiveFlags.Dirty | _ReactiveFlags.Pending)
118114
}
119115
}
120116

@@ -139,17 +135,17 @@ export class ComputedRefImpl<T = any> implements Dependency, Subscriber {
139135
get value(): T {
140136
const flags = this.flags
141137
if (
142-
flags & SubscriberFlags.Dirty ||
143-
(flags & SubscriberFlags.Pending && checkDirty(this.deps!))
138+
flags & _ReactiveFlags.Dirty ||
139+
(flags & _ReactiveFlags.Pending && checkDirty(this.deps!, this))
144140
) {
145141
if (this.update()) {
146142
const subs = this.subs
147143
if (subs !== undefined) {
148144
shallowPropagate(subs)
149145
}
150146
}
151-
} else if (flags & SubscriberFlags.Pending) {
152-
this.flags = flags & ~SubscriberFlags.Pending
147+
} else if (flags & _ReactiveFlags.Pending) {
148+
this.flags = flags & ~_ReactiveFlags.Pending
153149
}
154150
if (activeSub !== undefined) {
155151
if (__DEV__) {

packages/reactivity/src/debug.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { extend } from '@vue/shared'
22
import type { DebuggerEventExtraInfo, ReactiveEffectOptions } from './effect'
3-
import { type Link, type Subscriber, SubscriberFlags } from './system'
3+
import { type Link, ReactiveFlags, type ReactiveNode } from './system'
44

55
export const triggerEventInfos: DebuggerEventExtraInfo[] = []
66

@@ -61,7 +61,7 @@ export function setupOnTrigger(target: { new (...args: any[]): any }): void {
6161
})
6262
}
6363

64-
function setupFlagsHandler(target: Subscriber): void {
64+
function setupFlagsHandler(target: ReactiveNode): void {
6565
;(target as any)._flags = target.flags
6666
Object.defineProperty(target, 'flags', {
6767
get() {
@@ -71,9 +71,9 @@ function setupFlagsHandler(target: Subscriber): void {
7171
if (
7272
!(
7373
(target as any)._flags &
74-
(SubscriberFlags.Dirty | SubscriberFlags.Pending)
74+
(ReactiveFlags.Dirty | ReactiveFlags.Pending)
7575
) &&
76-
!!(value & (SubscriberFlags.Dirty | SubscriberFlags.Pending))
76+
!!(value & (ReactiveFlags.Dirty | ReactiveFlags.Pending))
7777
) {
7878
onTrigger(this)
7979
}

packages/reactivity/src/dep.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,20 @@ import { type TrackOpTypes, TriggerOpTypes } from './constants'
33
import { onTrack, triggerEventInfos } from './debug'
44
import { activeSub } from './effect'
55
import {
6-
type Dependency,
76
type Link,
7+
ReactiveFlags,
8+
type ReactiveNode,
89
endBatch,
910
link,
1011
propagate,
12+
shallowPropagate,
1113
startBatch,
1214
} from './system'
1315

14-
class Dep implements Dependency {
16+
class Dep implements ReactiveNode {
1517
_subs: Link | undefined = undefined
1618
subsTail: Link | undefined = undefined
19+
flags: ReactiveFlags = ReactiveFlags.None
1720

1821
constructor(
1922
private map: KeyToDepMap,
@@ -103,7 +106,7 @@ export function trigger(
103106
return
104107
}
105108

106-
const run = (dep: Dependency | undefined) => {
109+
const run = (dep: ReactiveNode | undefined) => {
107110
if (dep !== undefined && dep.subs !== undefined) {
108111
if (__DEV__) {
109112
triggerEventInfos.push({
@@ -116,6 +119,7 @@ export function trigger(
116119
})
117120
}
118121
propagate(dep.subs)
122+
shallowPropagate(dep.subs)
119123
if (__DEV__) {
120124
triggerEventInfos.pop()
121125
}
@@ -190,7 +194,7 @@ export function trigger(
190194
export function getDepFromReactive(
191195
object: any,
192196
key: string | number | symbol,
193-
): Dependency | undefined {
197+
): ReactiveNode | undefined {
194198
const depMap = targetMap.get(object)
195199
return depMap && depMap.get(key)
196200
}

packages/reactivity/src/effect.ts

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@ import type { TrackOpTypes, TriggerOpTypes } from './constants'
33
import { setupOnTrigger } from './debug'
44
import { activeEffectScope } from './effectScope'
55
import {
6-
type Dependency,
76
type Link,
8-
type Subscriber,
9-
SubscriberFlags,
7+
ReactiveFlags,
8+
type ReactiveNode,
109
checkDirty,
1110
endTracking,
1211
link,
@@ -18,7 +17,7 @@ import { warn } from './warning'
1817
export type EffectScheduler = (...args: any[]) => any
1918

2019
export type DebuggerEvent = {
21-
effect: Subscriber
20+
effect: ReactiveNode
2221
} & DebuggerEventExtraInfo
2322

2423
export type DebuggerEventExtraInfo = {
@@ -55,16 +54,13 @@ export enum EffectFlags {
5554
}
5655

5756
export class ReactiveEffect<T = any>
58-
implements ReactiveEffectOptions, Dependency, Subscriber
57+
implements ReactiveEffectOptions, ReactiveNode
5958
{
60-
// Subscriber
6159
deps: Link | undefined = undefined
6260
depsTail: Link | undefined = undefined
63-
flags: number = SubscriberFlags.Dirty
64-
65-
// Dependency
6661
subs: Link | undefined = undefined
6762
subsTail: Link | undefined = undefined
63+
flags: number = ReactiveFlags.Watching | ReactiveFlags.Dirty
6864

6965
/**
7066
* @internal
@@ -129,6 +125,9 @@ export class ReactiveEffect<T = any>
129125
}
130126

131127
run(): T {
128+
if (!this.active) {
129+
return this.fn()
130+
}
132131
cleanup(this)
133132
const prevSub = activeSub
134133
setActiveSub(this)
@@ -147,10 +146,10 @@ export class ReactiveEffect<T = any>
147146
endTracking(this)
148147
const flags = this.flags
149148
if (
150-
(flags & (SubscriberFlags.Recursed | EffectFlags.ALLOW_RECURSE)) ===
151-
(SubscriberFlags.Recursed | EffectFlags.ALLOW_RECURSE)
149+
(flags & (ReactiveFlags.Recursed | EffectFlags.ALLOW_RECURSE)) ===
150+
(ReactiveFlags.Recursed | EffectFlags.ALLOW_RECURSE)
152151
) {
153-
this.flags = flags & ~SubscriberFlags.Recursed
152+
this.flags = flags & ~ReactiveFlags.Recursed
154153
this.notify()
155154
}
156155
}
@@ -161,23 +160,25 @@ export class ReactiveEffect<T = any>
161160
if (sub !== undefined) {
162161
unlink(sub)
163162
}
164-
startTracking(this)
165-
endTracking(this)
166-
cleanup(this)
163+
let dep = this.deps
164+
while (dep !== undefined) {
165+
dep = unlink(dep, this)
166+
}
167167
this.flags = 0
168+
cleanup(this)
168169
}
169170

170171
get dirty(): boolean {
171172
const flags = this.flags
172-
if (flags & SubscriberFlags.Dirty) {
173+
if (flags & ReactiveFlags.Dirty) {
173174
return true
174175
}
175-
if (flags & SubscriberFlags.Pending) {
176-
if (checkDirty(this.deps!)) {
177-
this.flags = flags | SubscriberFlags.Dirty
176+
if (flags & ReactiveFlags.Pending) {
177+
if (checkDirty(this.deps!, this)) {
178+
this.flags = flags | ReactiveFlags.Dirty
178179
return true
179180
} else {
180-
this.flags = flags & ~SubscriberFlags.Pending
181+
this.flags = flags & ~ReactiveFlags.Pending
181182
}
182183
}
183184
return false
@@ -234,7 +235,7 @@ export function stop(runner: ReactiveEffectRunner): void {
234235
runner.effect.stop()
235236
}
236237

237-
const resetTrackingStack: (Subscriber | undefined)[] = []
238+
const resetTrackingStack: (ReactiveNode | undefined)[] = []
238239

239240
/**
240241
* Temporarily pauses tracking.
@@ -284,7 +285,7 @@ export function resetTracking(): void {
284285
}
285286

286287
export function cleanup(
287-
sub: Subscriber & { cleanups: (() => void)[]; cleanupsLength: number },
288+
sub: ReactiveNode & { cleanups: (() => void)[]; cleanupsLength: number },
288289
): void {
289290
const l = sub.cleanupsLength
290291
if (l) {
@@ -329,8 +330,8 @@ function cleanupEffect(fn: () => void) {
329330
}
330331
}
331332

332-
export let activeSub: Subscriber | undefined = undefined
333+
export let activeSub: ReactiveNode | undefined = undefined
333334

334-
export function setActiveSub(sub: Subscriber | undefined): void {
335+
export function setActiveSub(sub: ReactiveNode | undefined): void {
335336
activeSub = sub
336337
}

packages/reactivity/src/effectScope.ts

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,15 @@
11
import { EffectFlags, cleanup } from './effect'
2-
import {
3-
type Dependency,
4-
type Link,
5-
type Subscriber,
6-
endTracking,
7-
link,
8-
startTracking,
9-
unlink,
10-
} from './system'
2+
import { type Link, type ReactiveNode, link, unlink } from './system'
113
import { warn } from './warning'
124

135
export let activeEffectScope: EffectScope | undefined
146

15-
export class EffectScope implements Subscriber, Dependency {
16-
// Subscriber
7+
export class EffectScope implements ReactiveNode {
178
deps: Link | undefined = undefined
189
depsTail: Link | undefined = undefined
19-
flags: number = 0
20-
21-
// Dependency
2210
subs: Link | undefined = undefined
2311
subsTail: Link | undefined = undefined
12+
flags: number = 0
2413

2514
/**
2615
* @internal
@@ -86,10 +75,12 @@ export class EffectScope implements Subscriber, Dependency {
8675
if (sub !== undefined) {
8776
unlink(sub)
8877
}
89-
startTracking(this)
90-
endTracking(this)
91-
cleanup(this)
78+
let dep = this.deps
79+
while (dep !== undefined) {
80+
dep = unlink(dep, this)
81+
}
9282
this.flags = 0
83+
cleanup(this)
9384
}
9485
}
9586

0 commit comments

Comments
 (0)