vite-plugin-taro 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/README.en.md +44 -0
  2. package/README.md +22 -497
  3. package/client.d.ts +9 -0
  4. package/dist/node/plugins/client/client-taro.d.ts +4 -0
  5. package/dist/node/plugins/client/client-taro.js +19 -0
  6. package/dist/node/plugins/client/constant.d.ts +4 -0
  7. package/dist/node/plugins/client/constant.js +4 -0
  8. package/dist/node/plugins/conditional/conditional-directives.d.ts +4 -0
  9. package/dist/node/plugins/{conditional-directives.js → conditional/conditional-directives.js} +27 -11
  10. package/dist/node/plugins/css/plugins.d.ts +4 -0
  11. package/dist/node/plugins/css/plugins.js +84 -0
  12. package/dist/node/plugins/h5/constant.d.ts +2 -0
  13. package/dist/node/plugins/h5/constant.js +3 -0
  14. package/dist/node/plugins/h5/plugins.d.ts +4 -0
  15. package/dist/node/plugins/h5/plugins.js +161 -0
  16. package/dist/node/plugins/h5/resolver/module-resolver.d.ts +14 -0
  17. package/dist/node/plugins/h5/resolver/module-resolver.js +19 -0
  18. package/dist/node/plugins/h5/transform-app.d.ts +10 -0
  19. package/dist/node/plugins/h5/transform-app.js +48 -0
  20. package/dist/node/plugins/wx/dev/dev-host.d.ts +15 -0
  21. package/dist/node/plugins/wx/dev/dev-host.js +352 -0
  22. package/dist/node/plugins/wx/dev/hmr-files.d.ts +28 -0
  23. package/dist/node/plugins/wx/dev/hmr-files.js +34 -0
  24. package/dist/node/plugins/wx/dev/patch-publisher.d.ts +22 -0
  25. package/dist/node/plugins/wx/dev/patch-publisher.js +40 -0
  26. package/dist/node/plugins/wx/dev/plugin.d.ts +7 -0
  27. package/dist/node/plugins/wx/dev/plugin.js +73 -0
  28. package/dist/node/plugins/wx/dev/react-refresh.d.ts +20 -0
  29. package/dist/node/plugins/wx/dev/react-refresh.js +198 -0
  30. package/dist/node/plugins/wx/module.d.ts +45 -0
  31. package/dist/node/plugins/wx/module.js +66 -0
  32. package/dist/node/plugins/wx/native/compile-native-component-interface.d.ts +21 -0
  33. package/dist/node/plugins/wx/native/compile-native-component-interface.js +29 -0
  34. package/dist/node/plugins/wx/native/create-native-component-output.d.ts +15 -0
  35. package/dist/node/plugins/wx/native/create-native-component-output.js +39 -0
  36. package/dist/node/plugins/wx/native/native-component-assets.d.ts +26 -0
  37. package/dist/node/plugins/wx/native/native-component-assets.js +76 -0
  38. package/dist/node/plugins/wx/native/native-component-interface.d.ts +12 -0
  39. package/dist/node/plugins/wx/native/native-component-interface.js +201 -0
  40. package/dist/node/plugins/wx/output/files.d.ts +12 -0
  41. package/dist/node/plugins/wx/output/files.js +12 -0
  42. package/dist/node/plugins/wx/output/json.d.ts +14 -0
  43. package/dist/node/plugins/wx/output/json.js +52 -0
  44. package/dist/node/plugins/wx/output/relative-root.d.ts +2 -0
  45. package/dist/node/plugins/wx/output/relative-root.js +6 -0
  46. package/dist/node/plugins/wx/output/templates.d.ts +7 -0
  47. package/dist/node/plugins/wx/output/templates.js +100 -0
  48. package/dist/node/plugins/wx/placement/placer.d.ts +78 -0
  49. package/dist/node/plugins/wx/placement/placer.js +145 -0
  50. package/dist/node/plugins/wx/placement/plan.d.ts +46 -0
  51. package/dist/node/plugins/wx/placement/plan.js +210 -0
  52. package/dist/node/plugins/wx/plugins.d.ts +4 -0
  53. package/dist/node/plugins/wx/plugins.js +137 -0
  54. package/dist/node/plugins/wx/render/capsule-wrapper.d.ts +3 -0
  55. package/dist/node/plugins/wx/render/capsule-wrapper.js +64 -0
  56. package/dist/node/plugins/wx/render/capsule.d.ts +4 -0
  57. package/dist/node/plugins/wx/render/capsule.js +13 -0
  58. package/dist/node/plugins/wx/render/native.d.ts +9 -0
  59. package/dist/node/plugins/wx/render/native.js +45 -0
  60. package/dist/node/plugins/wx/render/transport.d.ts +17 -0
  61. package/dist/node/plugins/wx/render/transport.js +94 -0
  62. package/dist/node/plugins/wx/resolve/resolver.d.ts +7 -0
  63. package/dist/node/plugins/wx/resolve/resolver.js +86 -0
  64. package/dist/node/plugins/wx/resolve/specialize-bootstrap.d.ts +9 -0
  65. package/dist/node/plugins/wx/resolve/specialize-bootstrap.js +9 -0
  66. package/dist/node/plugins/wx/resolve/specialize-page-capsule.d.ts +9 -0
  67. package/dist/node/plugins/wx/resolve/specialize-page-capsule.js +11 -0
  68. package/dist/node/utils/constant.d.ts +1 -0
  69. package/dist/node/utils/constant.js +1 -0
  70. package/dist/node/utils/memoize.d.ts +122 -0
  71. package/dist/node/utils/memoize.js +86 -0
  72. package/dist/node/utils/modules.d.ts +20 -24
  73. package/dist/node/utils/modules.js +21 -34
  74. package/dist/node/utils/once.d.ts +10 -0
  75. package/dist/node/utils/once.js +20 -0
  76. package/dist/node/utils/packages.d.ts +1 -0
  77. package/dist/node/utils/packages.js +1 -1
  78. package/dist/node/utils/project-config.d.ts +3 -0
  79. package/dist/node/utils/project-config.js +8 -0
  80. package/dist/node/utils/serialized-task-queue.d.ts +9 -0
  81. package/dist/node/utils/serialized-task-queue.js +17 -0
  82. package/dist/node/utils/transform.d.ts +11 -0
  83. package/dist/node/utils/transform.js +58 -0
  84. package/dist/node/vite-plugin.d.ts +1 -1
  85. package/dist/node/vite-plugin.js +11 -27
  86. package/dist/options.d.ts +3 -4
  87. package/dist/runtime/{taro → client/taro}/api.d.ts +0 -1
  88. package/dist/runtime/client/taro/api.js +9 -0
  89. package/dist/runtime/client/taro/component.d.ts +1 -0
  90. package/dist/runtime/client/taro/component.js +1 -0
  91. package/dist/runtime/client/taro/define-native-component.d.ts +7 -0
  92. package/dist/runtime/client/taro/define-native-component.js +4 -0
  93. package/dist/runtime/h5/app.d.ts +2 -0
  94. package/dist/runtime/h5/app.js +15 -0
  95. package/dist/runtime/h5/taro-runtime.d.ts +1 -1
  96. package/dist/runtime/h5/taro-runtime.js +1 -4
  97. package/dist/runtime/wx/amphibious/bootstrap.d.ts +4 -0
  98. package/dist/runtime/wx/amphibious/bootstrap.js +16 -0
  99. package/dist/runtime/wx/amphibious/transport.d.ts +2 -0
  100. package/dist/runtime/wx/amphibious/transport.js +4 -0
  101. package/dist/runtime/wx/capsule/app.d.ts +2 -0
  102. package/dist/runtime/wx/capsule/app.js +7 -0
  103. package/dist/runtime/wx/capsule/component.d.ts +3 -0
  104. package/dist/runtime/wx/capsule/component.js +4 -0
  105. package/dist/runtime/wx/capsule/page.d.ts +3 -0
  106. package/dist/runtime/wx/capsule/page.js +68 -0
  107. package/dist/runtime/wx/capsule/taro-runtime.d.ts +6 -0
  108. package/dist/runtime/wx/capsule/taro-runtime.js +6 -0
  109. package/dist/runtime/wx/dev/dev-runtime.d.ts +1 -0
  110. package/dist/runtime/wx/dev/dev-runtime.js +246 -0
  111. package/dist/runtime/wx/native/app.d.ts +1 -0
  112. package/dist/runtime/wx/native/app.js +3 -0
  113. package/dist/runtime/wx/native/component.d.ts +1 -0
  114. package/dist/runtime/wx/native/component.js +3 -0
  115. package/dist/runtime/wx/native/page.d.ts +1 -0
  116. package/dist/runtime/wx/native/page.js +4 -0
  117. package/dist/runtime/wx/systemjs/system-core.d.ts +4 -0
  118. package/dist/runtime/wx/systemjs/system-core.js +331 -0
  119. package/package.json +21 -14
  120. package/src/node/plugins/client/client-taro.ts +23 -0
  121. package/src/node/plugins/client/constant.ts +5 -0
  122. package/src/node/plugins/{conditional-directives.ts → conditional/conditional-directives.ts} +33 -13
  123. package/src/node/plugins/css/plugins.ts +96 -0
  124. package/src/node/plugins/h5/constant.ts +4 -0
  125. package/src/node/plugins/h5/plugins.ts +197 -0
  126. package/src/node/plugins/h5/resolver/module-resolver.ts +32 -0
  127. package/src/node/plugins/h5/transform-app.ts +90 -0
  128. package/src/node/plugins/wx/dev/dev-host.ts +448 -0
  129. package/src/node/plugins/wx/dev/hmr-files.ts +55 -0
  130. package/src/node/plugins/wx/dev/patch-publisher.ts +49 -0
  131. package/src/node/plugins/wx/dev/plugin.ts +82 -0
  132. package/src/node/plugins/wx/dev/react-refresh.ts +227 -0
  133. package/src/node/plugins/wx/module.ts +97 -0
  134. package/src/node/plugins/wx/native/compile-native-component-interface.ts +47 -0
  135. package/src/node/plugins/wx/native/create-native-component-output.ts +57 -0
  136. package/src/node/plugins/wx/native/native-component-assets.ts +114 -0
  137. package/src/node/plugins/wx/native/native-component-interface.ts +265 -0
  138. package/src/node/plugins/wx/output/files.ts +27 -0
  139. package/src/node/plugins/wx/output/json.ts +79 -0
  140. package/src/node/plugins/wx/output/relative-root.ts +7 -0
  141. package/src/node/plugins/wx/output/templates.ts +141 -0
  142. package/src/node/plugins/wx/placement/placer.ts +172 -0
  143. package/src/node/plugins/wx/placement/plan.ts +306 -0
  144. package/src/node/plugins/wx/plugins.ts +165 -0
  145. package/src/node/plugins/wx/render/capsule-wrapper.ts +86 -0
  146. package/src/node/plugins/wx/render/capsule.ts +21 -0
  147. package/src/node/plugins/wx/render/native.ts +84 -0
  148. package/src/node/plugins/wx/render/transport.ts +157 -0
  149. package/src/node/plugins/wx/resolve/resolver.ts +125 -0
  150. package/src/node/plugins/wx/resolve/specialize-bootstrap.ts +27 -0
  151. package/src/node/plugins/wx/resolve/specialize-page-capsule.ts +29 -0
  152. package/src/node/utils/constant.ts +1 -0
  153. package/src/node/utils/memoize.ts +149 -0
  154. package/src/node/utils/modules.ts +36 -38
  155. package/src/node/utils/once.ts +21 -0
  156. package/src/node/utils/packages.ts +1 -1
  157. package/src/node/utils/project-config.ts +10 -0
  158. package/src/node/utils/serialized-task-queue.ts +20 -0
  159. package/src/node/utils/transform.ts +82 -0
  160. package/src/node/vite-plugin.ts +12 -32
  161. package/src/options.ts +3 -4
  162. package/src/runtime/client/taro/api.ts +11 -0
  163. package/src/runtime/client/taro/component.ts +1 -0
  164. package/src/runtime/client/taro/define-native-component.ts +15 -0
  165. package/src/runtime/h5/app.ts +25 -0
  166. package/src/runtime/h5/taro-runtime.ts +1 -4
  167. package/src/runtime/wx/amphibious/bootstrap.ts +22 -0
  168. package/src/runtime/wx/amphibious/transport.ts +10 -0
  169. package/src/runtime/wx/capsule/app.ts +9 -0
  170. package/src/runtime/wx/capsule/component.ts +6 -0
  171. package/src/runtime/wx/capsule/page.ts +96 -0
  172. package/src/runtime/wx/capsule/taro-runtime.ts +14 -0
  173. package/src/runtime/wx/dev/dev-runtime.ts +317 -0
  174. package/src/runtime/wx/native/app.ts +4 -0
  175. package/src/runtime/wx/native/component.ts +4 -0
  176. package/src/runtime/wx/native/page.ts +6 -0
  177. package/src/runtime/wx/systemjs/LICENSE +10 -0
  178. package/src/runtime/wx/systemjs/system-core.js +370 -0
  179. package/src/runtime/wx/systemjs/system.d.ts +55 -0
  180. package/src/runtime/wx/wechat.d.ts +52 -0
  181. package/README.zh.md +0 -521
  182. package/dist/node/build-context.d.ts +0 -25
  183. package/dist/node/build-context.js +0 -47
  184. package/dist/node/css/css-pipeline.d.ts +0 -35
  185. package/dist/node/css/css-pipeline.js +0 -154
  186. package/dist/node/plugins/conditional-directives.d.ts +0 -3
  187. package/dist/node/plugins/taro-runtime.d.ts +0 -5
  188. package/dist/node/plugins/taro-runtime.js +0 -18
  189. package/dist/node/targets/h5/plugin.d.ts +0 -6
  190. package/dist/node/targets/h5/plugin.js +0 -117
  191. package/dist/node/targets/h5/virtual-modules.d.ts +0 -5
  192. package/dist/node/targets/h5/virtual-modules.js +0 -60
  193. package/dist/node/targets/wx/companion-assets.d.ts +0 -19
  194. package/dist/node/targets/wx/companion-assets.js +0 -129
  195. package/dist/node/targets/wx/dev-server/development-session.d.ts +0 -32
  196. package/dist/node/targets/wx/dev-server/development-session.js +0 -215
  197. package/dist/node/targets/wx/dev-server/full-build-scheduler.d.ts +0 -14
  198. package/dist/node/targets/wx/dev-server/full-build-scheduler.js +0 -60
  199. package/dist/node/targets/wx/dev-server/js-utils.d.ts +0 -5
  200. package/dist/node/targets/wx/dev-server/js-utils.js +0 -28
  201. package/dist/node/targets/wx/dev-server/output.d.ts +0 -19
  202. package/dist/node/targets/wx/dev-server/output.js +0 -44
  203. package/dist/node/targets/wx/dev-server/rolldown-runtime-source.d.ts +0 -8
  204. package/dist/node/targets/wx/dev-server/rolldown-runtime-source.js +0 -95
  205. package/dist/node/targets/wx/dev-server/update-server-state.d.ts +0 -65
  206. package/dist/node/targets/wx/dev-server/update-server-state.js +0 -116
  207. package/dist/node/targets/wx/dev-server/update-transport.d.ts +0 -28
  208. package/dist/node/targets/wx/dev-server/update-transport.js +0 -212
  209. package/dist/node/targets/wx/dev-server/vite-bundled-dev-adapter.d.ts +0 -44
  210. package/dist/node/targets/wx/dev-server/vite-bundled-dev-adapter.js +0 -145
  211. package/dist/node/targets/wx/development-files.d.ts +0 -8
  212. package/dist/node/targets/wx/development-files.js +0 -8
  213. package/dist/node/targets/wx/plugin.d.ts +0 -6
  214. package/dist/node/targets/wx/plugin.js +0 -144
  215. package/dist/node/targets/wx/react-refresh.d.ts +0 -4
  216. package/dist/node/targets/wx/react-refresh.js +0 -38
  217. package/dist/node/targets/wx/virtual-modules.d.ts +0 -16
  218. package/dist/node/targets/wx/virtual-modules.js +0 -120
  219. package/dist/node/utils/async.d.ts +0 -8
  220. package/dist/node/utils/async.js +0 -16
  221. package/dist/node/utils/filesystem.d.ts +0 -13
  222. package/dist/node/utils/filesystem.js +0 -43
  223. package/dist/runtime/taro/api.js +0 -11
  224. package/dist/runtime/taro/components.d.ts +0 -2
  225. package/dist/runtime/taro/components.js +0 -2
  226. package/dist/runtime/wx/page-update.d.ts +0 -6
  227. package/dist/runtime/wx/page-update.js +0 -157
  228. package/dist/runtime/wx/taro-runtime.d.ts +0 -5
  229. package/dist/runtime/wx/taro-runtime.js +0 -6
  230. package/dist/runtime/wx/update-client-state.d.ts +0 -68
  231. package/dist/runtime/wx/update-client-state.js +0 -84
  232. package/dist/runtime/wx/update-client.d.ts +0 -1
  233. package/dist/runtime/wx/update-client.js +0 -171
  234. package/src/node/build-context.ts +0 -62
  235. package/src/node/css/css-pipeline.ts +0 -171
  236. package/src/node/plugins/taro-runtime.ts +0 -22
  237. package/src/node/targets/h5/plugin.ts +0 -135
  238. package/src/node/targets/h5/virtual-modules.ts +0 -71
  239. package/src/node/targets/wx/companion-assets.ts +0 -174
  240. package/src/node/targets/wx/dev-server/development-session.ts +0 -271
  241. package/src/node/targets/wx/dev-server/full-build-scheduler.ts +0 -62
  242. package/src/node/targets/wx/dev-server/js-utils.ts +0 -33
  243. package/src/node/targets/wx/dev-server/output.ts +0 -56
  244. package/src/node/targets/wx/dev-server/rolldown-runtime-source.ts +0 -95
  245. package/src/node/targets/wx/dev-server/update-server-state.ts +0 -183
  246. package/src/node/targets/wx/dev-server/update-transport.ts +0 -261
  247. package/src/node/targets/wx/dev-server/vite-bundled-dev-adapter.ts +0 -203
  248. package/src/node/targets/wx/development-files.ts +0 -11
  249. package/src/node/targets/wx/plugin.ts +0 -164
  250. package/src/node/targets/wx/react-refresh.ts +0 -51
  251. package/src/node/targets/wx/virtual-modules.ts +0 -152
  252. package/src/node/utils/async.ts +0 -19
  253. package/src/node/utils/filesystem.ts +0 -45
  254. package/src/runtime/taro/api.ts +0 -13
  255. package/src/runtime/taro/components.ts +0 -2
  256. package/src/runtime/wx/page-update.ts +0 -230
  257. package/src/runtime/wx/react-refresh.d.ts +0 -20
  258. package/src/runtime/wx/taro-runtime.ts +0 -7
  259. package/src/runtime/wx/update-client-state.ts +0 -138
  260. package/src/runtime/wx/update-client.ts +0 -223
@@ -0,0 +1,317 @@
1
+ // WX dev runtime — bundled and injected verbatim at the end of the shared Rolldown
2
+ // runtime chunk (`assets/rolldown-runtime.js`, required first by every chunk). Defines the
3
+ // App-global `__rolldown_runtime__` that generated modules call.
4
+ //
5
+ // The `DevRuntime` base class is injected into the chunk by Rolldown's dev-mode
6
+ // transform, so the WX host only extends it.
7
+ //
8
+ // Delivery is passive: every valid hmr/patches.js suffix is acknowledged by Rolldown
9
+ // sequence, then applied synchronously before the Page continues evaluating. Already-applied
10
+ // sequences are ignored when another Page requires the same physical file.
11
+
12
+ import type { DevRuntime as RolldownDevRuntime } from 'rolldown/experimental/runtime-types'
13
+
14
+ /** Lexical base class injected into the runtime chunk by Rolldown; typed via the contract. */
15
+ declare const DevRuntime: new (clientId: string) => RolldownDevRuntime
16
+
17
+ /** Identity and report endpoint, materialized by the host into hmr/info.js for every full build. */
18
+ type HmrInfo = Readonly<{
19
+ buildId: string
20
+ endpoint: string
21
+ }>
22
+
23
+ /** One physical hmr/patches.js payload: the build identity plus one patch program per update. */
24
+ type PatchPayload = Readonly<{
25
+ buildId: string
26
+ patches: readonly PatchProgram[]
27
+ }>
28
+
29
+ /** One patch: its Rolldown sequence, changed module ids, and factory program. */
30
+ type PatchProgram = Readonly<{
31
+ seq: number
32
+ /** Stable ids of the changed modules; the sync apply walks the graph from these. */
33
+ changedIds: string[]
34
+ factory: () => void
35
+ }>
36
+
37
+ type HmrUpdate = Readonly<{
38
+ boundaries: readonly string[]
39
+ updateSet: ReadonlySet<string>
40
+ }>
41
+
42
+ type AcceptCallback = (moduleExports: unknown) => void
43
+
44
+ /**
45
+ * Per-module hot state, mirroring Rolldown's web runtime: accept is a passive registration;
46
+ * the propagation invokes the previous execution's callbacks with the fresh exports.
47
+ */
48
+ class WxHotContext {
49
+ readonly _internal = {
50
+ updateStyle(): void {},
51
+ removeStyle(): void {}
52
+ }
53
+
54
+ /** Registered self-accept callbacks; a bare accept is represented by a no-op callback. */
55
+ private readonly acceptCallbacks: AcceptCallback[] = []
56
+
57
+ /** Set when a callback rejects a Refresh boundary; the current update then rebuilds. */
58
+ private invalidationReason: string | undefined
59
+
60
+ accept(callback?: AcceptCallback): void {
61
+ this.acceptCallbacks.push(callback ?? (() => {}))
62
+ }
63
+
64
+ hasAccepts(): boolean {
65
+ return this.acceptCallbacks.length > 0
66
+ }
67
+
68
+ /** Invokes this old context's callbacks and returns any requested invalidation. */
69
+ runAccept(moduleExports: unknown): string | undefined {
70
+ for (const callback of this.acceptCallbacks) {
71
+ callback(moduleExports)
72
+ }
73
+ return this.invalidationReason
74
+ }
75
+
76
+ invalidate(reason?: string): void {
77
+ this.invalidationReason = reason ?? 'the accepting module invalidated the update'
78
+ }
79
+
80
+ // Vite's generated CSS module calls hot.prune with its style teardown; the physical
81
+ // rebuild replaces styles wholesale, so it is a no-op.
82
+ prune(_callback?: () => void): void {}
83
+ }
84
+
85
+ /** The WX host: extends the Rolldown contract instead of reimplementing it. */
86
+ class WxDevRuntime extends DevRuntime {
87
+ private hmrInfo: HmrInfo | undefined
88
+
89
+ /** Highest Rolldown sequence successfully applied. */
90
+ private appliedSeq = 0
91
+
92
+ /** Active hot contexts per module id; the propagation invokes their callbacks. */
93
+ private readonly moduleHotContexts = new Map<string, WxHotContext>()
94
+
95
+ constructor() {
96
+ // The base has no messenger: the engine tracks per-client shipped payloads instead
97
+ // of executed module ids, so the wx host registers the client session itself.
98
+ super('')
99
+ }
100
+
101
+ /**
102
+ * Generated code always calls this before registerModule and reads `_internal` from the
103
+ * return value. Mirrors Rolldown's web runtime: each execution immediately replaces the
104
+ * module's hot context; the apply plan has already captured the previous callbacks.
105
+ */
106
+ override createModuleHotContext(moduleId: string): WxHotContext {
107
+ const hotContext = new WxHotContext()
108
+ this.moduleHotContexts.set(moduleId, hotContext)
109
+ return hotContext
110
+ }
111
+
112
+ /** Computes accepting boundaries and every executed module that must be re-armed. */
113
+ private computeHmrUpdate(changedIds: readonly string[]): HmrUpdate | undefined {
114
+ // Mutable traversal accumulators are confined to one synchronous update plan.
115
+ const boundaries: string[] = []
116
+ const updateSet = new Set<string>()
117
+
118
+ for (const changedId of changedIds) {
119
+ if (!this.isExecuted(changedId)) continue
120
+
121
+ // Mutable only for the current DFS path, providing O(1) cycle checks.
122
+ const path = new Set([changedId])
123
+ const fullReloadReason = this.bubble(changedId, path, updateSet, boundaries)
124
+ if (fullReloadReason) {
125
+ throw new Error(fullReloadReason)
126
+ }
127
+ }
128
+
129
+ return boundaries.length > 0 ? { boundaries, updateSet } : undefined
130
+ }
131
+
132
+ /** Walks executed importers until an accepting boundary is found. */
133
+ private bubble(
134
+ moduleId: string,
135
+ path: Set<string>,
136
+ updateSet: Set<string>,
137
+ boundaries: string[]
138
+ ): string | undefined {
139
+ if (updateSet.has(moduleId)) return undefined
140
+ updateSet.add(moduleId)
141
+
142
+ if (this.moduleHotContexts.get(moduleId)?.hasAccepts()) {
143
+ boundaries.push(moduleId)
144
+ return undefined
145
+ }
146
+
147
+ const importers = this.getImporters(moduleId).filter((importer) => this.isExecuted(importer))
148
+ if (importers.length === 0) {
149
+ return `no HMR boundary found for module ${moduleId}`
150
+ }
151
+
152
+ for (const importer of importers) {
153
+ if (path.has(importer)) {
154
+ return `circular HMR propagation between ${moduleId} and ${importer}`
155
+ }
156
+
157
+ path.add(importer)
158
+ const fullReloadReason = this.bubble(importer, path, updateSet, boundaries)
159
+ path.delete(importer)
160
+ if (fullReloadReason) return fullReloadReason
161
+ }
162
+ return undefined
163
+ }
164
+
165
+ /**
166
+ * Applies one patch in three phases: capture old contexts, evict the whole update set,
167
+ * then re-run accepting modules and pass their fresh exports to the old contexts.
168
+ */
169
+ private applyHmrUpdate(changedIds: readonly string[]): void {
170
+ const update = this.computeHmrUpdate(changedIds)
171
+ if (!update) return
172
+
173
+ for (const moduleId of update.updateSet) {
174
+ if (!this.hasFactory(moduleId)) {
175
+ throw new Error(`no HMR factory for module ${moduleId}`)
176
+ }
177
+ }
178
+
179
+ const applies = update.boundaries.map((moduleId) => ({
180
+ moduleId,
181
+ hotContext: this.moduleHotContexts.get(moduleId)
182
+ }))
183
+
184
+ // This eviction must happen before initModule: otherwise its cache gate returns the
185
+ // old exports and the freshly registered factory never executes.
186
+ for (const moduleId of update.updateSet) {
187
+ this.removeModuleCache(moduleId)
188
+ }
189
+
190
+ for (const { moduleId, hotContext } of applies) {
191
+ const invalidationReason = hotContext?.runAccept(this.initModule(moduleId))
192
+ if (invalidationReason) {
193
+ throw new Error(`${moduleId}: ${invalidationReason}`)
194
+ }
195
+ }
196
+ }
197
+
198
+ /** Consumed once per App heap from hmr/info.js; the host buildId is the delivery identity. */
199
+ initialize(info: HmrInfo): void {
200
+ if (this.hmrInfo) {
201
+ return
202
+ }
203
+ this.hmrInfo = info
204
+ // Anchor: the host publishes only after the runtime reports its delivery position.
205
+ void this.sendReport({ kind: 'delivery', seq: this.appliedSeq })
206
+ }
207
+
208
+ /** True between a patch delivery and the next page show: a hot reload is in progress. */
209
+ private hotReloading = false
210
+
211
+ /** The capsule wrapper asks this during the synthetic lifecycle of a hot reload. */
212
+ isHotReloading(): boolean {
213
+ return this.hotReloading
214
+ }
215
+
216
+ /** The wrapped onShow ends the hot reload after the replacement cycle. */
217
+ clearHotReloading(): void {
218
+ this.hotReloading = false
219
+ }
220
+
221
+ /** The only direct effect of hmr/patches.js: validate, store, acknowledge, and apply. */
222
+ storePatches(payload: PatchPayload): void {
223
+ const info = this.hmrInfo
224
+ if (!info || payload.buildId !== info.buildId) {
225
+ console.warn('[vpt] patches for a stale build')
226
+ return
227
+ }
228
+
229
+ const deliveredSeq = Math.max(this.appliedSeq, payload.patches.at(-1)?.seq ?? 0)
230
+ void this.sendReport({ kind: 'delivery', seq: deliveredSeq })
231
+
232
+ // A delivered patch means DevTools is about to replay the page lifecycle on the
233
+ // re-executing Pages; the capsule wrapper suppresses the synthetic unmount/mount so
234
+ // the React tree survives and Refresh swaps the code in place.
235
+ this.hotReloading = true
236
+
237
+ // Apply synchronously: the page's imports below the require resolve against the
238
+ // freshly registered modules, so the re-executed Page evaluates with the new code.
239
+ this.applyPatches(payload.patches)
240
+ }
241
+
242
+ /** Applies one physical suffix in Rolldown sequence order. */
243
+ private applyPatches(patches: readonly PatchProgram[]): void {
244
+ for (const patch of patches) {
245
+ if (patch.seq <= this.appliedSeq) continue
246
+
247
+ try {
248
+ const expectedSeq = this.appliedSeq + 1
249
+ if (patch.seq !== expectedSeq) {
250
+ throw new Error(`missing patch sequence ${expectedSeq}`)
251
+ }
252
+ patch.factory()
253
+ this.applyHmrUpdate(patch.changedIds)
254
+ this.appliedSeq = patch.seq
255
+ } catch (error) {
256
+ console.warn(`[vpt] patch sequence ${patch.seq} failed; apply stopped`, error)
257
+ void this.sendReport({ kind: 'rebuild' })
258
+ return
259
+ }
260
+ }
261
+ }
262
+
263
+ /** Sends one metadata-only report to the host; executable code never travels over HTTP. */
264
+ private sendReport(data: Record<string, unknown>): Promise<void> {
265
+ const info = this.hmrInfo
266
+ if (!info) {
267
+ // A report without initialize is a programming error; fail loudly instead of
268
+ // silently dropping the sync traffic.
269
+ throw new Error('WX dev runtime is not initialized')
270
+ }
271
+ return new Promise((resolve, reject) => {
272
+ wx.request({
273
+ url: info.endpoint,
274
+ method: 'POST',
275
+ data: { buildId: info.buildId, ...data },
276
+ header: { 'content-type': 'application/json' },
277
+ success(): void {
278
+ resolve()
279
+ },
280
+ fail(error: unknown): void {
281
+ reject(error)
282
+ }
283
+ })
284
+ })
285
+ }
286
+ }
287
+
288
+ const runtime = new WxDevRuntime()
289
+ ;(globalThis as { __rolldown_runtime__?: WxDevRuntime }).__rolldown_runtime__ = runtime
290
+
291
+ // Install the React DevTools hook before the Taro renderer injects itself: the runtime chunk
292
+ // is the first module of the App heap, and the renderer checks the hook when it evaluates at
293
+ // App mount. The refresh runtime's own injection (see react-refresh.ts) replays this hook's
294
+ // renderers, so the hook must store what inject receives — a real DevTools hook keeps the
295
+ // renderer in the renderers Map; without the stored renderer the replay captures nothing and
296
+ // Refresh has no renderer helpers to schedule re-renders on.
297
+ //
298
+ // The hook lives on `global`, and every free `__REACT_DEVTOOLS_GLOBAL_HOOK__` reference in
299
+ // react-family modules is rewritten to `global.__REACT_DEVTOOLS_GLOBAL_HOOK__`: the
300
+ // The WeChat runtime scope does not resolve free variables against `global` (verified: the free
301
+ // lookup is undefined while the member access exists), so the renderer would never inject
302
+ // otherwise. `??=` keeps a pre-installed hook (e.g. a real DevTools integration) intact; the
303
+ // runtime chunk's own lowering keeps the operator es2018-compatible.
304
+ const reactDevtoolsHook = {
305
+ renderers: new Map<number, unknown>(),
306
+ supportsFiber: true,
307
+ inject: (injected: unknown) => {
308
+ const id = reactDevtoolsHook.renderers.size
309
+ reactDevtoolsHook.renderers.set(id, injected)
310
+ return id
311
+ },
312
+ onScheduleFiberRoot: () => {},
313
+ onCommitFiberRoot: () => {},
314
+ onCommitFiberUnmount: () => {}
315
+ }
316
+ // node types declare `global` as typeof globalThis, so the WeChat global needs a cast.
317
+ ;(global as WeChatGlobal).__REACT_DEVTOOLS_GLOBAL_HOOK__ ??= reactDevtoolsHook
@@ -0,0 +1,4 @@
1
+ import '../amphibious/bootstrap.ts'
2
+ import appConfig from '../capsule/app.ts'
3
+
4
+ App(appConfig)
@@ -0,0 +1,4 @@
1
+ import '../amphibious/bootstrap.ts'
2
+ import componentConfig from '../capsule/component.ts'
3
+
4
+ Component(componentConfig)
@@ -0,0 +1,6 @@
1
+ import '../amphibious/bootstrap.ts'
2
+
3
+ // @ts-expect-error: The wx build resolves the route-specific Page capsule.
4
+ import pageConfig from '\0vpt:page-capsule'
5
+
6
+ Page(pageConfig)
@@ -0,0 +1,10 @@
1
+ MIT License
2
+ -----------
3
+
4
+ Copyright (C) 2013-2022 Guy Bedford
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7
+
8
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
+
10
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.