@mybricks/to-code-taro 1.1.5 → 1.1.7

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 (126) hide show
  1. package/dist/cjs/core/mybricks/Subject.js +9 -5
  2. package/dist/cjs/core/mybricks/createJSHandle.js +43 -3
  3. package/dist/cjs/core/utils/comRefResolver.js +112 -0
  4. package/dist/cjs/core/utils/event.js +53 -0
  5. package/dist/cjs/core/utils/hooks.js +71 -29
  6. package/dist/cjs/core/utils/index.js +3 -0
  7. package/dist/cjs/core/utils/pageRouter.js +34 -11
  8. package/dist/cjs/core/utils/slots.js +55 -9
  9. package/dist/cjs/core/utils/tabbar.js +56 -0
  10. package/dist/cjs/core/utils/useContext.js +42 -2
  11. package/dist/cjs/core/utils/with.js +9 -34
  12. package/dist/cjs/generate/generateTaroProjectJson.js +3 -18
  13. package/dist/cjs/generate/utils/appConfig.d.ts +1 -1
  14. package/dist/cjs/generate/utils/appConfig.js +22 -12
  15. package/dist/cjs/generate/utils/commonDir.js +9 -0
  16. package/dist/cjs/generate/utils/customTabBar.d.ts +11 -0
  17. package/dist/cjs/generate/utils/customTabBar.js +73 -0
  18. package/dist/cjs/generate/utils/fileNode.d.ts +4 -0
  19. package/dist/cjs/generate/utils/fileNode.js +12 -2
  20. package/dist/cjs/handleCom.js +15 -16
  21. package/dist/cjs/handleGlobal.d.ts +1 -1
  22. package/dist/cjs/handleGlobal.js +6 -0
  23. package/dist/cjs/handleSlot.js +5 -10
  24. package/dist/cjs/processors/processScene.js +13 -1
  25. package/dist/cjs/processors/processSceneLogic.js +2 -6
  26. package/dist/cjs/taro-template.json +364 -66
  27. package/dist/cjs/toCodeTaro.d.ts +1 -2
  28. package/dist/cjs/utils/builder/buildResult.js +1 -2
  29. package/dist/cjs/utils/common/ImportManager.d.ts +7 -0
  30. package/dist/cjs/utils/common/ImportManager.js +19 -1
  31. package/dist/cjs/utils/logic/genJSModules.js +2 -2
  32. package/dist/cjs/utils/logic/handleProcess.js +59 -13
  33. package/dist/cjs/utils/templates/index.js +1 -1
  34. package/dist/cjs/utils/templates/renderManager.js +5 -5
  35. package/dist/cjs/utils/templates/scene.js +4 -4
  36. package/dist/esm/core/mybricks/Subject.js +11 -5
  37. package/dist/esm/core/mybricks/createJSHandle.js +55 -5
  38. package/dist/esm/core/utils/comRefResolver.js +134 -0
  39. package/dist/esm/core/utils/event.js +32 -0
  40. package/dist/esm/core/utils/hooks.js +109 -39
  41. package/dist/esm/core/utils/index.js +1 -0
  42. package/dist/esm/core/utils/pageRouter.js +56 -13
  43. package/dist/esm/core/utils/slots.js +78 -12
  44. package/dist/esm/core/utils/tabbar.js +47 -0
  45. package/dist/esm/core/utils/useContext.js +42 -2
  46. package/dist/esm/core/utils/with.js +19 -53
  47. package/dist/esm/generate/generateTaroProjectJson.js +2 -20
  48. package/dist/esm/generate/utils/appConfig.d.ts +1 -1
  49. package/dist/esm/generate/utils/appConfig.js +28 -9
  50. package/dist/esm/generate/utils/commonDir.js +13 -0
  51. package/dist/esm/generate/utils/customTabBar.d.ts +11 -0
  52. package/dist/esm/generate/utils/customTabBar.js +52 -0
  53. package/dist/esm/generate/utils/fileNode.d.ts +4 -0
  54. package/dist/esm/generate/utils/fileNode.js +13 -0
  55. package/dist/esm/handleCom.js +24 -21
  56. package/dist/esm/handleGlobal.d.ts +1 -1
  57. package/dist/esm/handleGlobal.js +6 -1
  58. package/dist/esm/handleSlot.js +7 -12
  59. package/dist/esm/processors/processScene.js +23 -3
  60. package/dist/esm/processors/processSceneLogic.js +3 -5
  61. package/dist/esm/taro-template.json +364 -66
  62. package/dist/esm/toCodeTaro.d.ts +1 -2
  63. package/dist/esm/toCodeTaro.js +1 -1
  64. package/dist/esm/utils/builder/buildResult.js +1 -2
  65. package/dist/esm/utils/common/ImportManager.d.ts +7 -0
  66. package/dist/esm/utils/common/ImportManager.js +42 -14
  67. package/dist/esm/utils/logic/genJSModules.js +2 -2
  68. package/dist/esm/utils/logic/handleProcess.js +73 -12
  69. package/dist/esm/utils/templates/index.js +1 -1
  70. package/dist/esm/utils/templates/renderManager.js +4 -7
  71. package/dist/esm/utils/templates/scene.js +2 -2
  72. package/package.json +1 -1
  73. package/dist/cjs/core/comlib/Index.js +0 -114
  74. package/dist/cjs/core/comlib/_AesEncode.js +0 -115
  75. package/dist/cjs/core/comlib/_BackTo.js +0 -80
  76. package/dist/cjs/core/comlib/_CallPhone.js +0 -58
  77. package/dist/cjs/core/comlib/_ChooseFile.js +0 -103
  78. package/dist/cjs/core/comlib/_ChooseMedia.js +0 -70
  79. package/dist/cjs/core/comlib/_Connector.js +0 -79
  80. package/dist/cjs/core/comlib/_ConnectorGlobalHeaders.js +0 -79
  81. package/dist/cjs/core/comlib/_Format.js +0 -123
  82. package/dist/cjs/core/comlib/_GetLocation.js +0 -60
  83. package/dist/cjs/core/comlib/_GetStorage.js +0 -68
  84. package/dist/cjs/core/comlib/_GetSystemInfo.js +0 -62
  85. package/dist/cjs/core/comlib/_Modal.js +0 -68
  86. package/dist/cjs/core/comlib/_OpenCamera.js +0 -73
  87. package/dist/cjs/core/comlib/_OpenPetalMap.js +0 -49
  88. package/dist/cjs/core/comlib/_OpenUrl.js +0 -62
  89. package/dist/cjs/core/comlib/_RemoveStorage.js +0 -68
  90. package/dist/cjs/core/comlib/_Router.js +0 -100
  91. package/dist/cjs/core/comlib/_ScanQrcode.js +0 -59
  92. package/dist/cjs/core/comlib/_SetStorage.js +0 -67
  93. package/dist/cjs/core/comlib/_Share.js +0 -58
  94. package/dist/cjs/core/comlib/_ShowToast.js +0 -69
  95. package/dist/cjs/core/comlib/_TextToSpeech.js +0 -120
  96. package/dist/cjs/core/comlib/_TimerDebounce.js +0 -72
  97. package/dist/cjs/core/comlib/_TimerDelay.js +0 -88
  98. package/dist/cjs/core/comlib/_TimerThrottle.js +0 -75
  99. package/dist/cjs/core/comlib/_Vibrate.js +0 -60
  100. package/dist/esm/core/comlib/Index.js +0 -39
  101. package/dist/esm/core/comlib/_AesEncode.js +0 -85
  102. package/dist/esm/core/comlib/_BackTo.js +0 -66
  103. package/dist/esm/core/comlib/_CallPhone.js +0 -30
  104. package/dist/esm/core/comlib/_ChooseFile.js +0 -81
  105. package/dist/esm/core/comlib/_ChooseMedia.js +0 -38
  106. package/dist/esm/core/comlib/_Connector.js +0 -77
  107. package/dist/esm/core/comlib/_ConnectorGlobalHeaders.js +0 -56
  108. package/dist/esm/core/comlib/_Format.js +0 -102
  109. package/dist/esm/core/comlib/_GetLocation.js +0 -26
  110. package/dist/esm/core/comlib/_GetStorage.js +0 -44
  111. package/dist/esm/core/comlib/_GetSystemInfo.js +0 -32
  112. package/dist/esm/core/comlib/_Modal.js +0 -51
  113. package/dist/esm/core/comlib/_OpenCamera.js +0 -44
  114. package/dist/esm/core/comlib/_OpenPetalMap.js +0 -28
  115. package/dist/esm/core/comlib/_OpenUrl.js +0 -36
  116. package/dist/esm/core/comlib/_RemoveStorage.js +0 -42
  117. package/dist/esm/core/comlib/_Router.js +0 -113
  118. package/dist/esm/core/comlib/_ScanQrcode.js +0 -26
  119. package/dist/esm/core/comlib/_SetStorage.js +0 -40
  120. package/dist/esm/core/comlib/_Share.js +0 -28
  121. package/dist/esm/core/comlib/_ShowToast.js +0 -45
  122. package/dist/esm/core/comlib/_TextToSpeech.js +0 -117
  123. package/dist/esm/core/comlib/_TimerDebounce.js +0 -66
  124. package/dist/esm/core/comlib/_TimerDelay.js +0 -79
  125. package/dist/esm/core/comlib/_TimerThrottle.js +0 -69
  126. package/dist/esm/core/comlib/_Vibrate.js +0 -34
@@ -64,10 +64,9 @@ export interface GeneratedFile {
64
64
  /** 当前页面/弹窗内用到的 JS 计算组件(用于生成 index.jsModules.ts) */
65
65
  jsModules?: import("./utils/context/collectJSModules").JSModule[];
66
66
  importManager: ImportManager;
67
- type: "normal" | "popup" | "module" | "global" | "extension-config" | "extension-api" | "extension-bus" | "abstractEventTypeDef" | "fx" | "api" | "connector-api" | "extension-event" | "jsModulesRuntime" | "tabBarConfig" | "customTabBar";
67
+ type: "normal" | "popup" | "module" | "global" | "extension-config" | "extension-api" | "extension-bus" | "abstractEventTypeDef" | "fx" | "api" | "rootConfig" | "connector-api" | "extension-event" | "jsModulesRuntime" | "tabBarConfig" | "customTabBar";
68
68
  meta?: ReturnType<typeof toCode>["scenes"][0]["scene"];
69
69
  name: string;
70
- tabBarConfig?: string;
71
70
  }
72
71
  /** 统一的生成结果结构 */
73
72
  export interface GenerationResult {
@@ -99,8 +99,7 @@ export const POPUP_MAP: Record<string, any> = {
99
99
  type: "tabBarConfig",
100
100
  content: globalTabBarConfig,
101
101
  importManager: new import_ImportManager.ImportManager(config),
102
- name: "tabBarConfig",
103
- tabBarConfig: globalTabBarConfig
102
+ name: "tabBarConfig"
104
103
  });
105
104
  files.push({
106
105
  type: "customTabBar",
@@ -14,6 +14,13 @@ export declare class ImportManager {
14
14
  dependencyNames: string[];
15
15
  importType: ImportType;
16
16
  }): void;
17
+ /**
18
+ * 获取 import 排序优先级
19
+ * 1. 第三方包(react, @tarojs 等)
20
+ * 2. 绝对路径别名(@/xxx)
21
+ * 3. 相对路径(./xxx, ../xxx)
22
+ */
23
+ private getImportPriority;
17
24
  /** 依赖解析为code */
18
25
  toCode(): string;
19
26
  }
@@ -53,10 +53,28 @@ var ImportManager = class {
53
53
  });
54
54
  }
55
55
  }
56
+ /**
57
+ * 获取 import 排序优先级
58
+ * 1. 第三方包(react, @tarojs 等)
59
+ * 2. 绝对路径别名(@/xxx)
60
+ * 3. 相对路径(./xxx, ../xxx)
61
+ */
62
+ getImportPriority(packageName) {
63
+ if (packageName.startsWith("./") || packageName.startsWith("../")) {
64
+ return 3;
65
+ }
66
+ if (packageName.startsWith("@/")) {
67
+ return 2;
68
+ }
69
+ return 1;
70
+ }
56
71
  /** 依赖解析为code */
57
72
  toCode() {
58
73
  const indent = (0, import_helper.indentation)(this._config.codeStyle.indent);
59
- return Object.entries(this._imports).reduce(
74
+ const sortedEntries = Object.entries(this._imports).sort(([a], [b]) => {
75
+ return this.getImportPriority(a) - this.getImportPriority(b);
76
+ });
77
+ return sortedEntries.reduce(
60
78
  (pre, [packageName, dependencies]) => {
61
79
  var _a;
62
80
  let defaultDependency = "";
@@ -83,7 +83,7 @@ var genScopedJSModules = (jsModules, importCreateJSHandleFrom, importRuntimeFrom
83
83
  import { createJSHandle } from "${importCreateJSHandleFrom}";
84
84
  import { _execJs } from "${importRuntimeFrom}";
85
85
 
86
- export const jsModules: Record<string, (props: any, appContext: any) => any> = {};
86
+ export const jsModules: Record<string, (props: any, appContext: any, handleKey?: string) => any> = {};
87
87
  `;
88
88
  jsModules.forEach((module2) => {
89
89
  const { id, title, transformCode } = module2;
@@ -100,7 +100,7 @@ export const jsModules: Record<string, (props: any, appContext: any) => any> = {
100
100
  `;
101
101
  code += `const _execJs_${id} = _execJs(js_${id});
102
102
  `;
103
- code += `jsModules.${id} = (props, appContext) => createJSHandle(_execJs_${id}, { props, appContext });
103
+ code += `jsModules.${id} = (props, appContext, handleKey) => createJSHandle(_execJs_${id}, { props, appContext }, handleKey);
104
104
  `;
105
105
  });
106
106
  code += `
@@ -29,7 +29,8 @@ var isJsCalculationComponent = (namespace) => {
29
29
  return namespace === "mybricks.taro._muilt-inputJs" || namespace === "mybricks.core-comlib.js-ai";
30
30
  };
31
31
  var isJsApiComponent = (namespace, rtType) => {
32
- return namespace.startsWith("mybricks.taro._") && (rtType == null ? void 0 : rtType.match(/^js/gi)) !== null;
32
+ const jsCompNamespace = ["mybricks.taro.", "mybricks.normal-pc."];
33
+ return jsCompNamespace.some((_namespace) => namespace.startsWith(_namespace)) && (rtType == null ? void 0 : rtType.match(/^js/gi)) !== null;
33
34
  };
34
35
  var handleProcess = (event, config) => {
35
36
  let code = "";
@@ -109,20 +110,25 @@ ${indent2}outputs: [${props.outputs.map((output) => `"${output}"`).join(", ")}],
109
110
  ${indent}}, appContext)
110
111
  `;
111
112
  });
113
+ const outputToInputPinMap = /* @__PURE__ */ new Map();
112
114
  process.nodesInvocation.forEach((props) => {
113
- var _a, _b, _c, _d;
115
+ var _a, _b, _c, _d, _e, _f, _g, _h;
114
116
  const { componentType, category, runType } = props;
115
- let nextValue = getNextValue(props, config, event);
117
+ const nextValue = getNextValue(props, config, event, outputToInputPinMap);
116
118
  const isSameScope = checkIsSameScope(event, props);
117
119
  const nextCode = getNextCode(props, config, isSameScope, event);
120
+ const inputPinId = props.id.replace(/[^a-zA-Z0-9_]/g, "_");
121
+ (_a = props.nextParam) == null ? void 0 : _a.forEach((np) => {
122
+ outputToInputPinMap.set(`${props.meta.id}_${np.id}`, inputPinId);
123
+ });
118
124
  if (code) {
119
125
  code += "\n";
120
126
  }
121
- const callTemplate = (_c = config.getCallTemplate) == null ? void 0 : _c.call(config, {
127
+ const callTemplate = (_d = config.getCallTemplate) == null ? void 0 : _d.call(config, {
122
128
  com: {
123
129
  ...props.meta,
124
130
  // 鸿蒙化:透传可能的场景 ID,增强识别能力
125
- sceneId: ((_b = (_a = props.meta.model) == null ? void 0 : _a.data) == null ? void 0 : _b._sceneId) || props.meta.id
131
+ sceneId: ((_c = (_b = props.meta.model) == null ? void 0 : _b.data) == null ? void 0 : _c._sceneId) || props.meta.id
126
132
  },
127
133
  pinId: props.id,
128
134
  args: nextValue
@@ -143,7 +149,7 @@ ${indent}${nextCode}${callTemplate.code}`;
143
149
  ${indent}${nextCode}this.${_sceneId}.${operateName}(${nextValue})`;
144
150
  } else if (category === "frameOutput") {
145
151
  const currentScene = config.getCurrentScene();
146
- const pinProxy = (_d = currentScene == null ? void 0 : currentScene.pinProxies) == null ? void 0 : _d[`${props.meta.id}-${props.id}`];
152
+ const pinProxy = (_e = currentScene == null ? void 0 : currentScene.pinProxies) == null ? void 0 : _e[`${props.meta.id}-${props.id}`];
147
153
  const method = (pinProxy == null ? void 0 : pinProxy.pinId) || props.id;
148
154
  const sceneId = (pinProxy == null ? void 0 : pinProxy.frameId) || (currentScene == null ? void 0 : currentScene.id);
149
155
  code += `${indent}/** ${props.meta.title} 输出 ${method} */
@@ -189,8 +195,24 @@ ${indent}${nextCode}this.$fxs.${props.meta.ioProxy.id}(${nextValue})`;
189
195
  }
190
196
  }
191
197
  } else {
192
- code += `${indent}/** 调用 ${props.meta.title} ${props.title} */
198
+ if (props.type === "frameOutput") {
199
+ const currentScene = config.getCurrentScene();
200
+ const parentComId = event.comId || ((_f = event.meta) == null ? void 0 : _f.parentComId);
201
+ const frameConEntry = Object.values(currentScene.cons || {}).flat().find((con) => {
202
+ if (con.type !== "frame" || con.pinId !== props.id)
203
+ return false;
204
+ if (parentComId && con.comId)
205
+ return con.comId === parentComId;
206
+ return true;
207
+ });
208
+ const comId = (frameConEntry == null ? void 0 : frameConEntry.comId) || props.meta.id;
209
+ const comTitle = ((_h = (_g = currentScene.coms) == null ? void 0 : _g[comId]) == null ? void 0 : _h.title) || props.meta.title || comId;
210
+ code += `${indent}/** 调用 ${comTitle} 的 ${props.title} */
211
+ ${indent}${nextCode}$outputs['${comId}'].${props.id}(${nextValue})`;
212
+ } else {
213
+ code += `${indent}/** 调用 ${props.meta.title} 的 ${props.title} */
193
214
  ${indent}${nextCode}this.${props.meta.id}.${props.id}(${nextValue})`;
215
+ }
194
216
  }
195
217
  });
196
218
  if (["fx", "extension-api", "extension-bus"].includes(event.type)) {
@@ -263,23 +285,29 @@ var getNextCode = (props, config, isSameScope, event) => {
263
285
  return "";
264
286
  }
265
287
  const componentNameWithId = getComponentNameWithId(props, config, event);
266
- return `const ${componentNameWithId}_result = `;
288
+ const pinId = props.id;
289
+ const sanitizedPinId = pinId.replace(/[^a-zA-Z0-9_]/g, "_");
290
+ return `const ${componentNameWithId}_${sanitizedPinId}_result: any = `;
267
291
  };
268
292
  function getFrameInputValueExpr(meta, config, event) {
269
- var _a, _b, _c;
293
+ var _a, _b, _c, _d;
270
294
  const scene = (_a = config.getCurrentScene) == null ? void 0 : _a.call(config);
271
295
  const inputPinId = ((_b = meta == null ? void 0 : meta.inputs) == null ? void 0 : _b[0]) || "getCurValue";
272
296
  const proxyKey = `${meta == null ? void 0 : meta.id}-${inputPinId}`;
273
297
  const pinProxy = (_c = scene == null ? void 0 : scene.pinValueProxies) == null ? void 0 : _c[proxyKey];
274
298
  const pinId = pinProxy == null ? void 0 : pinProxy.pinId;
275
299
  if (typeof pinId === "string" && pinId) {
300
+ const paramsMap = (_d = config.getParams) == null ? void 0 : _d.call(config);
301
+ if (paramsMap == null ? void 0 : paramsMap[pinId]) {
302
+ return paramsMap[pinId];
303
+ }
276
304
  return `params?.inputValues?.[${JSON.stringify(pinId)}]`;
277
305
  }
278
306
  }
279
- var getNextValue = (props, config, event) => {
307
+ var getNextValue = (props, config, event, outputToInputPinMap) => {
280
308
  const { paramSource } = props;
281
309
  const nextValue = paramSource.map((param) => {
282
- var _a, _b, _c, _d, _e;
310
+ var _a, _b, _c, _d, _e, _f, _g;
283
311
  if (param.type === "params") {
284
312
  const params = config.getParams();
285
313
  return params[param.id];
@@ -291,8 +319,18 @@ var getNextValue = (props, config, event) => {
291
319
  }
292
320
  const componentNameWithId = getComponentNameWithId(param, config, event);
293
321
  if ((_e = (_d = (_c = param.meta) == null ? void 0 : _c.def) == null ? void 0 : _d.namespace) == null ? void 0 : _e.includes(".var")) {
322
+ const key2 = `${(_f = param.meta) == null ? void 0 : _f.id}_${param.id}`;
323
+ const inputPinId2 = outputToInputPinMap == null ? void 0 : outputToInputPinMap.get(key2);
324
+ if (inputPinId2) {
325
+ return `${componentNameWithId}_${inputPinId2}_result`;
326
+ }
294
327
  return `${componentNameWithId}_result`;
295
328
  }
329
+ const key = `${(_g = param.meta) == null ? void 0 : _g.id}_${param.id}`;
330
+ const inputPinId = outputToInputPinMap == null ? void 0 : outputToInputPinMap.get(key);
331
+ if (inputPinId) {
332
+ return `${componentNameWithId}_${inputPinId}_result.${param.id}`;
333
+ }
296
334
  return `${componentNameWithId}_result.${param.id}`;
297
335
  });
298
336
  return nextValue.join(", ");
@@ -308,8 +346,16 @@ var getNextValueWithParam = (param, config, event) => {
308
346
  }
309
347
  const componentNameWithId = getComponentNameWithId(param, config, event);
310
348
  if ((_e = (_d = (_c = param.meta) == null ? void 0 : _c.def) == null ? void 0 : _d.namespace) == null ? void 0 : _e.includes(".var")) {
349
+ const connectId2 = param.connectId;
350
+ if (connectId2) {
351
+ return `${componentNameWithId}_${connectId2}_result`;
352
+ }
311
353
  return `${componentNameWithId}_result`;
312
354
  }
355
+ const connectId = param.connectId;
356
+ if (connectId) {
357
+ return `${componentNameWithId}_${connectId}_result.${param.id}`;
358
+ }
313
359
  return `${componentNameWithId}_result.${param.id}`;
314
360
  };
315
361
  var getCurrentProvider = (params, config) => {
@@ -348,7 +394,7 @@ ${indent2}data: ${(0, import_object.genObjectCode)(jsData, {
348
394
  })},` : "") + (props.inputs ? `
349
395
  ${indent2}inputs: [${props.inputs.map((input) => `"${input}"`).join(", ")}],` : "") + (props.outputs ? `
350
396
  ${indent2}outputs: [${props.outputs.map((output) => `"${output}"`).join(", ")}],` : "") + `
351
- ${indent}}, appContext)
397
+ ${indent}}, appContext, '${meta.id}')
352
398
  `;
353
399
  };
354
400
  var generateJsApiComponentCode = (params) => {
@@ -397,7 +443,7 @@ ${indent2} inputs: [${props.inputs.map((input) => `"${input}"`).join(", ")}],`
397
443
  ${indent2} outputs: [${props.outputs.map((output) => `"${output}"`).join(", ")}],` : "") + `
398
444
  ${indent2}},
399
445
  ${indent2}appContext
400
- ${indent}})
446
+ ${indent}}, '${meta.id}')
401
447
  `;
402
448
  };
403
449
  // Annotate the CommonJS export names for ESM import in node:
@@ -66,7 +66,7 @@ ${indent2}component={${componentName}}`;
66
66
  ui += `
67
67
  ${indent2}id='${meta.id}'`;
68
68
  ui += `
69
- ${indent2}className='${meta.id} mybricks_com'`;
69
+ ${indent2}className='mybricks_com ${meta.id}'`;
70
70
  if (meta.name) {
71
71
  ui += `
72
72
  ${indent2}name='${meta.name}'`;
@@ -58,6 +58,10 @@ var RenderManager = class {
58
58
  `;
59
59
  code += `${indent}${indent2}const { comRefs, $vars, $fxs, appContext } = useAppContext();
60
60
  `;
61
+ if (logicCode == null ? void 0 : logicCode.includes("$outputs")) {
62
+ code += `${indent}${indent2}const $outputs = comRefs.current.$outputs;
63
+ `;
64
+ }
61
65
  if (logicCode) {
62
66
  code += logicCode.split("\n").map((line) => `${indent}${line}`).join("\n") + "\n";
63
67
  }
@@ -99,7 +103,7 @@ var RenderManager = class {
99
103
  `;
100
104
  code += `${indent}${indent4}get inputs() { return comRefs.current['${child.id}'] },
101
105
  `;
102
- code += `${indent}${indent4}get outputs() { return outputs['${child.id}'] },
106
+ code += `${indent}${indent4}get outputs() { return comRefs.current.$outputs['${child.id}'] },
103
107
  `;
104
108
  code += `${indent}${indent4}jsx: ${varName},
105
109
  `;
@@ -117,11 +121,7 @@ var RenderManager = class {
117
121
  code += `${indent}${indent3}params?.wrap?.(descriptors)
118
122
  `;
119
123
  } else {
120
- code += `${indent}${indent3}<>
121
- `;
122
124
  code += modifiedRenderCode.split("\n").map((line) => `${indent}${indent2}${line}`).join("\n") + "\n";
123
- code += `${indent}${indent3}</>
124
- `;
125
125
  }
126
126
  code += `${indent}${indent2});
127
127
  `;
@@ -75,11 +75,11 @@ function ${componentName}() {
75
75
  ${combinedJsCode}
76
76
  return (
77
77
  <PageScopeContext.Provider value={pageScopeRef}>
78
- <>
79
- ${uiResult.split("\n").map((line) => ` ${line}`).join("\n")}
78
+ ` + (hasPopups ? ` <>
79
+ ` : "") + `${uiResult.split("\n").map((line) => ` ${line}`).join("\n")}
80
80
  ` + (hasPopups ? ` <PopupRenderer popupMap={POPUP_MAP} />
81
- ` : "") + ` </>
82
- </PageScopeContext.Provider>
81
+ ` : "") + (hasPopups ? ` </>
82
+ ` : "") + ` </PageScopeContext.Provider>
83
83
  );
84
84
  }
85
85
 
@@ -19,16 +19,22 @@ export var Subject = /*#__PURE__*/function () {
19
19
  _defineProperty(this, "_log", undefined);
20
20
  _defineProperty(this, "_empty", true);
21
21
  this._log = params.log;
22
+ this._subjectNextCache = {};
22
23
  return new Proxy(this, {
23
24
  get: function get(target, prop) {
24
25
  if (prop in target) {
25
26
  return target[prop];
26
27
  }
27
- var subjectNext = new SubjectNext(prop);
28
- target[SUBJECT_SUBSCRIBE](function (value, extra) {
29
- subjectNext[SUBJECT_NEXT](value, extra);
30
- });
31
- return subjectNext;
28
+
29
+ // 缓存 SubjectNext,避免重复访问同一属性时创建新实例和新订阅
30
+ if (!target._subjectNextCache[prop]) {
31
+ var subjectNext = new SubjectNext(prop);
32
+ target[SUBJECT_SUBSCRIBE](function (value, extra) {
33
+ subjectNext[SUBJECT_NEXT](value, extra);
34
+ });
35
+ target._subjectNextCache[prop] = subjectNext;
36
+ }
37
+ return target._subjectNextCache[prop];
32
38
  }
33
39
  });
34
40
  }
@@ -11,11 +11,40 @@ export var validateJsMultipleInputs = function validateJsMultipleInputs(input) {
11
11
  return input.match(/\./); // input.xxx 为多输入模式
12
12
  };
13
13
 
14
+ // 全局缓存,用于防抖/节流等需要保持状态的组件
15
+ var handleCache = new Map();
16
+
17
+ /** 尝试从缓存获取 exe,命中时重置输出 Subject 状态 */
18
+ var getFromCache = function getFromCache(handleKey) {
19
+ if (!handleKey || !handleCache.has(handleKey)) return null;
20
+ var cached = handleCache.get(handleKey);
21
+ if (cached._rels) {
22
+ Object.values(cached._rels).forEach(function (subject) {
23
+ var _subject$_observers, _subject$_observers$c;
24
+ (_subject$_observers = subject._observers) === null || _subject$_observers === void 0 || (_subject$_observers$c = _subject$_observers.clear) === null || _subject$_observers$c === void 0 || _subject$_observers$c.call(_subject$_observers);
25
+ subject._values = [];
26
+ subject._empty = true;
27
+ });
28
+ }
29
+ return cached;
30
+ };
31
+
32
+ /** 将 exe 存入缓存 */
33
+ var setToCache = function setToCache(handleKey, exe, rels, needsCache) {
34
+ exe._rels = rels;
35
+ if (handleKey && needsCache) {
36
+ handleCache.set(handleKey, exe);
37
+ }
38
+ };
39
+
14
40
  // JS
15
- export var createJSHandle = function createJSHandle(fn, options) {
16
- var controller;
41
+ export var createJSHandle = function createJSHandle(fn, options, handleKey) {
17
42
  var props = options.props,
18
43
  appContext = options.appContext;
44
+ var cached = getFromCache(handleKey);
45
+ if (cached) return cached;
46
+ var needsCache = fn.__useCache === true;
47
+ var controller;
19
48
  var inputs = new Proxy({}, {
20
49
  getOwnPropertyDescriptor: function getOwnPropertyDescriptor() {
21
50
  return {
@@ -61,13 +90,23 @@ export var createJSHandle = function createJSHandle(fn, options) {
61
90
  appContext: appContext
62
91
  });
63
92
  var isJsMultipleInputs = props.inputs[0] ? validateJsMultipleInputs(props.inputs[0]) : false;
93
+
94
+ // 缓存 exeOutputs 的属性访问结果,避免每次访问 .trigger 等属性时创建新的 SubjectNext
95
+ var exeOutputsCache = {};
64
96
  var exeOutputs = new Proxy({}, {
65
97
  get: function get(_, key) {
66
- return rels[key] || (rels[key] = new Subject({
67
- log: "".concat(EXE_TITLE_MAP["output"], " ").concat(props.title, " | ").concat(key)
68
- }));
98
+ if (!exeOutputsCache[key]) {
99
+ var subject = rels[key] || (rels[key] = new Subject({
100
+ log: "".concat(EXE_TITLE_MAP["output"], " ").concat(props.title, " | ").concat(key)
101
+ }));
102
+ exeOutputsCache[key] = subject;
103
+ }
104
+ return exeOutputsCache[key];
69
105
  }
70
106
  });
107
+
108
+ // 记录已订阅的 Subject,避免重复订阅
109
+ var subscribedSubjects = new Set();
71
110
  var exe = function exe() {
72
111
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
73
112
  args[_key] = arguments[_key];
@@ -80,6 +119,11 @@ export var createJSHandle = function createJSHandle(fn, options) {
80
119
  var valueAry = {};
81
120
  args.forEach(function (value, index) {
82
121
  if (value !== null && value !== void 0 && value[SUBJECT_SUBSCRIBE]) {
122
+ // 如果已经订阅过这个 Subject,跳过
123
+ if (subscribedSubjects.has(value)) {
124
+ return;
125
+ }
126
+ subscribedSubjects.add(value);
83
127
  value[SUBJECT_SUBSCRIBE](function (value) {
84
128
  log("".concat(EXE_TITLE_MAP["input"], " ").concat(props.title, " | ").concat(props.inputs[index]), JSON.stringify(value));
85
129
  valueAry[props.inputs[index]] = value;
@@ -113,6 +157,11 @@ export var createJSHandle = function createJSHandle(fn, options) {
113
157
  // 非多输入
114
158
  var value = args[0];
115
159
  if (value !== null && value !== void 0 && value[SUBJECT_SUBSCRIBE]) {
160
+ // 如果已经订阅过这个 Subject,跳过
161
+ if (subscribedSubjects.has(value)) {
162
+ return exeOutputs;
163
+ }
164
+ subscribedSubjects.add(value);
116
165
  value[SUBJECT_SUBSCRIBE](function (value) {
117
166
  log("".concat(EXE_TITLE_MAP["input"], " ").concat(props.title, " | ").concat(props.inputs[0]), JSON.stringify(value));
118
167
  createReactiveInputHandler({
@@ -135,5 +184,6 @@ export var createJSHandle = function createJSHandle(fn, options) {
135
184
  }
136
185
  return exeOutputs;
137
186
  };
187
+ setToCache(handleKey, exe, rels, needsCache);
138
188
  return exe;
139
189
  };
@@ -0,0 +1,134 @@
1
+ import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
2
+ import _createClass from "@babel/runtime/helpers/esm/createClass";
3
+ import { TodoPool } from "./pool";
4
+
5
+ /**
6
+ * 组件引用解析器
7
+ *
8
+ * 职责单一:管理组件引用的查找、创建和注册
9
+ *
10
+ * 核心机制:
11
+ * 1. 查找真实引用时,优先本地,再查父级
12
+ * 2. 未找到时创建影子对象,影子对象调用时会动态查找真实引用
13
+ * 3. 注册真实引用时,向上渗透到父级
14
+ */
15
+ export var ComRefResolver = /*#__PURE__*/function () {
16
+ function ComRefResolver(registry, parent, todoPool) {
17
+ var scopeIndex = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
18
+ _classCallCheck(this, ComRefResolver);
19
+ this.registry = registry;
20
+ this.parent = parent;
21
+ this.todoPool = todoPool;
22
+ this.scopeIndex = scopeIndex;
23
+ }
24
+
25
+ /**
26
+ * 获取组件引用
27
+ * @returns 真实引用或影子对象
28
+ */
29
+ _createClass(ComRefResolver, [{
30
+ key: "get",
31
+ value: function get(id) {
32
+ var _this$parent, _this$registry$id;
33
+ // 1. 优先检查本地是否有真实引用
34
+ if (this.registry[id] && !this.registry[id].__isShadow) {
35
+ return this.registry[id];
36
+ }
37
+
38
+ // 2. 检查父级是否有真实引用
39
+ var parentRef = (_this$parent = this.parent) === null || _this$parent === void 0 ? void 0 : _this$parent.findRealRef(id);
40
+ if (parentRef) {
41
+ return parentRef;
42
+ }
43
+
44
+ // 3. 如果已有影子对象,直接返回
45
+ if ((_this$registry$id = this.registry[id]) !== null && _this$registry$id !== void 0 && _this$registry$id.__isShadow) {
46
+ return this.registry[id];
47
+ }
48
+
49
+ // 4. 创建影子对象
50
+ return this.createShadowProxy(id);
51
+ }
52
+
53
+ /**
54
+ * 注册真实引用
55
+ */
56
+ }, {
57
+ key: "set",
58
+ value: function set(id, ref) {
59
+ var _this$parent2;
60
+ this.registry[id] = ref;
61
+ // 向上渗透到父级
62
+ (_this$parent2 = this.parent) === null || _this$parent2 === void 0 || _this$parent2.set(id, ref);
63
+ }
64
+
65
+ /**
66
+ * 删除引用
67
+ */
68
+ }, {
69
+ key: "delete",
70
+ value: function _delete(id) {
71
+ var _this$parent3;
72
+ delete this.registry[id];
73
+ (_this$parent3 = this.parent) === null || _this$parent3 === void 0 || _this$parent3.delete(id);
74
+ }
75
+
76
+ /**
77
+ * 查找真实引用(仅用于父级链查找)
78
+ */
79
+ }, {
80
+ key: "findRealRef",
81
+ value: function findRealRef(id) {
82
+ var _this$parent$findReal, _this$parent4;
83
+ var local = this.registry[id];
84
+ if (local && !local.__isShadow) {
85
+ return local;
86
+ }
87
+ return (_this$parent$findReal = (_this$parent4 = this.parent) === null || _this$parent4 === void 0 ? void 0 : _this$parent4.findRealRef(id)) !== null && _this$parent$findReal !== void 0 ? _this$parent$findReal : null;
88
+ }
89
+
90
+ /**
91
+ * 创建影子对象
92
+ * 关键:影子对象的方法被调用时,会动态查找真实引用
93
+ */
94
+ }, {
95
+ key: "createShadowProxy",
96
+ value: function createShadowProxy(id) {
97
+ var resolver = this;
98
+ var registry = this.registry;
99
+ var todoPool = this.todoPool;
100
+ var scopeIndex = this.scopeIndex;
101
+ var shadow = new Proxy({
102
+ __isShadow: true
103
+ }, {
104
+ get: function get(_, method) {
105
+ if (method === '__isShadow') return true;
106
+ return function () {
107
+ // 动态检查是否已有真实引用
108
+ // 注意:这里直接检查 registry[id],因为真实引用注册时会覆盖它
109
+ var realRef = registry[id];
110
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
111
+ args[_key] = arguments[_key];
112
+ }
113
+ if (realRef && !realRef.__isShadow) {
114
+ if (typeof realRef[method] === 'function') {
115
+ return realRef[method].apply(realRef, args);
116
+ }
117
+ return;
118
+ }
119
+
120
+ // 未找到真实引用,缓冲到 TodoPool
121
+ if (todoPool instanceof TodoPool) {
122
+ todoPool.push(id, scopeIndex, method, args);
123
+ }
124
+ };
125
+ }
126
+ });
127
+
128
+ // 存储影子对象
129
+ this.registry[id] = shadow;
130
+ return shadow;
131
+ }
132
+ }]);
133
+ return ComRefResolver;
134
+ }();
@@ -0,0 +1,32 @@
1
+ import _createClass from "@babel/runtime/helpers/esm/createClass";
2
+ import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
3
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
4
+ export var EventEmitter = /*#__PURE__*/_createClass(function EventEmitter() {
5
+ var _this = this;
6
+ _classCallCheck(this, EventEmitter);
7
+ _defineProperty(this, "eventsCache", {});
8
+ _defineProperty(this, "addEventListner", function (evtName, listner) {
9
+ if (!_this.eventsCache[evtName]) {
10
+ _this.eventsCache[evtName] = new Set([listner]);
11
+ return;
12
+ }
13
+ _this.eventsCache[evtName].add(listner);
14
+ });
15
+ _defineProperty(this, "removeEventListner", function (evtName, listner) {
16
+ if (_this.eventsCache[evtName]) {
17
+ _this.eventsCache[evtName].delete(listner);
18
+ }
19
+ });
20
+ _defineProperty(this, "dispatch", function (evtName, detail) {
21
+ var _this$eventsCache$evt;
22
+ if (!_this.eventsCache[evtName]) {
23
+ // console.warn(`no listner on this ${evtName}`);
24
+ return;
25
+ }
26
+ var hasPreventDefault = false;
27
+ ((_this$eventsCache$evt = _this.eventsCache[evtName]) !== null && _this$eventsCache$evt !== void 0 ? _this$eventsCache$evt : []).forEach(function (listner) {
28
+ return listner(detail);
29
+ });
30
+ return hasPreventDefault;
31
+ });
32
+ });