@cloudbase/lowcode-builder 1.0.3 → 1.0.6

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.
@@ -182,10 +182,11 @@ async function generateWxMp({ weapps, projDir, appId, domain, materials, plugins
182
182
  clientID: (_a = mainAppData.extra) === null || _a === void 0 ? void 0 : _a.clientId,
183
183
  },
184
184
  'datasources/datasource-profiles.js.tpl': {
185
- datasourceProfiles: (0, util_3.JsonToStringWithVariableName)((0, lowcode_generator_1.getDatasourceProfiles)(weapps.reduce((datasources, app) => {
186
- datasources.push(...(app.datasources || []));
187
- return datasources;
188
- }, [])), { EOL: false }),
185
+ datasourceProfiles: (0, util_3.JsonToStringWithVariableName)((0, lowcode_generator_1.getDatasourceProfiles)(
186
+ /**
187
+ * 精简文件生成,新 cloud-sdk 不依赖 profile 了
188
+ */
189
+ []), { EOL: false }),
189
190
  },
190
191
  'datasources/dataset-profiles.js.tpl': {
191
192
  datasetProfiles: (0, util_3.JsonToStringWithVariableName)((0, lowcode_generator_1.getDatasetProfiles)(mainAppData, weapps), { EOL: true }),
@@ -6,6 +6,7 @@ const weapp_1 = require("@cloudbase/lowcode-generator/lib/generator/util/weapp")
6
6
  const wxml_1 = require("./wxml");
7
7
  const mp_1 = require("@cloudbase/lowcode-generator/lib/generator/config/mp");
8
8
  function extractWidgetProps(props, compInfo) {
9
+ var _a, _b;
9
10
  const { classList } = props;
10
11
  const staticProps = {
11
12
  style: (0, weapps_core_1.toCssStyle)(props.commonStyle, {
@@ -16,6 +17,9 @@ function extractWidgetProps(props, compInfo) {
16
17
  };
17
18
  const { data = {} } = props;
18
19
  Object.assign(staticProps, generatedDynamicData(data, compInfo).staticProps);
20
+ if ((_a = props.directives) === null || _a === void 0 ? void 0 : _a.waForKey) {
21
+ staticProps._waForKey = (_b = props.directives) === null || _b === void 0 ? void 0 : _b.waForKey.value;
22
+ }
19
23
  return staticProps;
20
24
  }
21
25
  exports.extractWidgetProps = extractWidgetProps;
@@ -120,7 +124,7 @@ function createWidgetProps(widgets, ctx) {
120
124
  widgetProps[id] = extractWidgetProps(xProps, widegetComp);
121
125
  widgetProps[id]._parentId = parentId;
122
126
  widgetProps[id]._order = widget.xIndex;
123
- widgetProps[id].widgetType = xComponent.moduleName + ':' + xComponent.name;
127
+ widgetProps[id].widgetType = `${xComponent.moduleName}:${xComponent.name}`;
124
128
  });
125
129
  return widgetProps;
126
130
  }
@@ -52,7 +52,7 @@ function generateWxml(widgets, docTag, wxmlDataPrefix, ctx, usingComponents, com
52
52
  ];
53
53
  }
54
54
  function createXml(widgets, parent = null, parentForNodes = []) {
55
- var _a, _b, _c, _d, _e;
55
+ var _a, _b, _c, _d, _e, _f;
56
56
  const elements = [];
57
57
  for (const id of Object.keys(widgets !== null && widgets !== void 0 ? widgets : {})) {
58
58
  const { xComponent, xProps, properties, xIndex, genericComp } = widgets[id];
@@ -151,7 +151,7 @@ function generateWxml(widgets, docTag, wxmlDataPrefix, ctx, usingComponents, com
151
151
  .map((forNodeId) => `[${wxmlDataPrefix.forIndex}${forNodeId}]`)
152
152
  .join('')}`);
153
153
  node.attributes['wx:for-index'] = wxmlDataPrefix.forIndex + id;
154
- node.attributes['wx:key'] = 'id';
154
+ node.attributes['wx:key'] = ((_f = directives.waForKey) === null || _f === void 0 ? void 0 : _f.value) ? '_key' : '$$i';
155
155
  }
156
156
  const compSchema = componentProto.dataForm;
157
157
  for (const prop of Object.keys(data || {})) {
@@ -290,11 +290,7 @@ function getWebpackWebBuildParams(appId, appBuildDir, publicPath = '/', mode = c
290
290
  '@zxing/library': 'window.ZXing',
291
291
  '@cloudbase/lowcode-render': 'window["weda-render"]',
292
292
  },
293
- resolveModules: [
294
- // path.resolve(appBuildDir, 'node_modules'),
295
- path_1.default.resolve(appBuildDir),
296
- 'node_modules',
297
- ],
293
+ resolveModules: [path_1.default.resolve(appBuildDir), 'node_modules'],
298
294
  definePlugin: {
299
295
  'process.env.buildType': `"${buildTypeList[0]}"`,
300
296
  'process.env.isApp': buildTypeList.includes(common_1.BuildType.APP),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/lowcode-builder",
3
- "version": "1.0.3",
3
+ "version": "1.0.6",
4
4
  "description": "云开发 Tencent CloudBase Framework Low Code Plugin,将低码配置生成完整项目并一键部署云开发资源。",
5
5
  "author": "yhsunshining@gmail.com",
6
6
  "homepage": "https://github.com/TencentCloudBase/cloudbase-framework#readme",
@@ -38,8 +38,8 @@
38
38
  "url": "https://github.com/TencentCloudBase/cloudbase-framework/issues"
39
39
  },
40
40
  "dependencies": {
41
- "@cloudbase/cals": "^0.3.31",
42
- "@cloudbase/lowcode-generator": "^1.0.1",
41
+ "@cloudbase/cals": "^0.3.34",
42
+ "@cloudbase/lowcode-generator": "^1.0.2",
43
43
  "axios": "^0.21.0",
44
44
  "browserfs": "^1.4.3",
45
45
  "browserify-zlib": "^0.2.0",
@@ -461,7 +461,7 @@
461
461
  ></script>
462
462
  <script
463
463
  crossorigin
464
- src="https://qbase.cdn-go.cn/lcap/lcap-resource-cdngo/-/0.1.4/_files/static/weda-render/main.1bdb55327899bf5969df.bundle.js"
464
+ src="https://qbase.cdn-go.cn/lcap/lcap-resource-cdngo/-/0.1.4/_files/static/weda-render/main.32804d9240f6c35683e2.bundle.js"
465
465
  ></script>
466
466
  </body>
467
467
  </html>
@@ -52,7 +52,7 @@ setConfig({
52
52
  icon: 'error',
53
53
  });
54
54
  }
55
- console.error('beforeCallFunction error', e);
55
+ // console.error('beforeCallFunction error', e);
56
56
  }
57
57
  return params;
58
58
  },
@@ -1,46 +1,104 @@
1
- import { observable, autorun, untracked } from 'mobx'
2
- import { styleToCss } from './style'
3
- import { getDeep } from './util'
4
- import { compLowcodes, create$comp } from './weapp-component'
5
- import EventEmitter from './event-emitter'
1
+ import { observable, autorun, untracked } from 'mobx';
2
+ import { styleToCss } from './style';
3
+ import { getDeep } from './util';
4
+ import { compLowcodes, create$comp } from './weapp-component';
5
+ import EventEmitter from './event-emitter';
6
+ import lodashSet from 'lodash.set';
7
+
8
+ function basePullAt(array, indexes) {
9
+ let length = array ? indexes.length : 0;
10
+ let lastIndex = length - 1;
11
+
12
+ // eslint-disable-next-line no-plusplus
13
+ while (length--) {
14
+ let index = indexes[length];
15
+ let previous;
16
+ if (length == lastIndex || index !== previous) {
17
+ previous = index;
18
+ Array.prototype.splice.call(array, index, 1);
19
+ }
20
+ }
21
+ return array;
22
+ }
23
+
24
+ function remove(array, predicate) {
25
+ const result = [];
26
+ if (!(array != null && array.length)) {
27
+ return result;
28
+ }
29
+ let index = -1;
30
+ const indexes = [];
31
+ const { length } = array;
32
+
33
+ while (++index < length) {
34
+ const value = array[index];
35
+ if (predicate(value, index, array)) {
36
+ result.push(value);
37
+ indexes.push(index);
38
+ }
39
+ }
40
+ basePullAt(array, indexes);
41
+ return result;
42
+ }
6
43
 
7
44
  /**
8
45
  * convert widget prop to data for wxml
9
46
  * @param {*} props
10
47
  */
11
48
  function resolveWidgetProp(props) {
12
- let { classList = [] } = props
13
- const data = {}
14
- Object.keys(props).forEach(key => {
49
+ let { classList = [] } = props;
50
+ const data = {};
51
+ Object.keys(props).forEach((key) => {
15
52
  if (props[key] instanceof Function || props[key] === undefined) {
16
- return
53
+ return;
17
54
  }
18
- data[key] = props[key]
19
- })
20
- data.style = styleToCss(props.style)
21
- data.className = classList.join ? classList.join(' ') : classList
22
- const extraProps = ['classList', '_forItems', '_disposers', 'children', 'parent', '_parentId', 'id', '_order', 'widgetType', '$comp']
23
- extraProps.map(prop => {
24
- delete data[prop]
25
- })
26
- return data
55
+ data[key] = props[key];
56
+ });
57
+ data.style = styleToCss(props.style);
58
+ data.className = classList.join ? classList.join(' ') : classList;
59
+ const extraProps = [
60
+ 'classList',
61
+ '_forItems',
62
+ '_disposers',
63
+ 'children',
64
+ 'parent',
65
+ '_parentId',
66
+ 'id',
67
+ '_order',
68
+ 'widgetType',
69
+ '$comp',
70
+ ];
71
+ extraProps.map((prop) => {
72
+ delete data[prop];
73
+ });
74
+ return data;
27
75
  }
28
76
 
29
77
  // widget prop -> wxml data
30
78
  export function resolveWidgetData(props) {
31
79
  if (!Array.isArray(props)) {
32
- return resolveWidgetProp(props)
80
+ return resolveWidgetProp(props);
33
81
  }
34
- return props.map(resolveWidgetData)
82
+ return props.map(resolveWidgetData);
35
83
  }
36
84
 
37
-
38
85
  export function createWidgets(widgetProps, dataBinds, widgetHolder, context, ownerMpInst) {
39
- const rootNode = createWidgetDataTree(widgetProps, dataBinds)
40
- const failedBinds = []
41
- const result = createSubWidgetTree(rootNode, widgetProps, dataBinds, ownerMpInst, widgetHolder, 0, {}, null, failedBinds, undefined, context)
42
- retryFailedBinds(failedBinds, true)
43
- return result
86
+ const rootNode = createWidgetDataTree(widgetProps, dataBinds);
87
+ const failedBinds = [];
88
+ const result = createSubWidgetTree(
89
+ rootNode,
90
+ widgetProps,
91
+ dataBinds,
92
+ ownerMpInst,
93
+ widgetHolder,
94
+ {},
95
+ null,
96
+ failedBinds,
97
+ undefined,
98
+ context,
99
+ );
100
+ retryFailedBinds(failedBinds, true);
101
+ return result;
44
102
  }
45
103
 
46
104
  /**
@@ -49,66 +107,101 @@ export function createWidgets(widgetProps, dataBinds, widgetHolder, context, own
49
107
  * @param curForNode a component node or a virtual root tree node
50
108
  * @returns {widgets: {id1:[], id2}, rootWidget: {children: [], _disposers: [], ...otherProps}}
51
109
  */
52
- function createSubWidgetTree(curForNode, widgetProps, dataBinds, ownerMpInst, widgetHolder = {},
53
- index = 0, forItems = {}, ownerForWidgetHolder = null,
54
- failedBinds = [], defaultParent = { children: observable([]), _disposers: [] }, context) {
55
- const indexPostfix = (forItems.lists || []).slice().reverse().map(list => idSeparator + list.currentIndex).join('')
110
+ function createSubWidgetTree(
111
+ curForNode,
112
+ widgetProps,
113
+ dataBinds,
114
+ ownerMpInst,
115
+ widgetHolder = {},
116
+ forItems = {},
117
+ ownerForWidgetHolder = null,
118
+ failedBinds = [],
119
+ defaultParent = { children: observable([]), _disposers: [] },
120
+ context,
121
+ ) {
122
+ const indexPostfix = (forItems.lists || [])
123
+ .slice()
124
+ .reverse()
125
+ .map((list) => idSeparator + list.currentIndex)
126
+ .join('');
56
127
 
57
128
  // traverse down the tree to set up all widgets
58
- dfsTree(curForNode, (node) => {
59
- const parentForWidgetArr = ownerForWidgetHolder && ownerForWidgetHolder[node.id] || []
60
- const existedWidget = index < parentForWidgetArr.length ? parentForWidgetArr[index] : null // try to reuse previous node when rerun for
129
+ dfsTree(curForNode, (node, parentNode, cache) => {
130
+ const parentForWidgetArr = ownerForWidgetHolder?.[node.id] || [];
131
+ const { _waForKey } = node.value;
132
+ const key = forItems.itemsById?.[node.id]?.[_waForKey];
133
+ const index = cache[parentNode?.id]
134
+ ? cache[parentNode.id].index
135
+ : parentForWidgetArr.findIndex((widget) => key && widget._key === key);
136
+ const existedWidget = index !== -1 ? parentForWidgetArr[index] : null; // try to reuse previous node when rerun for
137
+
138
+ if (existedWidget) {
139
+ cache[node.id] = {
140
+ index,
141
+ };
142
+ }
61
143
 
62
- if (node.forCount === curForNode.forCount) { // Leaf node
63
- let w = existedWidget
144
+ if (node.forCount === curForNode.forCount) {
145
+ // Leaf node
146
+ let w = existedWidget;
64
147
  if (!existedWidget) {
65
- const parentNode = node.parent
66
- let parentWidget = null
148
+ const parentNode = node.parent;
149
+ let parentWidget = null;
67
150
  if (parentNode) {
68
- parentWidget = widgetHolder[parentNode.id] || ownerForWidgetHolder[parentNode.id]
151
+ parentWidget = widgetHolder[parentNode.id] || ownerForWidgetHolder[parentNode.id];
69
152
  }
70
- w = createAWidget(widgetProps[node.id], node.id + indexPostfix, parentWidget, ownerMpInst)
153
+ w = createAWidget(widgetProps[node.id], node.id + indexPostfix, parentWidget, ownerMpInst);
154
+ w._key = key;
71
155
  if (!parentWidget) {
72
- defaultParent.children.push(w)
156
+ defaultParent.children.push(w);
73
157
  }
74
- parentForWidgetArr.push(w)
158
+ parentForWidgetArr.push(w);
75
159
  } else {
76
- disposeWidget(existedWidget, true)
160
+ disposeWidget(existedWidget, true);
77
161
  }
78
- setUpWidgetDataBinds(w, dataBinds[node.id], forItems, failedBinds, ownerMpInst.getWeAppInst(), context)
79
- widgetHolder[node.id] = w
162
+ setUpWidgetDataBinds(w, dataBinds[node.id], forItems, failedBinds, ownerMpInst.getWeAppInst(), context);
163
+ widgetHolder[node.id] = w;
80
164
  } else if (!existedWidget) {
81
- const len = parentForWidgetArr.push(observable([]))
82
- widgetHolder[node.id] = parentForWidgetArr[len - 1]
165
+ const len = parentForWidgetArr.push(observable([]));
166
+ widgetHolder[node.id] = parentForWidgetArr[len - 1];
83
167
  } else {
84
168
  // Reuse existed for widget array
85
- widgetHolder[node.id] = existedWidget
169
+ widgetHolder[node.id] = existedWidget;
86
170
  }
87
- })
171
+ });
88
172
 
89
173
  // run for of next level
90
174
  dfsTree(curForNode, (node) => {
91
175
  if (node.forCount === curForNode.forCount + 1 && dataBinds[node.id] && dataBinds[node.id]._waFor) {
92
176
  // find the node bound with next level for
93
- const parent = node.parent ? widgetHolder[node.parent.id] : defaultParent
94
- const dispose = runFor(node, widgetProps, dataBinds, ownerMpInst, forItems, widgetHolder, failedBinds, parent, context)
95
- parent._disposers.push(dispose) // Add the for bind dispose to the parent node of forNode
177
+ const parent = node.parent ? widgetHolder[node.parent.id] : defaultParent;
178
+ const dispose = runFor(
179
+ node,
180
+ widgetProps,
181
+ dataBinds,
182
+ ownerMpInst,
183
+ forItems,
184
+ widgetHolder,
185
+ failedBinds,
186
+ parent,
187
+ context,
188
+ );
189
+ parent._disposers.push(dispose); // Add the for bind dispose to the parent node of forNode
96
190
  }
97
- })
191
+ });
98
192
 
99
- retryFailedBinds(failedBinds)
193
+ retryFailedBinds(failedBinds);
100
194
 
101
- return { widgets: widgetHolder, rootWidget: widgetHolder[curForNode.id] || defaultParent }
195
+ return { widgets: widgetHolder, rootWidget: widgetHolder[curForNode.id] || defaultParent };
102
196
  }
103
197
 
104
198
  // Retry failed databinds
105
199
  function retryFailedBinds(failedBinds, finalTry) {
106
- const len = failedBinds.length
200
+ const len = failedBinds.length;
107
201
  for (let i = 0; i < len; i++) {
108
- const setUpDataBind = failedBinds.shift()
109
- setUpDataBind(finalTry)
202
+ const setUpDataBind = failedBinds.shift();
203
+ setUpDataBind(finalTry);
110
204
  }
111
-
112
205
  }
113
206
 
114
207
  /**
@@ -119,280 +212,360 @@ function retryFailedBinds(failedBinds, finalTry) {
119
212
  * @param {*} parentWidget
120
213
  * @returns top level widgets or for dispose
121
214
  */
122
- function runFor(curForNode, widgetProps, dataBinds, ownerMpInst, forItems, ownerForWidgetHolder, failedBinds, defaultParent, context) {
123
- const nodeId = curForNode.id
215
+ const _FOR_ERROR_CACHE_MAP = {};
216
+ function runFor(
217
+ curForNode,
218
+ widgetProps,
219
+ dataBinds,
220
+ ownerMpInst,
221
+ forItems,
222
+ ownerForWidgetHolder,
223
+ failedBinds,
224
+ defaultParent,
225
+ context,
226
+ ) {
227
+ const nodeId = curForNode.id;
228
+ const { _waForKey } = curForNode.value;
229
+
124
230
  const dispose = autorun(() => {
125
- let forList = []
231
+ let forList = [];
126
232
  try {
127
- forList = dataBinds[nodeId]._waFor.call(ownerMpInst.getWeAppInst(), ownerMpInst.getWeAppInst(), forItems.lists, forItems.itemsById, undefined, context)
233
+ clearTimeout(_FOR_ERROR_CACHE_MAP[nodeId]);
234
+ forList = dataBinds[nodeId]._waFor.call(
235
+ ownerMpInst.getWeAppInst(),
236
+ ownerMpInst.getWeAppInst(),
237
+ forItems.lists,
238
+ forItems.itemsById,
239
+ undefined,
240
+ context,
241
+ );
128
242
  if (!Array.isArray(forList)) {
129
- forList = []
243
+ forList = [];
130
244
  }
131
245
  } catch (e) {
132
- forList = []
133
- console.warn('For binding error', e)
246
+ forList = [];
247
+ _FOR_ERROR_CACHE_MAP[nodeId] = setTimeout(() => {
248
+ console.warn('For binding error', nodeId, e);
249
+ }, 1000);
134
250
  }
135
251
 
136
252
  // Track list change (e.g. push)
137
- forList.forEach(e => { })
253
+ forList.forEach((e) => {});
138
254
 
139
255
  untracked(() => {
140
256
  // dispose widgets before reused instead
141
257
  // disposeWidgets(parentForWidgets[curForNode.id])
258
+ const exsitMap = forList.reduce((map, item) => {
259
+ if (item[_waForKey]) {
260
+ map[item[_waForKey]] = true;
261
+ }
262
+ return map;
263
+ }, {});
264
+ const forWidgets = ownerForWidgetHolder[nodeId];
265
+ const existedWidgetIndex = [];
266
+ const extraWidgetsIndex = [];
267
+ const extraWidgets = [];
268
+ forWidgets.forEach((widget, index) => {
269
+ if (exsitMap[widget._key]) {
270
+ existedWidgetIndex.push(index);
271
+ // need to use uqique key
272
+ exsitMap[widget._key] = undefined;
273
+ } else {
274
+ extraWidgetsIndex.push(index);
275
+ }
276
+ });
277
+ const extraWidgetsIndexMap = extraWidgetsIndex.reduce((map, item) => {
278
+ map[item] = true;
279
+ extraWidgets.push(forWidgets[item]);
280
+ return map;
281
+ }, {});
142
282
 
143
283
  // clean extra widgets of previous for run
144
284
  dfsTree(curForNode, (node) => {
145
- const arr = ownerForWidgetHolder[node.id]
146
- const extraWidgets = arr.splice(forList.length, arr.length)
147
- //console.log('@@ delete widgets', node.id, extraWidgets)
148
-
149
- if (node.id === curForNode.id) { // clean the root widget.children only(recursive)
150
- extraWidgets.map(w => {
151
- disposeWidget(w)
152
- const { children } = w.parent || defaultParent
153
- children.remove(w)
154
- // w.parent = null
155
- })
156
- }
157
- })
285
+ const arr = ownerForWidgetHolder[node.id];
286
+ remove(arr, (_, index) => {
287
+ return extraWidgetsIndexMap[index];
288
+ });
289
+ });
290
+
291
+ // 清理根 for 的 autorun, 并递归清理子节点
292
+ extraWidgets.map((w) => {
293
+ disposeWidget(w);
294
+ const { children } = w.parent || defaultParent;
295
+ children.remove(w);
296
+ // w.parent = null
297
+ });
158
298
 
159
299
  forList.forEach((item, index) => {
160
- let { lists = [], itemsById = {}, } = forItems
300
+ let { lists = [], itemsById = {} } = forItems;
161
301
  const _forItems = {
162
302
  lists: [{ currentItem: item, currentIndex: index }, ...lists],
163
- itemsById: { ...itemsById, [nodeId]: item },
164
- }
165
- const { rootWidget } = createSubWidgetTree(curForNode, widgetProps, dataBinds, ownerMpInst, {}, index, _forItems, ownerForWidgetHolder, failedBinds, defaultParent, context)
166
- rootWidget._forItems = _forItems
167
- })
168
- })
169
- })
170
-
171
- return dispose
303
+ itemsById: { ...itemsById, [nodeId]: item, index: { ...itemsById?.index, [nodeId]: index } },
304
+ };
305
+ const { rootWidget } = createSubWidgetTree(
306
+ curForNode,
307
+ widgetProps,
308
+ dataBinds,
309
+ ownerMpInst,
310
+ {},
311
+ _forItems,
312
+ ownerForWidgetHolder,
313
+ failedBinds,
314
+ defaultParent,
315
+ context,
316
+ );
317
+ rootWidget._forItems = _forItems;
318
+ });
319
+ });
320
+ });
321
+
322
+ return dispose;
172
323
  }
173
324
 
174
325
  function createAWidget(props, id, parent, ownerMpInst) {
175
-
176
- const w = observable(props)
326
+ const w = observable(props);
177
327
 
178
328
  // Builtin props
179
- Object.defineProperty(w, 'id', { value: id })
180
- const { widgetType } = w
181
- delete w.widgetType
182
- Object.defineProperty(w, 'widgetType', { value: widgetType })
183
-
184
- //w._disposers = []
185
- //w.children = []
186
- Object.defineProperty(w, 'children', { value: observable([]) })
187
- Object.defineProperty(w, '_disposers', { value: observable([]) })
188
- Object.defineProperty(w, '_eventListeners', {value: new EventEmitter()})
329
+ Object.defineProperty(w, 'id', { value: id });
330
+ const { widgetType } = w;
331
+ delete w.widgetType;
332
+ Object.defineProperty(w, 'widgetType', { value: widgetType });
333
+
334
+ // w._disposers = []
335
+ // w.children = []
336
+ Object.defineProperty(w, 'children', { value: observable([]) });
337
+ Object.defineProperty(w, '_disposers', { value: observable([]) });
338
+ Object.defineProperty(w, '_eventListeners', { value: new EventEmitter() });
189
339
  if (parent) {
190
- //w.parent = parent
191
- Object.defineProperty(w, 'parent', { value: parent })
192
- parent.children.push(w)
340
+ // w.parent = parent
341
+ Object.defineProperty(w, 'parent', { value: parent });
342
+ parent.children.push(w);
193
343
  }
194
- delete w._parentId
344
+ delete w._parentId;
195
345
 
196
- Object.defineProperty(w, '$comp', { value: create$comp(w) })
197
- mountBuiltinWigetsAPI(w, ownerMpInst)
198
- return w
346
+ Object.defineProperty(w, '$comp', { value: create$comp(w) });
347
+ mountBuiltinWigetsAPI(w, ownerMpInst);
348
+ return w;
199
349
  }
200
350
 
201
351
  function setUpWidgetDataBinds(w, dataBinds, forItems, failedBinds, ctx, context) {
202
- Object.keys(dataBinds || {}).map(prop => {
203
- if (prop === '_waFor') { return }
204
- const setUpDataBind = (isFinalTry) => {
205
- let firstRunError = null
206
- let ran = false
207
- const dispose = autorun((reaction) => {
208
- try {
209
- // Computed data bind in the next tick since data bind may read widgets data
210
- w[prop] = dataBinds[prop].call(ctx,ctx,forItems.lists, forItems.itemsById, undefined, context)
211
- } catch (e) {
212
- if (prop === '_waIf') {
213
- w[prop] = false
214
- }
215
-
216
- if(isFinalTry || ran){
217
- console.warn(`Error computing data bind ${w.id}.${prop}`, e)
218
- } else {
219
- reaction.dispose()
220
- failedBinds.push(setUpDataBind)
352
+ Object.keys(dataBinds || {})
353
+ .sort((a, b) => {
354
+ return a.length - b.length > 0 ? 1 : -1;
355
+ })
356
+ .map((prop) => {
357
+ if (prop === '_waFor') {
358
+ return;
359
+ }
360
+ let timer = null;
361
+ const setUpDataBind = (isFinalTry) => {
362
+ let ran = false;
363
+ const dispose = autorun((reaction) => {
364
+ try {
365
+ clearTimeout(timer);
366
+ // Computed data bind in the next tick since data bind may read widgets data
367
+ const value = dataBinds[prop].call(ctx, ctx, forItems.lists, forItems.itemsById, undefined, context);
368
+ const paths = prop.split('.').filter((key) => !!key);
369
+ if (paths.length > 1) {
370
+ // 一定要 untracked 不然爆栈了
371
+ untracked(() => lodashSet(w, prop, value));
372
+ } else {
373
+ // 普通 key 直接赋值
374
+ w[prop] = value;
375
+ }
376
+ } catch (e) {
377
+ if (prop === '_waIf') {
378
+ w[prop] = false;
379
+ }
380
+
381
+ if (isFinalTry || ran) {
382
+ timer = setTimeout(() => {
383
+ console.warn(`Error computing data bind ${w.id}.${prop}`, e);
384
+ }, 1000);
385
+ } else {
386
+ reaction.dispose();
387
+ failedBinds.push(setUpDataBind);
388
+ }
389
+
390
+ ran = true;
221
391
  }
222
-
223
- ran = true
224
- }
225
- })
226
- w._disposers.push(dispose)
227
- }
228
- setUpDataBind()
229
- })
392
+ });
393
+ w._disposers.push(dispose);
394
+ };
395
+ setUpDataBind();
396
+ });
230
397
  }
231
398
 
232
399
  export function findForItemsOfWidget(widget) {
233
- const forItems = widget._forItems
234
- if (forItems) return forItems
235
- if (widget.parent) return findForItemsOfWidget(widget.parent)
400
+ const forItems = widget._forItems;
401
+ if (forItems) return forItems;
402
+ if (widget.parent) return findForItemsOfWidget(widget.parent);
236
403
  }
237
404
 
238
- const idSeparator = '-'
405
+ const idSeparator = '-';
239
406
 
240
407
  export function getWidget(widgets, id) {
241
- return getDeep(widgets, id, idSeparator)
408
+ return getDeep(widgets, id, idSeparator);
242
409
  }
243
410
 
244
411
  /**
245
412
  * Add parent, children to widget
246
413
  */
247
414
  function createWidgetDataTree(widgets, dataBinds) {
248
- const virtualRoot = { children: [], forCount: 0 }
415
+ const virtualRoot = { children: [], forCount: 0 };
249
416
  const nodes = Object.keys(widgets).reduce((result, id) => {
250
- const w = widgets[id]
251
- result[id] = { id, value: w, _order: w._order, children: [], parent: null, forCount: 0 }
252
- return result
253
- }, {})
417
+ const w = widgets[id];
418
+ result[id] = { id, value: w, _order: w._order, children: [], parent: null, forCount: 0 };
419
+ return result;
420
+ }, {});
254
421
 
255
422
  // Create widgets tree API
256
- Object.keys(nodes).map(id => {
257
- const curNode = nodes[id]
258
- const parent = nodes[widgets[id]._parentId]
259
- //delete widgets[id]._parentId
423
+ Object.keys(nodes).map((id) => {
424
+ const curNode = nodes[id];
425
+ const parent = nodes[widgets[id]._parentId];
426
+ // delete widgets[id]._parentId
260
427
  if (!parent) {
261
- virtualRoot.children.push(curNode)
262
- return
428
+ virtualRoot.children.push(curNode);
429
+ return;
263
430
  }
264
- curNode.parent = parent
265
- parent.children.push(curNode)
266
- })
431
+ curNode.parent = parent;
432
+ parent.children.push(curNode);
433
+ });
267
434
 
268
435
  // Sort children
269
- Object.keys(nodes).map(id => {
270
- nodes[id].children.sort((a, b) => a._order - b._order)
271
- })
436
+ Object.keys(nodes).map((id) => {
437
+ nodes[id].children.sort((a, b) => a._order - b._order);
438
+ });
272
439
 
273
- virtualRoot.children.map(addForCount)
440
+ virtualRoot.children.map(addForCount);
274
441
 
275
442
  // dfs, add forCount
276
443
  function addForCount(node) {
277
444
  if (node.parent) {
278
- node.forCount = node.parent.forCount
445
+ node.forCount = node.parent.forCount;
279
446
  }
280
- if (dataBinds[node.id] && dataBinds[node.id]._waFor) {
281
- node.forCount++
447
+ if (dataBinds[node.id]?._waFor) {
448
+ node.forCount++;
282
449
  }
283
- node.children.map(addForCount)
450
+ node.children.map(addForCount);
284
451
  }
285
452
 
286
- return virtualRoot
453
+ return virtualRoot;
287
454
  }
288
455
 
289
- function dfsTree(node, fn, parent) {
290
- node.value && fn(node, parent)
291
- node.children.map(e => dfsTree(e, fn, node.value ? node : null))
456
+ function dfsTree(node, fn, parent, cache = {}) {
457
+ node.value && fn(node, parent, cache);
458
+ node.children.map((e) => dfsTree(e, fn, node.value ? node : null, cache));
292
459
  }
293
460
 
294
461
  // dispose autorun, widget can be the virtual root widget
295
462
  export function disposeWidget(widget, noRecursive) {
296
- const disposers = widget._disposers
297
- disposers.map(dispose => dispose())
298
- disposers.splice(0, disposers.length)
299
- !noRecursive && widget.children.forEach(w => disposeWidget(w))
463
+ const disposers = widget._disposers;
464
+ disposers.map((dispose) => dispose());
465
+ disposers.splice(0, disposers.length);
466
+ !noRecursive && widget.children.forEach((w) => disposeWidget(w));
300
467
  }
301
468
 
302
469
  export function createInitData(widgets, dataBinds, keyPrefix = '') {
303
470
  return Object.keys(widgets).reduce((result, id) => {
304
471
  if (!isWidgetInFor(id, widgets, dataBinds)) {
305
- result[keyPrefix + id] = resolveWidgetData(widgets[id])
472
+ result[keyPrefix + id] = resolveWidgetData(widgets[id]);
306
473
  } else {
307
- result[keyPrefix + id] = []
474
+ result[keyPrefix + id] = [];
308
475
  }
309
- return result
310
- }, {})
476
+ return result;
477
+ }, {});
311
478
  }
312
479
 
313
480
  function isWidgetInFor(id, widgets, dataBinds) {
314
- let curNode = widgets[id]
315
- let nodeId = id
481
+ let curNode = widgets[id];
482
+ let nodeId = id;
316
483
  while (curNode) {
317
- if (dataBinds[nodeId] && dataBinds[nodeId]._waFor) {
318
- return true
484
+ if (dataBinds[nodeId]?._waFor) {
485
+ return true;
319
486
  }
320
- nodeId = curNode._parentId
321
- curNode = widgets[nodeId]
487
+ nodeId = curNode._parentId;
488
+ curNode = widgets[nodeId];
322
489
  }
323
490
  }
324
491
 
325
492
  function mountBuiltinWigetsAPI(widget, owner) {
326
493
  // #1 builtin APIs
327
494
  widget.findWidgets = function (filter, includeInvisibleDescendants) {
328
- let { children = [] } = this
329
- if (!includeInvisibleDescendants) { // include visible widgets only by default
330
- children = children.filter(e => e._waIf !== false)
495
+ let { children = [] } = this;
496
+ if (!includeInvisibleDescendants) {
497
+ // include visible widgets only by default
498
+ children = children.filter((e) => e._waIf !== false);
331
499
  }
332
- const matched = []
333
- children.forEach(w => {
500
+ const matched = [];
501
+ children.forEach((w) => {
334
502
  if (filter(w)) {
335
- matched.push(w)
503
+ matched.push(w);
336
504
  }
337
- matched.push(...w.findWidgets(filter, includeInvisibleDescendants))
338
- })
339
- return matched
340
- }
505
+ matched.push(...w.findWidgets(filter, includeInvisibleDescendants));
506
+ });
507
+ return matched;
508
+ };
341
509
 
342
510
  widget.getWidgetsByType = function (type, includeInvisibleDescendants) {
343
- return this.findWidgets(w => w.widgetType === type, includeInvisibleDescendants)
344
- }
511
+ return this.findWidgets((w) => w.widgetType === type, includeInvisibleDescendants);
512
+ };
345
513
 
346
514
  /**
347
515
  * Similar to selectOwnerComponent of WX MP: https://developers.weixin.qq.com/miniprogram/dev/reference/api/Component.html
348
516
  */
349
517
  widget.getOwnerWidget = function () {
350
- return owner && owner.getWeAppInst().node
351
- }
518
+ return owner?.getWeAppInst?.()?.node;
519
+ };
352
520
 
353
521
  // Will be overwritten by composited component
354
522
  widget.getDom = function (fields) {
355
523
  return new Promise((resolve, reject) => {
356
- const query = (owner || wx).createSelectorQuery()
357
- query.select('#' + this.id).fields(fields, res => {
358
- resolve(res)
359
- }).exec()
360
- })
361
- }
362
-
363
- widget.on = function(type,listener){
364
- this._eventListeners.on(type,listener)
365
- }
366
-
367
- widget.off = function(type,listener){
368
- this._eventListeners.off(type,listener)
369
- }
370
-
371
- widget.getConfig = () => ({})
372
-
373
- const lowcode = compLowcodes[widget.widgetType]
524
+ const query = (owner || wx).createSelectorQuery();
525
+ query
526
+ .select(`#${this.id}`)
527
+ .fields(fields, (res) => {
528
+ resolve(res);
529
+ })
530
+ .exec();
531
+ });
532
+ };
533
+
534
+ widget.on = function (type, listener) {
535
+ this._eventListeners.on(type, listener);
536
+ };
537
+
538
+ widget.off = function (type, listener) {
539
+ this._eventListeners.off(type, listener);
540
+ };
541
+
542
+ widget.getConfig = () => ({});
543
+
544
+ const lowcode = compLowcodes[widget.widgetType];
374
545
  if (lowcode) {
375
- const { index = {}, config } = lowcode
376
- const builtinProps = Object.keys(widget.$comp)
546
+ const { index = {}, config } = lowcode;
547
+ const builtinProps = Object.keys(widget.$comp);
377
548
 
378
- widget.getConfig = () => config
549
+ widget.getConfig = () => config;
379
550
 
380
551
  // #2 User defined APIs
381
- const { publicMethods = {} } = index
382
- Object.keys(publicMethods).map(name => {
383
- if (builtinProps.indexOf(name) > -1 ) {
384
- console.error(`Invalid publicMethod name(${name}) of Component(${widget.widgetType}), builtin name can't be used, please rename this method.`)
385
- return
552
+ const { publicMethods = {} } = index;
553
+ Object.keys(publicMethods).map((name) => {
554
+ if (builtinProps.indexOf(name) > -1) {
555
+ console.error(
556
+ `Invalid publicMethod name(${name}) of Component(${widget.widgetType}), builtin name can't be used, please rename this method.`,
557
+ );
558
+ return;
386
559
  }
387
- const method = publicMethods[name]
560
+ const method = publicMethods[name];
388
561
  if (method instanceof Function) {
389
- Object.defineProperty(widget, name, { value: method.bind(widget.$comp) })
390
- Object.defineProperty(widget.$comp, name, { value: method })
562
+ Object.defineProperty(widget, name, { value: method.bind(widget.$comp) });
563
+ Object.defineProperty(widget.$comp, name, { value: method });
391
564
  } else {
392
- console.error(`Component(${widget.widgetType}) method(${name}) is not a function.`)
565
+ console.error(`Component(${widget.widgetType}) method(${name}) is not a function.`);
393
566
  }
394
- })
567
+ });
395
568
  }
396
569
 
397
- widget._methods = {}
570
+ widget._methods = {};
398
571
  }
@@ -35,7 +35,7 @@ const behaviors = [<% if(formEvents) { %>'wx://form-field'<% } %>]
35
35
  const properties = {<% Object.entries(propDefs).filter(([prop,def])=>{
36
36
  return !!jsonSchemaType2jsClass[def.type]
37
37
  }).map(([prop, def])=> {%>
38
- <%= prop %>: {
38
+ "<%= prop %>": {
39
39
  type: <%= jsonSchemaType2jsClass[def.type] %>,<%if(def.extraTypes) { %>
40
40
  optionalTypes: [<%= def.extraTypes.split('|').map(t => jsonSchemaType2jsClass[t]).join(',') %>], <% }%>
41
41
  <%if(def.default != null) {%>value: <%= JSON.stringify(def.default) %><%}%>
@@ -52,7 +52,7 @@ const handler = {<% handlers.forEach(h => {%>
52
52
 
53
53
  const dataBinds = {<% Object.entries(dataBinds).map(([id, widgetBinds])=>{%>
54
54
  <%= id %>: { <% Object.entries(widgetBinds).map(([prop, expr]) => { %>
55
- <%= prop %>: function ($comp, lists, forItems, event, $context) {const $for=forItems; return (
55
+ "<%= prop %>": function ($comp, lists, forItems, event, $context) {const $for=forItems; return (
56
56
  <%= expr === '' ? 'undefined': expr %>
57
57
  ); },<% }) %>
58
58
  },<%}) %>
@@ -7,7 +7,6 @@ const {
7
7
  createStateDataSourceVar,
8
8
  generateParamsParser,
9
9
  EXTRA_API,
10
- DS_API,
11
10
  DS_SDK,
12
11
  } = WEDA_CLOUD_SDK
13
12
  const getAccessToken = auth.getAccessToken
@@ -18,7 +17,6 @@ export {
18
17
  generateParamsParser,
19
18
  EXTRA_API,
20
19
  CLOUD_SDK,
21
- DS_API,
22
20
  DS_SDK,
23
21
  setConfig,
24
22
  getAccessToken,
@@ -3,7 +3,8 @@
3
3
  "version": "1.0.8",
4
4
  "scripts": {},
5
5
  "dependencies": {
6
- "@cloudbase/weda-client": "^0.2.15",
6
+ "@cloudbase/weda-client": "0.2.18-alpha.1",
7
+ "@cloudbase/weda-cloud-sdk": "1.0.13",
7
8
  "@cloudbase/oauth": "0.1.1-alpha.5",
8
9
  "mobx": "^5.15.4",
9
10
  "lodash.get": "^4.4.2",
@@ -29,7 +29,7 @@ const evtListeners = {<% Object.entries(eventHanlders).map(([handlerName, listen
29
29
  }
30
30
  const dataBinds = {<% Object.entries(dataBinds).map(([id, widgetBinds])=>{%>
31
31
  <%= id %>: { <% Object.entries(widgetBinds).map(([prop, expr]) => { %>
32
- <%= prop %>: function ($page, lists, forItems, event, $context) {const $for = forItems; return (
32
+ "<%= prop %>": function ($page, lists, forItems, event, $context) {const $for = forItems; return (
33
33
  <%= expr === '' ? 'undefined': expr %>
34
34
  ); },<% }) %>
35
35
  },<%}) %>
@@ -10,7 +10,6 @@
10
10
  "@tcwd/weapps-sdk": "1.2.10",
11
11
  "@zxing/library": "^0.18.6",
12
12
  "@cloudbase/weda-client": "^0.2.4",
13
- "fastclick": "^1.0.6",
14
13
  "lodash": "^4.17.19",
15
14
  "mobx": "^5.15.4",
16
15
  "mobx-react-lite": "^2.0.7",
@@ -42,7 +41,7 @@
42
41
  "css-loader": "^5",
43
42
  "css-minimizer-webpack-plugin": "^1.2.0",
44
43
  "happypack": "^5.0.1",
45
- "dart-sass": "^1.24.0",
44
+ "sass": "^1.24.0",
46
45
  "postcss": "^8.3.6",
47
46
  "postcss-pxtorem": "^6.0.0",
48
47
  "postcss-loader": "^4.0.3",
@@ -225,7 +225,7 @@ module.exports = function (options) {
225
225
  {
226
226
  loader: 'sass-loader',
227
227
  options: {
228
- implementation: require('dart-sass'),
228
+ implementation: require('sass'),
229
229
  },
230
230
  },
231
231
  ],