@mpxjs/core 2.10.17-beta.6 → 2.10.17-beta.8-effect-log
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/core/proxy.js +10 -1
- package/src/observer/array.js +1 -1
- package/src/observer/computed.js +2 -2
- package/src/observer/dep.js +25 -5
- package/src/observer/effect.js +46 -6
- package/src/observer/reactive.js +13 -7
- package/src/observer/watch.js +1 -1
- package/src/platform/env/navigationHelper.ios.js +3 -2
- package/src/platform/patch/getDefaultOptions.ios.js +24 -6
package/package.json
CHANGED
package/src/core/proxy.js
CHANGED
|
@@ -166,6 +166,7 @@ export default class MpxProxy {
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
created () {
|
|
169
|
+
console.log('[mpx] create proxy instance')
|
|
169
170
|
if (__mpx_dynamic_runtime__) {
|
|
170
171
|
// 缓存上下文,在 destoryed 阶段删除
|
|
171
172
|
contextMap.set(this.uid, this.target)
|
|
@@ -752,6 +753,13 @@ export default class MpxProxy {
|
|
|
752
753
|
const moduleId = this.target.__moduleId
|
|
753
754
|
const dynamicTarget = this.target.__dynamic
|
|
754
755
|
|
|
756
|
+
const debugConfig = typeof global.__getMpxRenderEffectDebugRules === 'function'
|
|
757
|
+
? global.__getMpxRenderEffectDebugRules(this.options?.mpxFileResource)
|
|
758
|
+
: {
|
|
759
|
+
debug: 1,
|
|
760
|
+
name: `MpxRenderEffect-${this.options?.mpxFileResource || 'unknown'}`
|
|
761
|
+
}
|
|
762
|
+
|
|
755
763
|
const effect = this.effect = new ReactiveEffect(() => {
|
|
756
764
|
// pre render for props update
|
|
757
765
|
if (this.propsUpdatedFlag) {
|
|
@@ -781,8 +789,9 @@ export default class MpxProxy {
|
|
|
781
789
|
} else {
|
|
782
790
|
this.render()
|
|
783
791
|
}
|
|
784
|
-
}, () => queueJob(update), this.scope)
|
|
792
|
+
}, () => queueJob(update), this.scope, this.scope, debugConfig.debug, debugConfig.name)
|
|
785
793
|
|
|
794
|
+
console.log(`[mpx] ${this.options?.mpxFileResource} will initRender`)
|
|
786
795
|
const update = this.update = effect.run.bind(effect)
|
|
787
796
|
update.id = this.uid
|
|
788
797
|
// render effect允许自触发
|
package/src/observer/array.js
CHANGED
package/src/observer/computed.js
CHANGED
|
@@ -3,7 +3,7 @@ import Dep from './dep'
|
|
|
3
3
|
import { createRef } from './ref'
|
|
4
4
|
import { ReactiveEffect } from './effect'
|
|
5
5
|
|
|
6
|
-
export function computed (getterOrOptions) {
|
|
6
|
+
export function computed (getterOrOptions, options = {}) {
|
|
7
7
|
let getter, setter
|
|
8
8
|
if (isFunction(getterOrOptions)) {
|
|
9
9
|
getter = getterOrOptions
|
|
@@ -17,7 +17,7 @@ export function computed (getterOrOptions) {
|
|
|
17
17
|
let value
|
|
18
18
|
const effect = new ReactiveEffect(getter, () => {
|
|
19
19
|
dirty = true
|
|
20
|
-
})
|
|
20
|
+
}, undefined, options.debug || 0, options.name || 'anonymous computed')
|
|
21
21
|
|
|
22
22
|
return createRef({
|
|
23
23
|
get: () => {
|
package/src/observer/dep.js
CHANGED
|
@@ -7,30 +7,50 @@ let uid = 0
|
|
|
7
7
|
* directives subscribing to it.
|
|
8
8
|
*/
|
|
9
9
|
export default class Dep {
|
|
10
|
-
constructor () {
|
|
10
|
+
constructor (key) {
|
|
11
11
|
this.id = uid++
|
|
12
12
|
this.subs = []
|
|
13
|
+
this.addSubStacks = new Map()
|
|
14
|
+
this.key = key
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
addSub (sub) {
|
|
18
|
+
const addSubStack = new Error('此时被添加到订阅者列表').stack
|
|
19
|
+
this.addSubStacks.set(sub, addSubStack)
|
|
16
20
|
this.subs.push(sub)
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
removeSub (sub) {
|
|
20
24
|
remove(this.subs, sub)
|
|
25
|
+
this.addSubStacks.delete(sub)
|
|
21
26
|
}
|
|
22
27
|
|
|
23
|
-
depend () {
|
|
28
|
+
depend (key, value) {
|
|
24
29
|
if (Dep.target) {
|
|
25
|
-
|
|
30
|
+
// if (this.key === 'link_params' || key === 'link_params') console.log(new Error('此时被依赖').stack)
|
|
31
|
+
Dep.target.addDep(this, key, value)
|
|
26
32
|
}
|
|
27
33
|
}
|
|
28
34
|
|
|
29
|
-
notify () {
|
|
35
|
+
notify (key, value, oldvalue, stack) {
|
|
30
36
|
// stabilize the subscriber list first
|
|
31
37
|
const subs = this.subs.slice()
|
|
38
|
+
try {
|
|
39
|
+
console.log('[Mpx Dep] notify ' +
|
|
40
|
+
this.subs.length +
|
|
41
|
+
' subs, from ' +
|
|
42
|
+
key +
|
|
43
|
+
': ' +
|
|
44
|
+
(typeof oldvalue === 'object' ? JSON.stringify(oldvalue) : oldvalue) +
|
|
45
|
+
' -> ' +
|
|
46
|
+
(typeof value === 'object' ? JSON.stringify(value) : value) +
|
|
47
|
+
', subs: ' +
|
|
48
|
+
subs.map(s => `id:${s.id} name:${s.name}`).join(', '))
|
|
49
|
+
} catch (e) {
|
|
50
|
+
// do nothing
|
|
51
|
+
}
|
|
32
52
|
for (let i = 0, l = subs.length; i < l; i++) {
|
|
33
|
-
subs[i].update()
|
|
53
|
+
subs[i].update(key, value, oldvalue, stack, this.addSubStacks.get(subs[i]))
|
|
34
54
|
}
|
|
35
55
|
}
|
|
36
56
|
}
|
package/src/observer/effect.js
CHANGED
|
@@ -17,6 +17,8 @@ export function resetTracking () {
|
|
|
17
17
|
shouldTrack = last === undefined ? true : last
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
global.__setMpxReactiveEffect = (value) => {}
|
|
21
|
+
|
|
20
22
|
export class ReactiveEffect {
|
|
21
23
|
active = true
|
|
22
24
|
deps = []
|
|
@@ -24,15 +26,45 @@ export class ReactiveEffect {
|
|
|
24
26
|
depIds = new Set()
|
|
25
27
|
newDepIds = new Set()
|
|
26
28
|
allowRecurse = false
|
|
29
|
+
debug = 0
|
|
30
|
+
name = 'no-name'
|
|
27
31
|
|
|
28
32
|
constructor (
|
|
29
33
|
fn,
|
|
30
34
|
scheduler,
|
|
31
|
-
scope
|
|
35
|
+
scope,
|
|
36
|
+
debug,
|
|
37
|
+
name
|
|
32
38
|
) {
|
|
39
|
+
this.debug = debug || 0
|
|
40
|
+
this.name = name || 'no-name'
|
|
33
41
|
this.id = ++uid
|
|
34
|
-
this.fn =
|
|
35
|
-
|
|
42
|
+
this.fn = (...args) => {
|
|
43
|
+
this.debug > 0 && console.log(`[Mpx Effect] id:${this.id} name: ${this.name} will run`)
|
|
44
|
+
this.debug > 1 && console.log(new Error('此时触发了run').stack)
|
|
45
|
+
const t = global.__setMpxReactiveEffect
|
|
46
|
+
global.__setMpxReactiveEffect = (option) => {
|
|
47
|
+
Object.entries(option).forEach(([key, value]) => {
|
|
48
|
+
this[key] = value
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
const result = fn(...args)
|
|
52
|
+
global.__setMpxReactiveEffect = t
|
|
53
|
+
return result
|
|
54
|
+
}
|
|
55
|
+
this.scheduler = (...args) => {
|
|
56
|
+
this.debug > 0 && console.log(`[Mpx Effect] id:${this.id} name: ${this.name} will scheduled`)
|
|
57
|
+
this.debug > 1 && console.log(new Error('此时触发scheduler').stack)
|
|
58
|
+
const t = global.__setMpxReactiveEffect
|
|
59
|
+
global.__setMpxReactiveEffect = (option) => {
|
|
60
|
+
Object.entries(option).forEach(([key, value]) => {
|
|
61
|
+
this[key] = value
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
const result = scheduler(...args)
|
|
65
|
+
global.__setMpxReactiveEffect = t
|
|
66
|
+
return result
|
|
67
|
+
}
|
|
36
68
|
this.pausedState = PausedState.resumed
|
|
37
69
|
recordEffectScope(this, scope)
|
|
38
70
|
}
|
|
@@ -53,14 +85,14 @@ export class ReactiveEffect {
|
|
|
53
85
|
}
|
|
54
86
|
|
|
55
87
|
// add dependency to this
|
|
56
|
-
addDep (dep) {
|
|
88
|
+
addDep (dep, key, value) {
|
|
57
89
|
if (!shouldTrack) return
|
|
58
90
|
const id = dep.id
|
|
59
91
|
if (!this.newDepIds.has(id)) {
|
|
60
92
|
this.newDepIds.add(id)
|
|
61
93
|
this.newDeps.push(dep)
|
|
62
94
|
if (!this.depIds.has(id)) {
|
|
63
|
-
dep.addSub(this)
|
|
95
|
+
dep.addSub(this, key, value)
|
|
64
96
|
}
|
|
65
97
|
}
|
|
66
98
|
}
|
|
@@ -85,12 +117,20 @@ export class ReactiveEffect {
|
|
|
85
117
|
}
|
|
86
118
|
|
|
87
119
|
// same as trigger
|
|
88
|
-
update () {
|
|
120
|
+
update (key, value, stack, fromAddSubStack) {
|
|
121
|
+
const debugOptions = global.__getMpxReactiveEffectDebugRules?.(key, value)
|
|
122
|
+
const debug = debugOptions ? debugOptions.debug : this.debug
|
|
89
123
|
// avoid dead cycle
|
|
90
124
|
if (Dep.target !== this || this.allowRecurse) {
|
|
91
125
|
if (this.pausedState !== PausedState.resumed) {
|
|
126
|
+
debug > 0 && console.log(`[Mpx Effect] id:${this.id} name: ${this.name} pausedState will set to dirty with, from ${key}: ${typeof value === 'object' ? JSON.stringify(value) : value}`)
|
|
127
|
+
debug > 1 && console.log(stack)
|
|
128
|
+
debug > 2 && console.log(fromAddSubStack)
|
|
92
129
|
this.pausedState = PausedState.dirty
|
|
93
130
|
} else {
|
|
131
|
+
debug > 0 && console.log(`[Mpx Effect] id:${this.id} name: ${this.name} will updated, from ${key}: ${typeof value === 'object' ? JSON.stringify(value) : value}`)
|
|
132
|
+
debug > 1 && console.log(stack)
|
|
133
|
+
debug > 2 && console.log(fromAddSubStack)
|
|
94
134
|
this.scheduler ? this.scheduler() : this.run()
|
|
95
135
|
}
|
|
96
136
|
}
|
package/src/observer/reactive.js
CHANGED
|
@@ -110,7 +110,7 @@ function observe (value, shallow) {
|
|
|
110
110
|
* Define a reactive property on an Object.
|
|
111
111
|
*/
|
|
112
112
|
export function defineReactive (obj, key, val, shallow) {
|
|
113
|
-
const dep = new Dep()
|
|
113
|
+
const dep = new Dep(key)
|
|
114
114
|
|
|
115
115
|
const property = Object.getOwnPropertyDescriptor(obj, key)
|
|
116
116
|
if (property && property.configurable === false) {
|
|
@@ -121,6 +121,8 @@ export function defineReactive (obj, key, val, shallow) {
|
|
|
121
121
|
const getter = property && property.get
|
|
122
122
|
const setter = property && property.set
|
|
123
123
|
|
|
124
|
+
const stack = new Error().stack
|
|
125
|
+
|
|
124
126
|
let childOb = shallow ? getObserver(val) : observe(val)
|
|
125
127
|
Object.defineProperty(obj, key, {
|
|
126
128
|
enumerable: true,
|
|
@@ -128,9 +130,9 @@ export function defineReactive (obj, key, val, shallow) {
|
|
|
128
130
|
get: function reactiveGetter () {
|
|
129
131
|
const value = getter ? getter.call(obj) : val
|
|
130
132
|
if (Dep.target) {
|
|
131
|
-
dep.depend()
|
|
133
|
+
dep.depend(key, value)
|
|
132
134
|
if (childOb) {
|
|
133
|
-
childOb.dep.depend()
|
|
135
|
+
childOb.dep.depend(key, value)
|
|
134
136
|
if (Array.isArray(value)) {
|
|
135
137
|
dependArray(value)
|
|
136
138
|
}
|
|
@@ -140,10 +142,12 @@ export function defineReactive (obj, key, val, shallow) {
|
|
|
140
142
|
},
|
|
141
143
|
set: function reactiveSetter (newVal) {
|
|
142
144
|
const value = getter ? getter.call(obj) : val
|
|
145
|
+
let oldVal = value
|
|
143
146
|
if (!(shallow && isForceTrigger) && !hasChanged(newVal, value)) {
|
|
144
147
|
return
|
|
145
148
|
}
|
|
146
149
|
if (!shallow && isRef(value) && !isRef(newVal)) {
|
|
150
|
+
oldVal = value.value
|
|
147
151
|
value.value = newVal
|
|
148
152
|
} else if (setter) {
|
|
149
153
|
setter.call(obj, newVal)
|
|
@@ -151,7 +155,7 @@ export function defineReactive (obj, key, val, shallow) {
|
|
|
151
155
|
val = newVal
|
|
152
156
|
}
|
|
153
157
|
childOb = shallow ? getObserver(newVal) : observe(newVal)
|
|
154
|
-
dep.notify()
|
|
158
|
+
dep.notify(key, newVal, oldVal, stack)
|
|
155
159
|
}
|
|
156
160
|
})
|
|
157
161
|
}
|
|
@@ -176,8 +180,9 @@ export function set (target, key, val) {
|
|
|
176
180
|
target[key] = val
|
|
177
181
|
return val
|
|
178
182
|
}
|
|
183
|
+
const oldVal = target[key]
|
|
179
184
|
defineReactive(ob.value, key, val, ob.shallow)
|
|
180
|
-
ob.dep.notify()
|
|
185
|
+
ob.dep.notify(key, val, oldVal, new Error('此时被通知变更').stack)
|
|
181
186
|
return val
|
|
182
187
|
}
|
|
183
188
|
|
|
@@ -193,11 +198,12 @@ export function del (target, key) {
|
|
|
193
198
|
if (!hasOwn(target, key)) {
|
|
194
199
|
return
|
|
195
200
|
}
|
|
201
|
+
const oldVal = target[key]
|
|
196
202
|
delete target[key]
|
|
197
203
|
if (!ob) {
|
|
198
204
|
return
|
|
199
205
|
}
|
|
200
|
-
ob.dep.notify()
|
|
206
|
+
ob.dep.notify(key, undefined, oldVal, new Error('此时被通知变更').stack)
|
|
201
207
|
}
|
|
202
208
|
|
|
203
209
|
/**
|
|
@@ -208,7 +214,7 @@ function dependArray (arr) {
|
|
|
208
214
|
for (let i = 0, l = arr.length; i < l; i++) {
|
|
209
215
|
const item = arr[i]
|
|
210
216
|
const ob = getObserver(item)
|
|
211
|
-
ob && ob.dep.depend()
|
|
217
|
+
ob && ob.dep.depend(i, item)
|
|
212
218
|
if (Array.isArray(item)) {
|
|
213
219
|
dependArray(item)
|
|
214
220
|
}
|
package/src/observer/watch.js
CHANGED
|
@@ -137,7 +137,7 @@ export function watch (source, cb, options = {}) {
|
|
|
137
137
|
|
|
138
138
|
job.allowRecurse = !!cb
|
|
139
139
|
|
|
140
|
-
const effect = new ReactiveEffect(getter, scheduler)
|
|
140
|
+
const effect = new ReactiveEffect(getter, scheduler, undefined, options.debug || 0, options.name || 'anonymous watch')
|
|
141
141
|
|
|
142
142
|
if (cb) {
|
|
143
143
|
if (immediate) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createNativeStackNavigator } from '@react-navigation/native-stack'
|
|
2
2
|
import { NavigationContainer, StackActions } from '@react-navigation/native'
|
|
3
3
|
import PortalHost from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-portal/portal-host'
|
|
4
|
-
import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
4
|
+
import { SafeAreaProvider, useSafeAreaInsets, initialWindowMetrics } from 'react-native-safe-area-context'
|
|
5
5
|
import { GestureHandlerRootView } from 'react-native-gesture-handler'
|
|
6
6
|
|
|
7
7
|
export {
|
|
@@ -11,5 +11,6 @@ export {
|
|
|
11
11
|
GestureHandlerRootView,
|
|
12
12
|
PortalHost,
|
|
13
13
|
SafeAreaProvider,
|
|
14
|
-
useSafeAreaInsets
|
|
14
|
+
useSafeAreaInsets,
|
|
15
|
+
initialWindowMetrics
|
|
15
16
|
}
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
ProviderContext,
|
|
17
17
|
RouteContext
|
|
18
18
|
} from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/context'
|
|
19
|
-
import { PortalHost, useSafeAreaInsets } from '../env/navigationHelper'
|
|
19
|
+
import { PortalHost, useSafeAreaInsets, initialWindowMetrics } from '../env/navigationHelper'
|
|
20
20
|
import { useInnerHeaderHeight } from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-nav'
|
|
21
21
|
|
|
22
22
|
function getSystemInfo () {
|
|
@@ -33,12 +33,13 @@ function getSystemInfo () {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
function createEffect (proxy, componentsMap) {
|
|
36
|
+
function createEffect (proxy, componentsMap, rawOptions) {
|
|
37
37
|
const update = proxy.update = () => {
|
|
38
38
|
// react update props in child render(async), do not need exec pre render
|
|
39
39
|
// if (proxy.propsUpdatedFlag) {
|
|
40
40
|
// proxy.updatePreRender()
|
|
41
41
|
// }
|
|
42
|
+
// console.log(`[mpx] ${proxy.options?.mpxFileResource} 组件render响应时数据变更,开始修改stateVersion,驱动组件更新`)
|
|
42
43
|
if (proxy.isMounted()) {
|
|
43
44
|
proxy.callHook(BEFOREUPDATE)
|
|
44
45
|
proxy.pendingUpdatedFlag = true
|
|
@@ -61,11 +62,18 @@ function createEffect (proxy, componentsMap) {
|
|
|
61
62
|
return createElement(type, ...rest)
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
const debugConfig = typeof global.__getMpxRenderEffectDebugRules === 'function'
|
|
66
|
+
? global.__getMpxRenderEffectDebugRules(rawOptions.mpxFileResource)
|
|
67
|
+
: {
|
|
68
|
+
debug: 1,
|
|
69
|
+
name: `MpxRenderEffect-${rawOptions.mpxFileResource || 'unknown'}`
|
|
70
|
+
}
|
|
71
|
+
|
|
64
72
|
proxy.effect = new ReactiveEffect(() => {
|
|
65
73
|
// reset instance
|
|
66
74
|
proxy.target.__resetInstance()
|
|
67
75
|
return callWithErrorHandling(proxy.target.__injectedRender.bind(proxy.target), proxy, 'render function', [innerCreateElement, getComponent])
|
|
68
|
-
}, () => queueJob(update), proxy.scope)
|
|
76
|
+
}, () => { return queueJob(update) }, proxy.scope, debugConfig.debug, debugConfig.name)
|
|
69
77
|
// render effect允许自触发
|
|
70
78
|
proxy.toggleRecurse(true)
|
|
71
79
|
}
|
|
@@ -332,7 +340,7 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
332
340
|
stateVersion: Symbol(),
|
|
333
341
|
subscribe: (onStoreChange) => {
|
|
334
342
|
if (!proxy.effect) {
|
|
335
|
-
createEffect(proxy, componentsMap)
|
|
343
|
+
createEffect(proxy, componentsMap, rawOptions)
|
|
336
344
|
proxy.stateVersion = Symbol()
|
|
337
345
|
}
|
|
338
346
|
proxy.onStoreChange = onStoreChange
|
|
@@ -348,7 +356,7 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
348
356
|
})
|
|
349
357
|
// react数据响应组件更新管理器
|
|
350
358
|
if (!proxy.effect) {
|
|
351
|
-
createEffect(proxy, componentsMap)
|
|
359
|
+
createEffect(proxy, componentsMap, rawOptions)
|
|
352
360
|
}
|
|
353
361
|
|
|
354
362
|
return instance
|
|
@@ -509,7 +517,17 @@ function getLayoutData (headerHeight) {
|
|
|
509
517
|
// 在横屏状态下 screen.height = window.height + bottomVirtualHeight
|
|
510
518
|
// 在正常状态 screen.height = window.height + bottomVirtualHeight + statusBarHeight
|
|
511
519
|
const isLandscape = screenDimensions.height < screenDimensions.width
|
|
512
|
-
const bottomVirtualHeight = isLandscape ? screenDimensions.height - windowDimensions.height : ((screenDimensions.height - windowDimensions.height - ReactNative.StatusBar.currentHeight) || 0)
|
|
520
|
+
// const bottomVirtualHeight = isLandscape ? screenDimensions.height - windowDimensions.height : ((screenDimensions.height - windowDimensions.height - ReactNative.StatusBar.currentHeight) || 0)
|
|
521
|
+
let bottomVirtualHeight = 0
|
|
522
|
+
// 红米手机&魅族16T手机的screen.height = windowHeight + bottomVirtualHeight 导致计算出来的底部虚拟偏少。此部分端引擎同学进行修改中
|
|
523
|
+
// mpx临时兼容 bottomVirtualHeight取 initialWindowMetrics.inset.bottom 和 反算出来的bottomVirtualHeight的更大的值
|
|
524
|
+
if (ReactNative.Platform.OS === 'android') {
|
|
525
|
+
if (isLandscape) {
|
|
526
|
+
bottomVirtualHeight = screenDimensions.height - windowDimensions.height
|
|
527
|
+
} else {
|
|
528
|
+
bottomVirtualHeight = Math.max(screenDimensions.height - windowDimensions.height - ReactNative.StatusBar.currentHeight, initialWindowMetrics?.insets?.bottom || 0, 0)
|
|
529
|
+
}
|
|
530
|
+
}
|
|
513
531
|
return {
|
|
514
532
|
left: 0,
|
|
515
533
|
top: headerHeight,
|