@mpxjs/core 2.9.69-beta.2 → 2.9.69-beta.5
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/platform/createApp.ios.js +32 -37
- package/src/platform/createApp.js +20 -27
- package/src/platform/env/index.ios.js +19 -9
- package/src/platform/env/index.web.js +1 -1
- package/src/platform/export/inject.js +2 -3
- package/src/platform/patch/getDefaultOptions.ios.js +14 -9
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import transferOptions from '../core/transferOptions'
|
|
2
2
|
import builtInKeysMap from './patch/builtInKeysMap'
|
|
3
|
-
import { makeMap, spreadProp, getFocusedNavigation, hasOwn
|
|
3
|
+
import { makeMap, spreadProp, getFocusedNavigation, hasOwn } from '@mpxjs/utils'
|
|
4
4
|
import { mergeLifecycle } from '../convertor/mergeLifecycle'
|
|
5
5
|
import { LIFECYCLE } from '../platform/patch/lifecycle/index'
|
|
6
6
|
import Mpx from '../index'
|
|
7
7
|
import { createElement, memo, useRef, useEffect } from 'react'
|
|
8
8
|
import * as ReactNative from 'react-native'
|
|
9
9
|
import { Image } from 'react-native'
|
|
10
|
-
import { ref } from '../observer/ref'
|
|
11
10
|
|
|
12
11
|
const appHooksMap = makeMap(mergeLifecycle(LIFECYCLE).app)
|
|
13
12
|
|
|
@@ -30,22 +29,24 @@ function filterOptions (options, appData) {
|
|
|
30
29
|
return newOptions
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
function
|
|
34
|
-
return extend({}, Mpx.prototype, appData)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export default function createApp (option, config = {}) {
|
|
32
|
+
export default function createApp (options) {
|
|
38
33
|
const appData = {}
|
|
39
34
|
|
|
40
35
|
const { NavigationContainer, createStackNavigator, SafeAreaProvider } = global.__navigationHelper
|
|
41
36
|
// app选项目前不需要进行转换
|
|
42
|
-
const { rawOptions, currentInject } = transferOptions(
|
|
37
|
+
const { rawOptions, currentInject } = transferOptions(options, 'app', false)
|
|
43
38
|
const defaultOptions = filterOptions(spreadProp(rawOptions, 'methods'), appData)
|
|
44
|
-
defaultOptions.onAppInit && defaultOptions.onAppInit()
|
|
45
39
|
// 在页面script执行前填充getApp()
|
|
46
40
|
global.getApp = function () {
|
|
47
41
|
return appData
|
|
48
42
|
}
|
|
43
|
+
|
|
44
|
+
defaultOptions.onShow && global.__mpxAppCbs.show.push(defaultOptions.onShow.bind(appData))
|
|
45
|
+
defaultOptions.onHide && global.__mpxAppCbs.hide.push(defaultOptions.onHide.bind(appData))
|
|
46
|
+
defaultOptions.onError && global.__mpxAppCbs.error.push(defaultOptions.onError.bind(appData))
|
|
47
|
+
defaultOptions.onUnhandledRejection && global.__mpxAppCbs.rejection.push(defaultOptions.onUnhandledRejection.bind(appData))
|
|
48
|
+
defaultOptions.onAppInit && defaultOptions.onAppInit()
|
|
49
|
+
|
|
49
50
|
const pages = currentInject.getPages() || {}
|
|
50
51
|
const firstPage = currentInject.firstPage
|
|
51
52
|
const Stack = createStackNavigator()
|
|
@@ -82,55 +83,50 @@ export default function createApp (option, config = {}) {
|
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
global.__mpxAppLaunched = false
|
|
85
|
-
|
|
86
|
-
global.__mpxAppFocusedState = ref('show')
|
|
87
86
|
global.__mpxOptionsMap[currentInject.moduleId] = memo((props) => {
|
|
88
|
-
const
|
|
89
|
-
if (!instanceRef.current) {
|
|
90
|
-
instanceRef.current = createAppInstance(appData)
|
|
91
|
-
}
|
|
92
|
-
const instance = instanceRef.current
|
|
87
|
+
const firstRef = useRef(true)
|
|
93
88
|
const initialRouteRef = useRef({
|
|
94
89
|
initialRouteName: firstPage,
|
|
95
90
|
initialParams: {}
|
|
96
91
|
})
|
|
97
|
-
|
|
98
|
-
|
|
92
|
+
if (firstRef.current) {
|
|
93
|
+
// 热启动情况下,app会被销毁重建,将__mpxAppHotLaunched重置保障路由等初始化逻辑正确执行
|
|
94
|
+
global.__mpxAppHotLaunched = false
|
|
95
|
+
// 热启动情况下重置__mpxPagesMap避免页面销毁函数未及时执行时错误地引用到之前的navigation
|
|
96
|
+
global.__mpxPagesMap = {}
|
|
97
|
+
firstRef.current = false
|
|
98
|
+
}
|
|
99
|
+
if (!global.__mpxAppHotLaunched) {
|
|
99
100
|
const { initialRouteName, initialParams } = Mpx.config.rnConfig.parseAppProps?.(props) || {}
|
|
100
101
|
initialRouteRef.current.initialRouteName = initialRouteName || initialRouteRef.current.initialRouteName
|
|
101
102
|
initialRouteRef.current.initialParams = initialParams || initialRouteRef.current.initialParams
|
|
102
103
|
|
|
103
104
|
global.__mpxAppOnLaunch = (navigation) => {
|
|
104
|
-
global.__mpxAppLaunched = true
|
|
105
105
|
const state = navigation.getState()
|
|
106
106
|
Mpx.config.rnConfig.onStateChange?.(state)
|
|
107
107
|
const current = state.routes[state.index]
|
|
108
|
-
|
|
108
|
+
const options = {
|
|
109
109
|
path: current.name,
|
|
110
110
|
query: current.params,
|
|
111
111
|
scene: 0,
|
|
112
112
|
shareTicket: '',
|
|
113
|
-
referrerInfo: {}
|
|
113
|
+
referrerInfo: {},
|
|
114
|
+
isLaunch: true
|
|
115
|
+
}
|
|
116
|
+
global.__mpxEnterOptions = options
|
|
117
|
+
if (!global.__mpxAppLaunched) {
|
|
118
|
+
global.__mpxLaunchOptions = options
|
|
119
|
+
defaultOptions.onLaunch && defaultOptions.onLaunch.call(appData, options)
|
|
114
120
|
}
|
|
115
|
-
|
|
116
|
-
|
|
121
|
+
global.__mpxAppCbs.show.forEach((cb) => {
|
|
122
|
+
cb(options)
|
|
123
|
+
})
|
|
124
|
+
global.__mpxAppLaunched = true
|
|
125
|
+
global.__mpxAppHotLaunched = true
|
|
117
126
|
}
|
|
118
127
|
}
|
|
119
128
|
|
|
120
129
|
useEffect(() => {
|
|
121
|
-
if (defaultOptions.onShow) {
|
|
122
|
-
global.__mpxAppCbs.show.push(defaultOptions.onShow.bind(instance))
|
|
123
|
-
}
|
|
124
|
-
if (defaultOptions.onHide) {
|
|
125
|
-
global.__mpxAppCbs.hide.push(defaultOptions.onHide.bind(instance))
|
|
126
|
-
}
|
|
127
|
-
if (defaultOptions.onError) {
|
|
128
|
-
global.__mpxAppCbs.error.push(defaultOptions.onError.bind(instance))
|
|
129
|
-
}
|
|
130
|
-
if (defaultOptions.onUnhandledRejection) {
|
|
131
|
-
global.__mpxAppCbs.rejection.push(defaultOptions.onUnhandledRejection.bind(instance))
|
|
132
|
-
}
|
|
133
|
-
|
|
134
130
|
const changeSubscription = ReactNative.AppState.addEventListener('change', (currentState) => {
|
|
135
131
|
if (currentState === 'active') {
|
|
136
132
|
let options = global.__mpxEnterOptions
|
|
@@ -183,7 +179,6 @@ export default function createApp (option, config = {}) {
|
|
|
183
179
|
const { initialRouteName, initialParams } = initialRouteRef.current
|
|
184
180
|
const headerBackImageProps = Mpx.config.rnConfig.headerBackImageProps || null
|
|
185
181
|
const navScreenOpts = {
|
|
186
|
-
gestureEnabled: true,
|
|
187
182
|
// 7.x替换headerBackTitleVisible
|
|
188
183
|
// headerBackButtonDisplayMode: 'minimal',
|
|
189
184
|
headerBackTitleVisible: false,
|
|
@@ -24,19 +24,19 @@ function filterOptions (options, appData) {
|
|
|
24
24
|
return newOptions
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export default function createApp (
|
|
28
|
-
|
|
27
|
+
export default function createApp (options, config = {}) {
|
|
28
|
+
const appData = {}
|
|
29
|
+
// app选项目前不需要进行转换
|
|
30
|
+
const { rawOptions, currentInject } = transferOptions(options, 'app', false)
|
|
29
31
|
const builtInMixins = [{
|
|
32
|
+
// 在App中挂载mpx对象供周边工具访问,如e2e测试
|
|
30
33
|
getMpx () {
|
|
31
34
|
return Mpx
|
|
32
35
|
}
|
|
33
36
|
}]
|
|
34
|
-
const appData = {}
|
|
35
37
|
if (__mpx_mode__ === 'web') {
|
|
36
38
|
builtInMixins.push({
|
|
37
39
|
created () {
|
|
38
|
-
Object.assign(this, Mpx.prototype)
|
|
39
|
-
Object.assign(this, appData)
|
|
40
40
|
const current = this.$root.$options?.router?.currentRoute || {}
|
|
41
41
|
const options = {
|
|
42
42
|
path: current.path && current.path.replace(/^\//, ''),
|
|
@@ -45,48 +45,41 @@ export default function createApp (option, config = {}) {
|
|
|
45
45
|
shareTicket: '',
|
|
46
46
|
referrerInfo: {}
|
|
47
47
|
}
|
|
48
|
+
// web不分冷启动和热启动
|
|
48
49
|
global.__mpxEnterOptions = options
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
if (this.$options.onHide) {
|
|
56
|
-
global.__mpxAppCbs.hide.push(this.$options.onHide.bind(this))
|
|
57
|
-
}
|
|
58
|
-
if (this.$options.onError) {
|
|
59
|
-
global.__mpxAppCbs.error.push(this.$options.onError.bind(this))
|
|
60
|
-
}
|
|
61
|
-
if (this.$options.onUnhandledRejection) {
|
|
62
|
-
global.__mpxAppCbs.rejection.push(this.$options.onUnhandledRejection.bind(this))
|
|
63
|
-
}
|
|
64
|
-
}
|
|
50
|
+
global.__mpxLaunchOptions = options
|
|
51
|
+
rawOptions.onLaunch && rawOptions.onLaunch.call(appData, options)
|
|
52
|
+
global.__mpxAppCbs.show.forEach((cb) => {
|
|
53
|
+
cb(options)
|
|
54
|
+
})
|
|
65
55
|
}
|
|
66
56
|
})
|
|
67
57
|
} else {
|
|
68
58
|
builtInMixins.push({
|
|
69
59
|
onLaunch () {
|
|
70
|
-
|
|
60
|
+
initAppProvides(rawOptions.provide, this)
|
|
71
61
|
}
|
|
72
62
|
})
|
|
73
63
|
}
|
|
74
|
-
// app选项目前不需要进行转换
|
|
75
|
-
const { rawOptions, currentInject } = transferOptions(option, 'app', false)
|
|
76
64
|
rawOptions.mixins = builtInMixins
|
|
77
65
|
const defaultOptions = filterOptions(spreadProp(mergeOptions(rawOptions, 'app', false), 'methods'), appData)
|
|
78
66
|
|
|
79
67
|
if (__mpx_mode__ === 'web') {
|
|
80
|
-
global.__mpxOptionsMap = global.__mpxOptionsMap || {}
|
|
81
|
-
global.__mpxOptionsMap[currentInject.moduleId] = defaultOptions
|
|
82
68
|
global.getApp = function () {
|
|
83
69
|
if (!isBrowser) {
|
|
84
70
|
console.error('[Mpx runtime error]: Dangerous API! global.getApp method is running in non browser environments')
|
|
85
71
|
}
|
|
86
72
|
return appData
|
|
87
73
|
}
|
|
74
|
+
if (isBrowser) {
|
|
75
|
+
defaultOptions.onShow && global.__mpxAppCbs.show.push(defaultOptions.onShow.bind(appData))
|
|
76
|
+
defaultOptions.onHide && global.__mpxAppCbs.hide.push(defaultOptions.onHide.bind(appData))
|
|
77
|
+
defaultOptions.onError && global.__mpxAppCbs.error.push(defaultOptions.onError.bind(appData))
|
|
78
|
+
defaultOptions.onUnhandledRejection && global.__mpxAppCbs.rejection.push(defaultOptions.onUnhandledRejection.bind(appData))
|
|
79
|
+
}
|
|
80
|
+
global.__mpxOptionsMap = global.__mpxOptionsMap || {}
|
|
81
|
+
global.__mpxOptionsMap[currentInject.moduleId] = defaultOptions
|
|
88
82
|
} else {
|
|
89
|
-
initAppProvides(rawOptions)
|
|
90
83
|
defaultOptions.onAppInit && defaultOptions.onAppInit()
|
|
91
84
|
const ctor = config.customCtor || global.currentCtor || App
|
|
92
85
|
ctor(defaultOptions)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isFunction, isNumber, isString } from '@mpxjs/utils'
|
|
1
2
|
import { createI18n } from '../builtInMixins/i18nMixin'
|
|
2
3
|
|
|
3
4
|
export function init (Mpx) {
|
|
@@ -30,21 +31,30 @@ function initGlobalErrorHandling () {
|
|
|
30
31
|
})
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
function onUnhandledRejection (event) {
|
|
35
|
+
if (global.__mpxAppCbs && global.__mpxAppCbs.rejection && global.__mpxAppCbs.rejection.length) {
|
|
36
|
+
global.__mpxAppCbs.rejection.forEach((cb) => {
|
|
37
|
+
cb(event)
|
|
38
|
+
})
|
|
39
|
+
} else {
|
|
40
|
+
console.warn(`UNHANDLED PROMISE REJECTION ${(isNumber(event.id) || isString(event.id)) ? '(id:' + event.id + ')' : ''}: ${event.reason}\n`)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
33
43
|
const rejectionTrackingOptions = {
|
|
34
44
|
allRejections: true,
|
|
35
45
|
onUnhandled (id, error) {
|
|
36
|
-
|
|
37
|
-
global.__mpxAppCbs.rejection.forEach((cb) => {
|
|
38
|
-
cb(error, id)
|
|
39
|
-
})
|
|
40
|
-
} else {
|
|
41
|
-
console.warn(`UNHANDLED PROMISE REJECTION (id: ${id}): ${error}\n`)
|
|
42
|
-
}
|
|
46
|
+
onUnhandledRejection({ id, reason: error, promise: null })
|
|
43
47
|
}
|
|
44
48
|
}
|
|
45
49
|
|
|
46
|
-
|
|
47
|
-
|
|
50
|
+
// 支持 core-js promise polyfill
|
|
51
|
+
const oldOnUnhandledRejection = global.onunhandledrejection
|
|
52
|
+
global.onunhandledrejection = function onunhandledrejection (event) {
|
|
53
|
+
onUnhandledRejection(event)
|
|
54
|
+
isFunction(oldOnUnhandledRejection) && oldOnUnhandledRejection.call(this, event)
|
|
55
|
+
}
|
|
56
|
+
if (global.HermesInternal?.hasPromise?.()) {
|
|
57
|
+
global.HermesInternal.enablePromiseRejectionTracker?.(rejectionTrackingOptions)
|
|
48
58
|
} else {
|
|
49
59
|
require('promise/setimmediate/rejection-tracking').enable(rejectionTrackingOptions)
|
|
50
60
|
}
|
|
@@ -38,7 +38,7 @@ function initGlobalErrorHandling () {
|
|
|
38
38
|
window.addEventListener('unhandledrejection', (event) => {
|
|
39
39
|
if (global.__mpxAppCbs && global.__mpxAppCbs.rejection && global.__mpxAppCbs.rejection.length) {
|
|
40
40
|
global.__mpxAppCbs.rejection.forEach((cb) => {
|
|
41
|
-
cb(event
|
|
41
|
+
cb(event)
|
|
42
42
|
})
|
|
43
43
|
} else {
|
|
44
44
|
console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}\n`)
|
|
@@ -11,11 +11,10 @@ const providesMap = {
|
|
|
11
11
|
global.__mpxProvidesMap = providesMap
|
|
12
12
|
|
|
13
13
|
/** @internal createApp() 初始化应用层 scope provide */
|
|
14
|
-
export function initAppProvides (
|
|
15
|
-
const provideOpt = appOptions.provide
|
|
14
|
+
export function initAppProvides (provideOpt, instance) {
|
|
16
15
|
if (provideOpt) {
|
|
17
16
|
const provided = isFunction(provideOpt)
|
|
18
|
-
? callWithErrorHandling(provideOpt.bind(
|
|
17
|
+
? callWithErrorHandling(provideOpt.bind(instance), instance, 'createApp provide function')
|
|
19
18
|
: provideOpt
|
|
20
19
|
if (isObject(provided)) {
|
|
21
20
|
providesMap.__app = provided
|
|
@@ -367,14 +367,10 @@ function usePageStatus (navigation, pageId) {
|
|
|
367
367
|
const blurSubscription = navigation.addListener('blur', () => {
|
|
368
368
|
pageStatusMap[pageId] = 'hide'
|
|
369
369
|
})
|
|
370
|
-
const unWatchAppFocusedState = watch(global.__mpxAppFocusedState, (value) => {
|
|
371
|
-
pageStatusMap[pageId] = value
|
|
372
|
-
})
|
|
373
370
|
|
|
374
371
|
return () => {
|
|
375
372
|
focusSubscription()
|
|
376
373
|
blurSubscription()
|
|
377
|
-
unWatchAppFocusedState()
|
|
378
374
|
del(pageStatusMap, pageId)
|
|
379
375
|
}
|
|
380
376
|
}, [navigation])
|
|
@@ -445,10 +441,17 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
445
441
|
|
|
446
442
|
useEffect(() => {
|
|
447
443
|
if (type === 'page') {
|
|
448
|
-
if (!global.
|
|
444
|
+
if (!global.__mpxAppHotLaunched && global.__mpxAppOnLaunch) {
|
|
449
445
|
global.__mpxAppOnLaunch(props.navigation)
|
|
450
446
|
}
|
|
451
|
-
|
|
447
|
+
const loadParams = {}
|
|
448
|
+
// 此处拿到的props.route.params内属性的value被进行过了一次decode, 不符合预期,此处额外进行一次encode来与微信对齐
|
|
449
|
+
if (isObject(props.route.params)) {
|
|
450
|
+
for (const key in props.route.params) {
|
|
451
|
+
loadParams[key] = encodeURIComponent(props.route.params[key])
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
proxy.callHook(ONLOAD, [loadParams])
|
|
452
455
|
}
|
|
453
456
|
proxy.mounted()
|
|
454
457
|
return () => {
|
|
@@ -530,9 +533,11 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
530
533
|
|
|
531
534
|
useEffect(() => {
|
|
532
535
|
const unsubscribe = navigation.addListener('transitionEnd', (e) => {
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
+
setTimeout(() => {
|
|
537
|
+
rootRef.current?.measureInWindow((x, y, width, height) => {
|
|
538
|
+
navigation.layout = { x, y, width, height }
|
|
539
|
+
})
|
|
540
|
+
}, 200)
|
|
536
541
|
});
|
|
537
542
|
return unsubscribe;
|
|
538
543
|
}, [navigation]);
|