]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor: rename things
authorEvan You <yyx990803@gmail.com>
Tue, 13 Nov 2018 16:03:35 +0000 (11:03 -0500)
committerEvan You <yyx990803@gmail.com>
Tue, 13 Nov 2018 16:03:35 +0000 (11:03 -0500)
22 files changed:
packages/observer/__tests__/collections/Map.spec.ts
packages/observer/__tests__/collections/Set.spec.ts
packages/observer/__tests__/collections/WeakMap.spec.ts
packages/observer/__tests__/collections/WeakSet.spec.ts
packages/observer/__tests__/computed.spec.ts
packages/observer/__tests__/effect.spec.ts [moved from packages/observer/__tests__/autorun.spec.ts with 84% similarity]
packages/observer/__tests__/immutable.spec.ts
packages/observer/src/autorun.ts [deleted file]
packages/observer/src/baseHandlers.ts
packages/observer/src/collectionHandlers.ts
packages/observer/src/computed.ts
packages/observer/src/effect.ts [new file with mode: 0644]
packages/observer/src/index.ts
packages/observer/src/state.ts
packages/runtime-core/__tests__/fragment.spec.ts
packages/runtime-core/src/component.ts
packages/runtime-core/src/componentComputed.ts
packages/runtime-core/src/componentUtils.ts
packages/runtime-core/src/componentWatch.ts
packages/runtime-core/src/createRenderer.ts
packages/scheduler/__tests__/scheduler.spec.ts
packages/scheduler/src/index.ts

index b69c1f82d77a4e76b67f1c849033d97c2026b933..6ba047b8bc6170c6239c8bc15b14a7a78029a290 100644 (file)
@@ -1,4 +1,4 @@
-import { observable, autorun, unwrap, isObservable } from '../../src'
+import { observable, effect, unwrap, isObservable } from '../../src'
 
 describe('observer/collections', () => {
   describe('Map', () => {
@@ -13,7 +13,7 @@ describe('observer/collections', () => {
     it('should observe mutations', () => {
       let dummy
       const map = observable(new Map())
-      autorun(() => {
+      effect(() => {
         dummy = map.get('key')
       })
 
@@ -29,7 +29,7 @@ describe('observer/collections', () => {
     it('should observe size mutations', () => {
       let dummy
       const map = observable(new Map())
-      autorun(() => (dummy = map.size))
+      effect(() => (dummy = map.size))
 
       expect(dummy).toBe(0)
       map.set('key1', 'value')
@@ -44,7 +44,7 @@ describe('observer/collections', () => {
     it('should observe for of iteration', () => {
       let dummy
       const map = observable(new Map())
-      autorun(() => {
+      effect(() => {
         dummy = 0
         // eslint-disable-next-line no-unused-vars
         for (let [key, num] of map) {
@@ -67,7 +67,7 @@ describe('observer/collections', () => {
     it('should observe forEach iteration', () => {
       let dummy: any
       const map = observable(new Map())
-      autorun(() => {
+      effect(() => {
         dummy = 0
         map.forEach((num: any) => (dummy += num))
       })
@@ -86,7 +86,7 @@ describe('observer/collections', () => {
     it('should observe keys iteration', () => {
       let dummy
       const map = observable(new Map())
-      autorun(() => {
+      effect(() => {
         dummy = 0
         for (let key of map.keys()) {
           dummy += key
@@ -107,7 +107,7 @@ describe('observer/collections', () => {
     it('should observe values iteration', () => {
       let dummy
       const map = observable(new Map())
-      autorun(() => {
+      effect(() => {
         dummy = 0
         for (let num of map.values()) {
           dummy += num
@@ -128,7 +128,7 @@ describe('observer/collections', () => {
     it('should observe entries iteration', () => {
       let dummy
       const map = observable(new Map())
-      autorun(() => {
+      effect(() => {
         dummy = 0
         // eslint-disable-next-line no-unused-vars
         for (let [key, num] of map.entries()) {
@@ -151,7 +151,7 @@ describe('observer/collections', () => {
     it('should be triggered by clearing', () => {
       let dummy
       const map = observable(new Map())
-      autorun(() => (dummy = map.get('key')))
+      effect(() => (dummy = map.get('key')))
 
       expect(dummy).toBe(undefined)
       map.set('key', 3)
@@ -163,7 +163,7 @@ describe('observer/collections', () => {
     it('should not observe custom property mutations', () => {
       let dummy
       const map: any = observable(new Map())
-      autorun(() => (dummy = map.customProp))
+      effect(() => (dummy = map.customProp))
 
       expect(dummy).toBe(undefined)
       map.customProp = 'Hello World'
@@ -174,7 +174,7 @@ describe('observer/collections', () => {
       let dummy
       const map = observable(new Map())
       const mapSpy = jest.fn(() => (dummy = map.get('key')))
-      autorun(mapSpy)
+      effect(mapSpy)
 
       expect(dummy).toBe(undefined)
       expect(mapSpy).toHaveBeenCalledTimes(1)
@@ -198,7 +198,7 @@ describe('observer/collections', () => {
     it('should not observe raw data', () => {
       let dummy
       const map = observable(new Map())
-      autorun(() => (dummy = unwrap(map).get('key')))
+      effect(() => (dummy = unwrap(map).get('key')))
 
       expect(dummy).toBe(undefined)
       map.set('key', 'Hello')
@@ -229,7 +229,7 @@ describe('observer/collections', () => {
       const observed = observable(new Map())
       observed.set('key', { a: 1 })
       let dummy
-      autorun(() => {
+      effect(() => {
         dummy = observed.get('key').a
       })
       observed.get('key').a = 2
@@ -239,7 +239,7 @@ describe('observer/collections', () => {
     it('should observe nested values in iterations (forEach)', () => {
       const map = observable(new Map([[1, { foo: 1 }]]))
       let dummy: any
-      autorun(() => {
+      effect(() => {
         dummy = 0
         map.forEach(value => {
           expect(isObservable(value)).toBe(true)
@@ -254,7 +254,7 @@ describe('observer/collections', () => {
     it('should observe nested values in iterations (values)', () => {
       const map = observable(new Map([[1, { foo: 1 }]]))
       let dummy: any
-      autorun(() => {
+      effect(() => {
         dummy = 0
         for (const value of map.values()) {
           expect(isObservable(value)).toBe(true)
@@ -270,7 +270,7 @@ describe('observer/collections', () => {
       const key = {}
       const map = observable(new Map([[key, { foo: 1 }]]))
       let dummy: any
-      autorun(() => {
+      effect(() => {
         dummy = 0
         for (const [key, value] of map.entries()) {
           key
@@ -288,7 +288,7 @@ describe('observer/collections', () => {
       const key = {}
       const map = observable(new Map([[key, { foo: 1 }]]))
       let dummy: any
-      autorun(() => {
+      effect(() => {
         dummy = 0
         for (const [key, value] of map) {
           key
index 4d6fa84524fa2596ca25e2f1c0d68d7650279f15..d2d999c2a66d73cd3eeef4006756c2ee04448238 100644 (file)
@@ -1,4 +1,4 @@
-import { observable, autorun, isObservable, unwrap } from '../../src'
+import { observable, effect, isObservable, unwrap } from '../../src'
 
 describe('observer/collections', () => {
   describe('Set', () => {
@@ -13,7 +13,7 @@ describe('observer/collections', () => {
     it('should observe mutations', () => {
       let dummy
       const set = observable(new Set())
-      autorun(() => (dummy = set.has('value')))
+      effect(() => (dummy = set.has('value')))
 
       expect(dummy).toBe(false)
       set.add('value')
@@ -25,7 +25,7 @@ describe('observer/collections', () => {
     it('should observe for of iteration', () => {
       let dummy
       const set = observable(new Set())
-      autorun(() => {
+      effect(() => {
         dummy = 0
         for (let num of set) {
           dummy += num
@@ -45,7 +45,7 @@ describe('observer/collections', () => {
     it('should observe forEach iteration', () => {
       let dummy: any
       const set = observable(new Set())
-      autorun(() => {
+      effect(() => {
         dummy = 0
         set.forEach(num => (dummy += num))
       })
@@ -63,7 +63,7 @@ describe('observer/collections', () => {
     it('should observe values iteration', () => {
       let dummy
       const set = observable(new Set())
-      autorun(() => {
+      effect(() => {
         dummy = 0
         for (let num of set.values()) {
           dummy += num
@@ -83,7 +83,7 @@ describe('observer/collections', () => {
     it('should observe keys iteration', () => {
       let dummy
       const set = observable(new Set())
-      autorun(() => {
+      effect(() => {
         dummy = 0
         for (let num of set.keys()) {
           dummy += num
@@ -103,7 +103,7 @@ describe('observer/collections', () => {
     it('should observe entries iteration', () => {
       let dummy
       const set = observable(new Set())
-      autorun(() => {
+      effect(() => {
         dummy = 0
         // eslint-disable-next-line no-unused-vars
         for (let [key, num] of set.entries()) {
@@ -125,7 +125,7 @@ describe('observer/collections', () => {
     it('should be triggered by clearing', () => {
       let dummy
       const set = observable(new Set())
-      autorun(() => (dummy = set.has('key')))
+      effect(() => (dummy = set.has('key')))
 
       expect(dummy).toBe(false)
       set.add('key')
@@ -137,7 +137,7 @@ describe('observer/collections', () => {
     it('should not observe custom property mutations', () => {
       let dummy
       const set: any = observable(new Set())
-      autorun(() => (dummy = set.customProp))
+      effect(() => (dummy = set.customProp))
 
       expect(dummy).toBe(undefined)
       set.customProp = 'Hello World'
@@ -147,7 +147,7 @@ describe('observer/collections', () => {
     it('should observe size mutations', () => {
       let dummy
       const set = observable(new Set())
-      autorun(() => (dummy = set.size))
+      effect(() => (dummy = set.size))
 
       expect(dummy).toBe(0)
       set.add('value')
@@ -163,7 +163,7 @@ describe('observer/collections', () => {
       let dummy
       const set = observable(new Set())
       const setSpy = jest.fn(() => (dummy = set.has('value')))
-      autorun(setSpy)
+      effect(setSpy)
 
       expect(dummy).toBe(false)
       expect(setSpy).toHaveBeenCalledTimes(1)
@@ -187,7 +187,7 @@ describe('observer/collections', () => {
     it('should not observe raw data', () => {
       let dummy
       const set = observable(new Set())
-      autorun(() => (dummy = unwrap(set).has('value')))
+      effect(() => (dummy = unwrap(set).has('value')))
 
       expect(dummy).toBe(false)
       set.add('value')
@@ -197,7 +197,7 @@ describe('observer/collections', () => {
     it('should not observe raw iterations', () => {
       let dummy = 0
       const set = observable(new Set())
-      autorun(() => {
+      effect(() => {
         dummy = 0
         for (let [num] of unwrap(set).entries()) {
           dummy += num
@@ -227,7 +227,7 @@ describe('observer/collections', () => {
     it('should not be triggered by raw mutations', () => {
       let dummy
       const set = observable(new Set())
-      autorun(() => (dummy = set.has('value')))
+      effect(() => (dummy = set.has('value')))
 
       expect(dummy).toBe(false)
       unwrap(set).add('value')
@@ -242,7 +242,7 @@ describe('observer/collections', () => {
     it('should not observe raw size mutations', () => {
       let dummy
       const set = observable(new Set())
-      autorun(() => (dummy = unwrap(set).size))
+      effect(() => (dummy = unwrap(set).size))
 
       expect(dummy).toBe(0)
       set.add('value')
@@ -252,7 +252,7 @@ describe('observer/collections', () => {
     it('should not be triggered by raw size mutations', () => {
       let dummy
       const set = observable(new Set())
-      autorun(() => (dummy = set.size))
+      effect(() => (dummy = set.size))
 
       expect(dummy).toBe(0)
       unwrap(set).add('value')
@@ -264,7 +264,7 @@ describe('observer/collections', () => {
       const key = {}
       const set = observable(new Set())
       const setSpy = jest.fn(() => (dummy = set.has(key)))
-      autorun(setSpy)
+      effect(setSpy)
 
       expect(dummy).toBe(false)
       expect(setSpy).toHaveBeenCalledTimes(1)
@@ -290,7 +290,7 @@ describe('observer/collections', () => {
     it('should observe nested values in iterations (forEach)', () => {
       const set = observable(new Set([{ foo: 1 }]))
       let dummy: any
-      autorun(() => {
+      effect(() => {
         dummy = 0
         set.forEach(value => {
           expect(isObservable(value)).toBe(true)
@@ -307,7 +307,7 @@ describe('observer/collections', () => {
     it('should observe nested values in iterations (values)', () => {
       const set = observable(new Set([{ foo: 1 }]))
       let dummy: any
-      autorun(() => {
+      effect(() => {
         dummy = 0
         for (const value of set.values()) {
           expect(isObservable(value)).toBe(true)
@@ -324,7 +324,7 @@ describe('observer/collections', () => {
     it('should observe nested values in iterations (entries)', () => {
       const set = observable(new Set([{ foo: 1 }]))
       let dummy: any
-      autorun(() => {
+      effect(() => {
         dummy = 0
         for (const [key, value] of set.entries()) {
           expect(isObservable(key)).toBe(true)
@@ -342,7 +342,7 @@ describe('observer/collections', () => {
     it('should observe nested values in iterations (for...of)', () => {
       const set = observable(new Set([{ foo: 1 }]))
       let dummy: any
-      autorun(() => {
+      effect(() => {
         dummy = 0
         for (const value of set) {
           expect(isObservable(value)).toBe(true)
index f20a1961d91d38401329af3a9e4cb5e2f34ae180..ec6550dc6bab48fca305071df61d2a6fd91f5235 100644 (file)
@@ -1,4 +1,4 @@
-import { observable, autorun, unwrap, isObservable } from '../../src'
+import { observable, effect, unwrap, isObservable } from '../../src'
 
 describe('observer/collections', () => {
   describe('WeakMap', () => {
@@ -14,7 +14,7 @@ describe('observer/collections', () => {
       let dummy
       const key = {}
       const map = observable(new WeakMap())
-      autorun(() => {
+      effect(() => {
         dummy = map.get(key)
       })
 
@@ -30,7 +30,7 @@ describe('observer/collections', () => {
     it('should not observe custom property mutations', () => {
       let dummy
       const map: any = observable(new WeakMap())
-      autorun(() => (dummy = map.customProp))
+      effect(() => (dummy = map.customProp))
 
       expect(dummy).toBe(undefined)
       map.customProp = 'Hello World'
@@ -42,7 +42,7 @@ describe('observer/collections', () => {
       const key = {}
       const map = observable(new WeakMap())
       const mapSpy = jest.fn(() => (dummy = map.get(key)))
-      autorun(mapSpy)
+      effect(mapSpy)
 
       expect(dummy).toBe(undefined)
       expect(mapSpy).toHaveBeenCalledTimes(1)
@@ -64,7 +64,7 @@ describe('observer/collections', () => {
       let dummy
       const key = {}
       const map = observable(new WeakMap())
-      autorun(() => (dummy = unwrap(map).get(key)))
+      effect(() => (dummy = unwrap(map).get(key)))
 
       expect(dummy).toBe(undefined)
       map.set(key, 'Hello')
@@ -98,7 +98,7 @@ describe('observer/collections', () => {
       const key = {}
       observed.set(key, { a: 1 })
       let dummy
-      autorun(() => {
+      effect(() => {
         dummy = observed.get(key).a
       })
       observed.get(key).a = 2
index 23b0534239a1c4cc19a050374c9a2df4906b17cc..1ec2a4647fccce158b99a98d35ddacf43b4b7d77 100644 (file)
@@ -1,4 +1,4 @@
-import { observable, isObservable, autorun, unwrap } from '../../src'
+import { observable, isObservable, effect, unwrap } from '../../src'
 
 describe('observer/collections', () => {
   describe('WeakSet', () => {
@@ -14,7 +14,7 @@ describe('observer/collections', () => {
       let dummy
       const value = {}
       const set = observable(new WeakSet())
-      autorun(() => (dummy = set.has(value)))
+      effect(() => (dummy = set.has(value)))
 
       expect(dummy).toBe(false)
       set.add(value)
@@ -26,7 +26,7 @@ describe('observer/collections', () => {
     it('should not observe custom property mutations', () => {
       let dummy
       const set: any = observable(new WeakSet())
-      autorun(() => (dummy = set.customProp))
+      effect(() => (dummy = set.customProp))
 
       expect(dummy).toBe(undefined)
       set.customProp = 'Hello World'
@@ -38,7 +38,7 @@ describe('observer/collections', () => {
       const value = {}
       const set = observable(new WeakSet())
       const setSpy = jest.fn(() => (dummy = set.has(value)))
-      autorun(setSpy)
+      effect(setSpy)
 
       expect(dummy).toBe(false)
       expect(setSpy).toHaveBeenCalledTimes(1)
@@ -60,7 +60,7 @@ describe('observer/collections', () => {
       const value = {}
       let dummy
       const set = observable(new WeakSet())
-      autorun(() => (dummy = unwrap(set).has(value)))
+      effect(() => (dummy = unwrap(set).has(value)))
 
       expect(dummy).toBe(false)
       set.add(value)
@@ -71,7 +71,7 @@ describe('observer/collections', () => {
       const value = {}
       let dummy
       const set = observable(new WeakSet())
-      autorun(() => (dummy = set.has(value)))
+      effect(() => (dummy = set.has(value)))
 
       expect(dummy).toBe(false)
       unwrap(set).add(value)
index 973e3c0fdb895b77c8518ffbb78ddb3e82bcc48e..e07eb8e7ccf20e329924348205ddd68b1b24b71b 100644 (file)
@@ -1,4 +1,4 @@
-import { computed, observable, autorun, stop } from '../src'
+import { computed, observable, effect, stop } from '../src'
 
 describe('observer/computed', () => {
   it('should return updated value', () => {
@@ -52,11 +52,11 @@ describe('observer/computed', () => {
     expect(callArg).toBe(ctx)
   })
 
-  it('should trigger autorun', () => {
+  it('should trigger effect', () => {
     const value: any = observable({})
     const cValue = computed(() => value.foo)
     let dummy
-    autorun(() => {
+    effect(() => {
       dummy = cValue()
     })
     expect(dummy).toBe(undefined)
@@ -75,7 +75,7 @@ describe('observer/computed', () => {
     expect(c1()).toBe(1)
   })
 
-  it('should trigger autorun when chained', () => {
+  it('should trigger effect when chained', () => {
     const value: any = observable({ foo: 0 })
     const getter1 = jest.fn(() => value.foo)
     const getter2 = jest.fn(() => {
@@ -85,7 +85,7 @@ describe('observer/computed', () => {
     const c2 = computed(getter2)
 
     let dummy
-    autorun(() => {
+    effect(() => {
       dummy = c2()
     })
     expect(dummy).toBe(1)
@@ -98,7 +98,7 @@ describe('observer/computed', () => {
     expect(getter2).toHaveBeenCalledTimes(2)
   })
 
-  it('should trigger autorun when chained (mixed invocations)', () => {
+  it('should trigger effect when chained (mixed invocations)', () => {
     const value: any = observable({ foo: 0 })
     const getter1 = jest.fn(() => value.foo)
     const getter2 = jest.fn(() => {
@@ -108,7 +108,7 @@ describe('observer/computed', () => {
     const c2 = computed(getter2)
 
     let dummy
-    autorun(() => {
+    effect(() => {
       dummy = c1() + c2()
     })
     expect(dummy).toBe(1)
@@ -126,13 +126,13 @@ describe('observer/computed', () => {
     const value: any = observable({})
     const cValue = computed(() => value.foo)
     let dummy
-    autorun(() => {
+    effect(() => {
       dummy = cValue()
     })
     expect(dummy).toBe(undefined)
     value.foo = 1
     expect(dummy).toBe(1)
-    stop(cValue.runner)
+    stop(cValue.effect)
     value.foo = 2
     expect(dummy).toBe(1)
   })
similarity index 84%
rename from packages/observer/__tests__/autorun.spec.ts
rename to packages/observer/__tests__/effect.spec.ts
index 31f0470f5dc19e251ed39a4e30780de28a6aee9d..fcbc31fb17dda84b9e8cfefaef55ef69efac93b2 100644 (file)
@@ -1,25 +1,25 @@
 import {
   observable,
-  autorun,
+  effect,
   stop,
   unwrap,
   OperationTypes,
   DebuggerEvent,
   markNonReactive
 } from '../src/index'
-import { ITERATE_KEY } from '../src/autorun'
+import { ITERATE_KEY } from '../src/effect'
 
-describe('observer/autorun', () => {
-  it('should run the passed function once (wrapped by a autorun)', () => {
+describe('observer/effect', () => {
+  it('should run the passed function once (wrapped by a effect)', () => {
     const fnSpy = jest.fn(() => {})
-    autorun(fnSpy)
+    effect(fnSpy)
     expect(fnSpy).toHaveBeenCalledTimes(1)
   })
 
   it('should observe basic properties', () => {
     let dummy
     const counter = observable({ num: 0 })
-    autorun(() => (dummy = counter.num))
+    effect(() => (dummy = counter.num))
 
     expect(dummy).toBe(0)
     counter.num = 7
@@ -29,18 +29,18 @@ describe('observer/autorun', () => {
   it('should observe multiple properties', () => {
     let dummy
     const counter = observable({ num1: 0, num2: 0 })
-    autorun(() => (dummy = counter.num1 + counter.num1 + counter.num2))
+    effect(() => (dummy = counter.num1 + counter.num1 + counter.num2))
 
     expect(dummy).toBe(0)
     counter.num1 = counter.num2 = 7
     expect(dummy).toBe(21)
   })
 
-  it('should handle multiple autoruns', () => {
+  it('should handle multiple effects', () => {
     let dummy1, dummy2
     const counter = observable({ num: 0 })
-    autorun(() => (dummy1 = counter.num))
-    autorun(() => (dummy2 = counter.num))
+    effect(() => (dummy1 = counter.num))
+    effect(() => (dummy2 = counter.num))
 
     expect(dummy1).toBe(0)
     expect(dummy2).toBe(0)
@@ -52,7 +52,7 @@ describe('observer/autorun', () => {
   it('should observe nested properties', () => {
     let dummy
     const counter = observable({ nested: { num: 0 } })
-    autorun(() => (dummy = counter.nested.num))
+    effect(() => (dummy = counter.nested.num))
 
     expect(dummy).toBe(0)
     counter.nested.num = 8
@@ -62,7 +62,7 @@ describe('observer/autorun', () => {
   it('should observe delete operations', () => {
     let dummy
     const obj = observable({ prop: 'value' })
-    autorun(() => (dummy = obj.prop))
+    effect(() => (dummy = obj.prop))
 
     expect(dummy).toBe('value')
     delete obj.prop
@@ -72,7 +72,7 @@ describe('observer/autorun', () => {
   it('should observe has operations', () => {
     let dummy
     const obj: any = observable({ prop: 'value' })
-    autorun(() => (dummy = 'prop' in obj))
+    effect(() => (dummy = 'prop' in obj))
 
     expect(dummy).toBe(true)
     delete obj.prop
@@ -86,7 +86,7 @@ describe('observer/autorun', () => {
     const counter = observable({ num: 0 })
     const parentCounter = observable({ num: 2 })
     Object.setPrototypeOf(counter, parentCounter)
-    autorun(() => (dummy = counter.num))
+    effect(() => (dummy = counter.num))
 
     expect(dummy).toBe(0)
     delete counter.num
@@ -102,7 +102,7 @@ describe('observer/autorun', () => {
     const counter = observable({ num: 0 })
     const parentCounter = observable({ num: 2 })
     Object.setPrototypeOf(counter, parentCounter)
-    autorun(() => (dummy = 'num' in counter))
+    effect(() => (dummy = 'num' in counter))
 
     expect(dummy).toBe(true)
     delete counter.num
@@ -125,8 +125,8 @@ describe('observer/autorun', () => {
       }
     })
     Object.setPrototypeOf(obj, parent)
-    autorun(() => (dummy = obj.prop))
-    autorun(() => (parentDummy = parent.prop))
+    effect(() => (dummy = obj.prop))
+    effect(() => (parentDummy = parent.prop))
 
     expect(dummy).toBe(undefined)
     expect(parentDummy).toBe(undefined)
@@ -142,7 +142,7 @@ describe('observer/autorun', () => {
   it('should observe function call chains', () => {
     let dummy
     const counter = observable({ num: 0 })
-    autorun(() => (dummy = getNum()))
+    effect(() => (dummy = getNum()))
 
     function getNum() {
       return counter.num
@@ -156,7 +156,7 @@ describe('observer/autorun', () => {
   it('should observe iteration', () => {
     let dummy
     const list = observable(['Hello'])
-    autorun(() => (dummy = list.join(' ')))
+    effect(() => (dummy = list.join(' ')))
 
     expect(dummy).toBe('Hello')
     list.push('World!')
@@ -168,7 +168,7 @@ describe('observer/autorun', () => {
   it('should observe implicit array length changes', () => {
     let dummy
     const list = observable(['Hello'])
-    autorun(() => (dummy = list.join(' ')))
+    effect(() => (dummy = list.join(' ')))
 
     expect(dummy).toBe('Hello')
     list[1] = 'World!'
@@ -181,7 +181,7 @@ describe('observer/autorun', () => {
     let dummy
     const list: any[] = observable([])
     list[1] = 'World!'
-    autorun(() => (dummy = list.join(' ')))
+    effect(() => (dummy = list.join(' ')))
 
     expect(dummy).toBe(' World!')
     list[0] = 'Hello'
@@ -193,7 +193,7 @@ describe('observer/autorun', () => {
   it('should observe enumeration', () => {
     let dummy = 0
     const numbers: any = observable({ num1: 3 })
-    autorun(() => {
+    effect(() => {
       dummy = 0
       for (let key in numbers) {
         dummy += numbers[key]
@@ -211,8 +211,8 @@ describe('observer/autorun', () => {
     const key = Symbol('symbol keyed prop')
     let dummy, hasDummy
     const obj = observable({ [key]: 'value' })
-    autorun(() => (dummy = obj[key]))
-    autorun(() => (hasDummy = key in obj))
+    effect(() => (dummy = obj[key]))
+    effect(() => (hasDummy = key in obj))
 
     expect(dummy).toBe('value')
     expect(hasDummy).toBe(true)
@@ -227,7 +227,7 @@ describe('observer/autorun', () => {
     const key = Symbol.isConcatSpreadable
     let dummy
     const array: any = observable([])
-    autorun(() => (dummy = array[key]))
+    effect(() => (dummy = array[key]))
 
     expect(array[key]).toBe(undefined)
     expect(dummy).toBe(undefined)
@@ -242,7 +242,7 @@ describe('observer/autorun', () => {
 
     let dummy
     const obj = observable({ func: oldFunc })
-    autorun(() => (dummy = obj.func))
+    effect(() => (dummy = obj.func))
 
     expect(dummy).toBe(oldFunc)
     obj.func = newFunc
@@ -255,8 +255,8 @@ describe('observer/autorun', () => {
 
     const getSpy = jest.fn(() => (getDummy = obj.prop))
     const hasSpy = jest.fn(() => (hasDummy = 'prop' in obj))
-    autorun(getSpy)
-    autorun(hasSpy)
+    effect(getSpy)
+    effect(hasSpy)
 
     expect(getDummy).toBe('value')
     expect(hasDummy).toBe(true)
@@ -270,7 +270,7 @@ describe('observer/autorun', () => {
   it('should not observe raw mutations', () => {
     let dummy
     const obj: any = observable()
-    autorun(() => (dummy = unwrap(obj).prop))
+    effect(() => (dummy = unwrap(obj).prop))
 
     expect(dummy).toBe(undefined)
     obj.prop = 'value'
@@ -280,7 +280,7 @@ describe('observer/autorun', () => {
   it('should not be triggered by raw mutations', () => {
     let dummy
     const obj: any = observable()
-    autorun(() => (dummy = obj.prop))
+    effect(() => (dummy = obj.prop))
 
     expect(dummy).toBe(undefined)
     unwrap(obj).prop = 'value'
@@ -299,8 +299,8 @@ describe('observer/autorun', () => {
       }
     })
     Object.setPrototypeOf(obj, parent)
-    autorun(() => (dummy = obj.prop))
-    autorun(() => (parentDummy = parent.prop))
+    effect(() => (dummy = obj.prop))
+    effect(() => (parentDummy = parent.prop))
 
     expect(dummy).toBe(undefined)
     expect(parentDummy).toBe(undefined)
@@ -313,7 +313,7 @@ describe('observer/autorun', () => {
     const counter = observable({ num: 0 })
 
     const counterSpy = jest.fn(() => counter.num++)
-    autorun(counterSpy)
+    effect(counterSpy)
     expect(counter.num).toBe(1)
     expect(counterSpy).toHaveBeenCalledTimes(1)
     counter.num = 4
@@ -329,18 +329,18 @@ describe('observer/autorun', () => {
         numSpy()
       }
     })
-    autorun(numSpy)
+    effect(numSpy)
     expect(counter.num).toEqual(10)
     expect(numSpy).toHaveBeenCalledTimes(10)
   })
 
-  it('should avoid infinite loops with other autoruns', () => {
+  it('should avoid infinite loops with other effects', () => {
     const nums = observable({ num1: 0, num2: 1 })
 
     const spy1 = jest.fn(() => (nums.num1 = nums.num2))
     const spy2 = jest.fn(() => (nums.num2 = nums.num1))
-    autorun(spy1)
-    autorun(spy2)
+    effect(spy1)
+    effect(spy2)
     expect(nums.num1).toBe(1)
     expect(nums.num2).toBe(1)
     expect(spy1).toHaveBeenCalledTimes(1)
@@ -361,12 +361,12 @@ describe('observer/autorun', () => {
     function greet() {
       return 'Hello World'
     }
-    const autorun1 = autorun(greet)
-    const autorun2 = autorun(greet)
-    expect(typeof autorun1).toBe('function')
-    expect(typeof autorun2).toBe('function')
-    expect(autorun1).not.toBe(greet)
-    expect(autorun1).not.toBe(autorun2)
+    const effect1 = effect(greet)
+    const effect2 = effect(greet)
+    expect(typeof effect1).toBe('function')
+    expect(typeof effect2).toBe('function')
+    expect(effect1).not.toBe(greet)
+    expect(effect1).not.toBe(effect2)
   })
 
   it('should discover new branches while running automatically', () => {
@@ -376,7 +376,7 @@ describe('observer/autorun', () => {
     const conditionalSpy = jest.fn(() => {
       dummy = obj.run ? obj.prop : 'other'
     })
-    autorun(conditionalSpy)
+    effect(conditionalSpy)
 
     expect(dummy).toBe('other')
     expect(conditionalSpy).toHaveBeenCalledTimes(1)
@@ -395,7 +395,7 @@ describe('observer/autorun', () => {
     let dummy
     let run = false
     const obj = observable({ prop: 'value' })
-    const runner = autorun(() => {
+    const runner = effect(() => {
       dummy = run ? obj.prop : 'other'
     })
 
@@ -416,7 +416,7 @@ describe('observer/autorun', () => {
     const conditionalSpy = jest.fn(() => {
       dummy = obj.run ? obj.prop : 'other'
     })
-    autorun(conditionalSpy)
+    effect(conditionalSpy)
 
     expect(dummy).toBe('value')
     expect(conditionalSpy).toHaveBeenCalledTimes(1)
@@ -428,9 +428,9 @@ describe('observer/autorun', () => {
     expect(conditionalSpy).toHaveBeenCalledTimes(2)
   })
 
-  it('should not double wrap if the passed function is a autorun', () => {
-    const runner = autorun(() => {})
-    const otherRunner = autorun(runner)
+  it('should not double wrap if the passed function is a effect', () => {
+    const runner = effect(() => {})
+    const otherRunner = effect(runner)
     expect(runner).not.toBe(otherRunner)
     expect(runner.raw).toBe(otherRunner.raw)
   })
@@ -444,7 +444,7 @@ describe('observer/autorun', () => {
       }
       dummy = obj.prop
     })
-    autorun(fnSpy)
+    effect(fnSpy)
 
     expect(fnSpy).toHaveBeenCalledTimes(1)
     obj.prop = 16
@@ -452,33 +452,33 @@ describe('observer/autorun', () => {
     expect(fnSpy).toHaveBeenCalledTimes(2)
   })
 
-  it('should allow nested autoruns', () => {
+  it('should allow nested effects', () => {
     const nums = observable({ num1: 0, num2: 1, num3: 2 })
     const dummy: any = {}
 
     const childSpy = jest.fn(() => (dummy.num1 = nums.num1))
-    const childautorun = autorun(childSpy)
+    const childeffect = effect(childSpy)
     const parentSpy = jest.fn(() => {
       dummy.num2 = nums.num2
-      childautorun()
+      childeffect()
       dummy.num3 = nums.num3
     })
-    autorun(parentSpy)
+    effect(parentSpy)
 
     expect(dummy).toEqual({ num1: 0, num2: 1, num3: 2 })
     expect(parentSpy).toHaveBeenCalledTimes(1)
     expect(childSpy).toHaveBeenCalledTimes(2)
-    // this should only call the childautorun
+    // this should only call the childeffect
     nums.num1 = 4
     expect(dummy).toEqual({ num1: 4, num2: 1, num3: 2 })
     expect(parentSpy).toHaveBeenCalledTimes(1)
     expect(childSpy).toHaveBeenCalledTimes(3)
-    // this calls the parentautorun, which calls the childautorun once
+    // this calls the parenteffect, which calls the childeffect once
     nums.num2 = 10
     expect(dummy).toEqual({ num1: 4, num2: 10, num3: 2 })
     expect(parentSpy).toHaveBeenCalledTimes(2)
     expect(childSpy).toHaveBeenCalledTimes(4)
-    // this calls the parentautorun, which calls the childautorun once
+    // this calls the parenteffect, which calls the childeffect once
     nums.num3 = 7
     expect(dummy).toEqual({ num1: 4, num2: 10, num3: 7 })
     expect(parentSpy).toHaveBeenCalledTimes(3)
@@ -497,7 +497,7 @@ describe('observer/autorun', () => {
     }
     const model = observable(new Model())
     let dummy
-    autorun(() => {
+    effect(() => {
       dummy = model.count
     })
     expect(dummy).toBe(0)
@@ -511,7 +511,7 @@ describe('observer/autorun', () => {
       runner = _runner
     })
     const obj = observable({ foo: 1 })
-    autorun(
+    effect(
       () => {
         dummy = obj.foo
       },
@@ -537,7 +537,7 @@ describe('observer/autorun', () => {
       events.push(e)
     })
     const obj = observable({ foo: 1, bar: 2 })
-    const runner = autorun(
+    const runner = effect(
       () => {
         dummy = obj.foo
         dummy = 'bar' in obj
@@ -549,19 +549,19 @@ describe('observer/autorun', () => {
     expect(onTrack).toHaveBeenCalledTimes(3)
     expect(events).toEqual([
       {
-        runner,
+        effect: runner,
         target: unwrap(obj),
         type: OperationTypes.GET,
         key: 'foo'
       },
       {
-        runner,
+        effect: runner,
         target: unwrap(obj),
         type: OperationTypes.HAS,
         key: 'bar'
       },
       {
-        runner,
+        effect: runner,
         target: unwrap(obj),
         type: OperationTypes.ITERATE,
         key: ITERATE_KEY
@@ -576,7 +576,7 @@ describe('observer/autorun', () => {
       events.push(e)
     })
     const obj = observable({ foo: 1 })
-    const runner = autorun(
+    const runner = effect(
       () => {
         dummy = obj.foo
       },
@@ -587,7 +587,7 @@ describe('observer/autorun', () => {
     expect(dummy).toBe(2)
     expect(onTrigger).toHaveBeenCalledTimes(1)
     expect(events[0]).toEqual({
-      runner,
+      effect: runner,
       target: unwrap(obj),
       type: OperationTypes.SET,
       key: 'foo',
@@ -599,7 +599,7 @@ describe('observer/autorun', () => {
     expect(dummy).toBeUndefined()
     expect(onTrigger).toHaveBeenCalledTimes(2)
     expect(events[1]).toEqual({
-      runner,
+      effect: runner,
       target: unwrap(obj),
       type: OperationTypes.DELETE,
       key: 'foo',
@@ -610,7 +610,7 @@ describe('observer/autorun', () => {
   it('stop', () => {
     let dummy
     const obj = observable({ prop: 1 })
-    const runner = autorun(() => {
+    const runner = effect(() => {
       dummy = obj.prop
     })
     obj.prop = 2
@@ -619,7 +619,7 @@ describe('observer/autorun', () => {
     obj.prop = 3
     expect(dummy).toBe(2)
 
-    // stopped runner should still be manually callable
+    // stopped effect should still be manually callable
     runner()
     expect(dummy).toBe(3)
   })
@@ -631,7 +631,7 @@ describe('observer/autorun', () => {
       })
     })
     let dummy
-    autorun(() => {
+    effect(() => {
       dummy = obj.foo.prop
     })
     expect(dummy).toBe(0)
index 71ce192a5a0c3801dc92b2375126784514519d99..07c7fe932fbaa5f2ec6c3091fcedc1645600d7c3 100644 (file)
@@ -8,7 +8,7 @@ import {
   markImmutable,
   lock,
   unlock,
-  autorun
+  effect
 } from '../src'
 
 describe('observer/immutable', () => {
@@ -75,10 +75,10 @@ describe('observer/immutable', () => {
       expect(warn).not.toHaveBeenCalled()
     })
 
-    it('should not trigger autoruns when locked', () => {
+    it('should not trigger effects when locked', () => {
       const observed = immutable({ a: 1 })
       let dummy
-      autorun(() => {
+      effect(() => {
         dummy = observed.a
       })
       expect(dummy).toBe(1)
@@ -87,10 +87,10 @@ describe('observer/immutable', () => {
       expect(dummy).toBe(1)
     })
 
-    it('should trigger autoruns when unlocked', () => {
+    it('should trigger effects when unlocked', () => {
       const observed = immutable({ a: 1 })
       let dummy
-      autorun(() => {
+      effect(() => {
         dummy = observed.a
       })
       expect(dummy).toBe(1)
@@ -161,10 +161,10 @@ describe('observer/immutable', () => {
       expect(warn).not.toHaveBeenCalled()
     })
 
-    it('should not trigger autoruns when locked', () => {
+    it('should not trigger effects when locked', () => {
       const observed = immutable([{ a: 1 }])
       let dummy
-      autorun(() => {
+      effect(() => {
         dummy = observed[0].a
       })
       expect(dummy).toBe(1)
@@ -176,10 +176,10 @@ describe('observer/immutable', () => {
       expect(dummy).toBe(1)
     })
 
-    it('should trigger autoruns when unlocked', () => {
+    it('should trigger effects when unlocked', () => {
       const observed = immutable([{ a: 1 }])
       let dummy
-      autorun(() => {
+      effect(() => {
         dummy = observed[0].a
       })
       expect(dummy).toBe(1)
@@ -220,11 +220,11 @@ describe('observer/immutable', () => {
         expect(isImmutable(original.get(key1))).toBe(false)
       })
 
-      test('should not allow mutation & not trigger autorun', () => {
+      test('should not allow mutation & not trigger effect', () => {
         const map = immutable(new Collection())
         const key = {}
         let dummy
-        autorun(() => {
+        effect(() => {
           dummy = map.get(key)
         })
         expect(dummy).toBeUndefined()
@@ -234,12 +234,12 @@ describe('observer/immutable', () => {
         expect(warn).toHaveBeenCalledTimes(1)
       })
 
-      test('should allow mutation & trigger autorun when unlocked', () => {
+      test('should allow mutation & trigger effect when unlocked', () => {
         const map = immutable(new Collection())
         const isWeak = Collection === WeakMap
         const key = {}
         let dummy
-        autorun(() => {
+        effect(() => {
           dummy = map.get(key) + (isWeak ? 0 : map.size)
         })
         expect(dummy).toBeNaN()
@@ -289,11 +289,11 @@ describe('observer/immutable', () => {
         expect(original.has(observable(key1))).toBe(false)
       })
 
-      test('should not allow mutation & not trigger autorun', () => {
+      test('should not allow mutation & not trigger effect', () => {
         const set = immutable(new Collection())
         const key = {}
         let dummy
-        autorun(() => {
+        effect(() => {
           dummy = set.has(key)
         })
         expect(dummy).toBe(false)
@@ -303,11 +303,11 @@ describe('observer/immutable', () => {
         expect(warn).toHaveBeenCalledTimes(1)
       })
 
-      test('should allow mutation & trigger autorun when unlocked', () => {
+      test('should allow mutation & trigger effect when unlocked', () => {
         const set = immutable(new Collection())
         const key = {}
         let dummy
-        autorun(() => {
+        effect(() => {
           dummy = set.has(key)
         })
         expect(dummy).toBe(false)
diff --git a/packages/observer/src/autorun.ts b/packages/observer/src/autorun.ts
deleted file mode 100644 (file)
index f47eb59..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-import { OperationTypes } from './operations'
-import { Dep, KeyToDepMap, targetMap } from './state'
-
-export interface Autorun {
-  (): any
-  isAutorun: true
-  active: boolean
-  raw: Function
-  deps: Array<Dep>
-  computed?: boolean
-  scheduler?: Scheduler
-  onTrack?: Debugger
-  onTrigger?: Debugger
-}
-
-export interface AutorunOptions {
-  lazy?: boolean
-  scheduler?: Scheduler
-  onTrack?: Debugger
-  onTrigger?: Debugger
-}
-
-export type Scheduler = (run: () => any) => void
-
-export type DebuggerEvent = {
-  runner: Autorun
-  target: any
-  type: OperationTypes
-  key: string | symbol | undefined
-}
-
-export type Debugger = (event: DebuggerEvent) => void
-
-export const activeAutorunStack: Autorun[] = []
-
-export const ITERATE_KEY = Symbol('iterate')
-
-export function createAutorun(fn: Function, options: AutorunOptions): Autorun {
-  const runner = function runner(...args): any {
-    return run(runner as Autorun, fn, args)
-  } as Autorun
-  runner.isAutorun = true
-  runner.active = true
-  runner.raw = fn
-  runner.scheduler = options.scheduler
-  runner.onTrack = options.onTrack
-  runner.onTrigger = options.onTrigger
-  runner.deps = []
-  return runner
-}
-
-function run(runner: Autorun, fn: Function, args: any[]): any {
-  if (!runner.active) {
-    return fn(...args)
-  }
-  if (activeAutorunStack.indexOf(runner) === -1) {
-    cleanup(runner)
-    try {
-      activeAutorunStack.push(runner)
-      return fn(...args)
-    } finally {
-      activeAutorunStack.pop()
-    }
-  }
-}
-
-export function cleanup(runner: Autorun) {
-  for (let i = 0; i < runner.deps.length; i++) {
-    runner.deps[i].delete(runner)
-  }
-  runner.deps = []
-}
-
-export function track(
-  target: any,
-  type: OperationTypes,
-  key?: string | symbol
-) {
-  const runner = activeAutorunStack[activeAutorunStack.length - 1]
-  if (runner) {
-    if (type === OperationTypes.ITERATE) {
-      key = ITERATE_KEY
-    }
-    // keyMap must exist because only an observed target can call this function
-    const depsMap = targetMap.get(target) as KeyToDepMap
-    let dep = depsMap.get(key as string | symbol)
-    if (!dep) {
-      depsMap.set(key as string | symbol, (dep = new Set()))
-    }
-    if (!dep.has(runner)) {
-      dep.add(runner)
-      runner.deps.push(dep)
-      if (__DEV__ && runner.onTrack) {
-        runner.onTrack({
-          runner,
-          target,
-          type,
-          key
-        })
-      }
-    }
-  }
-}
-
-export function trigger(
-  target: any,
-  type: OperationTypes,
-  key?: string | symbol,
-  extraInfo?: any
-) {
-  const depsMap = targetMap.get(target) as KeyToDepMap
-  const runners = new Set()
-  const computedRunners = new Set()
-  if (type === OperationTypes.CLEAR) {
-    // collection being cleared, trigger all runners for target
-    depsMap.forEach(dep => {
-      addRunners(runners, computedRunners, dep)
-    })
-  } else {
-    // schedule runs for SET | ADD | DELETE
-    if (key !== void 0) {
-      addRunners(runners, computedRunners, depsMap.get(key as string | symbol))
-    }
-    // also run for iteration key on ADD | DELETE
-    if (type === OperationTypes.ADD || type === OperationTypes.DELETE) {
-      const iterationKey = Array.isArray(target) ? 'length' : ITERATE_KEY
-      addRunners(runners, computedRunners, depsMap.get(iterationKey))
-    }
-  }
-  const run = (runner: Autorun) => {
-    scheduleRun(runner, target, type, key, extraInfo)
-  }
-  // Important: computed runners must be run first so that computed getters
-  // can be invalidated before any normal runners that depend on them are run.
-  computedRunners.forEach(run)
-  runners.forEach(run)
-}
-
-function addRunners(
-  runners: Set<Autorun>,
-  computedRunners: Set<Autorun>,
-  runnersToAdd: Set<Autorun> | undefined
-) {
-  if (runnersToAdd !== void 0) {
-    runnersToAdd.forEach(runner => {
-      if (runner.computed) {
-        computedRunners.add(runner)
-      } else {
-        runners.add(runner)
-      }
-    })
-  }
-}
-
-function scheduleRun(
-  runner: Autorun,
-  target: any,
-  type: OperationTypes,
-  key: string | symbol | undefined,
-  extraInfo: any
-) {
-  if (__DEV__ && runner.onTrigger) {
-    runner.onTrigger(
-      Object.assign(
-        {
-          runner,
-          target,
-          key,
-          type
-        },
-        extraInfo
-      )
-    )
-  }
-  if (runner.scheduler !== void 0) {
-    runner.scheduler(runner)
-  } else {
-    runner()
-  }
-}
index 0be06e3ac2c6954c294d8802e1a5db7b959c4e29..62515469186a77f91785424c20ea8ac20bbd65f1 100644 (file)
@@ -1,6 +1,6 @@
 import { observable, immutable, unwrap } from './index'
 import { OperationTypes } from './operations'
-import { track, trigger } from './autorun'
+import { track, trigger } from './effect'
 import { LOCKED } from './lock'
 import { isObject } from '@vue/shared'
 
index 8fd40a94cab4c17f09d5b1007a8b74bbe8d8bde9..75e32c7ba1f51f20187405fc0e1b09ddd6f83d70 100644 (file)
@@ -1,5 +1,5 @@
 import { unwrap, observable, immutable } from './index'
-import { track, trigger } from './autorun'
+import { track, trigger } from './effect'
 import { OperationTypes } from './operations'
 import { LOCKED } from './lock'
 import { isObject } from '@vue/shared'
index 31033bbbe78f51d7748022b9e3811369340f5d55..b74f8ca54edbc536bfcc4796202325c307903272 100644 (file)
@@ -1,9 +1,9 @@
-import { autorun } from './index'
-import { Autorun, activeAutorunStack } from './autorun'
+import { effect } from './index'
+import { ReactiveEffect, activeReactiveEffectStack } from './effect'
 
 export interface ComputedGetter<T = any> {
   (): T
-  runner: Autorun
+  effect: ReactiveEffect
 }
 
 export function computed<T, C = null>(
@@ -12,7 +12,7 @@ export function computed<T, C = null>(
 ): ComputedGetter<T> {
   let dirty: boolean = true
   let value: any = undefined
-  const runner = autorun(() => getter.call(context, context), {
+  const runner = effect(() => getter.call(context, context), {
     lazy: true,
     scheduler: () => {
       dirty = true
@@ -23,21 +23,22 @@ export function computed<T, C = null>(
       value = runner()
       dirty = false
     }
-    // When computed autoruns are accessed in a parent autorun, the parent
+    // When computed effects are accessed in a parent effect, the parent
     // should track all the dependencies the computed property has tracked.
     // This should also apply for chained computed properties.
     trackChildRun(runner)
     return value
   }) as ComputedGetter
-  // expose runner so computed can be stopped
-  computedGetter.runner = runner
-  // mark runner as computed so that it gets priority during trigger
+  // expose effect so computed can be stopped
+  computedGetter.effect = runner
+  // mark effect as computed so that it gets priority during trigger
   runner.computed = true
   return computedGetter
 }
 
-function trackChildRun(childRunner: Autorun) {
-  const parentRunner = activeAutorunStack[activeAutorunStack.length - 1]
+function trackChildRun(childRunner: ReactiveEffect) {
+  const parentRunner =
+    activeReactiveEffectStack[activeReactiveEffectStack.length - 1]
   if (parentRunner) {
     for (let i = 0; i < childRunner.deps.length; i++) {
       const dep = childRunner.deps[i]
diff --git a/packages/observer/src/effect.ts b/packages/observer/src/effect.ts
new file mode 100644 (file)
index 0000000..e4ae3d9
--- /dev/null
@@ -0,0 +1,183 @@
+import { OperationTypes } from './operations'
+import { Dep, KeyToDepMap, targetMap } from './state'
+
+export interface ReactiveEffect {
+  (): any
+  isEffect: true
+  active: boolean
+  raw: Function
+  deps: Array<Dep>
+  computed?: boolean
+  scheduler?: Scheduler
+  onTrack?: Debugger
+  onTrigger?: Debugger
+}
+
+export interface ReactiveEffectOptions {
+  lazy?: boolean
+  scheduler?: Scheduler
+  onTrack?: Debugger
+  onTrigger?: Debugger
+}
+
+export type Scheduler = (run: () => any) => void
+
+export type DebuggerEvent = {
+  effect: ReactiveEffect
+  target: any
+  type: OperationTypes
+  key: string | symbol | undefined
+}
+
+export type Debugger = (event: DebuggerEvent) => void
+
+export const activeReactiveEffectStack: ReactiveEffect[] = []
+
+export const ITERATE_KEY = Symbol('iterate')
+
+export function createReactiveEffect(
+  fn: Function,
+  options: ReactiveEffectOptions
+): ReactiveEffect {
+  const effect = function effect(...args): any {
+    return run(effect as ReactiveEffect, fn, args)
+  } as ReactiveEffect
+  effect.isEffect = true
+  effect.active = true
+  effect.raw = fn
+  effect.scheduler = options.scheduler
+  effect.onTrack = options.onTrack
+  effect.onTrigger = options.onTrigger
+  effect.deps = []
+  return effect
+}
+
+function run(effect: ReactiveEffect, fn: Function, args: any[]): any {
+  if (!effect.active) {
+    return fn(...args)
+  }
+  if (activeReactiveEffectStack.indexOf(effect) === -1) {
+    cleanup(effect)
+    try {
+      activeReactiveEffectStack.push(effect)
+      return fn(...args)
+    } finally {
+      activeReactiveEffectStack.pop()
+    }
+  }
+}
+
+export function cleanup(effect: ReactiveEffect) {
+  for (let i = 0; i < effect.deps.length; i++) {
+    effect.deps[i].delete(effect)
+  }
+  effect.deps = []
+}
+
+export function track(
+  target: any,
+  type: OperationTypes,
+  key?: string | symbol
+) {
+  const effect = activeReactiveEffectStack[activeReactiveEffectStack.length - 1]
+  if (effect) {
+    if (type === OperationTypes.ITERATE) {
+      key = ITERATE_KEY
+    }
+    // keyMap must exist because only an observed target can call this function
+    const depsMap = targetMap.get(target) as KeyToDepMap
+    let dep = depsMap.get(key as string | symbol)
+    if (!dep) {
+      depsMap.set(key as string | symbol, (dep = new Set()))
+    }
+    if (!dep.has(effect)) {
+      dep.add(effect)
+      effect.deps.push(dep)
+      if (__DEV__ && effect.onTrack) {
+        effect.onTrack({
+          effect,
+          target,
+          type,
+          key
+        })
+      }
+    }
+  }
+}
+
+export function trigger(
+  target: any,
+  type: OperationTypes,
+  key?: string | symbol,
+  extraInfo?: any
+) {
+  const depsMap = targetMap.get(target) as KeyToDepMap
+  const effects = new Set()
+  const computedRunners = new Set()
+  if (type === OperationTypes.CLEAR) {
+    // collection being cleared, trigger all effects for target
+    depsMap.forEach(dep => {
+      addRunners(effects, computedRunners, dep)
+    })
+  } else {
+    // schedule runs for SET | ADD | DELETE
+    if (key !== void 0) {
+      addRunners(effects, computedRunners, depsMap.get(key as string | symbol))
+    }
+    // also run for iteration key on ADD | DELETE
+    if (type === OperationTypes.ADD || type === OperationTypes.DELETE) {
+      const iterationKey = Array.isArray(target) ? 'length' : ITERATE_KEY
+      addRunners(effects, computedRunners, depsMap.get(iterationKey))
+    }
+  }
+  const run = (effect: ReactiveEffect) => {
+    scheduleRun(effect, target, type, key, extraInfo)
+  }
+  // Important: computed effects must be run first so that computed getters
+  // can be invalidated before any normal effects that depend on them are run.
+  computedRunners.forEach(run)
+  effects.forEach(run)
+}
+
+function addRunners(
+  effects: Set<ReactiveEffect>,
+  computedRunners: Set<ReactiveEffect>,
+  effectsToAdd: Set<ReactiveEffect> | undefined
+) {
+  if (effectsToAdd !== void 0) {
+    effectsToAdd.forEach(effect => {
+      if (effect.computed) {
+        computedRunners.add(effect)
+      } else {
+        effects.add(effect)
+      }
+    })
+  }
+}
+
+function scheduleRun(
+  effect: ReactiveEffect,
+  target: any,
+  type: OperationTypes,
+  key: string | symbol | undefined,
+  extraInfo: any
+) {
+  if (__DEV__ && effect.onTrigger) {
+    effect.onTrigger(
+      Object.assign(
+        {
+          effect,
+          target,
+          key,
+          type
+        },
+        extraInfo
+      )
+    )
+  }
+  if (effect.scheduler !== void 0) {
+    effect.scheduler(effect)
+  } else {
+    effect()
+  }
+}
index 005b82d3b94b5c6b98827d0d0cfa1afe82841cb0..a2cdf80698871bd2fd5737eeb9ec68582fac21fe 100644 (file)
@@ -17,14 +17,14 @@ import {
 } from './state'
 
 import {
-  createAutorun,
+  createReactiveEffect,
   cleanup,
-  Autorun,
-  AutorunOptions,
+  ReactiveEffect,
+  ReactiveEffectOptions,
   DebuggerEvent
-} from './autorun'
+} from './effect'
 
-export { Autorun, AutorunOptions, DebuggerEvent }
+export { ReactiveEffect, ReactiveEffectOptions, DebuggerEvent }
 export { OperationTypes } from './operations'
 export { computed, ComputedGetter } from './computed'
 export { lock, unlock } from './lock'
@@ -114,24 +114,24 @@ function createObservable(
   return observed
 }
 
-export function autorun(
+export function effect(
   fn: Function,
-  options: AutorunOptions = EMPTY_OBJ
-): Autorun {
-  if ((fn as Autorun).isAutorun) {
-    fn = (fn as Autorun).raw
+  options: ReactiveEffectOptions = EMPTY_OBJ
+): ReactiveEffect {
+  if ((fn as ReactiveEffect).isEffect) {
+    fn = (fn as ReactiveEffect).raw
   }
-  const runner = createAutorun(fn, options)
+  const effect = createReactiveEffect(fn, options)
   if (!options.lazy) {
-    runner()
+    effect()
   }
-  return runner
+  return effect
 }
 
-export function stop(runner: Autorun) {
-  if (runner.active) {
-    cleanup(runner)
-    runner.active = false
+export function stop(effect: ReactiveEffect) {
+  if (effect.active) {
+    cleanup(effect)
+    effect.active = false
   }
 }
 
index 9efbe37337be8b53711d0a70101fc85ea94b8735..eee65d22f6c47833251c71163a5cbe051e9b96a0 100644 (file)
@@ -1,10 +1,10 @@
-import { Autorun } from './autorun'
+import { ReactiveEffect } from './effect'
 
 // The main WeakMap that stores {target -> key -> dep} connections.
 // Conceptually, it's easier to think of a dependency as a Dep class
 // which maintains a Set of subscribers, but we simply store them as
 // raw Sets to reduce memory overhead.
-export type Dep = Set<Autorun>
+export type Dep = Set<ReactiveEffect>
 export type KeyToDepMap = Map<string | symbol, Dep>
 export const targetMap: WeakMap<any, KeyToDepMap> = new WeakMap()
 
index 0096cc771a479efa20f577f469bba404b18647cf..52157472f5c92dbebefbeea44d9b97086826d3c2 100644 (file)
@@ -12,7 +12,9 @@ import {
   nextTick,
   resetOps,
   dumpOps,
-  NodeOpTypes
+  NodeOpTypes,
+  createFragment,
+  createTextVNode
 } from '@vue/runtime-test'
 
 describe('Fragments', () => {
@@ -57,9 +59,12 @@ describe('Fragments', () => {
     class App extends Component {
       render() {
         return state.ok
-          ? h.f([h('div', 'one'), h.t('two')], ChildrenFlags.NONE_KEYED_VNODES)
-          : h.f(
-              [h('div', 'foo'), h.t('bar'), h.t('baz')],
+          ? createFragment(
+              [h('div', 'one'), createTextVNode('two')],
+              ChildrenFlags.NONE_KEYED_VNODES
+            )
+          : createFragment(
+              [h('div', 'foo'), createTextVNode('bar'), createTextVNode('baz')],
               ChildrenFlags.NONE_KEYED_VNODES
             )
       }
index 6de11b647fe5ea736d4b3d8f37aa75249e4a7319..72d5d8731f07864055dc45079e49f2633288e6ee 100644 (file)
@@ -8,7 +8,7 @@ import {
   WatchOptions
 } from './componentOptions'
 import { setupWatcher } from './componentWatch'
-import { Autorun, DebuggerEvent, ComputedGetter } from '@vue/observer'
+import { ReactiveEffect, DebuggerEvent, ComputedGetter } from '@vue/observer'
 import { nextTick } from '@vue/scheduler'
 import { ErrorTypes } from './errorHandling'
 import { initializeComponentInstance } from './componentUtils'
@@ -101,7 +101,7 @@ export interface ComponentInstance<P = {}, D = {}>
   $children: ComponentInstance[]
   $options: ComponentOptions<P, D>
 
-  _updateHandle: Autorun
+  _update: ReactiveEffect
   _queueJob: ((fn: () => void) => void)
   _self: ComponentInstance<P, D> // on proxies only
 }
@@ -128,11 +128,11 @@ class InternalComponent implements PublicInstanceMethods {
 
   _rawData: Data | null = null
   _computedGetters: Record<string, ComputedGetter> | null = null
-  _watchHandles: Set<Autorun> | null = null
+  _watchHandles: Set<ReactiveEffect> | null = null
   _mounted: boolean = false
   _unmounted: boolean = false
   _events: { [event: string]: Function[] | null } | null = null
-  _updateHandle: Autorun | null = null
+  _update: ReactiveEffect | null = null
   _queueJob: ((fn: () => void) => void) | null = null
   _isVue: boolean = true
   _inactiveRoot: boolean = false
index 3ab80a67cc19f80f9acb839aff25f6ad9c619dd9..0cc7796e97f08826fbc4f65bb0208f51d2f7d7b9 100644 (file)
@@ -25,7 +25,7 @@ export function teardownComputed(instance: ComponentInstance) {
   const handles = instance._computedGetters
   if (handles !== null) {
     for (const key in handles) {
-      stop(handles[key].runner)
+      stop(handles[key].effect)
     }
   }
 }
index 48e457a6e82473eec282ff2857e7d54bae21e73d..3582b57f7795fe047cda84e930789c45b8872bf8 100644 (file)
@@ -158,7 +158,7 @@ export function teardownComponentInstance(instance: ComponentInstance) {
       1
     )
   }
-  stop(instance._updateHandle)
+  stop(instance._update)
   teardownComputed(instance)
   teardownWatch(instance)
 }
index 183c230b3ad49ee71319ddbc77e0495a2fdbb9b0..ad607e535028895eaff096d642bb2b5937df866e 100644 (file)
@@ -8,7 +8,7 @@ import {
 } from '@vue/shared'
 import { ComponentInstance } from './component'
 import { ComponentWatchOptions, WatchOptions } from './componentOptions'
-import { autorun, stop } from '@vue/observer'
+import { effect, stop } from '@vue/observer'
 import { queueJob } from '@vue/scheduler'
 import { handleError, ErrorTypes } from './errorHandling'
 import { warn } from './warning'
@@ -70,7 +70,7 @@ export function setupWatcher(
     }
   }
 
-  const runner = autorun(getter, {
+  const runner = effect(getter, {
     lazy: true,
     scheduler: options.sync
       ? applyCb
index 27a008e9c3fcc9930f821cf2ae078bbf54a579ac..08b870601cbb79b78087e5e958138a802660a9c7 100644 (file)
@@ -1,15 +1,15 @@
 import {
-  autorun,
-  stop,
-  Autorun,
+  effect as createReactiveEffect,
+  stop as stopReactiveEffect,
+  ReactiveEffect,
   immutable,
-  AutorunOptions
+  ReactiveEffectOptions
 } from '@vue/observer'
 import {
   queueJob,
   handleSchedulerError,
   nextTick,
-  queueEffect,
+  queuePostEffect,
   flushEffects,
   queueNodeOp
 } from '@vue/scheduler'
@@ -78,7 +78,7 @@ export interface RendererOptions {
 export interface FunctionalHandle {
   prev: VNode
   next: VNode
-  update: Autorun
+  update: ReactiveEffect
   container: RenderNode | null
 }
 
@@ -206,12 +206,12 @@ export function createRenderer(options: RendererOptions) {
       queueInsertOrAppend(container, el, endNode)
     }
     if (ref) {
-      queueEffect(() => {
+      queuePostEffect(() => {
         ref(el)
       })
     }
     if (data != null && data.vnodeMounted) {
-      queueEffect(() => {
+      queuePostEffect(() => {
         data.vnodeMounted(vnode)
       })
     }
@@ -272,7 +272,7 @@ export function createRenderer(options: RendererOptions) {
     })
 
     const doMount = () => {
-      handle.update = autorun(
+      handle.update = createReactiveEffect(
         () => {
           if (!handle.next) {
             // initial mount
@@ -280,7 +280,7 @@ export function createRenderer(options: RendererOptions) {
               pushWarningContext(vnode)
             }
             const subTree = (vnode.children = renderFunctionalRoot(vnode))
-            queueEffect(() => {
+            queuePostEffect(() => {
               vnode.el = subTree.el as RenderNode
             })
             mount(subTree, container, vnode as MountedVNode, isSVG, endNode)
@@ -306,7 +306,7 @@ export function createRenderer(options: RendererOptions) {
         doMount()
         // cleanup if mount is invalidated before committed
         return () => {
-          stop(handle.update)
+          stopReactiveEffect(handle.update)
         }
       })
     }
@@ -319,7 +319,7 @@ export function createRenderer(options: RendererOptions) {
     }
     const prevTree = prev.children as MountedVNode
     const nextTree = (next.children = renderFunctionalRoot(next))
-    queueEffect(() => {
+    queuePostEffect(() => {
       next.el = nextTree.el
     })
     patch(
@@ -355,7 +355,7 @@ export function createRenderer(options: RendererOptions) {
     const { children, childFlags } = vnode
     switch (childFlags) {
       case ChildrenFlags.SINGLE_VNODE:
-        queueEffect(() => {
+        queuePostEffect(() => {
           vnode.el = (children as MountedVNode).el
         })
         mount(children as VNode, container, contextVNode, isSVG, endNode)
@@ -366,7 +366,7 @@ export function createRenderer(options: RendererOptions) {
         vnode.el = placeholder.el
         break
       default:
-        queueEffect(() => {
+        queuePostEffect(() => {
           vnode.el = (children as MountedVNode[])[0].el
         })
         mountArrayChildren(
@@ -403,7 +403,7 @@ export function createRenderer(options: RendererOptions) {
       )
     }
     if (ref) {
-      queueEffect(() => {
+      queuePostEffect(() => {
         ref(target)
       })
     }
@@ -638,7 +638,7 @@ export function createRenderer(options: RendererOptions) {
     // then retrieve its next sibling to use as the end node for patchChildren.
     const endNode = platformNextSibling(getVNodeLastEl(prevVNode))
     const { childFlags, children } = nextVNode
-    queueEffect(() => {
+    queuePostEffect(() => {
       switch (childFlags) {
         case ChildrenFlags.SINGLE_VNODE:
           nextVNode.el = (children as MountedVNode).el
@@ -1181,7 +1181,7 @@ export function createRenderer(options: RendererOptions) {
         }
       } else {
         // functional
-        stop((handle as FunctionalHandle).update)
+        stopReactiveEffect((handle as FunctionalHandle).update)
         unmount(children as MountedVNode)
       }
     } else if (flags & VNodeFlags.PORTAL) {
@@ -1293,16 +1293,16 @@ export function createRenderer(options: RendererOptions) {
     } = instance
 
     instance.$forceUpdate = () => {
-      queueJob(instance._updateHandle)
+      queueJob(instance._update)
     }
 
-    const autorunOptions: AutorunOptions = {
+    const effectOptions: ReactiveEffectOptions = {
       scheduler: queueJob
     }
 
     if (__DEV__) {
       if (renderTracked) {
-        autorunOptions.onTrack = event => {
+        effectOptions.onTrack = event => {
           callLifecycleHookWithHandler(
             renderTracked,
             $proxy,
@@ -1312,7 +1312,7 @@ export function createRenderer(options: RendererOptions) {
         }
       }
       if (renderTriggered) {
-        autorunOptions.onTrigger = event => {
+        effectOptions.onTrigger = event => {
           callLifecycleHookWithHandler(
             renderTriggered,
             $proxy,
@@ -1323,7 +1323,7 @@ export function createRenderer(options: RendererOptions) {
       }
     }
 
-    instance._updateHandle = autorun(() => {
+    instance._update = createReactiveEffect(() => {
       if (instance._unmounted) {
         return
       }
@@ -1340,7 +1340,7 @@ export function createRenderer(options: RendererOptions) {
 
         instance.$vnode = renderInstanceRoot(instance) as MountedVNode
 
-        queueEffect(() => {
+        queuePostEffect(() => {
           vnode.el = instance.$vnode.el
           if (__COMPAT__) {
             // expose __vue__ for devtools
@@ -1360,7 +1360,7 @@ export function createRenderer(options: RendererOptions) {
 
         mount(instance.$vnode, container, vnode as MountedVNode, isSVG, endNode)
       }
-    }, autorunOptions)
+    }, effectOptions)
 
     if (__DEV__) {
       popWarningContext()
@@ -1397,7 +1397,7 @@ export function createRenderer(options: RendererOptions) {
 
     const nextVNode = renderInstanceRoot(instance) as MountedVNode
 
-    queueEffect(() => {
+    queuePostEffect(() => {
       instance.$vnode = nextVNode
       const el = nextVNode.el as RenderNode
       if (__COMPAT__) {
@@ -1486,7 +1486,7 @@ export function createRenderer(options: RendererOptions) {
     if (__DEV__) {
       popWarningContext()
     }
-    queueEffect(() => {
+    queuePostEffect(() => {
       callActivatedHook(instance, true)
     })
   }
index e18881e609c7475e46e38d9566287a5e7eddd5aa..d196ce9af9954b651fd4484007560cf0bc51de86 100644 (file)
@@ -1,4 +1,4 @@
-import { queueJob, queueEffect, nextTick } from '../src/index'
+import { queueJob, queuePostEffect, nextTick } from '../src/index'
 
 describe('scheduler', () => {
   it('queueJob', async () => {
@@ -36,11 +36,11 @@ describe('scheduler', () => {
     const calls: any = []
     const job1 = () => {
       calls.push('job1')
-      queueEffect(cb1)
+      queuePostEffect(cb1)
     }
     const job2 = () => {
       calls.push('job2')
-      queueEffect(cb2)
+      queuePostEffect(cb2)
     }
     const cb1 = () => {
       calls.push('cb1')
@@ -59,13 +59,13 @@ describe('scheduler', () => {
     const calls: any = []
     const job1 = () => {
       calls.push('job1')
-      queueEffect(cb1)
+      queuePostEffect(cb1)
       // job1 queues job2
       queueJob(job2)
     }
     const job2 = () => {
       calls.push('job2')
-      queueEffect(cb2)
+      queuePostEffect(cb2)
     }
     const cb1 = () => {
       calls.push('cb1')
@@ -96,11 +96,11 @@ describe('scheduler', () => {
     expect(calls).toEqual(['job1', 'job2'])
   })
 
-  it('queueJob inside postCommitCb', async () => {
+  it('queueJob inside postEffect', async () => {
     const calls: any = []
     const job1 = () => {
       calls.push('job1')
-      queueEffect(cb1)
+      queuePostEffect(cb1)
     }
     const cb1 = () => {
       // queue another job in postFlushCb
@@ -109,7 +109,7 @@ describe('scheduler', () => {
     }
     const job2 = () => {
       calls.push('job2')
-      queueEffect(cb2)
+      queuePostEffect(cb2)
     }
     const cb2 = () => {
       calls.push('cb2')
index 79e9a564914e49c47b9c913249e16224b1e15722..89323efd4ab128148cd340bead5272b1fbc732e0 100644 (file)
@@ -31,15 +31,15 @@ interface Job<T extends Function = () => void> {
   ops: Op[]
   // Any post DOM mutation side-effects (updated / mounted hooks, refs) are
   // buffered inside the job's effects queue.
-  // Effects are queued by calling `queueEffect` inside the job function.
-  effects: Function[]
+  // Effects are queued by calling `queuePostEffect` inside the job function.
+  postEffects: Function[]
   // A job may queue other jobs (e.g. a parent component update triggers the
   // update of a child component). Jobs queued by another job is kept in the
   // parent's children array, so that in case the parent job is invalidated,
   // all its children can be invalidated as well (recursively).
   children: Job[]
   // Sometimes it's inevitable for a stage fn to produce some side effects
-  // (e.g. a component instance sets up an Autorun). In those cases the stage fn
+  // (e.g. a component instance sets up an ReactiveEffect). In those cases the stage fn
   // can return a cleanup function which will be called when the job is
   // invalidated.
   cleanup: T | null
@@ -172,8 +172,8 @@ function flushAfterMacroTask() {
 // This is the main API of the scheduler. The raw job can actually be any
 // function, but since they are invalidated by identity, it is important that
 // a component's update job is a consistent function across its lifecycle -
-// in the renderer, it's actually instance._updateHandle which is in turn
-// an Autorun function.
+// in the renderer, it's actually instance._update which is in turn
+// an ReactiveEffect function.
 export function queueJob(rawJob: Function) {
   const job = rawJob as Job
   if (currentJob) {
@@ -196,9 +196,9 @@ export function queueJob(rawJob: Function) {
   }
 }
 
-export function queueEffect(fn: Function) {
+export function queuePostEffect(fn: Function) {
   if (currentJob) {
-    currentJob.effects.push(fn)
+    currentJob.postEffects.push(fn)
   } else {
     postEffectsQueue.push(fn)
   }
@@ -296,13 +296,13 @@ function flush(): void {
 
 function resetJob(job: Job) {
   job.ops.length = 0
-  job.effects.length = 0
+  job.postEffects.length = 0
   job.children.length = 0
 }
 
 function queueJobForStaging(job: Job) {
   job.ops = job.ops || []
-  job.effects = job.effects || []
+  job.postEffects = job.postEffects || []
   job.children = job.children || []
   resetJob(job)
   // inherit parent job's expiration deadline
@@ -361,13 +361,13 @@ function stageJob(job: Job) {
 }
 
 function commitJob(job: Job) {
-  const { ops, effects } = job
+  const { ops, postEffects } = job
   for (let i = 0; i < ops.length; i++) {
     applyOp(ops[i])
   }
   // queue post commit cbs
-  if (effects) {
-    postEffectsQueue.push(...effects)
+  if (postEffects) {
+    postEffectsQueue.push(...postEffects)
   }
   resetJob(job)
   job.status = JobStatus.IDLE