Skip to content

Commit

Permalink
refactor(reactivity): ports alien-signals 1.0.0 (#12570)
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsoncodehk authored Jan 15, 2025
1 parent f7d95ce commit 9d651e2
Show file tree
Hide file tree
Showing 9 changed files with 372 additions and 338 deletions.
8 changes: 6 additions & 2 deletions packages/reactivity/__tests__/computed.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -467,8 +467,12 @@ describe('reactivity/computed', () => {
const c2 = computed(() => c1.value) as unknown as ComputedRefImpl

c2.value
expect(c1.flags & SubscriberFlags.Dirtys).toBe(0)
expect(c2.flags & SubscriberFlags.Dirtys).toBe(0)
expect(
c1.flags & (SubscriberFlags.Dirty | SubscriberFlags.PendingComputed),
).toBe(0)
expect(
c2.flags & (SubscriberFlags.Dirty | SubscriberFlags.PendingComputed),
).toBe(0)
})

it('should chained computeds dirtyLevel update with first computed effect', () => {
Expand Down
73 changes: 30 additions & 43 deletions packages/reactivity/src/computed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,20 @@ import {
type DebuggerEvent,
type DebuggerOptions,
activeSub,
activeTrackId,
nextTrackId,
setActiveSub,
} from './effect'
import { activeEffectScope } from './effectScope'
import type { Ref } from './ref'
import {
type Dependency,
type IComputed,
type Link,
type Subscriber,
SubscriberFlags,
checkDirty,
endTrack,
endTracking,
link,
startTrack,
processComputedUpdate,
startTracking,
updateDirtyFlag,
} from './system'
import { warn } from './warning'

Expand Down Expand Up @@ -54,22 +53,20 @@ export interface WritableComputedOptions<T, S = T> {
* @private exported by @vue/reactivity for Vue core use, but not exported from
* the main vue package
*/
export class ComputedRefImpl<T = any> implements IComputed {
export class ComputedRefImpl<T = any> implements Dependency, Subscriber {
/**
* @internal
*/
_value: T | undefined = undefined
version = 0

// Dependency
subs: Link | undefined = undefined
subsTail: Link | undefined = undefined
lastTrackedId = 0

// Subscriber
deps: Link | undefined = undefined
depsTail: Link | undefined = undefined
flags: SubscriberFlags = SubscriberFlags.Dirty
flags: SubscriberFlags = SubscriberFlags.Computed | SubscriberFlags.Dirty

/**
* @internal
Expand All @@ -93,24 +90,20 @@ export class ComputedRefImpl<T = any> implements IComputed {
// for backwards compat
get _dirty(): boolean {
const flags = this.flags
if (flags & SubscriberFlags.Dirty) {
if (
flags & SubscriberFlags.Dirty ||
(flags & SubscriberFlags.PendingComputed &&
updateDirtyFlag(this, this.flags))
) {
return true
} else if (flags & SubscriberFlags.ToCheckDirty) {
if (checkDirty(this.deps!)) {
this.flags |= SubscriberFlags.Dirty
return true
} else {
this.flags &= ~SubscriberFlags.ToCheckDirty
return false
}
}
return false
}
set _dirty(v: boolean) {
if (v) {
this.flags |= SubscriberFlags.Dirty
} else {
this.flags &= ~SubscriberFlags.Dirtys
this.flags &= ~(SubscriberFlags.Dirty | SubscriberFlags.PendingComputed)
}
}

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

get value(): T {
if (this._dirty) {
this.update()
const flags = this.flags
if (flags & (SubscriberFlags.Dirty | SubscriberFlags.PendingComputed)) {
processComputedUpdate(this, flags)
}
if (activeTrackId !== 0 && this.lastTrackedId !== activeTrackId) {
if (activeSub !== undefined) {
if (__DEV__) {
onTrack(activeSub!, {
target: this,
type: TrackOpTypes.GET,
key: 'value',
})
}
this.lastTrackedId = activeTrackId
link(this, activeSub!).version = this.version
} else if (
activeEffectScope !== undefined &&
this.lastTrackedId !== activeEffectScope.trackId
) {
link(this, activeSub)
} else if (activeEffectScope !== undefined) {
link(this, activeEffectScope)
}
return this._value!
Expand All @@ -165,23 +155,20 @@ export class ComputedRefImpl<T = any> implements IComputed {

update(): boolean {
const prevSub = activeSub
const prevTrackId = activeTrackId
setActiveSub(this, nextTrackId())
startTrack(this)
const oldValue = this._value
let newValue: T
setActiveSub(this)
startTracking(this)
try {
newValue = this.fn(oldValue)
const oldValue = this._value
const newValue = this.fn(oldValue)
if (hasChanged(oldValue, newValue)) {
this._value = newValue
return true
}
return false
} finally {
setActiveSub(prevSub, prevTrackId)
endTrack(this)
setActiveSub(prevSub)
endTracking(this)
}
if (hasChanged(oldValue, newValue)) {
this._value = newValue
this.version++
return true
}
return false
}
}

Expand Down
17 changes: 8 additions & 9 deletions packages/reactivity/src/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,23 +62,22 @@ export function setupOnTrigger(target: { new (...args: any[]): any }): void {
}

function setupFlagsHandler(target: Subscriber): void {
// @ts-expect-error
target._flags = target.flags
;(target as any)._flags = target.flags
Object.defineProperty(target, 'flags', {
get() {
// @ts-expect-error
return target._flags
return (target as any)._flags
},
set(value) {
if (
// @ts-expect-error
!(target._flags >> SubscriberFlags.DirtyFlagsIndex) &&
!!(value >> SubscriberFlags.DirtyFlagsIndex)
!(
(target as any)._flags &
(SubscriberFlags.PendingComputed | SubscriberFlags.Dirty)
) &&
!!(value & (SubscriberFlags.PendingComputed | SubscriberFlags.Dirty))
) {
onTrigger(this)
}
// @ts-expect-error
target._flags = value
;(target as any)._flags = value
},
})
}
22 changes: 9 additions & 13 deletions packages/reactivity/src/dep.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { isArray, isIntegerKey, isMap, isSymbol } from '@vue/shared'
import { type TrackOpTypes, TriggerOpTypes } from './constants'
import { onTrack, triggerEventInfos } from './debug'
import { activeSub, activeTrackId } from './effect'
import { activeSub } from './effect'
import {
type Dependency,
type Link,
Expand All @@ -14,7 +14,6 @@ import {
class Dep implements Dependency {
_subs: Link | undefined = undefined
subsTail: Link | undefined = undefined
lastTrackedId = 0

constructor(
private map: KeyToDepMap,
Expand Down Expand Up @@ -62,7 +61,7 @@ export const ARRAY_ITERATE_KEY: unique symbol = Symbol(
* @param key - Identifier of the reactive property to track.
*/
export function track(target: object, type: TrackOpTypes, key: unknown): void {
if (activeTrackId > 0) {
if (activeSub !== undefined) {
let depsMap = targetMap.get(target)
if (!depsMap) {
targetMap.set(target, (depsMap = new Map()))
Expand All @@ -71,17 +70,14 @@ export function track(target: object, type: TrackOpTypes, key: unknown): void {
if (!dep) {
depsMap.set(key, (dep = new Dep(depsMap, key)))
}
if (dep.lastTrackedId !== activeTrackId) {
if (__DEV__) {
onTrack(activeSub!, {
target,
type,
key,
})
}
dep.lastTrackedId = activeTrackId
link(dep, activeSub!)
if (__DEV__) {
onTrack(activeSub!, {
target,
type,
key,
})
}
link(dep, activeSub!)
}
}

Expand Down
Loading

0 comments on commit 9d651e2

Please sign in to comment.