@wyw-in-js/transform 1.1.0 → 2.0.0-alpha.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 (603) hide show
  1. package/esm/cache.js +426 -289
  2. package/esm/cache.js.map +1 -1
  3. package/esm/debug/fileReporter.js +137 -134
  4. package/esm/debug/fileReporter.js.map +1 -1
  5. package/esm/eval/broker.js +2134 -0
  6. package/esm/eval/broker.js.map +1 -0
  7. package/esm/eval/lru.js +36 -0
  8. package/esm/eval/lru.js.map +1 -0
  9. package/esm/eval/prepareModuleOnDemand.js +21 -0
  10. package/esm/eval/prepareModuleOnDemand.js.map +1 -0
  11. package/esm/eval/protocol.js +2 -0
  12. package/esm/eval/protocol.js.map +1 -0
  13. package/esm/eval/resolverStrategy.js +51 -0
  14. package/esm/eval/resolverStrategy.js.map +1 -0
  15. package/esm/eval/runner.js +1759 -0
  16. package/esm/eval/runner.js.map +1 -0
  17. package/esm/eval/serialize.js +333 -0
  18. package/esm/eval/serialize.js.map +1 -0
  19. package/esm/eval/writeQueue.js +81 -0
  20. package/esm/eval/writeQueue.js.map +1 -0
  21. package/esm/evaluators/index.js +11 -12
  22. package/esm/evaluators/index.js.map +1 -1
  23. package/esm/index.js +25 -29
  24. package/esm/index.js.map +1 -1
  25. package/esm/module.js +896 -520
  26. package/esm/module.js.map +1 -1
  27. package/esm/shaker.js +14 -80
  28. package/esm/shaker.js.map +1 -1
  29. package/esm/transform/BaseEntrypoint.js +162 -164
  30. package/esm/transform/BaseEntrypoint.js.map +1 -1
  31. package/esm/transform/Entrypoint.helpers.js +96 -253
  32. package/esm/transform/Entrypoint.helpers.js.map +1 -1
  33. package/esm/transform/Entrypoint.js +336 -270
  34. package/esm/transform/Entrypoint.js.map +1 -1
  35. package/esm/transform/Entrypoint.types.js +1 -1
  36. package/esm/transform/Entrypoint.types.js.map +1 -1
  37. package/esm/transform/EvaluatedEntrypoint.js +10 -4
  38. package/esm/transform/EvaluatedEntrypoint.js.map +1 -1
  39. package/esm/transform/actions/AbortError.js +6 -6
  40. package/esm/transform/actions/AbortError.js.map +1 -1
  41. package/esm/transform/actions/BaseAction.js +140 -136
  42. package/esm/transform/actions/BaseAction.js.map +1 -1
  43. package/esm/transform/actions/UnprocessedEntrypointError.js +6 -6
  44. package/esm/transform/actions/UnprocessedEntrypointError.js.map +1 -1
  45. package/esm/transform/actions/actionRunner.js +63 -66
  46. package/esm/transform/actions/actionRunner.js.map +1 -1
  47. package/esm/transform/actions/types.js +1 -1
  48. package/esm/transform/actions/types.js.map +1 -1
  49. package/esm/transform/barrelManifest.types.js +2 -0
  50. package/esm/transform/barrelManifest.types.js.map +1 -0
  51. package/esm/transform/generators/baseProcessingHandlers.js +15 -17
  52. package/esm/transform/generators/baseProcessingHandlers.js.map +1 -1
  53. package/esm/transform/generators/collect.js +27 -55
  54. package/esm/transform/generators/collect.js.map +1 -1
  55. package/esm/transform/generators/createStylisPreprocessor.js +353 -321
  56. package/esm/transform/generators/createStylisPreprocessor.js.map +1 -1
  57. package/esm/transform/generators/evalFile.js +48 -47
  58. package/esm/transform/generators/evalFile.js.map +1 -1
  59. package/esm/transform/generators/extract.js +78 -90
  60. package/esm/transform/generators/extract.js.map +1 -1
  61. package/esm/transform/generators/getExports.js +57 -74
  62. package/esm/transform/generators/getExports.js.map +1 -1
  63. package/esm/transform/generators/index.js +11 -11
  64. package/esm/transform/generators/index.js.map +1 -1
  65. package/esm/transform/generators/processEntrypoint.js +78 -67
  66. package/esm/transform/generators/processEntrypoint.js.map +1 -1
  67. package/esm/transform/generators/processImports.js +102 -67
  68. package/esm/transform/generators/processImports.js.map +1 -1
  69. package/esm/transform/generators/resolveImports.js +165 -196
  70. package/esm/transform/generators/resolveImports.js.map +1 -1
  71. package/esm/transform/generators/resolveStaticOxcValues.js +2911 -0
  72. package/esm/transform/generators/resolveStaticOxcValues.js.map +1 -0
  73. package/esm/transform/generators/rewriteOxcBarrelImports.js +822 -0
  74. package/esm/transform/generators/rewriteOxcBarrelImports.js.map +1 -0
  75. package/esm/transform/generators/transform.js +239 -248
  76. package/esm/transform/generators/transform.js.map +1 -1
  77. package/esm/transform/generators/workflow.js +87 -90
  78. package/esm/transform/generators/workflow.js.map +1 -1
  79. package/esm/transform/helpers/loadWywOptions.js +154 -74
  80. package/esm/transform/helpers/loadWywOptions.js.map +1 -1
  81. package/esm/transform/helpers/withDefaultServices.js +13 -22
  82. package/esm/transform/helpers/withDefaultServices.js.map +1 -1
  83. package/esm/transform/isStaticallyEvaluatableModule.js +140 -152
  84. package/esm/transform/isStaticallyEvaluatableModule.js.map +1 -1
  85. package/esm/transform/oxcBarrelManifest.js +349 -0
  86. package/esm/transform/oxcBarrelManifest.js.map +1 -0
  87. package/esm/transform/rootLog.js +3 -3
  88. package/esm/transform/rootLog.js.map +1 -1
  89. package/esm/transform/syntax.js +2 -0
  90. package/esm/transform/syntax.js.map +1 -0
  91. package/esm/transform/types.js +2 -2
  92. package/esm/transform/types.js.map +1 -1
  93. package/esm/transform.js +123 -147
  94. package/esm/transform.js.map +1 -1
  95. package/esm/types.js +4 -1
  96. package/esm/types.js.map +1 -1
  97. package/esm/utils/EventEmitter.js +46 -48
  98. package/esm/utils/EventEmitter.js.map +1 -1
  99. package/esm/utils/ShakerMetadata.js +2 -2
  100. package/esm/utils/ShakerMetadata.js.map +1 -1
  101. package/esm/utils/TransformDiagnostics.js +9 -9
  102. package/esm/utils/TransformDiagnostics.js.map +1 -1
  103. package/esm/utils/TransformMetadata.js +24 -26
  104. package/esm/utils/TransformMetadata.js.map +1 -1
  105. package/esm/utils/applyOxcProcessors.js +1217 -0
  106. package/esm/utils/applyOxcProcessors.js.map +1 -0
  107. package/esm/utils/collectOxcExportsAndImports.js +934 -0
  108. package/esm/utils/collectOxcExportsAndImports.js.map +1 -0
  109. package/esm/utils/collectOxcRuntime.js +220 -0
  110. package/esm/utils/collectOxcRuntime.js.map +1 -0
  111. package/esm/utils/collectOxcTemplateDependencies.js +1398 -0
  112. package/esm/utils/collectOxcTemplateDependencies.js.map +1 -0
  113. package/esm/utils/dispose-polyfill.js +3 -4
  114. package/esm/utils/dispose-polyfill.js.map +1 -1
  115. package/esm/utils/getFileIdx.js +6 -6
  116. package/esm/utils/getFileIdx.js.map +1 -1
  117. package/esm/utils/getPluginKey.js +12 -12
  118. package/esm/utils/getPluginKey.js.map +1 -1
  119. package/esm/utils/getVisitorKeys.js +9 -3
  120. package/esm/utils/getVisitorKeys.js.map +1 -1
  121. package/esm/utils/hasCachedWywPrevalExport.js +23 -0
  122. package/esm/utils/hasCachedWywPrevalExport.js.map +1 -0
  123. package/esm/utils/hasWywPreval.js +5 -5
  124. package/esm/utils/hasWywPreval.js.map +1 -1
  125. package/esm/utils/importOverrides.js +75 -90
  126. package/esm/utils/importOverrides.js.map +1 -1
  127. package/esm/utils/isNode.js +2 -2
  128. package/esm/utils/isNode.js.map +1 -1
  129. package/esm/utils/isNotNull.js +2 -2
  130. package/esm/utils/isNotNull.js.map +1 -1
  131. package/esm/utils/isSerializable.js +11 -11
  132. package/esm/utils/isSerializable.js.map +1 -1
  133. package/esm/utils/oxcAstService.js +121 -0
  134. package/esm/utils/oxcAstService.js.map +1 -0
  135. package/esm/utils/oxcEmit.js +447 -0
  136. package/esm/utils/oxcEmit.js.map +1 -0
  137. package/esm/utils/oxcPreevalStage.js +97 -0
  138. package/esm/utils/oxcPreevalStage.js.map +1 -0
  139. package/esm/utils/oxcPreevalTransforms.js +1054 -0
  140. package/esm/utils/oxcPreevalTransforms.js.map +1 -0
  141. package/esm/utils/oxcShaker.js +662 -0
  142. package/esm/utils/oxcShaker.js.map +1 -0
  143. package/esm/utils/parseOxc.js +37 -0
  144. package/esm/utils/parseOxc.js.map +1 -0
  145. package/esm/utils/parseRequest.js +27 -27
  146. package/esm/utils/parseRequest.js.map +1 -1
  147. package/esm/utils/peek.js +1 -1
  148. package/esm/utils/peek.js.map +1 -1
  149. package/esm/utils/processorLookup.js +125 -0
  150. package/esm/utils/processorLookup.js.map +1 -0
  151. package/esm/utils/resolveWithConditions.js +99 -0
  152. package/esm/utils/resolveWithConditions.js.map +1 -0
  153. package/esm/vm/createVmContext.js +140 -141
  154. package/esm/vm/createVmContext.js.map +1 -1
  155. package/esm/vm/process.js +11 -13
  156. package/esm/vm/process.js.map +1 -1
  157. package/package.json +18 -26
  158. package/types/cache.d.ts +17 -8
  159. package/types/cache.js +237 -95
  160. package/types/debug/fileReporter.js +22 -22
  161. package/types/eval/broker.d.ts +88 -0
  162. package/types/eval/broker.js +2262 -0
  163. package/types/eval/lru.d.ts +10 -0
  164. package/types/eval/lru.js +36 -0
  165. package/types/eval/prepareModuleOnDemand.d.ts +7 -0
  166. package/types/eval/prepareModuleOnDemand.js +24 -0
  167. package/types/eval/protocol.d.ts +97 -0
  168. package/types/eval/protocol.js +1 -0
  169. package/types/eval/resolverStrategy.d.ts +13 -0
  170. package/types/eval/resolverStrategy.js +46 -0
  171. package/types/eval/serialize.d.ts +78 -0
  172. package/types/eval/serialize.js +357 -0
  173. package/types/eval/writeQueue.d.ts +13 -0
  174. package/types/eval/writeQueue.js +80 -0
  175. package/types/evaluators/index.d.ts +2 -2
  176. package/types/evaluators/index.js +6 -9
  177. package/types/index.d.ts +3 -6
  178. package/types/index.js +24 -82
  179. package/types/module.d.ts +35 -7
  180. package/types/module.js +535 -163
  181. package/types/shaker.d.ts +2 -10
  182. package/types/shaker.js +10 -100
  183. package/types/transform/BaseEntrypoint.js +6 -11
  184. package/types/transform/Entrypoint.d.ts +15 -15
  185. package/types/transform/Entrypoint.helpers.d.ts +2 -5
  186. package/types/transform/Entrypoint.helpers.js +43 -203
  187. package/types/transform/Entrypoint.js +130 -53
  188. package/types/transform/Entrypoint.types.d.ts +28 -6
  189. package/types/transform/Entrypoint.types.js +1 -2
  190. package/types/transform/EvaluatedEntrypoint.d.ts +13 -2
  191. package/types/transform/EvaluatedEntrypoint.js +7 -6
  192. package/types/transform/actions/AbortError.js +2 -7
  193. package/types/transform/actions/BaseAction.js +4 -8
  194. package/types/transform/actions/UnprocessedEntrypointError.js +2 -7
  195. package/types/transform/actions/actionRunner.js +8 -12
  196. package/types/transform/actions/types.d.ts +2 -2
  197. package/types/transform/actions/types.js +1 -2
  198. package/types/transform/{barrelManifest.d.ts → barrelManifest.types.d.ts} +0 -2
  199. package/types/transform/barrelManifest.types.js +1 -0
  200. package/types/transform/generators/baseProcessingHandlers.d.ts +4 -5
  201. package/types/transform/generators/baseProcessingHandlers.js +10 -14
  202. package/types/transform/generators/collect.js +13 -39
  203. package/types/transform/generators/createStylisPreprocessor.js +19 -60
  204. package/types/transform/generators/evalFile.d.ts +2 -2
  205. package/types/transform/generators/evalFile.js +26 -28
  206. package/types/transform/generators/extract.js +5 -8
  207. package/types/transform/generators/getExports.js +23 -30
  208. package/types/transform/generators/index.d.ts +2 -2
  209. package/types/transform/generators/index.js +11 -14
  210. package/types/transform/generators/processEntrypoint.d.ts +2 -2
  211. package/types/transform/generators/processEntrypoint.js +60 -26
  212. package/types/transform/generators/processImports.d.ts +0 -3
  213. package/types/transform/generators/processImports.js +60 -20
  214. package/types/transform/generators/resolveImports.js +18 -22
  215. package/types/transform/generators/resolveStaticOxcValues.d.ts +2 -0
  216. package/types/transform/generators/resolveStaticOxcValues.js +3235 -0
  217. package/types/transform/generators/{rewriteBarrelImports.d.ts → rewriteOxcBarrelImports.d.ts} +2 -3
  218. package/types/transform/generators/{rewriteBarrelImports.js → rewriteOxcBarrelImports.js} +282 -225
  219. package/types/transform/generators/transform.d.ts +3 -7
  220. package/types/transform/generators/transform.js +203 -199
  221. package/types/transform/generators/workflow.js +62 -45
  222. package/types/transform/helpers/loadWywOptions.js +94 -20
  223. package/types/transform/helpers/withDefaultServices.d.ts +1 -1
  224. package/types/transform/helpers/withDefaultServices.js +6 -44
  225. package/types/transform/isStaticallyEvaluatableModule.d.ts +1 -2
  226. package/types/transform/isStaticallyEvaluatableModule.js +125 -126
  227. package/types/transform/oxcBarrelManifest.d.ts +2 -0
  228. package/types/transform/{barrelManifest.js → oxcBarrelManifest.js} +156 -97
  229. package/types/transform/rootLog.js +2 -5
  230. package/types/transform/syntax.d.ts +38 -0
  231. package/types/transform/syntax.js +1 -0
  232. package/types/transform/types.d.ts +9 -6
  233. package/types/transform/types.js +1 -4
  234. package/types/transform.d.ts +2 -2
  235. package/types/transform.js +88 -101
  236. package/types/types.d.ts +0 -23
  237. package/types/types.js +1 -2
  238. package/types/utils/EventEmitter.js +3 -9
  239. package/types/utils/ShakerMetadata.js +1 -5
  240. package/types/utils/TransformDiagnostics.js +3 -7
  241. package/types/utils/TransformMetadata.js +8 -16
  242. package/types/utils/applyOxcProcessors.d.ts +16 -0
  243. package/types/utils/applyOxcProcessors.js +1391 -0
  244. package/types/utils/collectOxcExportsAndImports.d.ts +35 -0
  245. package/types/utils/collectOxcExportsAndImports.js +957 -0
  246. package/types/utils/collectOxcRuntime.d.ts +14 -0
  247. package/types/utils/collectOxcRuntime.js +250 -0
  248. package/types/utils/collectOxcTemplateDependencies.d.ts +38 -0
  249. package/types/utils/collectOxcTemplateDependencies.js +1580 -0
  250. package/types/utils/getFileIdx.js +1 -4
  251. package/types/utils/getPluginKey.d.ts +5 -2
  252. package/types/utils/getPluginKey.js +2 -6
  253. package/types/utils/getVisitorKeys.d.ts +4 -4
  254. package/types/utils/getVisitorKeys.js +9 -6
  255. package/types/utils/hasCachedWywPrevalExport.d.ts +14 -0
  256. package/types/utils/hasCachedWywPrevalExport.js +30 -0
  257. package/types/utils/hasWywPreval.js +1 -4
  258. package/types/utils/importOverrides.js +17 -27
  259. package/types/utils/isNode.d.ts +2 -2
  260. package/types/utils/isNode.js +2 -6
  261. package/types/utils/isNotNull.js +1 -4
  262. package/types/utils/isSerializable.js +3 -6
  263. package/types/utils/oxcAstService.d.ts +11 -0
  264. package/types/utils/oxcAstService.js +79 -0
  265. package/types/utils/oxcEmit.d.ts +19 -0
  266. package/types/utils/oxcEmit.js +506 -0
  267. package/types/utils/oxcPreevalStage.d.ts +20 -0
  268. package/types/utils/oxcPreevalStage.js +102 -0
  269. package/types/utils/oxcPreevalTransforms.d.ts +13 -0
  270. package/types/utils/oxcPreevalTransforms.js +1179 -0
  271. package/types/utils/oxcShaker.d.ts +13 -0
  272. package/types/utils/oxcShaker.js +751 -0
  273. package/types/utils/parseOxc.d.ts +11 -0
  274. package/types/utils/parseOxc.js +38 -0
  275. package/types/utils/parseRequest.js +2 -7
  276. package/types/utils/peek.js +1 -5
  277. package/types/utils/processorLookup.d.ts +8 -0
  278. package/types/utils/processorLookup.js +135 -0
  279. package/types/utils/resolveWithConditions.d.ts +12 -0
  280. package/types/utils/resolveWithConditions.js +103 -0
  281. package/types/vm/createVmContext.d.ts +2 -2
  282. package/types/vm/createVmContext.js +25 -62
  283. package/types/vm/process.js +20 -26
  284. package/esm/babel.js +0 -2
  285. package/esm/babel.js.map +0 -1
  286. package/esm/options/buildOptions.js +0 -168
  287. package/esm/options/buildOptions.js.map +0 -1
  288. package/esm/options/buildOptions.test.js +0 -138
  289. package/esm/options/buildOptions.test.js.map +0 -1
  290. package/esm/options/loadBabelOptions.js +0 -24
  291. package/esm/options/loadBabelOptions.js.map +0 -1
  292. package/esm/plugins/babel-transform.js +0 -53
  293. package/esm/plugins/babel-transform.js.map +0 -1
  294. package/esm/plugins/collector.js +0 -60
  295. package/esm/plugins/collector.js.map +0 -1
  296. package/esm/plugins/dynamic-import.js +0 -56
  297. package/esm/plugins/dynamic-import.js.map +0 -1
  298. package/esm/plugins/preeval.js +0 -73
  299. package/esm/plugins/preeval.js.map +0 -1
  300. package/esm/plugins/shaker.js +0 -680
  301. package/esm/plugins/shaker.js.map +0 -1
  302. package/esm/transform/barrelManifest.js +0 -291
  303. package/esm/transform/barrelManifest.js.map +0 -1
  304. package/esm/transform/generators/explodeReexports.js +0 -64
  305. package/esm/transform/generators/explodeReexports.js.map +0 -1
  306. package/esm/transform/generators/rewriteBarrelImports.js +0 -733
  307. package/esm/transform/generators/rewriteBarrelImports.js.map +0 -1
  308. package/esm/utils/addIdentifierToWywPreval.js +0 -68
  309. package/esm/utils/addIdentifierToWywPreval.js.map +0 -1
  310. package/esm/utils/collectExportsAndImports.js +0 -1157
  311. package/esm/utils/collectExportsAndImports.js.map +0 -1
  312. package/esm/utils/collectTemplateDependencies.js +0 -228
  313. package/esm/utils/collectTemplateDependencies.js.map +0 -1
  314. package/esm/utils/createId.js +0 -6
  315. package/esm/utils/createId.js.map +0 -1
  316. package/esm/utils/findIdentifiers.js +0 -62
  317. package/esm/utils/findIdentifiers.js.map +0 -1
  318. package/esm/utils/getConstantStringValue.js +0 -58
  319. package/esm/utils/getConstantStringValue.js.map +0 -1
  320. package/esm/utils/getMemberExpressionPropertyName.js +0 -11
  321. package/esm/utils/getMemberExpressionPropertyName.js.map +0 -1
  322. package/esm/utils/getScope.js +0 -6
  323. package/esm/utils/getScope.js.map +0 -1
  324. package/esm/utils/getSource.js +0 -15
  325. package/esm/utils/getSource.js.map +0 -1
  326. package/esm/utils/getTagProcessor.js +0 -404
  327. package/esm/utils/getTagProcessor.js.map +0 -1
  328. package/esm/utils/isExports.js +0 -22
  329. package/esm/utils/isExports.js.map +0 -1
  330. package/esm/utils/isGlobal.js +0 -6
  331. package/esm/utils/isGlobal.js.map +0 -1
  332. package/esm/utils/isNodePath.js +0 -4
  333. package/esm/utils/isNodePath.js.map +0 -1
  334. package/esm/utils/isRemoved.js +0 -46
  335. package/esm/utils/isRemoved.js.map +0 -1
  336. package/esm/utils/isRequire.js +0 -13
  337. package/esm/utils/isRequire.js.map +0 -1
  338. package/esm/utils/isTypedNode.js +0 -6
  339. package/esm/utils/isTypedNode.js.map +0 -1
  340. package/esm/utils/isUnnecessaryReactCall.js +0 -72
  341. package/esm/utils/isUnnecessaryReactCall.js.map +0 -1
  342. package/esm/utils/removeDangerousCode.js +0 -276
  343. package/esm/utils/removeDangerousCode.js.map +0 -1
  344. package/esm/utils/replaceImportMetaEnv.js +0 -44
  345. package/esm/utils/replaceImportMetaEnv.js.map +0 -1
  346. package/esm/utils/scopeHelpers.js +0 -527
  347. package/esm/utils/scopeHelpers.js.map +0 -1
  348. package/esm/utils/traversalCache.js +0 -23
  349. package/esm/utils/traversalCache.js.map +0 -1
  350. package/esm/utils/unwrapExpression.js +0 -18
  351. package/esm/utils/unwrapExpression.js.map +0 -1
  352. package/esm/utils/unwrapSequence.js +0 -14
  353. package/esm/utils/unwrapSequence.js.map +0 -1
  354. package/esm/utils/valueToLiteral.js +0 -59
  355. package/esm/utils/valueToLiteral.js.map +0 -1
  356. package/esm/utils/visitors/JSXElementsRemover.js +0 -51
  357. package/esm/utils/visitors/JSXElementsRemover.js.map +0 -1
  358. package/lib/babel.js +0 -2
  359. package/lib/babel.js.map +0 -1
  360. package/lib/cache.js +0 -308
  361. package/lib/cache.js.map +0 -1
  362. package/lib/debug/fileReporter.js +0 -153
  363. package/lib/debug/fileReporter.js.map +0 -1
  364. package/lib/evaluators/index.js +0 -20
  365. package/lib/evaluators/index.js.map +0 -1
  366. package/lib/index.js +0 -286
  367. package/lib/index.js.map +0 -1
  368. package/lib/module.js +0 -552
  369. package/lib/module.js.map +0 -1
  370. package/lib/options/buildOptions.js +0 -176
  371. package/lib/options/buildOptions.js.map +0 -1
  372. package/lib/options/buildOptions.test.js +0 -141
  373. package/lib/options/buildOptions.test.js.map +0 -1
  374. package/lib/options/loadBabelOptions.js +0 -31
  375. package/lib/options/loadBabelOptions.js.map +0 -1
  376. package/lib/plugins/babel-transform.js +0 -60
  377. package/lib/plugins/babel-transform.js.map +0 -1
  378. package/lib/plugins/collector.js +0 -70
  379. package/lib/plugins/collector.js.map +0 -1
  380. package/lib/plugins/dynamic-import.js +0 -61
  381. package/lib/plugins/dynamic-import.js.map +0 -1
  382. package/lib/plugins/preeval.js +0 -81
  383. package/lib/plugins/preeval.js.map +0 -1
  384. package/lib/plugins/shaker.js +0 -691
  385. package/lib/plugins/shaker.js.map +0 -1
  386. package/lib/shaker.js +0 -95
  387. package/lib/shaker.js.map +0 -1
  388. package/lib/transform/BaseEntrypoint.js +0 -179
  389. package/lib/transform/BaseEntrypoint.js.map +0 -1
  390. package/lib/transform/Entrypoint.helpers.js +0 -279
  391. package/lib/transform/Entrypoint.helpers.js.map +0 -1
  392. package/lib/transform/Entrypoint.js +0 -289
  393. package/lib/transform/Entrypoint.js.map +0 -1
  394. package/lib/transform/Entrypoint.types.js +0 -2
  395. package/lib/transform/Entrypoint.types.js.map +0 -1
  396. package/lib/transform/EvaluatedEntrypoint.js +0 -13
  397. package/lib/transform/EvaluatedEntrypoint.js.map +0 -1
  398. package/lib/transform/actions/AbortError.js +0 -16
  399. package/lib/transform/actions/AbortError.js.map +0 -1
  400. package/lib/transform/actions/BaseAction.js +0 -150
  401. package/lib/transform/actions/BaseAction.js.map +0 -1
  402. package/lib/transform/actions/UnprocessedEntrypointError.js +0 -16
  403. package/lib/transform/actions/UnprocessedEntrypointError.js.map +0 -1
  404. package/lib/transform/actions/actionRunner.js +0 -82
  405. package/lib/transform/actions/actionRunner.js.map +0 -1
  406. package/lib/transform/actions/types.js +0 -2
  407. package/lib/transform/actions/types.js.map +0 -1
  408. package/lib/transform/barrelManifest.js +0 -300
  409. package/lib/transform/barrelManifest.js.map +0 -1
  410. package/lib/transform/generators/baseProcessingHandlers.js +0 -27
  411. package/lib/transform/generators/baseProcessingHandlers.js.map +0 -1
  412. package/lib/transform/generators/collect.js +0 -66
  413. package/lib/transform/generators/collect.js.map +0 -1
  414. package/lib/transform/generators/createStylisPreprocessor.js +0 -372
  415. package/lib/transform/generators/createStylisPreprocessor.js.map +0 -1
  416. package/lib/transform/generators/evalFile.js +0 -57
  417. package/lib/transform/generators/evalFile.js.map +0 -1
  418. package/lib/transform/generators/explodeReexports.js +0 -71
  419. package/lib/transform/generators/explodeReexports.js.map +0 -1
  420. package/lib/transform/generators/extract.js +0 -102
  421. package/lib/transform/generators/extract.js.map +0 -1
  422. package/lib/transform/generators/getExports.js +0 -85
  423. package/lib/transform/generators/getExports.js.map +0 -1
  424. package/lib/transform/generators/index.js +0 -19
  425. package/lib/transform/generators/index.js.map +0 -1
  426. package/lib/transform/generators/processEntrypoint.js +0 -76
  427. package/lib/transform/generators/processEntrypoint.js.map +0 -1
  428. package/lib/transform/generators/processImports.js +0 -82
  429. package/lib/transform/generators/processImports.js.map +0 -1
  430. package/lib/transform/generators/resolveImports.js +0 -221
  431. package/lib/transform/generators/resolveImports.js.map +0 -1
  432. package/lib/transform/generators/rewriteBarrelImports.js +0 -743
  433. package/lib/transform/generators/rewriteBarrelImports.js.map +0 -1
  434. package/lib/transform/generators/transform.js +0 -272
  435. package/lib/transform/generators/transform.js.map +0 -1
  436. package/lib/transform/generators/workflow.js +0 -100
  437. package/lib/transform/generators/workflow.js.map +0 -1
  438. package/lib/transform/helpers/loadWywOptions.js +0 -88
  439. package/lib/transform/helpers/loadWywOptions.js.map +0 -1
  440. package/lib/transform/helpers/withDefaultServices.js +0 -31
  441. package/lib/transform/helpers/withDefaultServices.js.map +0 -1
  442. package/lib/transform/isStaticallyEvaluatableModule.js +0 -159
  443. package/lib/transform/isStaticallyEvaluatableModule.js.map +0 -1
  444. package/lib/transform/rootLog.js +0 -9
  445. package/lib/transform/rootLog.js.map +0 -1
  446. package/lib/transform/types.js +0 -8
  447. package/lib/transform/types.js.map +0 -1
  448. package/lib/transform.js +0 -160
  449. package/lib/transform.js.map +0 -1
  450. package/lib/types.js +0 -2
  451. package/lib/types.js.map +0 -1
  452. package/lib/utils/EventEmitter.js +0 -61
  453. package/lib/utils/EventEmitter.js.map +0 -1
  454. package/lib/utils/ShakerMetadata.js +0 -9
  455. package/lib/utils/ShakerMetadata.js.map +0 -1
  456. package/lib/utils/TransformDiagnostics.js +0 -20
  457. package/lib/utils/TransformDiagnostics.js.map +0 -1
  458. package/lib/utils/TransformMetadata.js +0 -45
  459. package/lib/utils/TransformMetadata.js.map +0 -1
  460. package/lib/utils/addIdentifierToWywPreval.js +0 -75
  461. package/lib/utils/addIdentifierToWywPreval.js.map +0 -1
  462. package/lib/utils/collectExportsAndImports.js +0 -1173
  463. package/lib/utils/collectExportsAndImports.js.map +0 -1
  464. package/lib/utils/collectTemplateDependencies.js +0 -242
  465. package/lib/utils/collectTemplateDependencies.js.map +0 -1
  466. package/lib/utils/createId.js +0 -13
  467. package/lib/utils/createId.js.map +0 -1
  468. package/lib/utils/dispose-polyfill.js +0 -9
  469. package/lib/utils/dispose-polyfill.js.map +0 -1
  470. package/lib/utils/findIdentifiers.js +0 -73
  471. package/lib/utils/findIdentifiers.js.map +0 -1
  472. package/lib/utils/getConstantStringValue.js +0 -66
  473. package/lib/utils/getConstantStringValue.js.map +0 -1
  474. package/lib/utils/getFileIdx.js +0 -16
  475. package/lib/utils/getFileIdx.js.map +0 -1
  476. package/lib/utils/getMemberExpressionPropertyName.js +0 -18
  477. package/lib/utils/getMemberExpressionPropertyName.js.map +0 -1
  478. package/lib/utils/getPluginKey.js +0 -21
  479. package/lib/utils/getPluginKey.js.map +0 -1
  480. package/lib/utils/getScope.js +0 -12
  481. package/lib/utils/getScope.js.map +0 -1
  482. package/lib/utils/getSource.js +0 -24
  483. package/lib/utils/getSource.js.map +0 -1
  484. package/lib/utils/getTagProcessor.js +0 -424
  485. package/lib/utils/getTagProcessor.js.map +0 -1
  486. package/lib/utils/getVisitorKeys.js +0 -11
  487. package/lib/utils/getVisitorKeys.js.map +0 -1
  488. package/lib/utils/hasWywPreval.js +0 -13
  489. package/lib/utils/hasWywPreval.js.map +0 -1
  490. package/lib/utils/importOverrides.js +0 -119
  491. package/lib/utils/importOverrides.js.map +0 -1
  492. package/lib/utils/isExports.js +0 -27
  493. package/lib/utils/isExports.js.map +0 -1
  494. package/lib/utils/isGlobal.js +0 -13
  495. package/lib/utils/isGlobal.js.map +0 -1
  496. package/lib/utils/isNode.js +0 -9
  497. package/lib/utils/isNode.js.map +0 -1
  498. package/lib/utils/isNodePath.js +0 -10
  499. package/lib/utils/isNodePath.js.map +0 -1
  500. package/lib/utils/isNotNull.js +0 -10
  501. package/lib/utils/isNotNull.js.map +0 -1
  502. package/lib/utils/isRemoved.js +0 -52
  503. package/lib/utils/isRemoved.js.map +0 -1
  504. package/lib/utils/isRequire.js +0 -18
  505. package/lib/utils/isRequire.js.map +0 -1
  506. package/lib/utils/isSerializable.js +0 -19
  507. package/lib/utils/isSerializable.js.map +0 -1
  508. package/lib/utils/isTypedNode.js +0 -13
  509. package/lib/utils/isTypedNode.js.map +0 -1
  510. package/lib/utils/isUnnecessaryReactCall.js +0 -81
  511. package/lib/utils/isUnnecessaryReactCall.js.map +0 -1
  512. package/lib/utils/parseRequest.js +0 -37
  513. package/lib/utils/parseRequest.js.map +0 -1
  514. package/lib/utils/peek.js +0 -9
  515. package/lib/utils/peek.js.map +0 -1
  516. package/lib/utils/removeDangerousCode.js +0 -284
  517. package/lib/utils/removeDangerousCode.js.map +0 -1
  518. package/lib/utils/replaceImportMetaEnv.js +0 -50
  519. package/lib/utils/replaceImportMetaEnv.js.map +0 -1
  520. package/lib/utils/scopeHelpers.js +0 -557
  521. package/lib/utils/scopeHelpers.js.map +0 -1
  522. package/lib/utils/traversalCache.js +0 -31
  523. package/lib/utils/traversalCache.js.map +0 -1
  524. package/lib/utils/unwrapExpression.js +0 -25
  525. package/lib/utils/unwrapExpression.js.map +0 -1
  526. package/lib/utils/unwrapSequence.js +0 -20
  527. package/lib/utils/unwrapSequence.js.map +0 -1
  528. package/lib/utils/valueToLiteral.js +0 -65
  529. package/lib/utils/valueToLiteral.js.map +0 -1
  530. package/lib/utils/visitors/JSXElementsRemover.js +0 -57
  531. package/lib/utils/visitors/JSXElementsRemover.js.map +0 -1
  532. package/lib/vm/createVmContext.js +0 -166
  533. package/lib/vm/createVmContext.js.map +0 -1
  534. package/lib/vm/process.js +0 -38
  535. package/lib/vm/process.js.map +0 -1
  536. package/types/babel.d.ts +0 -2
  537. package/types/babel.js +0 -2
  538. package/types/options/buildOptions.d.ts +0 -6
  539. package/types/options/buildOptions.js +0 -178
  540. package/types/options/loadBabelOptions.d.ts +0 -3
  541. package/types/options/loadBabelOptions.js +0 -26
  542. package/types/plugins/babel-transform.d.ts +0 -4
  543. package/types/plugins/babel-transform.js +0 -49
  544. package/types/plugins/collector.d.ts +0 -23
  545. package/types/plugins/collector.js +0 -62
  546. package/types/plugins/dynamic-import.d.ts +0 -6
  547. package/types/plugins/dynamic-import.js +0 -60
  548. package/types/plugins/preeval.d.ts +0 -16
  549. package/types/plugins/preeval.js +0 -69
  550. package/types/plugins/shaker.d.ts +0 -14
  551. package/types/plugins/shaker.js +0 -724
  552. package/types/transform/generators/explodeReexports.d.ts +0 -7
  553. package/types/transform/generators/explodeReexports.js +0 -65
  554. package/types/utils/addIdentifierToWywPreval.d.ts +0 -4
  555. package/types/utils/addIdentifierToWywPreval.js +0 -74
  556. package/types/utils/collectExportsAndImports.d.ts +0 -31
  557. package/types/utils/collectExportsAndImports.js +0 -1147
  558. package/types/utils/collectTemplateDependencies.d.ts +0 -17
  559. package/types/utils/collectTemplateDependencies.js +0 -220
  560. package/types/utils/createId.d.ts +0 -2
  561. package/types/utils/createId.js +0 -9
  562. package/types/utils/findIdentifiers.d.ts +0 -6
  563. package/types/utils/findIdentifiers.js +0 -67
  564. package/types/utils/getConstantStringValue.d.ts +0 -2
  565. package/types/utils/getConstantStringValue.js +0 -94
  566. package/types/utils/getMemberExpressionPropertyName.d.ts +0 -2
  567. package/types/utils/getMemberExpressionPropertyName.js +0 -46
  568. package/types/utils/getScope.d.ts +0 -2
  569. package/types/utils/getScope.js +0 -10
  570. package/types/utils/getSource.d.ts +0 -2
  571. package/types/utils/getSource.js +0 -22
  572. package/types/utils/getTagProcessor.d.ts +0 -13
  573. package/types/utils/getTagProcessor.js +0 -411
  574. package/types/utils/isExports.d.ts +0 -6
  575. package/types/utils/isExports.js +0 -19
  576. package/types/utils/isGlobal.d.ts +0 -2
  577. package/types/utils/isGlobal.js +0 -9
  578. package/types/utils/isNodePath.d.ts +0 -3
  579. package/types/utils/isNodePath.js +0 -6
  580. package/types/utils/isRemoved.d.ts +0 -5
  581. package/types/utils/isRemoved.js +0 -41
  582. package/types/utils/isRequire.d.ts +0 -6
  583. package/types/utils/isRequire.js +0 -14
  584. package/types/utils/isTypedNode.d.ts +0 -5
  585. package/types/utils/isTypedNode.js +0 -9
  586. package/types/utils/isUnnecessaryReactCall.d.ts +0 -3
  587. package/types/utils/isUnnecessaryReactCall.js +0 -75
  588. package/types/utils/removeDangerousCode.d.ts +0 -4
  589. package/types/utils/removeDangerousCode.js +0 -326
  590. package/types/utils/replaceImportMetaEnv.d.ts +0 -3
  591. package/types/utils/replaceImportMetaEnv.js +0 -39
  592. package/types/utils/scopeHelpers.d.ts +0 -12
  593. package/types/utils/scopeHelpers.js +0 -580
  594. package/types/utils/traversalCache.d.ts +0 -4
  595. package/types/utils/traversalCache.js +0 -27
  596. package/types/utils/unwrapExpression.d.ts +0 -2
  597. package/types/utils/unwrapExpression.js +0 -57
  598. package/types/utils/unwrapSequence.d.ts +0 -8
  599. package/types/utils/unwrapSequence.js +0 -16
  600. package/types/utils/valueToLiteral.d.ts +0 -3
  601. package/types/utils/valueToLiteral.js +0 -63
  602. package/types/utils/visitors/JSXElementsRemover.d.ts +0 -3
  603. package/types/utils/visitors/JSXElementsRemover.js +0 -51
@@ -0,0 +1,1759 @@
1
+ /* eslint-disable no-underscore-dangle */
2
+ /* global BigInt */
3
+ import fs from "node:fs";
4
+ import { Console } from "node:console";
5
+ import { Writable } from "node:stream";
6
+ import vm from "node:vm";
7
+ import path from "node:path";
8
+ import NativeModule, { createRequire } from "node:module";
9
+ import { pathToFileURL } from "node:url";
10
+ import { Minimatch } from "minimatch";
11
+ class LruCache {
12
+ constructor(maxSize) {
13
+ this.maxSize = Math.max(1, maxSize);
14
+ this.map = new Map();
15
+ }
16
+ get(key) {
17
+ if (!this.map.has(key)) return undefined;
18
+ const value = this.map.get(key);
19
+ this.map.delete(key);
20
+ this.map.set(key, value);
21
+ return value;
22
+ }
23
+ set(key, value) {
24
+ if (this.map.has(key)) {
25
+ this.map.delete(key);
26
+ }
27
+ this.map.set(key, value);
28
+ if (this.map.size > this.maxSize) {
29
+ const firstKey = this.map.keys().next().value;
30
+ if (firstKey !== undefined) {
31
+ this.map.delete(firstKey);
32
+ }
33
+ }
34
+ }
35
+ delete(key) {
36
+ this.map.delete(key);
37
+ }
38
+ clear() {
39
+ this.map.clear();
40
+ }
41
+ }
42
+ const NOOP = () => {};
43
+ // stdout is reserved for the JSON IPC protocol; host-side logs must not share it.
44
+ const prefixStream = (getPrefix) => new Writable({ write(chunk, _enc, cb) {
45
+ const p = getPrefix();
46
+ const s = chunk.toString();
47
+ // Prefix interior newlines but not the trailing one — avoids
48
+ // double-prefix when consecutive writes each start with a prefix.
49
+ const tail = s.endsWith("\n") ? "\n" : "";
50
+ const body = tail ? s.slice(0, -1) : s;
51
+ process.stderr.write(p + body.replaceAll("\n", `\n${p}`) + tail, cb);
52
+ } });
53
+ // require'd modules outside vm use host console — must not write to stdout (IPC channel).
54
+ global.console = new Console({
55
+ stdout: prefixStream(() => "[wyw-runner:host stdout] "),
56
+ stderr: prefixStream(() => "[wyw-runner:host stderr] ")
57
+ });
58
+ const VITE_VIRTUAL_PREFIX = "/@";
59
+ const REACT_REFRESH_VIRTUAL_ID = "/@react-refresh";
60
+ const reactRefreshRuntime = { createSignatureFunctionForTransform: () => () => {} };
61
+ const builtins = {
62
+ assert: true,
63
+ buffer: true,
64
+ child_process: false,
65
+ cluster: false,
66
+ console: true,
67
+ constants: true,
68
+ crypto: true,
69
+ dgram: false,
70
+ dns: false,
71
+ domain: true,
72
+ events: true,
73
+ fs: false,
74
+ http: true,
75
+ https: true,
76
+ module: false,
77
+ net: false,
78
+ os: true,
79
+ path: true,
80
+ punycode: true,
81
+ process: true,
82
+ querystring: true,
83
+ readline: false,
84
+ repl: false,
85
+ stream: true,
86
+ string_decoder: true,
87
+ sys: true,
88
+ timers: true,
89
+ tls: false,
90
+ tty: true,
91
+ url: true,
92
+ util: true,
93
+ vm: true,
94
+ zlib: true
95
+ };
96
+ const RESOLVE_CACHE_SIZE = 5e3;
97
+ const LOAD_CACHE_SIZE = 1e3;
98
+ const MODULE_VARIANT_LIMIT = 8;
99
+ const isBuiltinSpecifier = (specifier) => {
100
+ const normalized = specifier.startsWith("node:") ? specifier.slice(5) : specifier;
101
+ return NativeModule.builtinModules?.includes(normalized) || NativeModule.builtinModules?.includes(`node:${normalized}`);
102
+ };
103
+ const packageTypeCache = new Map();
104
+ const getPackageType = (filename) => {
105
+ let dir = path.dirname(filename);
106
+ while (dir && dir !== path.dirname(dir)) {
107
+ const cached = packageTypeCache.get(dir);
108
+ if (cached === "module" || cached === "commonjs") return cached;
109
+ const pkgPath = path.join(dir, "package.json");
110
+ if (fs.existsSync(pkgPath)) {
111
+ try {
112
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
113
+ const type = pkg?.type === "module" ? "module" : "commonjs";
114
+ packageTypeCache.set(dir, type);
115
+ return type;
116
+ } catch {
117
+ packageTypeCache.set(dir, null);
118
+ return null;
119
+ }
120
+ }
121
+ packageTypeCache.set(dir, null);
122
+ dir = path.dirname(dir);
123
+ }
124
+ return null;
125
+ };
126
+ const shouldPreferImport = (resolvedFile) => {
127
+ if (!resolvedFile) return false;
128
+ if (!path.isAbsolute(resolvedFile)) return false;
129
+ if (resolvedFile.endsWith(".mjs")) return true;
130
+ if (resolvedFile.endsWith(".cjs")) return false;
131
+ if (!resolvedFile.endsWith(".js")) return false;
132
+ return getPackageType(resolvedFile) === "module";
133
+ };
134
+ const isPlainObject = (value) => {
135
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
136
+ return false;
137
+ }
138
+ const prototype = Object.getPrototypeOf(value);
139
+ if (prototype === null || prototype === Object.prototype) {
140
+ return true;
141
+ }
142
+ return Object.getPrototypeOf(prototype) === null;
143
+ };
144
+ const ENCODED_GLOBAL_ENVELOPE_KEY = "__wyw_eval_global";
145
+ const ENCODED_GLOBAL_SIGNATURE = "wyw-eval-global";
146
+ const ENCODED_GLOBAL_VERSION = 1;
147
+ const IDENTIFIER_RE = /^[A-Za-z_$][\w$]*$/u;
148
+ const ARRAY_INDEX_RE = /^(?:0|[1-9]\d*)$/;
149
+ const IPC_SUPPORTED_VALUE_HINT = "Use importOverrides to mock the import or return plain data: null, booleans, strings, numbers, bigint, undefined, arrays, plain objects, and Error.";
150
+ const getObjectTypeName = (value) => {
151
+ const { constructor } = value ?? {};
152
+ if (constructor && typeof constructor.name === "string" && constructor.name.length > 0) {
153
+ return constructor.name;
154
+ }
155
+ const tag = Object.prototype.toString.call(value);
156
+ return tag.slice(8, -1) || "Object";
157
+ };
158
+ const getBoxedPrimitiveValue = (value) => {
159
+ const tag = Object.prototype.toString.call(value);
160
+ if (tag === "[object String]") {
161
+ return {
162
+ kind: "string",
163
+ value: String(value.valueOf())
164
+ };
165
+ }
166
+ if (tag === "[object Number]") {
167
+ return {
168
+ kind: "number",
169
+ value: Number(value.valueOf())
170
+ };
171
+ }
172
+ if (tag === "[object Boolean]") {
173
+ return {
174
+ kind: "boolean",
175
+ value: Boolean(value.valueOf())
176
+ };
177
+ }
178
+ return null;
179
+ };
180
+ const formatPath = (rootLabel, pathSegments) => pathSegments.reduce((acc, segment) => {
181
+ if (typeof segment === "number") {
182
+ return `${acc}[${segment}]`;
183
+ }
184
+ if (typeof segment === "symbol") {
185
+ return `${acc}[${String(segment)}]`;
186
+ }
187
+ if (IDENTIFIER_RE.test(segment)) {
188
+ return `${acc}.${segment}`;
189
+ }
190
+ return `${acc}[${JSON.stringify(segment)}]`;
191
+ }, rootLabel);
192
+ const formatGlobalsPath = (pathSegments) => formatPath("eval.globals", pathSegments);
193
+ const restoreGlobalFunction = (source, pathSegments) => {
194
+ try {
195
+ // eslint-disable-next-line no-eval
196
+ const restored = eval(`(${source})`);
197
+ if (typeof restored !== "function") {
198
+ throw new TypeError("decoded source is not a function");
199
+ }
200
+ return restored;
201
+ } catch (error) {
202
+ throw new Error(`[wyw-in-js] Failed to restore eval.globals function at ${formatGlobalsPath(pathSegments)}. ` + `Ensure the value is a user-defined function expression/arrow function. ` + `Native and bound functions are not supported. ` + `Original error: ${String(error)}`);
203
+ }
204
+ };
205
+ const isEncodedGlobalPayload = (value) => {
206
+ if (!isPlainObject(value)) {
207
+ return false;
208
+ }
209
+ if (value.signature !== ENCODED_GLOBAL_SIGNATURE || value.version !== ENCODED_GLOBAL_VERSION) {
210
+ return false;
211
+ }
212
+ if (value.kind === "function") {
213
+ return typeof value.source === "string";
214
+ }
215
+ if (value.kind === "symbol") {
216
+ return typeof value.description === "string";
217
+ }
218
+ return false;
219
+ };
220
+ const isEncodedGlobalEnvelope = (value) => {
221
+ if (!isPlainObject(value)) {
222
+ return false;
223
+ }
224
+ const keys = Object.keys(value);
225
+ if (keys.length !== 1 || keys[0] !== ENCODED_GLOBAL_ENVELOPE_KEY) {
226
+ return false;
227
+ }
228
+ return isEncodedGlobalPayload(value[ENCODED_GLOBAL_ENVELOPE_KEY]);
229
+ };
230
+ const canonicalizeForSignature = (value) => {
231
+ if (Array.isArray(value)) {
232
+ return value.map((item) => canonicalizeForSignature(item));
233
+ }
234
+ if (isPlainObject(value)) {
235
+ return Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonicalizeForSignature(value[key])]));
236
+ }
237
+ return value;
238
+ };
239
+ const decodeGlobals = (value, pathSegments = []) => {
240
+ if (Array.isArray(value)) {
241
+ return value.map((item, index) => decodeGlobals(item, [...pathSegments, index]));
242
+ }
243
+ if (isEncodedGlobalEnvelope(value)) {
244
+ const payload = value[ENCODED_GLOBAL_ENVELOPE_KEY];
245
+ if (payload.kind === "function") {
246
+ return restoreGlobalFunction(payload.source, pathSegments);
247
+ }
248
+ return Symbol(payload.description);
249
+ }
250
+ if (isPlainObject(value)) {
251
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, decodeGlobals(item, [...pathSegments, key])]));
252
+ }
253
+ return value;
254
+ };
255
+ const getEnumerableSymbolKeys = (value) => Object.getOwnPropertySymbols(value).filter((key) => Object.prototype.propertyIsEnumerable.call(value, key));
256
+ const isLikeError = (value) => typeof value === "object" && value !== null && !isPlainObject(value) && "message" in value && typeof value.message === "string" && ("stack" in value || "name" in value);
257
+ const throwUnsupportedIpcValue = (rootLabel, pathSegments, description) => {
258
+ throw new Error(`[wyw-in-js] ${rootLabel} contains ${description} at ${formatPath(rootLabel, pathSegments)}. ${IPC_SUPPORTED_VALUE_HINT}`);
259
+ };
260
+ const serializeValueAtPath = (value, rootLabel, pathSegments, seen, allowFunctions, allowSymbols) => {
261
+ if (value === null) {
262
+ return { kind: "null" };
263
+ }
264
+ if (value === undefined) return { kind: "undefined" };
265
+ if (typeof value === "boolean") {
266
+ return {
267
+ kind: "boolean",
268
+ value
269
+ };
270
+ }
271
+ if (typeof value === "string") {
272
+ return {
273
+ kind: "string",
274
+ value
275
+ };
276
+ }
277
+ if (typeof value === "number") {
278
+ if (Number.isNaN(value)) return { kind: "nan" };
279
+ if (value === Infinity) return { kind: "infinity" };
280
+ if (value === -Infinity) return { kind: "-infinity" };
281
+ return {
282
+ kind: "number",
283
+ value
284
+ };
285
+ }
286
+ if (typeof value === "bigint") {
287
+ return {
288
+ kind: "bigint",
289
+ value: value.toString()
290
+ };
291
+ }
292
+ if (typeof value === "function") {
293
+ if (allowFunctions) {
294
+ // __wywPreval consumers only rely on function-ness, not implementation
295
+ // identity. Preserve that signal explicitly instead of letting JSON
296
+ // coerce to null/undefined.
297
+ return { kind: "function" };
298
+ }
299
+ throwUnsupportedIpcValue(rootLabel, pathSegments, "an unsupported function");
300
+ }
301
+ if (typeof value === "symbol") {
302
+ if (allowSymbols) {
303
+ return {
304
+ kind: "symbol",
305
+ description: value.description ?? ""
306
+ };
307
+ }
308
+ throwUnsupportedIpcValue(rootLabel, pathSegments, "an unsupported symbol");
309
+ }
310
+ if (typeof value === "object" && value !== null) {
311
+ const boxed = getBoxedPrimitiveValue(value);
312
+ if (boxed) {
313
+ if (boxed.kind === "number") {
314
+ if (Number.isNaN(boxed.value)) return { kind: "nan" };
315
+ if (boxed.value === Infinity) return { kind: "infinity" };
316
+ if (boxed.value === -Infinity) return { kind: "-infinity" };
317
+ }
318
+ return boxed;
319
+ }
320
+ }
321
+ if (isLikeError(value)) {
322
+ return {
323
+ kind: "error",
324
+ error: {
325
+ message: value.message,
326
+ name: value.name,
327
+ stack: value.stack
328
+ }
329
+ };
330
+ }
331
+ const currentPath = formatPath(rootLabel, pathSegments);
332
+ const seenAt = seen.get(value);
333
+ if (seenAt) {
334
+ throw new Error(`[wyw-in-js] ${rootLabel} contains a circular reference at ${currentPath} (from ${seenAt}). ${IPC_SUPPORTED_VALUE_HINT}`);
335
+ }
336
+ if (Array.isArray(value)) {
337
+ const symbolKeys = getEnumerableSymbolKeys(value);
338
+ if (symbolKeys.length > 0) {
339
+ throwUnsupportedIpcValue(rootLabel, [...pathSegments, symbolKeys[0]], "an unsupported symbol-keyed property");
340
+ }
341
+ const extraKey = Object.keys(value).find((key) => !ARRAY_INDEX_RE.test(key) || Number(key) >= value.length);
342
+ if (extraKey !== undefined) {
343
+ throwUnsupportedIpcValue(rootLabel, [...pathSegments, extraKey], "an unsupported non-index array property");
344
+ }
345
+ seen.set(value, currentPath);
346
+ try {
347
+ return {
348
+ kind: "array",
349
+ items: Array.from({ length: value.length }, (_, index) => serializeValueAtPath(value[index], rootLabel, [...pathSegments, index], seen, allowFunctions, allowSymbols))
350
+ };
351
+ } finally {
352
+ seen.delete(value);
353
+ }
354
+ }
355
+ if (!isPlainObject(value)) {
356
+ throwUnsupportedIpcValue(rootLabel, pathSegments, `an unsupported non-plain object (${getObjectTypeName(value)})`);
357
+ }
358
+ const symbolKeys = getEnumerableSymbolKeys(value);
359
+ if (symbolKeys.length > 0) {
360
+ throwUnsupportedIpcValue(rootLabel, [...pathSegments, symbolKeys[0]], "an unsupported symbol-keyed property");
361
+ }
362
+ seen.set(value, currentPath);
363
+ try {
364
+ return {
365
+ kind: "object",
366
+ entries: Object.fromEntries(Object.entries(value).map(([key, item]) => [key, serializeValueAtPath(item, rootLabel, [...pathSegments, key], seen, allowFunctions, allowSymbols)]))
367
+ };
368
+ } finally {
369
+ seen.delete(value);
370
+ }
371
+ };
372
+ const isErrRequireEsm = (error) => typeof error === "object" && error !== null && "code" in error && error.code === "ERR_REQUIRE_ESM";
373
+ const serializeValue = (value, options = {}) => serializeValueAtPath(value, options.rootLabel ?? "value", options.path ?? [], new WeakMap(), options.allowFunctions ?? false, options.allowSymbols ?? false);
374
+ const deserializeValue = (value) => {
375
+ switch (value?.kind) {
376
+ case "null": return null;
377
+ case "boolean":
378
+ case "string":
379
+ case "number": return value.value;
380
+ case "undefined": return undefined;
381
+ case "bigint": return BigInt(value.value);
382
+ case "nan": return Number.NaN;
383
+ case "infinity": return Infinity;
384
+ case "-infinity": return -Infinity;
385
+ case "function": return () => {};
386
+ case "symbol":
387
+ // eslint-disable-next-line symbol-description
388
+ return value.description ? Symbol.for(value.description) : Symbol();
389
+ case "error": {
390
+ const error = new Error(value.error?.message ?? "");
391
+ if (value.error?.name) {
392
+ error.name = value.error.name;
393
+ }
394
+ if (value.error?.stack) {
395
+ error.stack = value.error.stack;
396
+ }
397
+ return error;
398
+ }
399
+ case "array": return value.items.map((item) => deserializeValue(item));
400
+ case "object": return Object.fromEntries(Object.entries(value.entries).map(([key, item]) => [key, deserializeValue(item)]));
401
+ case "value":
402
+ default: return value?.value;
403
+ }
404
+ };
405
+ const IMPORT_META_ENV = "__wyw_import_meta_env";
406
+ let importMetaEnvWarned = false;
407
+ let happyDomLoadWarned = false;
408
+ let happyDomUnavailable = false;
409
+ let happyDomImportPromise = null;
410
+ const debugEnabled = Boolean(process.env.WYW_EVAL_RUNNER_DEBUG);
411
+ const debug = (...args) => {
412
+ if (!debugEnabled) return;
413
+ // eslint-disable-next-line no-console
414
+ console.warn("[wyw-eval-runner:debug]", ...args);
415
+ };
416
+ const processShim = {
417
+ nextTick: (fn) => setTimeout(fn, 0),
418
+ platform: "browser",
419
+ arch: "browser",
420
+ execPath: "browser",
421
+ title: "browser",
422
+ pid: 1,
423
+ browser: true,
424
+ argv: [],
425
+ binding() {
426
+ throw new Error("No such module. (Possibly not yet loaded)");
427
+ },
428
+ cwd: () => "/",
429
+ exit: NOOP,
430
+ kill: NOOP,
431
+ chdir: NOOP,
432
+ umask: NOOP,
433
+ dlopen: NOOP,
434
+ uptime: NOOP,
435
+ memoryUsage: NOOP,
436
+ uvCounters: NOOP,
437
+ features: {},
438
+ env: process.env
439
+ };
440
+ const createImportMetaEnvProxy = () => {
441
+ const target = Object.create(null);
442
+ const warnOnce = () => {
443
+ if (importMetaEnvWarned) return;
444
+ importMetaEnvWarned = true;
445
+ // eslint-disable-next-line no-console
446
+ console.warn([
447
+ `[wyw-in-js] import.meta.env was accessed during build-time evaluation, but no env values were provided.`,
448
+ ``,
449
+ `If you're using Vite, make sure @wyw-in-js/vite plugin is enabled (it injects Vite env for evaluation).`,
450
+ `Otherwise provide "__wyw_import_meta_env" via pluginOptions.overrideContext.`
451
+ ].join("\n"));
452
+ };
453
+ return new Proxy(target, {
454
+ get(obj, key) {
455
+ if (typeof key === "symbol") return Reflect.get(obj, key);
456
+ warnOnce();
457
+ return obj[key];
458
+ },
459
+ has(obj, key) {
460
+ if (typeof key === "symbol") return Reflect.has(obj, key);
461
+ warnOnce();
462
+ return Reflect.has(obj, key);
463
+ },
464
+ getOwnPropertyDescriptor(obj, key) {
465
+ return Reflect.getOwnPropertyDescriptor(obj, key);
466
+ },
467
+ ownKeys(obj) {
468
+ return Reflect.ownKeys(obj);
469
+ },
470
+ set(obj, key, value) {
471
+ if (typeof key === "symbol") return Reflect.set(obj, key, value);
472
+ warnOnce();
473
+ return Reflect.set(obj, key, value);
474
+ }
475
+ });
476
+ };
477
+ const HAPPY_DOM_TIMEOUT_MS = Number(process.env.WYW_EVAL_HAPPYDOM_INIT_TIMEOUT_MS ?? process.env.WYW_HAPPYDOM_TIMEOUT_MS ?? 15e3);
478
+ const withTimeout = (promise, timeoutMs, label) => {
479
+ if (!timeoutMs || timeoutMs <= 0) return promise;
480
+ let timeoutId;
481
+ const timeout = new Promise((_, reject) => {
482
+ timeoutId = setTimeout(() => {
483
+ const error = new Error(`[wyw-in-js] Timed out while waiting for ${label}.`);
484
+ error.code = "WYW_HAPPYDOM_TIMEOUT";
485
+ reject(error);
486
+ }, timeoutMs);
487
+ });
488
+ return Promise.race([promise, timeout]).finally(() => {
489
+ if (timeoutId) clearTimeout(timeoutId);
490
+ });
491
+ };
492
+ const loadHappyDom = async () => {
493
+ if (!happyDomImportPromise) {
494
+ happyDomImportPromise = import("happy-dom");
495
+ }
496
+ return happyDomImportPromise;
497
+ };
498
+ const createWindow = async () => {
499
+ if (happyDomUnavailable) return undefined;
500
+ try {
501
+ debug("happyDom:import:start");
502
+ const importStart = Date.now();
503
+ const { Window, GlobalWindow } = await withTimeout(loadHappyDom(), HAPPY_DOM_TIMEOUT_MS, "happy-dom import");
504
+ debug("happyDom:import:done", Date.now() - importStart);
505
+ const HappyWindow = GlobalWindow || Window;
506
+ const windowStart = Date.now();
507
+ const win = new HappyWindow();
508
+ debug("happyDom:window:done", Date.now() - windowStart);
509
+ win.Buffer = Buffer;
510
+ win.Uint8Array = Uint8Array;
511
+ return win;
512
+ } catch (error) {
513
+ happyDomUnavailable = true;
514
+ happyDomImportPromise = null;
515
+ if (!happyDomLoadWarned) {
516
+ happyDomLoadWarned = true;
517
+ // eslint-disable-next-line no-console
518
+ console.warn([
519
+ `[wyw-in-js] DOM emulation is enabled (features.happyDOM), but "happy-dom" could not be loaded in this build-time runtime.`,
520
+ `WyW will continue without DOM emulation (as if features.happyDOM:false).`,
521
+ ``,
522
+ `To silence this warning: set features: { happyDOM: false }.`,
523
+ `To restore DOM emulation, ensure "happy-dom" can be imported in the build-time runtime.`
524
+ ].join("\n"));
525
+ }
526
+ return undefined;
527
+ }
528
+ };
529
+ const setReferencePropertyIfNotPresent = (context, key) => {
530
+ if (context[key] === context) return;
531
+ context[key] = context;
532
+ };
533
+ const createBaseContext = (win, additionalContext) => {
534
+ const baseContext = win ?? {};
535
+ setReferencePropertyIfNotPresent(baseContext, "window");
536
+ setReferencePropertyIfNotPresent(baseContext, "self");
537
+ setReferencePropertyIfNotPresent(baseContext, "top");
538
+ setReferencePropertyIfNotPresent(baseContext, "parent");
539
+ setReferencePropertyIfNotPresent(baseContext, "global");
540
+ setReferencePropertyIfNotPresent(baseContext, "process");
541
+ baseContext.document = win?.document;
542
+ baseContext.process = processShim;
543
+ baseContext.clearImmediate = NOOP;
544
+ baseContext.clearInterval = NOOP;
545
+ baseContext.clearTimeout = NOOP;
546
+ baseContext.setImmediate = NOOP;
547
+ baseContext.requestAnimationFrame = NOOP;
548
+ baseContext.setInterval = NOOP;
549
+ baseContext.setTimeout = NOOP;
550
+ Object.assign(baseContext, additionalContext);
551
+ return baseContext;
552
+ };
553
+ const featureMatchers = new Map();
554
+ const isFeatureEnabled = (features, featureName, filename) => {
555
+ const value = features?.[featureName] ?? false;
556
+ if (typeof value === "boolean") return value;
557
+ if (value === "*" || value === "**/*") return true;
558
+ const array = Array.isArray(value) ? value : [value];
559
+ return array.map((pattern) => {
560
+ let matcher = featureMatchers.get(pattern);
561
+ if (!matcher) {
562
+ matcher = [pattern.startsWith("!"), new Minimatch(pattern)];
563
+ featureMatchers.set(pattern, matcher);
564
+ }
565
+ return [matcher[0], matcher[1].match(filename)];
566
+ }).reduce((acc, [negated, match]) => negated ? acc && match : acc || match, false);
567
+ };
568
+ const createVmContext = async (filename, features, globals) => {
569
+ const isHappyDomEnabled = isFeatureEnabled(features, "happyDOM", filename);
570
+ const win = isHappyDomEnabled ? await createWindow() : undefined;
571
+ const envContext = { [IMPORT_META_ENV]: createImportMetaEnvProxy() };
572
+ const baseContext = createBaseContext(win, {
573
+ __filename: filename,
574
+ ...envContext,
575
+ ...globals
576
+ });
577
+ // Evaluated code must never write to stdout — it is the IPC channel.
578
+ const vmIdent = () => `vm(${path.basename(baseContext.__filename ?? "?")})`;
579
+ baseContext.console = new Console({
580
+ stdout: prefixStream(() => `[wyw-runner:${vmIdent()} stdout] `),
581
+ stderr: prefixStream(() => `[wyw-runner:${vmIdent()} stderr] `)
582
+ });
583
+ const context = vm.createContext(baseContext);
584
+ return {
585
+ context,
586
+ teardown: () => {
587
+ if (win?.happyDOM) {
588
+ win.happyDOM.abort();
589
+ }
590
+ }
591
+ };
592
+ };
593
+ const stripQueryAndHash = (value) => value.split("?")[0]?.split("#")[0] ?? value;
594
+ const normalizeResolvedId = (resolvedId, specifier, importer, extensions) => {
595
+ const stripped = stripQueryAndHash(resolvedId);
596
+ if (!stripped) return resolvedId;
597
+ if (path.extname(stripped)) return resolvedId;
598
+ const isFileSpecifier = specifier.startsWith(".") || path.isAbsolute(specifier);
599
+ if (!isFileSpecifier && !path.isAbsolute(stripped)) {
600
+ return resolvedId;
601
+ }
602
+ let candidate = stripped;
603
+ if (!path.isAbsolute(candidate)) {
604
+ if (!importer) {
605
+ return resolvedId;
606
+ }
607
+ const importerFile = stripQueryAndHash(importer);
608
+ candidate = path.resolve(path.dirname(importerFile), candidate);
609
+ }
610
+ const suffix = resolvedId.slice(stripped.length);
611
+ const resolvedExtensions = extensions ?? [];
612
+ for (let index = 0; index < resolvedExtensions.length; index += 1) {
613
+ const ext = resolvedExtensions[index];
614
+ const fileCandidate = `${candidate}${ext}`;
615
+ if (fs.existsSync(fileCandidate)) {
616
+ return `${fileCandidate}${suffix}`;
617
+ }
618
+ const indexCandidate = path.join(candidate, `index${ext}`);
619
+ if (fs.existsSync(indexCandidate)) {
620
+ return `${indexCandidate}${suffix}`;
621
+ }
622
+ }
623
+ if (importer) {
624
+ try {
625
+ const importerFile = stripQueryAndHash(importer);
626
+ const nodeRequire = createRequire(pathToFileURL(importerFile).href);
627
+ const resolved = nodeRequire.resolve(stripQueryAndHash(specifier));
628
+ if (resolved && resolved !== stripped) {
629
+ return `${resolved}${suffix}`;
630
+ }
631
+ } catch {}
632
+ }
633
+ return resolvedId;
634
+ };
635
+ const isNodeModulesId = (id) => {
636
+ if (!id) return false;
637
+ const normalized = stripQueryAndHash(id).replace(/\\/g, "/");
638
+ return normalized.includes("/node_modules/");
639
+ };
640
+ const mergeOnly = (current, next) => {
641
+ if (!current || current.length === 0) return next ?? [];
642
+ if (!next || next.length === 0) return current;
643
+ if (current.includes("*") || next.includes("*")) {
644
+ return ["*"];
645
+ }
646
+ return Array.from(new Set([...current, ...next]));
647
+ };
648
+ const toCanonicalFileKey = (resolved, root) => {
649
+ const rootDir = root ? path.resolve(root) : process.cwd();
650
+ const normalizedResolved = path.resolve(resolved);
651
+ let relative = path.relative(rootDir, normalizedResolved);
652
+ if (path.sep !== path.posix.sep) {
653
+ relative = relative.split(path.sep).join(path.posix.sep);
654
+ }
655
+ if (!relative.startsWith(".")) {
656
+ relative = `./${relative}`;
657
+ }
658
+ return relative;
659
+ };
660
+ const toImportKey = ({ source, resolved, root }) => {
661
+ const isFileImport = source.startsWith(".") || path.isAbsolute(source);
662
+ if (isFileImport && resolved) {
663
+ return {
664
+ key: toCanonicalFileKey(resolved, root),
665
+ kind: "file"
666
+ };
667
+ }
668
+ return {
669
+ key: source,
670
+ kind: "package"
671
+ };
672
+ };
673
+ const minimatchOptions = {
674
+ dot: true,
675
+ nocomment: true,
676
+ nonegate: true
677
+ };
678
+ const compileImportOverrides = (importOverrides) => {
679
+ const matchers = Object.entries(importOverrides).map(([pattern, override]) => ({
680
+ matcher: new Minimatch(pattern, minimatchOptions),
681
+ override,
682
+ pattern
683
+ })).sort((a, b) => b.pattern.length - a.pattern.length);
684
+ return { matchers };
685
+ };
686
+ const compiledOverridesCache = new WeakMap();
687
+ const getImportOverride = (importOverrides, key) => {
688
+ if (!importOverrides) return undefined;
689
+ const direct = importOverrides[key];
690
+ if (direct) return direct;
691
+ let compiled = compiledOverridesCache.get(importOverrides);
692
+ if (!compiled) {
693
+ compiled = compileImportOverrides(importOverrides);
694
+ compiledOverridesCache.set(importOverrides, compiled);
695
+ }
696
+ return compiled.matchers.find(({ matcher }) => matcher.match(key))?.override;
697
+ };
698
+ const resolveMockSpecifier = ({ mock, importer, root }) => {
699
+ const specifier = mock.startsWith(".") && root ? path.resolve(root, mock) : mock;
700
+ const nodeRequire = createRequire(pathToFileURL(importer).href);
701
+ return nodeRequire.resolve(specifier);
702
+ };
703
+ const state = {
704
+ context: null,
705
+ teardown: null,
706
+ happyDomEnabled: null,
707
+ globalsSignature: null,
708
+ evalOptions: {
709
+ mode: "strict",
710
+ require: "warn-and-run",
711
+ globals: {},
712
+ importOverrides: undefined,
713
+ root: undefined,
714
+ extensions: []
715
+ },
716
+ features: {},
717
+ entrypoint: "eval-runner"
718
+ };
719
+ const moduleCache = new LruCache(LOAD_CACHE_SIZE);
720
+ const moduleHashes = new Map();
721
+ const moduleData = new Map();
722
+ const moduleOnly = new Map();
723
+ const moduleVariants = new Map();
724
+ const moduleLastVariant = new Map();
725
+ const linkPromises = new Map();
726
+ const loadInFlight = new Map();
727
+ const externalInFlight = new Map();
728
+ const resolveCache = new LruCache(RESOLVE_CACHE_SIZE);
729
+ const resolveInFlight = new Map();
730
+ const pending = new Map();
731
+ const loadResultChunks = new Map();
732
+ let nextId = 0;
733
+ const stdoutWriteQueue = [];
734
+ let stdoutWriteInFlight = false;
735
+ let stdoutWriteFailed = null;
736
+ let shutdownRequested = false;
737
+ let shutdownFinished = false;
738
+ const resetModuleState = () => {
739
+ moduleCache.clear();
740
+ moduleHashes.clear();
741
+ moduleData.clear();
742
+ moduleOnly.clear();
743
+ moduleVariants.clear();
744
+ moduleLastVariant.clear();
745
+ linkPromises.clear();
746
+ loadInFlight.clear();
747
+ externalInFlight.clear();
748
+ resolveInFlight.clear();
749
+ resolveCache.clear();
750
+ sentNamespaceIdentifiers.clear();
751
+ };
752
+ // Tracks the SourceTextModule identifier (versioned with hash) that was last
753
+ // included in an EVAL_RESULT for each id. Reused module variants don't need
754
+ // re-serialization across eval sessions — same variant = same namespace =
755
+ // same exports the broker already has cached.
756
+ const sentNamespaceIdentifiers = new Map();
757
+ const resetSingleModuleState = (id, cachedModule = moduleCache.get(id)) => {
758
+ if (cachedModule) {
759
+ linkPromises.delete(cachedModule);
760
+ }
761
+ const variants = moduleVariants.get(id);
762
+ if (variants) {
763
+ variants.forEach((variant) => linkPromises.delete(variant));
764
+ }
765
+ moduleCache.delete(id);
766
+ moduleHashes.delete(id);
767
+ moduleData.delete(id);
768
+ moduleVariants.delete(id);
769
+ moduleLastVariant.delete(id);
770
+ };
771
+ const isFullModuleLoad = (loaded) => !loaded.only || loaded.only.length === 1 && loaded.only[0] === "*";
772
+ const getModuleVariant = (id, hash) => moduleVariants.get(id)?.get(hash);
773
+ const setModuleVariant = (id, hash, module) => {
774
+ let variants = moduleVariants.get(id);
775
+ if (!variants) {
776
+ variants = new Map();
777
+ moduleVariants.set(id, variants);
778
+ }
779
+ variants.set(hash, module);
780
+ moduleLastVariant.set(id, module);
781
+ if (variants.size > MODULE_VARIANT_LIMIT) {
782
+ const oldestHash = variants.keys().next().value;
783
+ if (oldestHash !== undefined) {
784
+ const oldest = variants.get(oldestHash);
785
+ if (oldest) {
786
+ linkPromises.delete(oldest);
787
+ }
788
+ variants.delete(oldestHash);
789
+ }
790
+ }
791
+ };
792
+ const toSourceModuleId = (id) => stripQueryAndHash(String(id));
793
+ const toVersionedModuleIdentifier = (id, hash) => {
794
+ if (!hash) return id;
795
+ const separator = id.includes("?") ? "&" : "?";
796
+ return `${id}${separator}wyw-hash=${hash}`;
797
+ };
798
+ const resetEvaluationState = () => {
799
+ if (state.teardown) {
800
+ state.teardown();
801
+ }
802
+ state.context = null;
803
+ state.teardown = null;
804
+ state.happyDomEnabled = null;
805
+ state.globalsSignature = null;
806
+ resetModuleState();
807
+ };
808
+ const normalizeWriteError = (label, error) => {
809
+ if (error instanceof Error) {
810
+ return error;
811
+ }
812
+ return new Error(`[wyw-in-js] Failed to write to ${label}: ${String(error)}`);
813
+ };
814
+ const keepAlive = setInterval(() => {}, 6e4);
815
+ const finishShutdown = (exitCode = 0) => {
816
+ if (shutdownFinished) {
817
+ return;
818
+ }
819
+ shutdownFinished = true;
820
+ clearInterval(keepAlive);
821
+ if (state.teardown) {
822
+ state.teardown();
823
+ }
824
+ process.exit(exitCode);
825
+ };
826
+ const flushStdoutWriteQueue = () => {
827
+ if (stdoutWriteInFlight || stdoutWriteFailed) {
828
+ return;
829
+ }
830
+ const next = stdoutWriteQueue.shift();
831
+ if (!next) {
832
+ if (shutdownRequested) {
833
+ finishShutdown(0);
834
+ }
835
+ return;
836
+ }
837
+ stdoutWriteInFlight = true;
838
+ let settled = false;
839
+ let writeCompleted = false;
840
+ let drainCompleted = true;
841
+ let onClose;
842
+ let onDrain;
843
+ let onError;
844
+ const cleanup = () => {
845
+ process.stdout.off("close", onClose);
846
+ process.stdout.off("drain", onDrain);
847
+ process.stdout.off("error", onError);
848
+ };
849
+ const finish = (error) => {
850
+ if (settled) {
851
+ return;
852
+ }
853
+ if (error) {
854
+ settled = true;
855
+ stdoutWriteInFlight = false;
856
+ cleanup();
857
+ stdoutWriteFailed = normalizeWriteError("eval runner stdout", error);
858
+ next.reject(stdoutWriteFailed);
859
+ while (stdoutWriteQueue.length > 0) {
860
+ stdoutWriteQueue.shift().reject(stdoutWriteFailed);
861
+ }
862
+ process.stderr.write(`[wyw-eval-runner] ${stdoutWriteFailed.message}\n`);
863
+ finishShutdown(1);
864
+ return;
865
+ }
866
+ if (!writeCompleted || !drainCompleted) {
867
+ return;
868
+ }
869
+ settled = true;
870
+ stdoutWriteInFlight = false;
871
+ cleanup();
872
+ next.resolve();
873
+ flushStdoutWriteQueue();
874
+ };
875
+ onClose = () => {
876
+ finish(new Error("eval runner stdout closed before pending write completed"));
877
+ };
878
+ onDrain = () => {
879
+ drainCompleted = true;
880
+ finish();
881
+ };
882
+ onError = (error) => {
883
+ finish(error);
884
+ };
885
+ process.stdout.once("close", onClose);
886
+ process.stdout.once("error", onError);
887
+ const needsDrain = !process.stdout.write(next.chunk, (error) => {
888
+ writeCompleted = true;
889
+ if (error) {
890
+ finish(error);
891
+ return;
892
+ }
893
+ finish();
894
+ });
895
+ if (needsDrain) {
896
+ drainCompleted = false;
897
+ process.stdout.once("drain", onDrain);
898
+ }
899
+ };
900
+ const queueStdoutWrite = (chunk) => new Promise((resolve, reject) => {
901
+ if (stdoutWriteFailed) {
902
+ reject(stdoutWriteFailed);
903
+ return;
904
+ }
905
+ stdoutWriteQueue.push({
906
+ chunk,
907
+ resolve,
908
+ reject
909
+ });
910
+ flushStdoutWriteQueue();
911
+ });
912
+ const sendMessage = (message) => {
913
+ queueStdoutWrite(`${JSON.stringify(message)}\n`).catch(() => {});
914
+ };
915
+ const shutdown = () => {
916
+ shutdownRequested = true;
917
+ if (!stdoutWriteInFlight && stdoutWriteQueue.length === 0) {
918
+ finishShutdown(0);
919
+ }
920
+ };
921
+ const sendWarn = (warning) => {
922
+ sendMessage({
923
+ type: "WARN",
924
+ payload: warning
925
+ });
926
+ };
927
+ const serializeError = (error) => {
928
+ const result = {
929
+ message: error?.message ?? String(error),
930
+ stack: error?.stack
931
+ };
932
+ if (error?.cause instanceof Error) {
933
+ result.cause = serializeError(error.cause);
934
+ }
935
+ return result;
936
+ };
937
+ const request = (type, payload) => {
938
+ nextId += 1;
939
+ const id = `${nextId}`;
940
+ sendMessage({
941
+ type,
942
+ id,
943
+ payload
944
+ });
945
+ return new Promise((resolve, reject) => {
946
+ pending.set(id, {
947
+ resolve,
948
+ reject
949
+ });
950
+ });
951
+ };
952
+ const resolvePending = (id, payload) => {
953
+ const pendingItem = pending.get(id);
954
+ if (!pendingItem) return;
955
+ pending.delete(id);
956
+ pendingItem.resolve(payload);
957
+ };
958
+ const handleLoadResult = (id, payload) => {
959
+ if (!payload || typeof payload.codeChunk !== "string" || typeof payload.chunkIndex !== "number" || typeof payload.chunkCount !== "number") {
960
+ resolvePending(id, payload);
961
+ return;
962
+ }
963
+ let entry = loadResultChunks.get(id);
964
+ if (!entry) {
965
+ entry = {
966
+ chunks: new Array(payload.chunkCount),
967
+ received: 0,
968
+ meta: null
969
+ };
970
+ loadResultChunks.set(id, entry);
971
+ }
972
+ if (!entry.chunks[payload.chunkIndex]) {
973
+ entry.received += 1;
974
+ }
975
+ entry.chunks[payload.chunkIndex] = payload.codeChunk;
976
+ if (payload.chunkIndex === 0) {
977
+ const { codeChunk, chunkIndex, chunkCount, ...meta } = payload;
978
+ entry.meta = meta;
979
+ }
980
+ if (entry.received >= payload.chunkCount) {
981
+ const code = entry.chunks.join("");
982
+ const finalPayload = {
983
+ ...entry.meta ?? {},
984
+ code
985
+ };
986
+ loadResultChunks.delete(id);
987
+ resolvePending(id, finalPayload);
988
+ }
989
+ };
990
+ const buildPreamble = (id) => [
991
+ `const __wyw_module = __wyw_getModule(${JSON.stringify(id)});`,
992
+ `let exports = __wyw_module.exports;`,
993
+ `const module = __wyw_module.module;`,
994
+ `const require = __wyw_module.require;`,
995
+ `const __filename = __wyw_module.filename;`,
996
+ `const __dirname = __wyw_module.dirname;`,
997
+ `const __wyw_dynamic_import = __wyw_module.dynamicImport;`,
998
+ ``
999
+ ].join("\n");
1000
+ const getImporterPackage = (importer) => {
1001
+ const normalized = importer.replace(/\\/g, "/");
1002
+ const marker = "/node_modules/";
1003
+ const idx = normalized.lastIndexOf(marker);
1004
+ if (idx === -1) return path.basename(importer);
1005
+ const rest = normalized.slice(idx + marker.length);
1006
+ if (rest.startsWith("@")) {
1007
+ const [scope, name] = rest.split("/").slice(0, 2);
1008
+ return `${scope}/${name}`;
1009
+ }
1010
+ return rest.split("/")[0];
1011
+ };
1012
+ const warnedRequires = new Set();
1013
+ const createRequireFn = (importer) => {
1014
+ const importerFile = stripQueryAndHash(importer);
1015
+ const nodeRequire = createRequire(pathToFileURL(importerFile).href);
1016
+ return (specifier, nonLiteralOrResolved, maybeResolved) => {
1017
+ const hasNonLiteralFlag = typeof nonLiteralOrResolved === "boolean";
1018
+ const nonLiteral = hasNonLiteralFlag ? nonLiteralOrResolved : false;
1019
+ const resolvedOverride = hasNonLiteralFlag ? maybeResolved : nonLiteralOrResolved;
1020
+ const hasResolvedOverride = typeof resolvedOverride === "string" && resolvedOverride.length > 0;
1021
+ if (state.evalOptions.require === "off") {
1022
+ throw new Error(`[wyw-in-js] require() fallback is disabled by eval.require: 'off'.`);
1023
+ }
1024
+ if (nonLiteral || typeof specifier !== "string") {
1025
+ if (state.evalOptions.mode === "strict") {
1026
+ throw new Error(`[wyw-in-js] Non-literal require() is not supported during eval.\n` + `importer: ${importerFile}\n` + `hint: make it a string literal or mock the import via importOverrides.`);
1027
+ }
1028
+ sendWarn({
1029
+ code: "require-error",
1030
+ message: "[wyw-in-js] Non-literal require() reached during eval (loose mode).",
1031
+ importer: importerFile
1032
+ });
1033
+ return {};
1034
+ }
1035
+ if (specifier === REACT_REFRESH_VIRTUAL_ID) {
1036
+ return reactRefreshRuntime;
1037
+ }
1038
+ if (specifier.startsWith(VITE_VIRTUAL_PREFIX) || specifier.startsWith("virtual:")) {
1039
+ return {};
1040
+ }
1041
+ const normalized = specifier.startsWith("node:") ? specifier.slice(5) : specifier;
1042
+ if (NativeModule.builtinModules?.includes(normalized) || NativeModule.builtinModules?.includes(`node:${normalized}`)) {
1043
+ if (normalized in builtins) {
1044
+ if (builtins[normalized]) {
1045
+ return nodeRequire(normalized);
1046
+ }
1047
+ return null;
1048
+ }
1049
+ }
1050
+ const extensions = NativeModule._extensions;
1051
+ const added = [];
1052
+ try {
1053
+ state.evalOptions.extensions?.forEach((ext) => {
1054
+ if (ext === ".cjs" || ext === ".mjs") return;
1055
+ if (ext in extensions) return;
1056
+ extensions[ext] = NOOP;
1057
+ added.push(ext);
1058
+ });
1059
+ let resolved = hasResolvedOverride ? stripQueryAndHash(resolvedOverride) : nodeRequire.resolve(stripQueryAndHash(specifier));
1060
+ const isFileSpecifier = specifier.startsWith(".") || path.isAbsolute(specifier);
1061
+ if (isFileSpecifier && path.extname(specifier) === "" && resolved.endsWith(".cjs")) {
1062
+ const candidate = `${resolved.slice(0, -4)}.js`;
1063
+ if (fs.existsSync(candidate)) {
1064
+ resolved = candidate;
1065
+ }
1066
+ }
1067
+ const keyInfo = toImportKey({
1068
+ source: specifier,
1069
+ resolved,
1070
+ root: state.evalOptions.root
1071
+ });
1072
+ const override = getImportOverride(state.evalOptions.importOverrides, keyInfo.key);
1073
+ let finalResolved = resolved;
1074
+ if (override?.mock) {
1075
+ finalResolved = resolveMockSpecifier({
1076
+ mock: override.mock,
1077
+ importer: importerFile,
1078
+ root: state.evalOptions.root,
1079
+ stack: [importerFile]
1080
+ });
1081
+ }
1082
+ const basePolicy = state.evalOptions.require === "warn-and-run" ? "warn" : "error";
1083
+ let policy = override?.unknown ?? (override ? "allow" : basePolicy);
1084
+ if (state.evalOptions.require === "off" && policy !== "error") {
1085
+ policy = "error";
1086
+ }
1087
+ if (policy === "error") {
1088
+ throw new Error([
1089
+ `[wyw-in-js] require() fallback reached during eval but eval.require='error'.`,
1090
+ ``,
1091
+ `importer: ${importerFile}`,
1092
+ `source: ${specifier}`,
1093
+ `hint: add importOverrides or set eval.require to "warn-and-run".`
1094
+ ].join("\n"));
1095
+ }
1096
+ if (policy === "warn") {
1097
+ const key = `${specifier}::${getImporterPackage(importerFile)}`;
1098
+ if (!warnedRequires.has(key)) {
1099
+ warnedRequires.add(key);
1100
+ sendWarn({
1101
+ code: "require-fallback",
1102
+ message: [
1103
+ `[wyw-in-js] Runtime require() fallback during eval`,
1104
+ ``,
1105
+ `importer: ${importerFile}`,
1106
+ `source: ${specifier}`,
1107
+ `resolved: ${resolved}`,
1108
+ override?.mock ? `mock: ${override.mock} -> ${finalResolved}` : ``,
1109
+ ``,
1110
+ `hint: use importOverrides to mock runtime-only deps and avoid eval-time requires.`
1111
+ ].filter(Boolean).join("\n"),
1112
+ importer: importerFile,
1113
+ specifier,
1114
+ resolved
1115
+ });
1116
+ }
1117
+ }
1118
+ return nodeRequire(finalResolved);
1119
+ } finally {
1120
+ added.forEach((ext) => delete extensions[ext]);
1121
+ }
1122
+ };
1123
+ };
1124
+ function createSyntheticModule(id, exportsValue, cache = true) {
1125
+ const exportNames = new Set(Object.keys(exportsValue));
1126
+ if (!exportNames.has("default")) {
1127
+ exportNames.add("default");
1128
+ }
1129
+ const module = new vm.SyntheticModule([...exportNames], function init() {
1130
+ exportNames.forEach((key) => {
1131
+ const value = key === "default" ? exportsValue.default : exportsValue[key];
1132
+ this.setExport(key, value);
1133
+ });
1134
+ }, {
1135
+ context: state.context,
1136
+ identifier: id
1137
+ });
1138
+ if (cache) {
1139
+ moduleCache.set(id, module);
1140
+ }
1141
+ return module;
1142
+ }
1143
+ const toSyntheticExports = (value) => {
1144
+ if (value && (typeof value === "object" || typeof value === "function")) {
1145
+ const exportsValue = {};
1146
+ Object.keys(value).forEach((key) => {
1147
+ exportsValue[key] = value[key];
1148
+ });
1149
+ exportsValue.default = Object.prototype.hasOwnProperty.call(value, "default") || Object.prototype.hasOwnProperty.call(exportsValue, "default") ? value.default : value;
1150
+ return exportsValue;
1151
+ }
1152
+ return { default: value };
1153
+ };
1154
+ const loadExternalModule = async (resolvedId, importer, specifier) => {
1155
+ const cacheId = resolvedId ?? specifier;
1156
+ const cached = moduleCache.get(cacheId);
1157
+ if (cached) return cached;
1158
+ const inFlight = externalInFlight.get(cacheId);
1159
+ if (inFlight) return inFlight;
1160
+ const task = (async () => {
1161
+ const start = Date.now();
1162
+ debug("external:start", {
1163
+ specifier,
1164
+ resolvedId,
1165
+ importer
1166
+ });
1167
+ const requireFn = createRequireFn(importer);
1168
+ let value;
1169
+ let hasValue = false;
1170
+ const resolvedFile = resolvedId ? stripQueryAndHash(resolvedId) : null;
1171
+ const importTarget = resolvedFile && path.isAbsolute(resolvedFile) ? pathToFileURL(resolvedFile).href : specifier;
1172
+ if (shouldPreferImport(resolvedFile)) {
1173
+ value = await import(importTarget);
1174
+ hasValue = true;
1175
+ }
1176
+ if (!hasValue) {
1177
+ try {
1178
+ value = requireFn(specifier, resolvedId ?? null);
1179
+ hasValue = true;
1180
+ } catch (error) {
1181
+ if (!isErrRequireEsm(error)) {
1182
+ throw error;
1183
+ }
1184
+ const isFileSpecifier = specifier.startsWith(".") || path.isAbsolute(specifier);
1185
+ const isPackageSpecifier = !isFileSpecifier && !isBuiltinSpecifier(specifier);
1186
+ if (resolvedId && isPackageSpecifier) {
1187
+ try {
1188
+ value = requireFn(specifier, null);
1189
+ hasValue = true;
1190
+ } catch (retryError) {
1191
+ if (!isErrRequireEsm(retryError)) {
1192
+ throw retryError;
1193
+ }
1194
+ }
1195
+ }
1196
+ if (!hasValue) {
1197
+ value = await import(importTarget);
1198
+ hasValue = true;
1199
+ }
1200
+ }
1201
+ }
1202
+ const module = createSyntheticModule(cacheId, toSyntheticExports(value));
1203
+ debug("external:done", {
1204
+ specifier,
1205
+ resolvedId,
1206
+ durationMs: Date.now() - start
1207
+ });
1208
+ return module;
1209
+ })();
1210
+ externalInFlight.set(cacheId, task);
1211
+ try {
1212
+ return await task;
1213
+ } finally {
1214
+ externalInFlight.delete(cacheId);
1215
+ }
1216
+ };
1217
+ let resolveModule;
1218
+ let loadModule;
1219
+ const linkModule = async (module) => {
1220
+ const cached = linkPromises.get(module);
1221
+ if (cached) return cached;
1222
+ if (module.status !== "unlinked") return module;
1223
+ const linking = (async () => {
1224
+ try {
1225
+ await module.link((specifier, referencingModule) => resolveModule(specifier, referencingModule.identifier, "import"));
1226
+ return module;
1227
+ } catch (error) {
1228
+ // ERR_VM_MODULE_LINK_FAILURE means a dependency is in "errored" state.
1229
+ // Node chains .cause through the link failure hierarchy. Walk to the
1230
+ // deepest cause to surface the original evaluation error (e.g. a
1231
+ // TypeError in user code), not intermediate "resolved to errored" hops.
1232
+ if (error?.code === "ERR_VM_MODULE_LINK_FAILURE") {
1233
+ let rootCause = error;
1234
+ while (rootCause.cause instanceof Error) {
1235
+ rootCause = rootCause.cause;
1236
+ }
1237
+ if (rootCause !== error) {
1238
+ const enhanced = new Error(`${error.message}\n` + ` Root cause: ${rootCause.name ?? "Error"}: ${rootCause.message}`);
1239
+ enhanced.cause = rootCause;
1240
+ throw enhanced;
1241
+ }
1242
+ }
1243
+ throw error;
1244
+ } finally {
1245
+ linkPromises.delete(module);
1246
+ }
1247
+ })();
1248
+ linkPromises.set(module, linking);
1249
+ return linking;
1250
+ };
1251
+ resolveModule = async (specifier, importer, kind) => {
1252
+ const importerId = toSourceModuleId(importer);
1253
+ if (process.env.WYW_DEBUG_EVAL_RESOLVE) {
1254
+ process.stderr.write(`[wyw-eval-runner:resolve] ${JSON.stringify({
1255
+ specifier,
1256
+ importer: importerId,
1257
+ kind
1258
+ })}\n`);
1259
+ }
1260
+ if (specifier === REACT_REFRESH_VIRTUAL_ID) {
1261
+ return createSyntheticModule(specifier, reactRefreshRuntime);
1262
+ }
1263
+ if (specifier.startsWith(VITE_VIRTUAL_PREFIX) || specifier.startsWith("virtual:")) {
1264
+ return createSyntheticModule(specifier, { default: {} });
1265
+ }
1266
+ const key = `${kind}:${importerId}:${specifier}`;
1267
+ const cached = resolveCache.get(key);
1268
+ if (cached) {
1269
+ if (!cached.resolvedId) {
1270
+ if (state.evalOptions.mode === "loose") {
1271
+ return createSyntheticModule(specifier, { default: undefined });
1272
+ }
1273
+ throw new Error([
1274
+ `[wyw-in-js] Unable to resolve "${specifier}" during evaluation.`,
1275
+ ``,
1276
+ `importer: ${importerId}`,
1277
+ `hint: check eval.resolver/customResolver or add importOverrides for this specifier.`
1278
+ ].join("\n"));
1279
+ }
1280
+ const treatExternal = cached.external || isBuiltinSpecifier(specifier) || isNodeModulesId(cached.resolvedId);
1281
+ if (treatExternal) {
1282
+ const normalized = normalizeResolvedId(cached.resolvedId, specifier, importerId, state.evalOptions.extensions);
1283
+ const externalModule = await loadExternalModule(normalized, importerId, specifier);
1284
+ return externalModule;
1285
+ }
1286
+ const normalized = normalizeResolvedId(cached.resolvedId, specifier, importerId, state.evalOptions.extensions);
1287
+ return loadModule(normalized, importerId, specifier);
1288
+ }
1289
+ const inFlight = resolveInFlight.get(key);
1290
+ if (inFlight) return inFlight;
1291
+ const task = (async () => {
1292
+ const resolved = await request("RESOLVE", {
1293
+ specifier,
1294
+ importerId,
1295
+ kind
1296
+ });
1297
+ if (resolved.error) {
1298
+ throw new Error(resolved.error.message);
1299
+ }
1300
+ const normalized = resolved.resolvedId ? normalizeResolvedId(resolved.resolvedId, specifier, importerId, state.evalOptions.extensions) : resolved.resolvedId;
1301
+ if (process.env.WYW_DEBUG_EVAL_RESOLVE) {
1302
+ process.stderr.write(`[wyw-eval-runner:resolved] ${JSON.stringify({
1303
+ specifier,
1304
+ importer: importerId,
1305
+ resolved: resolved.resolvedId ?? null,
1306
+ normalized: normalized ?? null,
1307
+ external: Boolean(resolved.external)
1308
+ })}\n`);
1309
+ }
1310
+ resolveCache.set(key, {
1311
+ resolvedId: normalized,
1312
+ external: Boolean(resolved.external)
1313
+ });
1314
+ if (!normalized) {
1315
+ if (state.evalOptions.mode === "loose") {
1316
+ return createSyntheticModule(specifier, { default: undefined });
1317
+ }
1318
+ throw new Error([
1319
+ `[wyw-in-js] Unable to resolve "${specifier}" during evaluation.`,
1320
+ ``,
1321
+ `importer: ${importerId}`,
1322
+ `hint: check eval.resolver/customResolver or add importOverrides for this specifier.`
1323
+ ].join("\n"));
1324
+ }
1325
+ const treatExternal = resolved.external || isBuiltinSpecifier(specifier) || isNodeModulesId(normalized);
1326
+ if (treatExternal) {
1327
+ return loadExternalModule(normalized, importerId, specifier);
1328
+ }
1329
+ return loadModule(normalized, importerId, specifier);
1330
+ })();
1331
+ resolveInFlight.set(key, task);
1332
+ try {
1333
+ return await task;
1334
+ } finally {
1335
+ resolveInFlight.delete(key);
1336
+ }
1337
+ };
1338
+ loadModule = async (id, importer, requestSpec) => {
1339
+ let cached = moduleCache.get(id);
1340
+ const inFlight = loadInFlight.get(id);
1341
+ if (inFlight) {
1342
+ await inFlight;
1343
+ cached = moduleCache.get(id);
1344
+ }
1345
+ const task = (async () => {
1346
+ const loadStart = Date.now();
1347
+ const loaded = await request("LOAD", {
1348
+ id,
1349
+ importerId: importer,
1350
+ request: requestSpec ?? null
1351
+ });
1352
+ debug("load:done", {
1353
+ id,
1354
+ importer,
1355
+ durationMs: Date.now() - loadStart
1356
+ });
1357
+ if (loaded.error) {
1358
+ throw new Error(loaded.error.message);
1359
+ }
1360
+ if (loaded.only) {
1361
+ const current = moduleOnly.get(id) ?? [];
1362
+ moduleOnly.set(id, mergeOnly(current, loaded.only));
1363
+ }
1364
+ if (loaded.exports) {
1365
+ // Serialized exports are a narrow slice — only the keys the importer
1366
+ // requested. If we have a fully evaluated module (in moduleCache or as
1367
+ // a variant), prefer it: its namespace has ALL exports, so any consumer
1368
+ // can link against it without "does not provide export" errors.
1369
+ //
1370
+ // An evaluated variant is only safe to reuse when its namespace covers
1371
+ // the serialized key set. A narrow variant that was evaluated first may
1372
+ // lack exports that a wider consumer needs (the 4df6e915 race).
1373
+ const requiredKeys = Object.keys(loaded.exports);
1374
+ const coversKeys = (mod) => {
1375
+ const ns = mod.namespace;
1376
+ return requiredKeys.every((k) => k in ns);
1377
+ };
1378
+ let evaluated = cached && cached.status === "evaluated" && coversKeys(cached) ? cached : undefined;
1379
+ if (!evaluated) {
1380
+ const variants = moduleVariants.get(id);
1381
+ if (variants) {
1382
+ for (const variant of variants.values()) {
1383
+ if (variant.status === "evaluated" && coversKeys(variant)) {
1384
+ evaluated = variant;
1385
+ break;
1386
+ }
1387
+ }
1388
+ }
1389
+ }
1390
+ if (evaluated) {
1391
+ return evaluated;
1392
+ }
1393
+ // Reuse a previously created SyntheticModule for this exact serialized set
1394
+ if (loaded.hash) {
1395
+ const existing = getModuleVariant(id, loaded.hash);
1396
+ if (existing) {
1397
+ return existing;
1398
+ }
1399
+ }
1400
+ const exportsValue = {};
1401
+ Object.entries(loaded.exports).forEach(([key, serialized]) => {
1402
+ exportsValue[key] = deserializeValue(serialized);
1403
+ });
1404
+ const module = createSyntheticModule(id, exportsValue, false);
1405
+ if (loaded.hash) {
1406
+ setModuleVariant(id, loaded.hash, module);
1407
+ }
1408
+ return module;
1409
+ }
1410
+ const usePrimaryCache = isFullModuleLoad(loaded);
1411
+ if (usePrimaryCache) {
1412
+ if (cached && loaded.hash && moduleHashes.get(id) === loaded.hash) {
1413
+ return cached;
1414
+ }
1415
+ } else if (loaded.hash) {
1416
+ const variant = getModuleVariant(id, loaded.hash);
1417
+ if (variant) {
1418
+ return variant;
1419
+ }
1420
+ }
1421
+ // The broker only ships empty `code` when it expects the runner to reuse
1422
+ // a cached module via the hash-match short-circuit above. Reaching this
1423
+ // point with no code means the broker's "what runner has" mirror is out
1424
+ // of sync with our actual moduleCache/moduleVariants — fail loudly rather
1425
+ // than feeding empty source into vm.SourceTextModule.
1426
+ if (loaded.code == null || loaded.code === "") {
1427
+ throw new Error(`[wyw-in-js] LoadResult for ${id} has empty code but no cached module ` + `matched hash ${loaded.hash ?? "(none)"}. ` + `This indicates a broker/runner cache desync.`);
1428
+ }
1429
+ if (usePrimaryCache) {
1430
+ resetSingleModuleState(id, cached);
1431
+ }
1432
+ const module = new vm.SourceTextModule(`${buildPreamble(id)}${loaded.code ?? ""}`, {
1433
+ context: state.context,
1434
+ identifier: toVersionedModuleIdentifier(id, loaded.hash),
1435
+ initializeImportMeta(meta, targetModule) {
1436
+ const identifier = typeof targetModule.identifier === "string" ? targetModule.identifier : id;
1437
+ const fileId = stripQueryAndHash(identifier);
1438
+ // eslint-disable-next-line no-param-reassign
1439
+ meta.url = path.isAbsolute(fileId) ? pathToFileURL(fileId).href : fileId;
1440
+ },
1441
+ importModuleDynamically(specifier, referencingModule) {
1442
+ return resolveModule(specifier, referencingModule.identifier, "dynamic-import");
1443
+ }
1444
+ });
1445
+ if (usePrimaryCache) {
1446
+ moduleCache.set(id, module);
1447
+ if (loaded.hash) {
1448
+ moduleHashes.set(id, loaded.hash);
1449
+ }
1450
+ } else if (loaded.hash) {
1451
+ setModuleVariant(id, loaded.hash, module);
1452
+ }
1453
+ return module;
1454
+ })();
1455
+ loadInFlight.set(id, task);
1456
+ try {
1457
+ return await task;
1458
+ } finally {
1459
+ loadInFlight.delete(id);
1460
+ }
1461
+ };
1462
+ const createDynamicImportFn = (importer) => {
1463
+ return async (specifier) => {
1464
+ if (typeof specifier !== "string") {
1465
+ sendWarn({
1466
+ code: "eval-error",
1467
+ message: "[wyw-in-js] Dynamic import with non-string specifier during eval.",
1468
+ importer
1469
+ });
1470
+ if (state.evalOptions.mode === "strict") {
1471
+ throw new Error(`[wyw-in-js] Dynamic import with non-string specifier is not supported during eval.\n` + `importer: ${importer}\n` + `hint: make it a string literal or mock the import via importOverrides.`);
1472
+ }
1473
+ return createSyntheticModule(`dynamic:${String(specifier)}`, { default: undefined });
1474
+ }
1475
+ sendWarn({
1476
+ code: "dynamic-import",
1477
+ message: `[wyw-in-js] Dynamic import executed during eval: ${specifier}`,
1478
+ importer,
1479
+ specifier
1480
+ });
1481
+ const resolved = await resolveModule(specifier, importer, "dynamic-import");
1482
+ await linkModule(resolved);
1483
+ await resolved.evaluate();
1484
+ return resolved;
1485
+ };
1486
+ };
1487
+ const getModuleData = (id) => {
1488
+ const cached = moduleData.get(id);
1489
+ if (cached) return cached;
1490
+ const filename = stripQueryAndHash(id);
1491
+ const exportsValue = {};
1492
+ const moduleObj = { exports: exportsValue };
1493
+ const data = {
1494
+ exports: exportsValue,
1495
+ module: moduleObj,
1496
+ require: createRequireFn(id),
1497
+ filename,
1498
+ dirname: path.dirname(filename),
1499
+ dynamicImport: createDynamicImportFn(id)
1500
+ };
1501
+ moduleData.set(id, data);
1502
+ return data;
1503
+ };
1504
+ const resolveExportValue = (source, key) => {
1505
+ if (key === "default") {
1506
+ if (source && typeof source === "object" && "default" in source) {
1507
+ return source.default;
1508
+ }
1509
+ return source;
1510
+ }
1511
+ if (source && (typeof source === "object" || typeof source === "function")) {
1512
+ if (key in source) {
1513
+ return source[key];
1514
+ }
1515
+ if (source.default && typeof source.default === "object" && key in source.default) {
1516
+ return source.default[key];
1517
+ }
1518
+ }
1519
+ return undefined;
1520
+ };
1521
+ const collectModuleExports = () => {
1522
+ const exportsByModule = {};
1523
+ moduleOnly.forEach((only, id) => {
1524
+ if (!only || only.length === 0) return;
1525
+ const module = moduleCache.get(id) ?? moduleLastVariant.get(id);
1526
+ const data = moduleData.get(id);
1527
+ if (!module || !data) return;
1528
+ // The broker already has the serialized exports for this exact variant
1529
+ // from a prior eval session. Re-serializing here just wastes CPU on the
1530
+ // runner side and bloats the EVAL_RESULT payload. Same variant identifier
1531
+ // ⇒ same namespace ⇒ no change to send.
1532
+ const moduleIdentifier = typeof module.identifier === "string" ? module.identifier : id;
1533
+ if (sentNamespaceIdentifiers.get(id) === moduleIdentifier) {
1534
+ return;
1535
+ }
1536
+ // .namespace is only safe on fully evaluated modules. Modules that
1537
+ // errored or were never evaluated (stale from a prior failed session
1538
+ // with reuseModules) have TDZ bindings that crash Object.keys().
1539
+ if (module.status !== "evaluated") {
1540
+ sendWarn({
1541
+ code: "eval-stale-module",
1542
+ message: `[wyw-in-js] Skipping export collection for ${id}: ` + `module status is "${module.status}" (expected "evaluated"). ` + `Cached exports for this module may be stale.`
1543
+ });
1544
+ return;
1545
+ }
1546
+ const { namespace } = module;
1547
+ const hasNamespace = namespace && typeof namespace === "object" && Object.keys(namespace).length;
1548
+ const source = hasNamespace ? namespace : data.module.exports;
1549
+ const discoveredKeys = Object.keys(source ?? {}).filter((key) => key !== "__wywPreval" && key !== "side-effect" && key !== "*");
1550
+ const requestedKeys = only.filter((key) => key !== "__wywPreval" && key !== "side-effect" && key !== "*");
1551
+ const keys = Array.from(new Set([...requestedKeys, ...discoveredKeys]));
1552
+ if (keys.length === 0) return;
1553
+ const serialized = {};
1554
+ keys.forEach((key) => {
1555
+ const value = resolveExportValue(source, key);
1556
+ try {
1557
+ serialized[key] = serializeValue(value, {
1558
+ rootLabel: "module exports",
1559
+ path: [id, key]
1560
+ });
1561
+ } catch {}
1562
+ });
1563
+ if (Object.keys(serialized).length) {
1564
+ exportsByModule[id] = serialized;
1565
+ sentNamespaceIdentifiers.set(id, moduleIdentifier);
1566
+ }
1567
+ });
1568
+ return exportsByModule;
1569
+ };
1570
+ async function evaluateEntrypoint(id) {
1571
+ const evalStart = Date.now();
1572
+ debug("eval:start", id);
1573
+ const module = await loadModule(id, id, id);
1574
+ debug("eval:loaded", {
1575
+ id,
1576
+ durationMs: Date.now() - evalStart
1577
+ });
1578
+ await linkModule(module);
1579
+ debug("eval:linked", {
1580
+ id,
1581
+ durationMs: Date.now() - evalStart
1582
+ });
1583
+ await module.evaluate();
1584
+ debug("eval:evaluated", {
1585
+ id,
1586
+ durationMs: Date.now() - evalStart
1587
+ });
1588
+ const data = getModuleData(id);
1589
+ const exportsValue = data.module.exports;
1590
+ const hasPrevalExport = exportsValue && typeof exportsValue === "object" && "__wywPreval" in exportsValue;
1591
+ const { namespace } = module;
1592
+ const hasPrevalNamespace = namespace && typeof namespace === "object" && "__wywPreval" in namespace;
1593
+ const modules = collectModuleExports();
1594
+ if (!hasPrevalExport && !hasPrevalNamespace) {
1595
+ return {
1596
+ values: null,
1597
+ modules
1598
+ };
1599
+ }
1600
+ const preval = hasPrevalExport ? exportsValue.__wywPreval : namespace.__wywPreval;
1601
+ if (!preval || typeof preval !== "object") {
1602
+ return {
1603
+ values: null,
1604
+ modules
1605
+ };
1606
+ }
1607
+ const values = {};
1608
+ Object.entries(preval).forEach(([key, lazy]) => {
1609
+ let value;
1610
+ try {
1611
+ value = typeof lazy === "function" ? lazy() : lazy;
1612
+ } catch (error) {
1613
+ value = error;
1614
+ }
1615
+ values[key] = serializeValue(value, {
1616
+ allowFunctions: true,
1617
+ allowSymbols: true,
1618
+ rootLabel: "__wywPreval",
1619
+ path: [key]
1620
+ });
1621
+ });
1622
+ return {
1623
+ values,
1624
+ modules
1625
+ };
1626
+ }
1627
+ const handleMessage = async (message) => {
1628
+ switch (message.type) {
1629
+ case "INIT": {
1630
+ try {
1631
+ const initStart = Date.now();
1632
+ debug("init:start", message.payload.entrypoint ?? "eval-runner");
1633
+ const encodedGlobals = message.payload.evalOptions.globals ?? {};
1634
+ const nextGlobalsSignature = JSON.stringify(canonicalizeForSignature(encodedGlobals));
1635
+ const nextFeatures = message.payload.features ?? {};
1636
+ const nextEntrypoint = message.payload.entrypoint ?? "eval-runner";
1637
+ const nextHappyDomEnabled = isFeatureEnabled(nextFeatures, "happyDOM", nextEntrypoint);
1638
+ const globalsChanged = state.globalsSignature !== null && state.globalsSignature !== nextGlobalsSignature;
1639
+ const nextGlobals = !globalsChanged && state.globalsSignature !== null ? state.evalOptions.globals : decodeGlobals(encodedGlobals);
1640
+ const nextEvalOptions = {
1641
+ ...state.evalOptions,
1642
+ ...message.payload.evalOptions,
1643
+ globals: nextGlobals
1644
+ };
1645
+ const canReuseContext = state.context && state.happyDomEnabled === nextHappyDomEnabled && !globalsChanged;
1646
+ const reuseModules = Boolean(message.payload.reuseModules);
1647
+ if (canReuseContext) {
1648
+ const modulesReset = !reuseModules;
1649
+ if (modulesReset) {
1650
+ resetModuleState();
1651
+ } else {
1652
+ // Clear resolution caches between sessions even when reusing modules.
1653
+ // The broker rebuilds onlyByModule from scratch each session (cleared
1654
+ // in evaluate()). If the runner's resolveCache persists, RESOLVE
1655
+ // requests for previously-seen (importer, specifier) pairs are
1656
+ // skipped, preventing the broker from learning what exports are
1657
+ // needed. This can cause a barrel module to be served with a stale
1658
+ // `only` set that's missing exports a consumer actually imports,
1659
+ // leading to "does not provide an export named 'X'" link errors.
1660
+ resolveCache.clear();
1661
+ resolveInFlight.clear();
1662
+ loadInFlight.clear();
1663
+ }
1664
+ state.evalOptions = nextEvalOptions;
1665
+ state.features = nextFeatures;
1666
+ state.entrypoint = nextEntrypoint;
1667
+ Object.assign(state.context, {
1668
+ __dirname: path.dirname(nextEntrypoint),
1669
+ __filename: nextEntrypoint,
1670
+ ...nextEvalOptions.globals,
1671
+ __wyw_getModule: (moduleId) => getModuleData(moduleId)
1672
+ });
1673
+ state.globalsSignature = nextGlobalsSignature;
1674
+ debug("init:reuse", Date.now() - initStart);
1675
+ sendMessage({
1676
+ type: "INIT_ACK",
1677
+ id: message.id,
1678
+ modulesReset
1679
+ });
1680
+ break;
1681
+ }
1682
+ resetEvaluationState();
1683
+ state.evalOptions = nextEvalOptions;
1684
+ state.features = nextFeatures;
1685
+ state.entrypoint = nextEntrypoint;
1686
+ debug("init:globals", Date.now() - initStart);
1687
+ const windowStart = Date.now();
1688
+ const { context, teardown } = await createVmContext(state.entrypoint, state.features, {
1689
+ ...state.evalOptions.globals,
1690
+ __wyw_getModule: (moduleId) => getModuleData(moduleId)
1691
+ });
1692
+ debug("init:context", Date.now() - windowStart);
1693
+ state.context = context;
1694
+ state.teardown = teardown;
1695
+ state.happyDomEnabled = nextHappyDomEnabled;
1696
+ state.globalsSignature = nextGlobalsSignature;
1697
+ // Full context rebuild ⇒ moduleCache was cleared by resetEvaluationState.
1698
+ sendMessage({
1699
+ type: "INIT_ACK",
1700
+ id: message.id,
1701
+ modulesReset: true
1702
+ });
1703
+ debug("init:done", Date.now() - initStart);
1704
+ } catch (error) {
1705
+ sendMessage({
1706
+ type: "INIT_ACK",
1707
+ id: message.id,
1708
+ error: serializeError(error)
1709
+ });
1710
+ }
1711
+ break;
1712
+ }
1713
+ case "EVAL": {
1714
+ try {
1715
+ const { values, modules } = await evaluateEntrypoint(message.payload.id);
1716
+ sendMessage({
1717
+ type: "EVAL_RESULT",
1718
+ id: message.id,
1719
+ payload: {
1720
+ values,
1721
+ modules
1722
+ }
1723
+ });
1724
+ } catch (error) {
1725
+ sendMessage({
1726
+ type: "EVAL_RESULT",
1727
+ id: message.id,
1728
+ payload: { values: null },
1729
+ error: serializeError(error)
1730
+ });
1731
+ }
1732
+ break;
1733
+ }
1734
+ case "RESOLVE_RESULT": {
1735
+ resolvePending(message.id, message.payload);
1736
+ break;
1737
+ }
1738
+ case "LOAD_RESULT": {
1739
+ handleLoadResult(message.id, message.payload);
1740
+ break;
1741
+ }
1742
+ default: break;
1743
+ }
1744
+ };
1745
+ let buffer = "";
1746
+ process.stdin.setEncoding("utf8");
1747
+ process.stdin.resume();
1748
+ process.stdin.on("data", (chunk) => {
1749
+ buffer += chunk;
1750
+ const lines = buffer.split("\n");
1751
+ buffer = lines.pop() ?? "";
1752
+ lines.forEach((line) => {
1753
+ if (!line.trim()) return;
1754
+ const message = JSON.parse(line);
1755
+ handleMessage(message);
1756
+ });
1757
+ });
1758
+ process.stdin.on("close", shutdown);
1759
+ //# sourceMappingURL=runner.js.map