@mpxjs/core 2.9.39 → 2.9.41

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.
Files changed (34) hide show
  1. package/package.json +37 -3
  2. package/src/convertor/convertor.js +4 -1
  3. package/src/convertor/getConvertMode.js +3 -1
  4. package/src/convertor/wxToReact.js +31 -0
  5. package/src/core/proxy.js +27 -5
  6. package/src/core/transferOptions.js +9 -1
  7. package/src/{vuePlugin.js → external/vuePlugin.js} +1 -1
  8. package/src/index.js +6 -2
  9. package/src/platform/builtInMixins/directiveHelperMixin.android.js +2 -0
  10. package/src/platform/builtInMixins/directiveHelperMixin.ios.js +15 -0
  11. package/src/platform/builtInMixins/directiveHelperMixin.js +3 -0
  12. package/src/platform/builtInMixins/index.js +12 -2
  13. package/src/platform/builtInMixins/proxyEventMixin.android.js +2 -0
  14. package/src/platform/builtInMixins/proxyEventMixin.ios.js +49 -0
  15. package/src/platform/builtInMixins/proxyEventMixin.js +0 -11
  16. package/src/platform/builtInMixins/refsMixin.android.js +2 -0
  17. package/src/platform/builtInMixins/refsMixin.ios.js +311 -0
  18. package/src/platform/builtInMixins/styleHelperMixin.android.js +2 -0
  19. package/src/platform/builtInMixins/styleHelperMixin.ios.js +141 -0
  20. package/src/platform/builtInMixins/styleHelperMixin.js +3 -0
  21. package/src/platform/createApp.android.js +2 -0
  22. package/src/platform/createApp.ios.js +104 -0
  23. package/src/platform/createApp.js +3 -5
  24. package/src/platform/export/api.web.js +1 -1
  25. package/src/platform/patch/ali/getDefaultOptions.js +4 -4
  26. package/src/platform/patch/index.js +9 -6
  27. package/src/platform/patch/react/getDefaultOptions.android.js +1 -0
  28. package/src/platform/patch/react/getDefaultOptions.ios.js +280 -0
  29. package/src/platform/patch/react/getDefaultOptions.js +1 -0
  30. package/src/platform/patch/swan/getDefaultOptions.js +1 -1
  31. package/src/platform/patch/web/getDefaultOptions.js +13 -3
  32. package/src/platform/patch/wx/getDefaultOptions.js +1 -1
  33. /package/src/{vue.js → external/vue.js} +0 -0
  34. /package/src/{vue.web.js → external/vue.web.js} +0 -0
@@ -0,0 +1,280 @@
1
+ import { useEffect, useLayoutEffect, useSyncExternalStore, useRef, createElement, memo, forwardRef, useImperativeHandle } from 'react'
2
+ import * as ReactNative from 'react-native'
3
+ import { ReactiveEffect } from '../../../observer/effect'
4
+ import { hasOwn, isFunction, noop, isObject, error, getByPath, collectDataset } from '@mpxjs/utils'
5
+ import MpxProxy from '../../../core/proxy'
6
+ import { BEFOREUPDATE, UPDATED } from '../../../core/innerLifecycle'
7
+ import mergeOptions from '../../../core/mergeOptions'
8
+ import { queueJob } from '../../../observer/scheduler'
9
+
10
+ function getRootProps (props) {
11
+ const rootProps = {}
12
+ for (const key in props) {
13
+ if (hasOwn(props, key)) {
14
+ const match = /^(bind|catch|capture-bind|capture-catch|style):?(.*?)(?:\.(.*))?$/.exec(key)
15
+ if (match) {
16
+ rootProps[key] = props[key]
17
+ }
18
+ }
19
+ }
20
+ return rootProps
21
+ }
22
+
23
+ function createEffect (proxy, components, props) {
24
+ const update = proxy.update = () => {
25
+ // pre render for props update
26
+ if (proxy.propsUpdatedFlag) {
27
+ proxy.updatePreRender()
28
+ }
29
+ if (proxy.isMounted()) {
30
+ proxy.callHook(BEFOREUPDATE)
31
+ proxy.pendingUpdatedFlag = true
32
+ }
33
+ // eslint-disable-next-line symbol-description
34
+ proxy.stateVersion = Symbol()
35
+ proxy.onStoreChange && proxy.onStoreChange()
36
+ }
37
+ update.id = proxy.uid
38
+ const getComponent = (tagName) => {
39
+ return components[tagName] || getByPath(ReactNative, tagName)
40
+ }
41
+ proxy.effect = new ReactiveEffect(() => {
42
+ return proxy.target.__injectedRender(createElement, getComponent, getRootProps(props))
43
+ }, () => queueJob(update), proxy.scope)
44
+ }
45
+
46
+ function createInstance ({ propsRef, ref, type, rawOptions, currentInject, validProps, components }) {
47
+ const instance = Object.create({
48
+ setData (data, callback) {
49
+ return this.__mpxProxy.forceUpdate(data, { sync: true }, callback)
50
+ },
51
+ __getProps () {
52
+ const propsData = {}
53
+ const props = propsRef.current
54
+ if (props) {
55
+ Object.keys(props).forEach((key) => {
56
+ if (hasOwn(validProps, key) && !isFunction(props[key])) {
57
+ propsData[key] = props[key]
58
+ }
59
+ })
60
+ }
61
+ return propsData
62
+ },
63
+ __getSlot (name) {
64
+ const { children } = propsRef.current || {}
65
+ if (children) {
66
+ const result = []
67
+ if (Array.isArray(children)) {
68
+ children.forEach(child => {
69
+ if (child && child.props && child.props.slot === name) {
70
+ result.push(child)
71
+ }
72
+ })
73
+ } else {
74
+ if (children && children.props && children.props.slot === name) {
75
+ result.push(children)
76
+ }
77
+ }
78
+ return result.filter(item => {
79
+ if (this.__dispatchedSlotSet.has(item)) {
80
+ return false
81
+ } else {
82
+ this.__dispatchedSlotSet.add(item)
83
+ return true
84
+ }
85
+ })
86
+ }
87
+ return null
88
+ },
89
+ __injectedRender: currentInject.render || noop,
90
+ __getRefsData: currentInject.getRefsData || noop,
91
+ // render helper
92
+ _i (val, fn) {
93
+ let i, l, keys, key
94
+ const result = []
95
+ if (Array.isArray(val) || typeof val === 'string') {
96
+ for (i = 0, l = val.length; i < l; i++) {
97
+ result.push(fn.call(this, val[i], i))
98
+ }
99
+ } else if (typeof val === 'number') {
100
+ for (i = 0; i < val; i++) {
101
+ result.push(fn.call(this, i + 1, i))
102
+ }
103
+ } else if (isObject(val)) {
104
+ keys = Object.keys(val)
105
+ for (i = 0, l = keys.length; i < l; i++) {
106
+ key = keys[i]
107
+ result.push(fn.call(this, val[key], key, i))
108
+ }
109
+ }
110
+ return result
111
+ },
112
+ triggerEvent (eventName, eventDetail) {
113
+ const props = propsRef.current
114
+ const handlerName = eventName.replace(/^./, matched => matched.toUpperCase()).replace(/-([a-z])/g, (match, p1) => p1.toUpperCase())
115
+ const handler = props && (props['bind' + handlerName] || props['catch' + handlerName] || props['capture-bind' + handlerName] || props['capture-catch' + handlerName])
116
+ if (handler && typeof handler === 'function') {
117
+ const timeStamp = +new Date()
118
+ const dataset = collectDataset(props)
119
+ const id = props.id || ''
120
+ const eventObj = {
121
+ type: eventName,
122
+ timeStamp,
123
+ target: {
124
+ id,
125
+ dataset,
126
+ targetDataset: dataset
127
+ },
128
+ currentTarget: {
129
+ id,
130
+ dataset
131
+ },
132
+ detail: eventDetail
133
+ }
134
+ handler.call(this, eventObj)
135
+ }
136
+ },
137
+ selectComponent () {
138
+ error('selectComponent is not supported in react native, please use ref instead')
139
+ },
140
+ selectAllComponents () {
141
+ error('selectAllComponents is not supported in react native, please use ref instead')
142
+ },
143
+ createSelectorQuery () {
144
+ error('createSelectorQuery is not supported in react native, please use ref instead')
145
+ },
146
+ createIntersectionObserver () {
147
+ error('createIntersectionObserver is not supported in react native, please use ref instead')
148
+ },
149
+ ...rawOptions.methods
150
+ }, {
151
+ dataset: {
152
+ get () {
153
+ const props = propsRef.current
154
+ return collectDataset(props)
155
+ },
156
+ enumerable: true
157
+ },
158
+ id: {
159
+ get () {
160
+ const props = propsRef.current
161
+ return props.id
162
+ },
163
+ enumerable: true
164
+ }
165
+ })
166
+
167
+ const proxy = instance.__mpxProxy = new MpxProxy(rawOptions, instance)
168
+ proxy.created()
169
+ Object.assign(proxy, {
170
+ onStoreChange: null,
171
+ // eslint-disable-next-line symbol-description
172
+ stateVersion: Symbol(),
173
+ subscribe: (onStoreChange) => {
174
+ if (!proxy.effect) {
175
+ createEffect(proxy, components, propsRef.current)
176
+ // eslint-disable-next-line symbol-description
177
+ proxy.stateVersion = Symbol()
178
+ }
179
+ proxy.onStoreChange = onStoreChange
180
+ return () => {
181
+ proxy.effect && proxy.effect.stop()
182
+ proxy.effect = null
183
+ proxy.onStoreChange = null
184
+ }
185
+ },
186
+ getSnapshot: () => {
187
+ return proxy.stateVersion
188
+ }
189
+ })
190
+ // react数据响应组件更新管理器
191
+ if (!proxy.effect) {
192
+ createEffect(proxy, components, propsRef.current)
193
+ }
194
+
195
+ return instance
196
+ }
197
+
198
+ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
199
+ rawOptions = mergeOptions(rawOptions, type, false)
200
+ const components = Object.assign({}, rawOptions.components, currentInject.getComponents())
201
+ const validProps = Object.assign({}, rawOptions.props, rawOptions.properties)
202
+ const defaultOptions = memo(forwardRef((props, ref) => {
203
+ const instanceRef = useRef(null)
204
+ const propsRef = useRef(props)
205
+ let isFirst = false
206
+ if (!instanceRef.current) {
207
+ isFirst = true
208
+ instanceRef.current = createInstance({ propsRef, ref, type, rawOptions, currentInject, validProps, components })
209
+ }
210
+ const instance = instanceRef.current
211
+ // reset instance
212
+ instance.__refs = {}
213
+ instance.__dispatchedSlotSet = new WeakSet()
214
+ useImperativeHandle(ref, () => {
215
+ return instance
216
+ })
217
+ const proxy = instance.__mpxProxy
218
+
219
+ if (!isFirst) {
220
+ // 处理props更新
221
+ propsRef.current = props
222
+ Object.keys(props).forEach(key => {
223
+ if (hasOwn(validProps, key) && !isFunction(props[key])) {
224
+ instance[key] = props[key]
225
+ }
226
+ })
227
+ proxy.propsUpdated()
228
+ }
229
+
230
+ useEffect(() => {
231
+ if (proxy.pendingUpdatedFlag) {
232
+ proxy.pendingUpdatedFlag = false
233
+ proxy.callHook(UPDATED)
234
+ }
235
+ })
236
+
237
+ useEffect(() => {
238
+ proxy.mounted()
239
+ return () => {
240
+ proxy.unmounted()
241
+ }
242
+ }, [])
243
+
244
+ useSyncExternalStore(proxy.subscribe, proxy.getSnapshot)
245
+
246
+ return proxy.effect.run()
247
+ }))
248
+
249
+ if (type === 'page') {
250
+ const { Provider } = global.__navigationHelper
251
+ const pageConfig = Object.assign({}, global.__mpxPageConfig, currentInject.pageConfig)
252
+ const Page = ({ navigation }) => {
253
+ useLayoutEffect(() => {
254
+ navigation.setOptions({
255
+ headerTitle: pageConfig.navigationBarTitleText || '',
256
+ headerStyle: {
257
+ backgroundColor: pageConfig.navigationBarBackgroundColor || '#000000'
258
+ },
259
+ headerTintColor: pageConfig.navigationBarTextStyle || 'white'
260
+ })
261
+ }, [])
262
+ return createElement(Provider,
263
+ null,
264
+ createElement(ReactNative.ScrollView,
265
+ {
266
+ style: {
267
+ ...ReactNative.StyleSheet.absoluteFillObject,
268
+ backgroundColor: pageConfig.backgroundColor || '#ffffff'
269
+ },
270
+ showsVerticalScrollIndicator: false
271
+ },
272
+ createElement(defaultOptions)
273
+ )
274
+ )
275
+ }
276
+ return Page
277
+ }
278
+
279
+ return defaultOptions
280
+ }
@@ -0,0 +1 @@
1
+ export function getDefaultOptions () {}
@@ -1,7 +1,7 @@
1
1
  import mergeOptions from '../../../core/mergeOptions'
2
2
  import { initProxy, filterOptions } from '../wx/getDefaultOptions'
3
3
 
4
- export function getDefaultOptions (type, { rawOptions = {}, currentInject }) {
4
+ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
5
5
  let hookNames = ['attached', 'ready', 'detached']
6
6
  // 当用户传入page作为构造器构造页面时,修改所有关键hooks
7
7
  if (rawOptions.__pageCtor__) {
@@ -3,7 +3,14 @@ import mergeOptions from '../../../core/mergeOptions'
3
3
  import { diffAndCloneA, hasOwn } from '@mpxjs/utils'
4
4
  import { getCurrentInstance as getCurrentVueInstance } from '../../export/index'
5
5
  import MpxProxy, { setCurrentInstance, unsetCurrentInstance } from '../../../core/proxy'
6
- import { BEFORECREATE, BEFOREUPDATE, UPDATED, BEFOREUNMOUNT, UNMOUNTED, SERVERPREFETCH } from '../../../core/innerLifecycle'
6
+ import {
7
+ BEFORECREATE,
8
+ BEFOREUPDATE,
9
+ UPDATED,
10
+ BEFOREUNMOUNT,
11
+ UNMOUNTED,
12
+ SERVERPREFETCH
13
+ } from '../../../core/innerLifecycle'
7
14
 
8
15
  function filterOptions (options) {
9
16
  const newOptions = {}
@@ -37,7 +44,7 @@ function initProxy (context, rawOptions) {
37
44
  }
38
45
  }
39
46
 
40
- export function getDefaultOptions (type, { rawOptions = {} }) {
47
+ export function getDefaultOptions ({ type, rawOptions = {} }) {
41
48
  const rawSetup = rawOptions.setup
42
49
  if (rawSetup) {
43
50
  rawOptions.setup = (props) => {
@@ -78,7 +85,10 @@ export function getDefaultOptions (type, { rawOptions = {} }) {
78
85
  if (this.__mpxProxy) this.__mpxProxy.callHook(BEFOREUNMOUNT)
79
86
  },
80
87
  destroyed () {
81
- if (this.__mpxProxy) this.__mpxProxy.callHook(UNMOUNTED)
88
+ if (this.__mpxProxy) {
89
+ this.__mpxProxy.state = UNMOUNTED
90
+ this.__mpxProxy.callHook(UNMOUNTED)
91
+ }
82
92
  },
83
93
  serverPrefetch () {
84
94
  if (this.__mpxProxy) return this.__mpxProxy.callHook(SERVERPREFETCH)
@@ -161,7 +161,7 @@ export function initProxy (context, rawOptions, currentInject) {
161
161
  }
162
162
  }
163
163
 
164
- export function getDefaultOptions (type, { rawOptions = {}, currentInject }) {
164
+ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
165
165
  let hookNames = ['attached', 'ready', 'detached']
166
166
  // 当用户传入page作为构造器构造页面时,修改所有关键hooks
167
167
  if (rawOptions.__pageCtor__) {
File without changes
File without changes