@mpxjs/core 2.9.39 → 2.9.41-react.0

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 +103 -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 +270 -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,270 @@
1
+ import { useEffect, 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 getNativeComponent (tagName) {
11
+ return getByPath(ReactNative, tagName)
12
+ }
13
+
14
+ function getRootProps (props) {
15
+ const rootProps = {}
16
+ for (const key in props) {
17
+ if (hasOwn(props, key)) {
18
+ const match = /^(bind|catch|capture-bind|capture-catch|style):?(.*?)(?:\.(.*))?$/.exec(key)
19
+ if (match) {
20
+ rootProps[key] = props[key]
21
+ }
22
+ }
23
+ }
24
+ return rootProps
25
+ }
26
+
27
+ function createEffect (proxy, components, props) {
28
+ const update = proxy.update = () => {
29
+ // pre render for props update
30
+ if (proxy.propsUpdatedFlag) {
31
+ proxy.updatePreRender()
32
+ }
33
+ if (proxy.isMounted()) {
34
+ proxy.callHook(BEFOREUPDATE)
35
+ proxy.pendingUpdatedFlag = true
36
+ }
37
+ // eslint-disable-next-line symbol-description
38
+ proxy.stateVersion = Symbol()
39
+ proxy.onStoreChange && proxy.onStoreChange()
40
+ }
41
+ update.id = proxy.uid
42
+ proxy.effect = new ReactiveEffect(() => {
43
+ return proxy.target.__injectedRender(createElement, components, getNativeComponent, getRootProps(props))
44
+ }, () => queueJob(update), proxy.scope)
45
+ }
46
+
47
+ function createInstance ({ propsRef, ref, type, rawOptions, currentInject, validProps, components }) {
48
+ const instance = Object.create({
49
+ setData (data, callback) {
50
+ return this.__mpxProxy.forceUpdate(data, { sync: true }, callback)
51
+ },
52
+ __getProps () {
53
+ const propsData = {}
54
+ const props = propsRef.current
55
+ if (props) {
56
+ Object.keys(props).forEach((key) => {
57
+ if (hasOwn(validProps, key) && !isFunction(props[key])) {
58
+ propsData[key] = props[key]
59
+ }
60
+ })
61
+ }
62
+ return propsData
63
+ },
64
+ __getSlot (name) {
65
+ const { children } = propsRef.current || {}
66
+ if (children) {
67
+ const result = []
68
+ if (Array.isArray(children)) {
69
+ children.forEach(child => {
70
+ if (child && child.props && child.props.slot === name) {
71
+ result.push(child)
72
+ }
73
+ })
74
+ } else {
75
+ if (children && children.props && children.props.slot === name) {
76
+ result.push(children)
77
+ }
78
+ }
79
+ return result.filter(item => {
80
+ if (this.__dispatchedSlotSet.has(item)) {
81
+ return false
82
+ } else {
83
+ this.__dispatchedSlotSet.add(item)
84
+ return true
85
+ }
86
+ })
87
+ }
88
+ return null
89
+ },
90
+ __injectedRender: currentInject.render || noop,
91
+ __getRefsData: currentInject.getRefsData || noop,
92
+ // render helper
93
+ _i (val, fn) {
94
+ let i, l, keys, key
95
+ const result = []
96
+ if (Array.isArray(val) || typeof val === 'string') {
97
+ for (i = 0, l = val.length; i < l; i++) {
98
+ result.push(fn.call(this, val[i], i))
99
+ }
100
+ } else if (typeof val === 'number') {
101
+ for (i = 0; i < val; i++) {
102
+ result.push(fn.call(this, i + 1, i))
103
+ }
104
+ } else if (isObject(val)) {
105
+ keys = Object.keys(val)
106
+ for (i = 0, l = keys.length; i < l; i++) {
107
+ key = keys[i]
108
+ result.push(fn.call(this, val[key], key, i))
109
+ }
110
+ }
111
+ return result
112
+ },
113
+ triggerEvent (eventName, eventDetail) {
114
+ const props = propsRef.current
115
+ const handlerName = eventName.replace(/^./, matched => matched.toUpperCase()).replace(/-([a-z])/g, (match, p1) => p1.toUpperCase())
116
+ const handler = props && (props['bind' + handlerName] || props['catch' + handlerName] || props['capture-bind' + handlerName] || props['capture-catch' + handlerName])
117
+ if (handler && typeof handler === 'function') {
118
+ const timeStamp = +new Date()
119
+ const dataset = collectDataset(props)
120
+ const id = props.id || ''
121
+ const eventObj = {
122
+ type: eventName,
123
+ timeStamp,
124
+ target: {
125
+ id,
126
+ dataset,
127
+ targetDataset: dataset
128
+ },
129
+ currentTarget: {
130
+ id,
131
+ dataset
132
+ },
133
+ detail: eventDetail
134
+ }
135
+ handler.call(this, eventObj)
136
+ }
137
+ },
138
+ selectComponent () {
139
+ error('selectComponent is not supported in react native, please use ref instead')
140
+ },
141
+ selectAllComponents () {
142
+ error('selectAllComponents is not supported in react native, please use ref instead')
143
+ },
144
+ createSelectorQuery () {
145
+ error('createSelectorQuery is not supported in react native, please use ref instead')
146
+ },
147
+ createIntersectionObserver () {
148
+ error('createIntersectionObserver is not supported in react native, please use ref instead')
149
+ },
150
+ ...rawOptions.methods
151
+ }, {
152
+ dataset: {
153
+ get () {
154
+ const props = propsRef.current
155
+ return collectDataset(props)
156
+ },
157
+ enumerable: true
158
+ },
159
+ id: {
160
+ get () {
161
+ const props = propsRef.current
162
+ return props.id
163
+ },
164
+ enumerable: true
165
+ }
166
+ })
167
+
168
+ const proxy = instance.__mpxProxy = new MpxProxy(rawOptions, instance)
169
+ proxy.created()
170
+ Object.assign(proxy, {
171
+ onStoreChange: null,
172
+ // eslint-disable-next-line symbol-description
173
+ stateVersion: Symbol(),
174
+ subscribe: (onStoreChange) => {
175
+ if (!proxy.effect) {
176
+ createEffect(proxy, components, propsRef.current)
177
+ // eslint-disable-next-line symbol-description
178
+ proxy.stateVersion = Symbol()
179
+ }
180
+ proxy.onStoreChange = onStoreChange
181
+ return () => {
182
+ proxy.effect && proxy.effect.stop()
183
+ proxy.effect = null
184
+ proxy.onStoreChange = null
185
+ }
186
+ },
187
+ getSnapshot: () => {
188
+ return proxy.stateVersion
189
+ }
190
+ })
191
+ // react数据响应组件更新管理器
192
+ if (!proxy.effect) {
193
+ createEffect(proxy, components, propsRef.current)
194
+ }
195
+
196
+ return instance
197
+ }
198
+
199
+ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
200
+ rawOptions = mergeOptions(rawOptions, type, false)
201
+ const { RootSiblingParent } = global.__navigationHelper
202
+ const components = currentInject.getComponents() || {}
203
+ const validProps = Object.assign({}, rawOptions.props, rawOptions.properties)
204
+ const defaultOptions = memo(forwardRef((props, ref) => {
205
+ const instanceRef = useRef(null)
206
+ const propsRef = useRef(props)
207
+ let isFirst = false
208
+ if (!instanceRef.current) {
209
+ isFirst = true
210
+ instanceRef.current = createInstance({ propsRef, ref, type, rawOptions, currentInject, validProps, components })
211
+ }
212
+ const instance = instanceRef.current
213
+ // reset instance
214
+ instance.__refs = {}
215
+ instance.__dispatchedSlotSet = new WeakSet()
216
+ useImperativeHandle(ref, () => {
217
+ return instance
218
+ })
219
+ const proxy = instance.__mpxProxy
220
+
221
+ if (!isFirst) {
222
+ // 处理props更新
223
+ propsRef.current = props
224
+ Object.keys(props).forEach(key => {
225
+ if (hasOwn(validProps, key) && !isFunction(props[key])) {
226
+ instance[key] = props[key]
227
+ }
228
+ })
229
+ proxy.propsUpdated()
230
+ }
231
+
232
+ useEffect(() => {
233
+ if (proxy.pendingUpdatedFlag) {
234
+ proxy.pendingUpdatedFlag = false
235
+ proxy.callHook(UPDATED)
236
+ }
237
+ })
238
+
239
+ useEffect(() => {
240
+ proxy.mounted()
241
+ return () => {
242
+ proxy.unmounted()
243
+ }
244
+ }, [])
245
+
246
+ useSyncExternalStore(proxy.subscribe, proxy.getSnapshot)
247
+
248
+ return proxy.effect.run()
249
+ }))
250
+
251
+ if (type === 'page') {
252
+ const Page = () => {
253
+ return createElement(RootSiblingParent,
254
+ null,
255
+ createElement(ReactNative.ScrollView,
256
+ {
257
+ style: {
258
+ ...ReactNative.StyleSheet.absoluteFillObject
259
+ },
260
+ showsVerticalScrollIndicator: false
261
+ },
262
+ createElement(defaultOptions)
263
+ )
264
+ )
265
+ }
266
+ return Page
267
+ }
268
+
269
+ return defaultOptions
270
+ }
@@ -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