android2harmony 0.1.6 → 0.1.8

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 (227) hide show
  1. package/agents/api-analyzer.md +113 -0
  2. package/agents/app-action.md +122 -0
  3. package/agents/code-reviewer.md +191 -295
  4. package/agents/coder.md +377 -0
  5. package/agents/self-tester.md +8 -8
  6. package/agents/spec-designer.md +56 -0
  7. package/package.json +1 -1
  8. package/skills/a2h-app-req-gen/SKILL.md +174 -0
  9. package/skills/a2h-app-req-gen/references/spec-handoff.md +99 -0
  10. package/skills/a2h-app-req-gen/references/subagent-render.md +115 -0
  11. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/build.gradle.kts +41 -0
  12. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradle/wrapper/gradle-wrapper.jar +0 -0
  13. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradle/wrapper/gradle-wrapper.properties +8 -0
  14. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradle.properties +3 -0
  15. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradlew +251 -0
  16. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradlew.bat +94 -0
  17. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/settings.gradle.kts +17 -0
  18. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawAnalysisDetector.java +1911 -0
  19. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawIssueRegistry.java +37 -0
  20. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawJson.java +146 -0
  21. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawLocation.java +96 -0
  22. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawRecordWriter.java +227 -0
  23. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry +1 -0
  24. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/resources/dev/reqgen/analyzer/jvm/raw-record-v1.schema.json +93 -0
  25. package/skills/a2h-app-req-gen/scripts/reqgen/assets/dashboard.html +151 -0
  26. package/skills/a2h-app-req-gen/scripts/reqgen/gradle/reqgen-lint.init.gradle +60 -0
  27. package/skills/a2h-app-req-gen/scripts/reqgen/gradle/reqgen-model.init.gradle +204 -0
  28. package/skills/a2h-app-req-gen/scripts/reqgen/package.json +14 -0
  29. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/backend.js +323 -0
  30. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/cli.js +811 -0
  31. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/gap-audit-link.js +62 -0
  32. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/index.js +66 -0
  33. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/merge.js +605 -0
  34. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/name-trace.js +153 -0
  35. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/orchestrate.js +1324 -0
  36. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/output-parse.js +50 -0
  37. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/overview.js +10 -0
  38. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/pool.js +23 -0
  39. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/post-merge-fix.js +146 -0
  40. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/prompt-loader.js +51 -0
  41. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/prompt.js +967 -0
  42. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/prompts.md +301 -0
  43. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/serve.js +78 -0
  44. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/short-id.js +46 -0
  45. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/snapshot.js +267 -0
  46. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/types.js +1 -0
  47. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/validate.js +122 -0
  48. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/callback-call-sites.js +62 -0
  49. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/gap-audit/build.js +1291 -0
  50. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/gap-audit/index.js +1 -0
  51. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/area-ownership.js +392 -0
  52. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/build.js +1995 -0
  53. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/callback-flow.js +277 -0
  54. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/component-variants.js +725 -0
  55. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/index.js +15 -0
  56. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/names/index.js +12 -0
  57. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/names/policy.js +469 -0
  58. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/names/traceability.js +468 -0
  59. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/req-model/build.js +1066 -0
  60. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/req-model/index.js +1 -0
  61. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/android-interaction-registry.js +174 -0
  62. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/android.js +1062 -0
  63. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/area-titles.js +678 -0
  64. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/builder.js +350 -0
  65. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/compose-api-registry.js +395 -0
  66. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/compose-call-sites.js +2008 -0
  67. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/compose.js +9059 -0
  68. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/dynamic-repeated-call-sites.js +529 -0
  69. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/index.js +1 -0
  70. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/interaction-effects.js +1149 -0
  71. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/jvm.js +6272 -0
  72. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/normalize.js +33 -0
  73. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/pending-intents.js +565 -0
  74. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/resource-id.js +42 -0
  75. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/route-state-variants.js +781 -0
  76. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/state.js +234 -0
  77. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/types.js +1 -0
  78. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/extract.js +40 -0
  79. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/index.js +6 -0
  80. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/manifest.js +513 -0
  81. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/resources.js +398 -0
  82. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/types.js +1 -0
  83. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/views.js +447 -0
  84. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/xml-parser.js +175 -0
  85. package/skills/a2h-app-req-gen/scripts/reqgen/src/cli.js +398 -0
  86. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/area-graph.js +1 -0
  87. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/artifact.js +1 -0
  88. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/common.js +16 -0
  89. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/diagnostic.js +10 -0
  90. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/gap-audit.js +14 -0
  91. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/index.js +11 -0
  92. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/name-traceability.js +26 -0
  93. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/raw-fact.js +40 -0
  94. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/req-model.js +1 -0
  95. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/run.js +19 -0
  96. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/semantic-completeness.js +11 -0
  97. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/source-facts.js +1 -0
  98. package/skills/a2h-app-req-gen/scripts/reqgen/src/core/output-guard.js +41 -0
  99. package/skills/a2h-app-req-gen/scripts/reqgen/src/core/stable-id.js +92 -0
  100. package/skills/a2h-app-req-gen/scripts/reqgen/src/dashboard-cli.js +169 -0
  101. package/skills/a2h-app-req-gen/scripts/reqgen/src/diagnostics.js +104 -0
  102. package/skills/a2h-app-req-gen/scripts/reqgen/src/dump/dump.js +1028 -0
  103. package/skills/a2h-app-req-gen/scripts/reqgen/src/dump/index.js +1 -0
  104. package/skills/a2h-app-req-gen/scripts/reqgen/src/dump-cli.js +251 -0
  105. package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/artifacts.js +49 -0
  106. package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/index.js +18 -0
  107. package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/quality-report.js +125 -0
  108. package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/render.js +353 -0
  109. package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/types.js +2 -0
  110. package/skills/a2h-app-req-gen/scripts/reqgen/src/graph/paths.js +474 -0
  111. package/skills/a2h-app-req-gen/scripts/reqgen/src/jvm/index.js +15 -0
  112. package/skills/a2h-app-req-gen/scripts/reqgen/src/jvm/protocol.js +408 -0
  113. package/skills/a2h-app-req-gen/scripts/reqgen/src/jvm/runner.js +452 -0
  114. package/skills/a2h-app-req-gen/scripts/reqgen/src/pipeline/index.js +8 -0
  115. package/skills/a2h-app-req-gen/scripts/reqgen/src/pipeline/output.js +165 -0
  116. package/skills/a2h-app-req-gen/scripts/reqgen/src/pipeline/run-stage1.js +891 -0
  117. package/skills/a2h-app-req-gen/scripts/reqgen/src/project/discovery.js +299 -0
  118. package/skills/a2h-app-req-gen/scripts/reqgen/src/project/gradle-model.js +358 -0
  119. package/skills/a2h-app-req-gen/scripts/reqgen/src/project/gradle-runner.js +165 -0
  120. package/skills/a2h-app-req-gen/scripts/reqgen/src/project/resource-profile.js +60 -0
  121. package/skills/a2h-app-req-gen/scripts/reqgen/src/project/types.js +1 -0
  122. package/skills/a2h-app-req-gen/scripts/reqgen/src/spec-handoff-cli.js +151 -0
  123. package/skills/a2h-app-req-gen/scripts/reqgen/src/spec-handoff.js +1004 -0
  124. package/skills/a2h-app-req-gen/scripts/reqgen/src/stage2-cli.js +109 -0
  125. package/skills/a2h-app-req-gen/scripts/reqgen/src/stage2-input.js +419 -0
  126. package/skills/a2h-app-req-gen/scripts/reqgen/src/stage2-name-trace-input.js +95 -0
  127. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/area-graph.js +444 -0
  128. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/index.js +7 -0
  129. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/req-model.js +580 -0
  130. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/req-text.js +195 -0
  131. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/semantic-area-graph.js +1431 -0
  132. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/types.js +1 -0
  133. package/skills/a2h-app-req-gen/scripts/reqgen-audit.mjs +298 -0
  134. package/skills/a2h-app-req-gen/scripts/reqgen-selfcheck.mjs +555 -0
  135. package/skills/a2h-code-review/SKILL.md +379 -0
  136. package/skills/{hmos-integration-test → a2h-integration-test}/README.md +6 -6
  137. package/skills/{hmos-integration-test → a2h-integration-test}/SKILL.md +6 -6
  138. package/skills/{hmos-integration-test → a2h-integration-test}/scripts/report-tool.mjs +1 -1
  139. package/skills/a2h-spec-design/SKILL.md +330 -0
  140. package/skills/a2h-spec-design/scripts/inspect_spec_design_inputs.mjs +207 -0
  141. package/skills/a2h-spec-design/scripts/move_spec_technical_reference.mjs +198 -0
  142. package/skills/a2h-spec-design/scripts/validate_spec_design_output.mjs +256 -0
  143. package/skills/a2h-spec-generate/SKILL.md +696 -0
  144. package/skills/a2h-spec-generate/references/trace-template.md +115 -0
  145. package/skills/a2h-spec-generate/scripts/parse_requirements.mjs +537 -0
  146. package/skills/a2h-spec-generate/template/REQ.txt +22 -0
  147. package/skills/a2h-spec-generate/template/REQ.xlsx +0 -0
  148. package/skills/a2h-spec-implement/SKILL.md +548 -0
  149. package/skills/a2h-spec-implement/references/harmony-pitfalls.md +186 -0
  150. package/skills/a2h-spec-implement/references/l1-unit-test.md +185 -0
  151. package/skills/a2h-spec-implement/references/l3-e2e-uitest.md +167 -0
  152. package/skills/a2h-spec-implement/references/test-core.md +132 -0
  153. package/skills/a2h-spec-implement/rules/arkts/arkts-standards.md +184 -0
  154. package/skills/a2h-spec-implement/rules/arkts/conventions/coding-style.md +96 -0
  155. package/skills/a2h-spec-implement/rules/arkts/conventions/security.md +126 -0
  156. package/skills/a2h-spec-implement/rules/arkts/language/arkts-rules.md +650 -0
  157. package/skills/a2h-spec-implement/rules/arkts/language/arkui-structure-rules.md +173 -0
  158. package/skills/a2h-spec-implement/rules/arkts/language/ts-to-arkts-rewrites.md +58 -0
  159. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@Link/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/217/214/345/220/221/345/220/214/346/255/245.md +648 -0
  160. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@Observed/350/243/205/351/245/260/345/231/250/345/222/214@ObjectLink/350/243/205/351/245/260/345/231/250/357/274/232/345/265/214/345/245/227/347/261/273/345/257/271/350/261/241/345/261/236/346/200/247/345/217/230/345/214/226.md +2089 -0
  161. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@Prop/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/215/225/345/220/221/345/220/214/346/255/245.md +1033 -0
  162. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@Provide/350/243/205/351/245/260/345/231/250/345/222/214@Consume/350/243/205/351/245/260/345/231/250/357/274/232/344/270/216/345/220/216/344/273/243/347/273/204/344/273/266/345/217/214/345/220/221/345/220/214/346/255/245.md +1183 -0
  163. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@State/350/243/205/351/245/260/345/231/250/357/274/232/347/273/204/344/273/266/345/206/205/347/212/266/346/200/201.md +576 -0
  164. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@Track/350/243/205/351/245/260/345/231/250/357/274/232class/345/257/271/350/261/241/345/261/236/346/200/247/347/272/247/346/233/264/346/226/260.md +297 -0
  165. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@Watch/350/243/205/351/245/260/345/231/250/357/274/232/347/212/266/346/200/201/345/217/230/351/207/217/346/233/264/346/224/271/351/200/232/347/237/245.md +395 -0
  166. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/AppStorage/357/274/232/345/272/224/347/224/250/345/205/250/345/261/200/347/232/204UI/347/212/266/346/200/201/345/255/230/345/202/250.md +903 -0
  167. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/Environment/357/274/232/350/256/276/345/244/207/347/216/257/345/242/203/346/237/245/350/257/242.md +106 -0
  168. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/LocalStorage/357/274/232/351/241/265/351/235/242/347/272/247UI/347/212/266/346/200/201/345/255/230/345/202/250.md +1178 -0
  169. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/MVVM/346/250/241/345/274/217/357/274/210V1/357/274/211.md +911 -0
  170. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/PersistentStorage/357/274/232/346/214/201/344/271/205/345/214/226/345/255/230/345/202/250UI/347/212/266/346/200/201.md +355 -0
  171. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1//347/256/241/347/220/206/345/272/224/347/224/250/346/213/245/346/234/211/347/232/204/347/212/266/346/200/201/346/246/202/350/277/260.md +11 -0
  172. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/!!/350/257/255/346/263/225/357/274/232/345/217/214/345/220/221/347/273/221/345/256/232.md +216 -0
  173. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Computed/350/243/205/351/245/260/345/231/250/357/274/232/350/256/241/347/256/227/345/261/236/346/200/247.md +442 -0
  174. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Event/350/243/205/351/245/260/345/231/250/357/274/232/350/247/204/350/214/203/347/273/204/344/273/266/350/276/223/345/207/272.md +169 -0
  175. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Local/350/243/205/351/245/260/345/231/250/357/274/232/347/273/204/344/273/266/345/206/205/351/203/250/347/212/266/346/200/201.md +763 -0
  176. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Monitor/350/243/205/351/245/260/345/231/250/357/274/232/347/212/266/346/200/201/345/217/230/351/207/217/344/277/256/346/224/271/345/274/202/346/255/245/347/233/221/345/220/254.md +2088 -0
  177. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@ObservedV2/350/243/205/351/245/260/345/231/250/345/222/214@Trace/350/243/205/351/245/260/345/231/250/357/274/232/347/261/273/345/261/236/346/200/247/345/217/230/345/214/226/350/247/202/346/265/213.md +1258 -0
  178. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Once/357/274/232/345/210/235/345/247/213/345/214/226/345/220/214/346/255/245/344/270/200/346/254/241.md +175 -0
  179. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Param/357/274/232/347/273/204/344/273/266/345/244/226/351/203/250/350/276/223/345/205/245.md +850 -0
  180. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Provider/350/243/205/351/245/260/345/231/250/345/222/214@Consumer/350/243/205/351/245/260/345/231/250/357/274/232/350/267/250/347/273/204/344/273/266/345/261/202/347/272/247/345/217/214/345/220/221/345/220/214/346/255/245.md +862 -0
  181. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Type/350/243/205/351/245/260/345/231/250/357/274/232/346/240/207/350/256/260/347/261/273/345/261/236/346/200/247/347/232/204/347/261/273/345/236/213.md +110 -0
  182. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/AppStorageV2/357/274/232/345/272/224/347/224/250/345/205/250/345/261/200UI/347/212/266/346/200/201/345/255/230/345/202/250.md +301 -0
  183. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/MVVM/346/250/241/345/274/217/357/274/210V2/357/274/211.md +1411 -0
  184. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/PersistenceV2/357/274/232/346/214/201/344/271/205/345/214/226/345/255/230/345/202/250UI/347/212/266/346/200/201.md +1392 -0
  185. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/getTarget/346/216/245/345/217/243/357/274/232/350/216/267/345/217/226/347/212/266/346/200/201/347/256/241/347/220/206/346/241/206/346/236/266/344/273/243/347/220/206/345/211/215/347/232/204/345/216/237/345/247/213/345/257/271/350/261/241.md +288 -0
  186. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/makeObserved/346/216/245/345/217/243/357/274/232/345/260/206/351/235/236/350/247/202/345/257/237/346/225/260/346/215/256/345/217/230/344/270/272/345/217/257/350/247/202/345/257/237/346/225/260/346/215/256.md +768 -0
  187. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2//347/212/266/346/200/201/347/256/241/347/220/206V1/345/222/214V2/346/267/267/347/224/250/346/214/207/345/257/274/357/274/210API version 19/345/217/212/344/271/213/345/220/216/357/274/211.md" +829 -0
  188. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2//347/212/266/346/200/201/347/256/241/347/220/206/346/246/202/350/277/260.md +184 -0
  189. package/skills/a2h-spec-implement/rules/arkts/ui/component-cookbook.md +431 -0
  190. package/skills/a2h-spec-implement/rules/arkts/ui/state-management.md +152 -0
  191. package/skills/a2h-spec-implement/rules/arkts/ui/ui-quality.md +67 -0
  192. package/skills/a2h-spec-implement/rules/arkts/ui/ui-runtime-diagnosis.md +32 -0
  193. package/skills/a2h-spec-implement/rules/pipeline/build/package-set-collection.md +43 -0
  194. package/skills/a2h-spec-implement/scripts/_lib/common.mjs +97 -0
  195. package/skills/a2h-spec-implement/scripts/_lib/config.mjs +70 -0
  196. package/skills/a2h-spec-implement/scripts/_lib/lessons_cli.mjs +48 -0
  197. package/skills/a2h-spec-implement/scripts/build_lessons.mjs +24 -0
  198. package/skills/a2h-spec-implement/scripts/code_pattern_lessons.mjs +26 -0
  199. package/skills/a2h-spec-implement/scripts/device_ui.mjs +433 -0
  200. package/skills/a2h-spec-implement/scripts/device_ui_core.mjs +895 -0
  201. package/skills/a2h-spec-implement/scripts/ledger/aggregate_run.mjs +207 -0
  202. package/skills/a2h-spec-implement/scripts/manifest/emit_summary_line.mjs +37 -0
  203. package/skills/a2h-spec-implement/scripts/manifest/finalize_run.mjs +115 -0
  204. package/skills/a2h-spec-implement/scripts/manifest/render_final_summary.mjs +78 -0
  205. package/skills/a2h-spec-implement/scripts/manifest/root_mirror.mjs +137 -0
  206. package/skills/a2h-spec-implement/scripts/package.json +12 -0
  207. package/skills/a2h-spec-implement/scripts/state_propagation_check.mjs +676 -0
  208. package/skills/a2h-spec-implement/scripts/test/l2_run.mjs +244 -0
  209. package/skills/a2h-spec-implement/scripts/test/tp_coverage.mjs +231 -0
  210. package/skills/a2h-spec-implement/scripts/ui_memory.mjs +161 -0
  211. package/skills/a2h-spec-implement/scripts/utils/ensure_app.mjs +134 -0
  212. package/skills/a2h-ui-transfer/SKILL.md +20 -9
  213. package/skills/a2h-ui-transfer/scripts/arkts_static_check.js +80 -0
  214. package/skills/hmos-convert-pipeline/SKILL.md +7 -5
  215. package/skills/hmos-incremental-ui-align/README.md +7 -7
  216. package/skills/hmos-incremental-ui-align/SKILL.md +1 -1
  217. package/skills/hmos-incremental-ui-align/page_align.md +1 -1
  218. package/skills/hmos-spec-generate/SKILL.md +2 -2
  219. package/skills/hmos-spec-generate/scripts/parse_requirements.mjs +537 -0
  220. package/skills/hmos-fix-build-errors/SKILL.md +0 -266
  221. package/skills/hmos-fix-build-errors/references/arkts-strict-patterns.md +0 -219
  222. package/skills/hmos-fix-build-errors/references/known-patterns.md +0 -157
  223. package/skills/hmos-fix-build-errors/references/rdb-entity-pattern.md +0 -131
  224. package/skills/hmos-spec-generate/scripts/parse_requirements.ts +0 -515
  225. /package/skills/{hmos-integration-test → a2h-integration-test}/scripts/resolve-metadata-tool.mjs +0 -0
  226. /package/skills/{hmos-integration-test → a2h-integration-test}/scripts/self-test-runner.mjs +0 -0
  227. /package/skills/{hmos-integration-test → a2h-integration-test}/scripts/testcases-tool.mjs +0 -0
@@ -0,0 +1,768 @@
1
+ # makeObserved接口:将非观察数据变为可观察数据
2
+ <!--Kit: ArkUI-->
3
+ <!--Subsystem: ArkUI-->
4
+ <!--Owner: @liwenzhen3-->
5
+ <!--Designer: @zhangboren-->
6
+ <!--Tester: @TerryTsao-->
7
+ <!--Adviser: @zhang_yixin13-->
8
+
9
+ 为了将普通不可观察数据变为可观察数据,开发者可以使用[makeObserved接口](../../reference/apis-arkui/js-apis-stateManagement.md#makeobserved)。
10
+
11
+
12
+ makeObserved可以在\@Trace无法标记的情况下使用。在阅读本文档前,建议提前阅读:[\@Trace](./arkts-new-observedV2-and-trace.md)。
13
+
14
+ >**说明:**
15
+ >
16
+ >从API version 12开始,开发者可以使用UIUtils中的makeObserved接口将普通不可观察数据变为可观察数据。
17
+
18
+ ## 概述
19
+
20
+ - 状态管理框架已提供[@ObservedV2/@Trace](./arkts-new-observedV2-and-trace.md)用于观察类属性变化,makeObserved接口提供主要应用于@ObservedV2/@Trace无法涵盖的场景:
21
+
22
+ - class的定义在三方包中:开发者无法手动对class中需要观察的属性加上@Trace标签,可以使用makeObserved使得当前对象可以被观察。
23
+
24
+ - 当前类的成员属性不能被修改:因为@Trace观察类属性会动态修改类的属性,这个行为在[@Sendable](../../arkts-utils/arkts-sendable.md#sendable装饰器)装饰的class中是不被允许的,此时可以使用makeObserved。
25
+
26
+ - interface或者JSON.parse返回的匿名对象:这类场景往往没有明确的class声明,开发者无法使用@Trace标记当前属性可以被观察,此时可以使用makeObserved。
27
+
28
+
29
+ - 使用makeObserved接口需要导入UIUtils。
30
+ ```ts
31
+ import { UIUtils } from '@kit.ArkUI';
32
+ ```
33
+
34
+ ## 限制条件
35
+
36
+ - makeObserved仅支持非空的对象类型传参。
37
+ - 不支持undefined和null:返回自身,不做任何处理。
38
+ - 非Object类型:编译拦截报错。
39
+
40
+ ```ts
41
+ import { UIUtils } from '@kit.ArkUI';
42
+ let res1 = UIUtils.makeObserved(2); // 非法类型入参,错误用法,编译报错
43
+ let res2 = UIUtils.makeObserved(undefined); // 非法类型入参,错误用法,返回自身,res2 === undefined
44
+ let res3 = UIUtils.makeObserved(null); // 非法类型入参,错误用法,返回自身,res3 === null
45
+
46
+ class Info {
47
+ id: number = 0;
48
+ }
49
+ let rawInfo: Info = UIUtils.makeObserved(new Info()); // 正确用法
50
+ ```
51
+
52
+ - makeObserved不支持传入被[@ObservedV2](./arkts-new-observedV2-and-trace.md)、[@Observed](./arkts-observed-and-objectlink.md)装饰的类的实例和被makeObserved封装过的代理数据。为了防止数据被双重代理,makeObserved发现入参为上述情况时则直接返回,不做处理。
53
+ ```ts
54
+ import { UIUtils } from '@kit.ArkUI';
55
+ @ObservedV2
56
+ class Info {
57
+ @Trace id: number = 0;
58
+ }
59
+ // 错误用法:makeObserved发现传入的实例是@ObservedV2装饰的类的实例,则返回传入对象自身
60
+ let observedInfo: Info = UIUtils.makeObserved(new Info());
61
+
62
+ class Info2 {
63
+ id: number = 0;
64
+ }
65
+ // 正确用法:传入对象既不是@ObservedV2/@Observed装饰的类的实例,也不是makeObserved封装过的代理数据
66
+ // 返回可观察数据
67
+ let observedInfo1: Info2 = UIUtils.makeObserved(new Info2());
68
+ // 错误用法:传入对象为makeObserved封装过的代理数据,此次makeObserved不做处理
69
+ let observedInfo2: Info2 = UIUtils.makeObserved(observedInfo1);
70
+ ```
71
+ - makeObserved可以用在[@Component](./arkts-create-custom-components.md#component)装饰的自定义组件中,但不能和状态管理V1的状态变量装饰器配合使用,如果一起使用,则会抛出运行时异常。
72
+ ```ts
73
+ // 错误写法,运行时异常
74
+ @State message: Info = UIUtils.makeObserved(new Info(20));
75
+ ```
76
+ 注意:下面`message2`的写法不会抛异常。原因是:
77
+ - this.message是[@State](./arkts-state.md)装饰的,其实现等同于@Observed。
78
+ - UIUtils.makeObserved的入参如果是@Observed装饰的class的实例,会直接返回自身。
79
+
80
+ 因此`message2`的初始值不是makeObserved返回的代理对象,而是@State装饰的`this.message`。
81
+ <!-- @[UI_will_not_refresh](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/MakeObserved/entry/src/main/ets/View/Page1.ets) -->
82
+
83
+ ``` TypeScript
84
+ import { UIUtils } from '@kit.ArkUI';
85
+ class Person {
86
+ public age: number = 10;
87
+ }
88
+ class Info {
89
+ public id: number = 0;
90
+ public person: Person = new Person();
91
+ }
92
+ @Entry
93
+ @Component
94
+ struct Page1 {
95
+ @State message: Info = new Info();
96
+ @State message2: Info = UIUtils.makeObserved(this.message); // 不会抛异常
97
+ build() {
98
+ Column() {
99
+ Text(`${this.message2.person.age}`)
100
+ .onClick(() => {
101
+ // UI不会刷新,因为State只能观察到第一层的变化
102
+ this.message2.person.age++;
103
+ })
104
+ }
105
+ }
106
+ }
107
+ ```
108
+
109
+ ### makeObserved仅对入参对象进行深度观察
110
+
111
+ - `message`被[@Local](./arkts-new-local.md)装饰,本身具有观察自身赋值的能力。其初始值为makeObserved的返回值,具有深度观察能力。需要注意,makeObserved仅对`message`进行深度观察,而`message`自身赋值的变化,则是由@Local观察的。
112
+ - 点击`change id`可以触发UI刷新。
113
+ - 点击`change Info`,将`this.message`重新赋值为不可观察数据后,再次点击`change id`,无法触发UI刷新。
114
+ - 再次点击`change Info1`,将`this.message`重新赋值为可观察数据,再次点击`change id`,可以触发UI刷新。
115
+ <!-- @[MakeObserved_only_applies_to_input_parameters](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/MakeObserved/entry/src/main/ets/View/Page2.ets) -->
116
+
117
+ ``` TypeScript
118
+ import { UIUtils } from '@kit.ArkUI';
119
+ class Info {
120
+ public id: number = 0;
121
+ constructor(id: number) {
122
+ this.id = id;
123
+ }
124
+ }
125
+ @Entry
126
+ @ComponentV2
127
+ struct Page2 {
128
+ // message初始化为makeObserved的返回值,具有深度观察能力
129
+ @Local message: Info = UIUtils.makeObserved(new Info(20));
130
+ build() {
131
+ Column() {
132
+ Button(`change id`).onClick(() => {
133
+ this.message.id++;
134
+ })
135
+ Button(`change Info ${this.message.id}`).onClick(() => {
136
+ this.message = new Info(30);
137
+ })
138
+ Button(`change Info1 ${this.message.id}`).onClick(() => {
139
+ this.message = UIUtils.makeObserved(new Info(30));
140
+ })
141
+ }
142
+ }
143
+ }
144
+ ```
145
+
146
+
147
+ ## 支持类型和观察变化
148
+
149
+ ### 支持类型
150
+
151
+ - 支持未被[\@Observed](./arkts-observed-and-objectlink.md)或[\@ObservedV2](./arkts-new-observedV2-and-trace.md)装饰的类。
152
+ - 支持Array、Map、Set和Date。
153
+ - 支持[collections.Array](../../reference/apis-arkts/arkts-apis-arkts-collections-Array.md), [collections.Set](../../reference/apis-arkts/arkts-apis-arkts-collections-Set.md)和[collections.Map](../../reference/apis-arkts/arkts-apis-arkts-collections-Map.md)。
154
+ - JSON.parse返回的Object。
155
+ - @Sendable装饰的类。
156
+
157
+ ### 观察变化
158
+
159
+ - makeObserved传入内置类型或collections类型的实例时,可以观测其API带来的变化:
160
+
161
+ | 类型 | 可观测变化的API |
162
+ | ----- | ------------------------------------------------------------ |
163
+ | Array | push、pop、shift、unshift、splice、copyWithin、fill、reverse、sort |
164
+ | collections.Array | push、pop、shift、unshift、splice、fill、reverse、sort、shrinkTo、extendTo |
165
+ | Map/collections.Map | set、clear、delete |
166
+ | Set/collections.Set | add、clear、delete |
167
+ | Date | setFullYear、setMonth、setDate、setHours、setMinutes、setSeconds、setMilliseconds、setTime、setUTCFullYear、setUTCMonth、setUTCDate、setUTCHours、setUTCMinutes、setUTCSeconds、setUTCMilliseconds |
168
+
169
+ ## 使用场景
170
+
171
+ ### makeObserved和@Sendable装饰的class配合使用
172
+
173
+ [@Sendable](../../arkts-utils/arkts-sendable.md)主要是为了处理应用场景中的并发任务。将makeObserved和@Sendable配合使用,可以满足一般应用开发中,在子线程做大数据处理,在UI线程做ViewModel的显示和观察数据的需求。@Sendable具体内容可参考[并发任务文档](../../arkts-utils/multi-thread-concurrency-overview.md)。
174
+
175
+ 本章节将说明下面的场景:
176
+ - makeObserved在传入@Sendable类型的数据后有观察能力,且其变化可以触发UI刷新。
177
+ - 从子线程中获取一个整体数据,然后对UI线程的可观察数据做整体替换。
178
+ - 从子线程获取的数据重新执行makeObserved,将数据变为可观察数据。
179
+ - 将数据从主线程传递回子线程时,仅传递不可观察的数据。makeObserved的返回值不可直接传给子线程。
180
+
181
+ 例子如下:
182
+ <!-- @[SendableData](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/MakeObserved/entry/src/main/ets/Model/modelView.ets) -->
183
+
184
+ ``` TypeScript
185
+ @Sendable
186
+ export class SendableData {
187
+ public name: string = 'Tom';
188
+ public age: number = 20;
189
+ public gender: number = 1;
190
+ // ....更多其他属性
191
+ public likes: number = 1;
192
+ public follow: boolean = false;
193
+ }
194
+ ```
195
+
196
+ <!-- @[function threadGetData](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/MakeObserved/entry/src/main/ets/View/Page3.ets) -->
197
+
198
+ ``` TypeScript
199
+ import { taskpool } from '@kit.ArkTS';
200
+ import { SendableData } from '../Model/modelView';
201
+ import { UIUtils } from '@kit.ArkUI';
202
+ import { hilog } from '@kit.PerformanceAnalysisKit';
203
+
204
+ @Concurrent
205
+ function threadGetData(param: string): SendableData {
206
+ const DOMAIN = 0xF811;
207
+ const TAG = '[Sample_MakeObserved]';
208
+ // 在子线程处理数据
209
+ let ret = new SendableData();
210
+ hilog.info(DOMAIN, TAG, `Concurrent threadGetData, param ${param}`);
211
+ ret.name = param + '-o';
212
+ ret.age = Math.floor(Math.random() * 40);
213
+ ret.likes = Math.floor(Math.random() * 100);
214
+ return ret;
215
+ }
216
+
217
+ @Entry
218
+ @ComponentV2
219
+ struct Page3 {
220
+ // 通过makeObserved给普通对象或是SendableData对象添加可观察能力
221
+ @Local send: SendableData = UIUtils.makeObserved(new SendableData());
222
+
223
+ build() {
224
+ Column() {
225
+ Text(this.send.name)
226
+ Button('change name').onClick(() => {
227
+ // ok 可以观察到属性的改变
228
+ this.send.name += '0';
229
+ })
230
+
231
+ Button('task').onClick(() => {
232
+ // 将待执行的函数放入taskpool内部任务队列等待,等待分发到工作线程执行。
233
+ taskpool.execute(threadGetData, this.send.name).then(val => {
234
+ // 和@Local一起使用,可以观察this.send的变化
235
+ this.send = UIUtils.makeObserved(val as SendableData);
236
+ })
237
+ })
238
+ }
239
+ }
240
+ }
241
+ ```
242
+
243
+ 需要注意:数据的构建和处理可以在子线程中完成,但有观察能力的数据不能传给子线程,只有在主线程里才可以操作可观察的数据。所以上述例子中只是将`this.send`的属性`name`传给子线程操作。
244
+
245
+ ### makeObserved和collections.Array/Set/Map配合使用
246
+ collections提供ArkTS容器集,可用于并发场景下的高性能数据传递。详情见[@arkts.collections (ArkTS容器集)](../../reference/apis-arkts/arkts-apis-arkts-collections.md)相关文档。
247
+
248
+ makeObserved可以在ArkUI中导入可观察的collections容器,但makeObserved不能和状态管理V1的状态变量装饰器如@State和[@Prop](./arkts-prop.md)等配合使用,否则会抛出运行时异常。
249
+
250
+ **collections.Array**
251
+
252
+ collections.Array可以触发UI刷新的API有:
253
+ - 改变数组长度:push、pop、shift、unshift、splice、shrinkTo、extendTo
254
+ - 改变数组项本身:sort、fill
255
+
256
+ 其他API不会改变原始数组,所以不会触发UI刷新。
257
+ <!-- @[makeObserved_collections_Array_Set_Map](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/MakeObserved/entry/src/main/ets/View/Page4.ets) -->
258
+
259
+ ``` TypeScript
260
+ import { collections } from '@kit.ArkTS';
261
+ import { UIUtils } from '@kit.ArkUI';
262
+
263
+ @Sendable
264
+ class Info {
265
+ public id: number = 0;
266
+ public name: string = 'cc';
267
+
268
+ constructor(id: number) {
269
+ this.id = id;
270
+ }
271
+ }
272
+
273
+
274
+ @Entry
275
+ @ComponentV2
276
+ struct Page4 {
277
+ scroller: Scroller = new Scroller();
278
+ @Local arrCollect: collections.Array<Info> =
279
+ UIUtils.makeObserved(new collections.Array<Info>(new Info(1), new Info(2)));
280
+
281
+ build() {
282
+ Column() {
283
+ // ForEach接口仅支持Array<any>,不支持collections.Array<any>。
284
+ // 但ForEach的实现用到的Array的API,collections.Array都有提供。所以可以使用as类型断言Array。
285
+ // 需要注意断言并不会改变原本的数据类型。
286
+ ForEach(this.arrCollect as object as Array<Info>, (item: Info) => {
287
+ Text(`${item.id}`)
288
+ .margin(5)
289
+ .onClick(() => {
290
+ item.id++;
291
+ })
292
+ }, (item: Info, index) => item.id.toString() + index.toString())
293
+ Divider()
294
+ .color('blue')
295
+ .margin(5)
296
+ if (this.arrCollect.length > 0) {
297
+ Text(`the first one ${this.arrCollect[0].id}`)
298
+ .margin(5)
299
+ Text(`the last one ${this.arrCollect[this.arrCollect.length - 1].id}`)
300
+ .margin(5)
301
+ }
302
+ Divider()
303
+ .color('blue')
304
+ .margin(5)
305
+
306
+ // 改变数据长度的API
307
+ Scroll(this.scroller) {
308
+ Column({ space: 10 }) {
309
+ // push: 新增新元素
310
+ Button('push')
311
+ .width('50%')
312
+ .onClick(() => {
313
+ this.arrCollect.push(new Info(30));
314
+ })
315
+ // pop: 删除最后一个
316
+ Button('pop')
317
+ .width('50%')
318
+ .onClick(() => {
319
+ this.arrCollect.pop();
320
+ })
321
+ // shift: 删除第一个
322
+ Button('shift')
323
+ .width('50%')
324
+ .onClick(() => {
325
+ this.arrCollect.shift();
326
+ })
327
+ // unshift: 在数组的开头插入新项
328
+ Button('unshift')
329
+ .width('50%')
330
+ .onClick(() => {
331
+ this.arrCollect.unshift(new Info(50));
332
+ })
333
+ // splice: 从数组的指定位置删除元素
334
+ Button('splice')
335
+ .width('50%')
336
+ .onClick(() => {
337
+ this.arrCollect.splice(1);
338
+ })
339
+
340
+ // shrinkTo: 将数组长度缩小到给定的长度
341
+ Button('shrinkTo')
342
+ .width('50%')
343
+ .onClick(() => {
344
+ this.arrCollect.shrinkTo(1);
345
+ })
346
+ // extendTo: 将数组长度扩展到给定的长度
347
+ Button('extendTo')
348
+ .width('50%')
349
+ .onClick(() => {
350
+ this.arrCollect.extendTo(6, new Info(20));
351
+ })
352
+
353
+ Divider()
354
+ .color('blue')
355
+
356
+ // 改变数组item本身
357
+ // sort:从大到小排序
358
+ Button('sort')
359
+ .width('50%')
360
+ .onClick(() => {
361
+ this.arrCollect.sort((a: Info, b: Info) => b.id - a.id);
362
+ })
363
+ // fill: 用值填充指定部分
364
+ Button('fill')
365
+ .width('50%')
366
+ .onClick(() => {
367
+ this.arrCollect.fill(new Info(5), 0, 2);
368
+ })
369
+
370
+ // 不会改变数组本身的API
371
+ // slice:返回新的数组,根据start end对原数组的拷贝,不会改变原数组,所以直接调用slice不会触发UI刷新
372
+ // 可以构建用例为返回的浅拷贝的数据赋值给this.arrCollect,需要注意这里依然要调用makeObserved,否则this.arrCollect被普通变量赋值后,会丧失观察能力
373
+ Button('slice')
374
+ .width('50%')
375
+ .onClick(() => {
376
+ this.arrCollect = UIUtils.makeObserved(this.arrCollect.slice(0, 1));
377
+ })
378
+ // map:原理同上
379
+ Button('map')
380
+ .width('50%')
381
+ .onClick(() => {
382
+ this.arrCollect = UIUtils.makeObserved(this.arrCollect.map((value) => {
383
+ value.id += 10;
384
+ return value;
385
+ }))
386
+ })
387
+ // filter:原理同上
388
+ Button('filter')
389
+ .width('50%')
390
+ .onClick(() => {
391
+ this.arrCollect = UIUtils.makeObserved(this.arrCollect.filter((value: Info) => value.id % 2 === 0));
392
+ })
393
+ // concat:原理同上
394
+ Button('concat')
395
+ .width('50%')
396
+ .onClick(() => {
397
+ let array1 = new collections.Array(new Info(100))
398
+ this.arrCollect = UIUtils.makeObserved(this.arrCollect.concat(array1));
399
+ })
400
+ }
401
+ .height('200%')
402
+ }
403
+ .height('100%')
404
+ }
405
+ .height('100%')
406
+ .width('100%')
407
+ }
408
+ }
409
+ ```
410
+ ![makeobserved-array](figures/makeobserved-array.gif)
411
+
412
+ **collections.Map**
413
+
414
+ collections.Map可以触发UI刷新的API有:set、clear、delete。
415
+ <!-- @[foreach_mapCollect_keys](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/MakeObserved/entry/src/main/ets/View/Page5.ets) -->
416
+
417
+ ``` TypeScript
418
+ import { collections } from '@kit.ArkTS';
419
+ import { UIUtils } from '@kit.ArkUI';
420
+
421
+ @Sendable
422
+ class Info {
423
+ public id: number = 0;
424
+
425
+ constructor(id: number) {
426
+ this.id = id;
427
+ }
428
+ }
429
+
430
+
431
+ @Entry
432
+ @ComponentV2
433
+ struct Page5 {
434
+ mapCollect: collections.Map<string, Info> =
435
+ UIUtils.makeObserved(new collections.Map<string, Info>([['a', new Info(10)], ['b', new Info(20)]]));
436
+
437
+ build() {
438
+ Column() {
439
+ // this.mapCollect.keys()返回迭代器。Foreach不支持迭代器,所以要Array.from浅拷贝生成数据。
440
+ ForEach(Array.from(this.mapCollect.keys()), (item: string) => {
441
+ Text(`${this.mapCollect.get(item)?.id}`)
442
+ .margin(5)
443
+ .onClick(() => {
444
+ let value: Info | undefined = this.mapCollect.get(item);
445
+ if (value) {
446
+ value.id++;
447
+ }
448
+ })
449
+ }, (item: string, index) => item + index.toString())
450
+
451
+ // set c
452
+ Button('set c')
453
+ .width('50%')
454
+ .margin(5)
455
+ .onClick(() => {
456
+ this.mapCollect.set('c', new Info(30));
457
+ })
458
+ // delete c
459
+ Button('delete c')
460
+ .width('50%')
461
+ .margin(5)
462
+ .onClick(() => {
463
+ if (this.mapCollect.has('c')) {
464
+ this.mapCollect.delete('c');
465
+ }
466
+ })
467
+ // clear
468
+ Button('clear')
469
+ .width('50%')
470
+ .margin(5)
471
+ .onClick(() => {
472
+ this.mapCollect.clear();
473
+ })
474
+ }
475
+ .height('100%')
476
+ .width('100%')
477
+ }
478
+ }
479
+ ```
480
+ ![makeobserved-map](figures/makeobserved-map.gif)
481
+
482
+ **collections.Set**
483
+
484
+ collections.Set可以触发UI刷新的API有:add、clear、delete。
485
+ <!-- @[Array_rom_shallow_copy](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/MakeObserved/entry/src/main/ets/View/Page6.ets) -->
486
+
487
+ ``` TypeScript
488
+ import { collections } from '@kit.ArkTS';
489
+ import { UIUtils } from '@kit.ArkUI';
490
+ import { hilog } from '@kit.PerformanceAnalysisKit';
491
+
492
+ const DOMAIN = 0xF811;
493
+ const TAG = '[Sample_MakeObserved]';
494
+
495
+ @Sendable
496
+ class Info {
497
+ public id: number = 0;
498
+
499
+ constructor(id: number) {
500
+ this.id = id;
501
+ }
502
+ }
503
+
504
+
505
+ @Entry
506
+ @ComponentV2
507
+ struct Page6 {
508
+ set: collections.Set<Info> = UIUtils.makeObserved(new collections.Set<Info>([new Info(10), new Info(20)]));
509
+
510
+ build() {
511
+ Column() {
512
+ // 因为ForEach不支持迭代器,所以需要使用Array.from浅拷贝生成数组。
513
+ // 但是浅拷贝生成的新的数组没有观察能力,为了ForEach组件在访问item的时候是可观察的数据,所以需要重新调用makeObserved。
514
+ ForEach((UIUtils.makeObserved(Array.from(this.set.values()))), (item: Info) => {
515
+ Text(`${item.id}`)
516
+ .margin(5)
517
+ .onClick(() => {
518
+ item.id++;
519
+ })
520
+ }, (item: Info, index) => item.id + index.toString())
521
+
522
+ Button('add')
523
+ .margin(5)
524
+ .width('50%')
525
+ .onClick(() => {
526
+ this.set.add(new Info(30));
527
+ hilog.info(DOMAIN, TAG, ('size:' + this.set.size));
528
+ })
529
+ Button('delete')
530
+ .margin(5)
531
+ .width('50%')
532
+ .onClick(() => {
533
+ let iterator = this.set.keys();
534
+ this.set.delete(iterator.next().value);
535
+ })
536
+ Button('clear')
537
+ .margin(5)
538
+ .width('50%')
539
+ .onClick(() => {
540
+ this.set.clear();
541
+ })
542
+ }
543
+ .height('100%')
544
+ .width('100%')
545
+ }
546
+ }
547
+ ```
548
+ ![makeobserved-set](figures/makeobserved-set.gif)
549
+
550
+ ### makeObserved的入参为JSON.parse的返回值
551
+ JSON.parse返回Object,无法使用@Trace装饰其属性,可以使用makeObserved使其变为可观察数据。
552
+ <!-- @[makeObserved_JSON.parse](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/MakeObserved/entry/src/main/ets/View/Page7.ets) -->
553
+
554
+ ``` TypeScript
555
+ import { JSON } from '@kit.ArkTS';
556
+ import { UIUtils } from '@kit.ArkUI';
557
+
558
+ class Info {
559
+ public id: number = 0;
560
+
561
+ constructor(id: number) {
562
+ this.id = id;
563
+ }
564
+ }
565
+
566
+ let test: Record<string, number> = { 'a': 123 };
567
+ let testJsonStr: string = JSON.stringify(test);
568
+ let test2: Record<string, Info> = { 'a': new Info(20) };
569
+ let test2JsonStr: string = JSON.stringify(test2);
570
+
571
+ @Entry
572
+ @ComponentV2
573
+ struct Page7 {
574
+ // JSON.parse返回的Object用makeObserved转为可观察数据
575
+ message: Record<string, number> =
576
+ UIUtils.makeObserved<Record<string, number>>(JSON.parse(testJsonStr) as Record<string, number>);
577
+ message2: Record<string, Info> =
578
+ UIUtils.makeObserved<Record<string, Info>>(JSON.parse(test2JsonStr) as Record<string, Info>);
579
+
580
+ build() {
581
+ Column() {
582
+ Text(`${this.message.a}`)
583
+ .id('textId1')
584
+ .fontSize(50)
585
+ .onClick(() => {
586
+ this.message.a++;
587
+ })
588
+ Text(`${this.message2.a.id}`)
589
+ .id('textId2')
590
+ .fontSize(50)
591
+ .onClick(() => {
592
+ this.message2.a.id++;
593
+ })
594
+ }
595
+ .height('100%')
596
+ .width('100%')
597
+ }
598
+ }
599
+ ```
600
+
601
+
602
+ ### makeObserved和V2装饰器配合使用
603
+ makeObserved可以和V2的装饰器一起使用。对于[@Monitor](./arkts-new-monitor.md)和[@Computed](./arkts-new-computed.md),因为makeObserved传入@Observed或ObservedV2装饰的类实例会返回其自身,所以@Monitor或者@Computed不能定义在class中,只能定义在自定义组件里。
604
+
605
+ 例子如下:
606
+ <!-- @[name_change_from_monitor_value](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/MakeObserved/entry/src/main/ets/View/Page8.ets) -->
607
+
608
+ ``` TypeScript
609
+ import { UIUtils } from '@kit.ArkUI';
610
+ import { hilog } from '@kit.PerformanceAnalysisKit';
611
+
612
+ const DOMAIN = 0xF811;
613
+ const TAG = '[Sample_MakeObserved]';
614
+
615
+ class Info {
616
+ public id: number = 0;
617
+ public age: number = 20;
618
+
619
+ constructor(id: number) {
620
+ this.id = id;
621
+ }
622
+ }
623
+
624
+ @Entry
625
+ @ComponentV2
626
+ struct Page8 {
627
+ @Local message: Info = UIUtils.makeObserved(new Info(20));
628
+
629
+ // 当message.id发生变化时,触发该函数调用
630
+ @Monitor('message.id')
631
+ onStrChange(monitor: IMonitor) {
632
+ hilog.info(DOMAIN, TAG, `name change from ${monitor.value()?.before} to ${monitor.value()?.now}`);
633
+ }
634
+
635
+ // 当message.id和message.age发生变化,需要重新计算时,触发该函数调用
636
+ @Computed
637
+ get ageId() {
638
+ hilog.info(DOMAIN, TAG, '---------Computed----------');
639
+ return this.message.id + ' ' + this.message.age;
640
+ }
641
+
642
+ build() {
643
+ Column() {
644
+ Text(`id: ${this.message.id}`)
645
+ .id('textIdMessage')
646
+ .fontSize(30)
647
+ .margin(5)
648
+ .onClick(() => {
649
+ this.message.id++;
650
+ })
651
+ Text(`age: ${this.message.age}`)
652
+ .id('textAgeMessageAge')
653
+ .fontSize(30)
654
+ .margin(5)
655
+ .onClick(() => {
656
+ this.message.age++;
657
+ })
658
+ Text(`Computed age + id: ${this.ageId}`)
659
+ .fontSize(30)
660
+ .margin(5)
661
+ Button('change Info')
662
+ .id('buttonChangeInfo')
663
+ .fontSize(30)
664
+ .margin(5)
665
+ .onClick(() => {
666
+ // 返回类实例本身,并赋值给message,触发@Computed和@Monitor
667
+ this.message = UIUtils.makeObserved(new Info(200));
668
+ })
669
+ Child({ message: this.message })
670
+ }
671
+ .height('100%')
672
+ .width('100%')
673
+ }
674
+ }
675
+
676
+ @ComponentV2
677
+ struct Child {
678
+ @Param @Require message: Info;
679
+
680
+ build() {
681
+ Text(`Child id: ${this.message.id}`)
682
+ .fontSize(30)
683
+ .margin(5)
684
+ }
685
+ }
686
+ ```
687
+ ![makeobserved-componentv2](figures/makeobserved-componentv2.gif)
688
+
689
+ ### makeObserved在@Component内使用
690
+ makeObserved不能和V1的状态变量装饰器一起使用,但可以在@Component装饰的自定义组件里使用。
691
+ <!-- @[makeObserved_Component](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/MakeObserved/entry/src/main/ets/View/Page9.ets) -->
692
+
693
+ ``` TypeScript
694
+ import { UIUtils } from '@kit.ArkUI';
695
+ class Info {
696
+ public id: number = 0;
697
+
698
+ constructor(id: number) {
699
+ this.id = id;
700
+ }
701
+ }
702
+
703
+
704
+ @Entry
705
+ @Component
706
+ struct Page9 {
707
+ // 如果和@State一起使用会抛出运行时异常
708
+ message: Info = UIUtils.makeObserved(new Info(20));
709
+
710
+ build() {
711
+ RelativeContainer() {
712
+ Text(`${this.message.id}`)
713
+ .id('textNumber')
714
+ .onClick(() => {
715
+ this.message.id++;
716
+ })
717
+ }
718
+ .height('100%')
719
+ .width('100%')
720
+ }
721
+ }
722
+ ```
723
+
724
+
725
+ ## 常见问题
726
+ ### getTarget后的数据可以正常赋值,但是无法触发UI刷新
727
+ [getTarget](./arkts-new-getTarget.md)可以获取状态管理框架代理前的原始对象。
728
+
729
+ makeObserved封装的观察对象,可以通过getTarget获取到其原始对象,对原始对象的赋值不会触发UI刷新。
730
+
731
+ 如下面例子:
732
+ 1. 先点击第一个Text组件,通过getTarget获取其原始对象,此时修改原始对象的属性不会触发UI刷新,但数据会正常赋值。
733
+ 2. 再点击第二个Text组件,此时修改`this.observedObj`的属性会触发UI刷新,Text显示21。
734
+ <!-- @[getTarget_observedObj](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/MakeObserved/entry/src/main/ets/View/Page10.ets) -->
735
+
736
+ ``` TypeScript
737
+ import { UIUtils } from '@kit.ArkUI';
738
+ class Info {
739
+ public id: number = 0;
740
+ }
741
+
742
+ @Entry
743
+ @Component
744
+ struct Page10 {
745
+ observedObj: Info = UIUtils.makeObserved(new Info());
746
+ build() {
747
+ Column() {
748
+ Text(`${this.observedObj.id}`)
749
+ .id('textobservedObj1')
750
+ .fontSize(50)
751
+ .onClick(() => {
752
+ // 通过getTarget获取其原始对象,将this.observedObj赋值为不可观察的数据
753
+ let rawObj: Info= UIUtils.getTarget(this.observedObj);
754
+ // 不会触发UI刷新,但数据会正常赋值
755
+ rawObj.id = 20;
756
+ })
757
+
758
+ Text(`${this.observedObj.id}`)
759
+ .id('textobservedObj2')
760
+ .fontSize(50)
761
+ .onClick(() => {
762
+ // 触发UI刷新,Text显示21
763
+ this.observedObj.id++;
764
+ })
765
+ }
766
+ }
767
+ }
768
+ ```