@tracecode/harness 0.6.6 → 0.7.0-beta7

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 (494) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +134 -15
  3. package/THIRD_PARTY_NOTICES.md +170 -0
  4. package/dist/browser.cjs +2361 -1033
  5. package/dist/browser.cjs.map +1 -1
  6. package/dist/browser.d.cts +33 -3
  7. package/dist/browser.d.ts +33 -3
  8. package/dist/browser.js +2357 -1033
  9. package/dist/browser.js.map +1 -1
  10. package/dist/cli.cjs +160 -23
  11. package/dist/cli.cjs.map +1 -1
  12. package/dist/cli.js +161 -24
  13. package/dist/cli.js.map +1 -1
  14. package/dist/core.cjs +748 -867
  15. package/dist/core.cjs.map +1 -1
  16. package/dist/core.d.cts +21 -85
  17. package/dist/core.d.ts +21 -85
  18. package/dist/core.js +734 -855
  19. package/dist/core.js.map +1 -1
  20. package/dist/cpp-worker-client-Bn7kC0_L.d.ts +84 -0
  21. package/dist/cpp-worker-client-BzdJLuZa.d.cts +84 -0
  22. package/dist/cpp.cjs +1063 -0
  23. package/dist/cpp.cjs.map +1 -0
  24. package/dist/cpp.d.cts +7 -0
  25. package/dist/cpp.d.ts +7 -0
  26. package/dist/cpp.js +1035 -0
  27. package/dist/cpp.js.map +1 -0
  28. package/dist/csharp-worker-client-DMHIa2YG.d.cts +69 -0
  29. package/dist/csharp-worker-client-JwqS6LiX.d.ts +69 -0
  30. package/dist/csharp.cjs +1012 -0
  31. package/dist/csharp.cjs.map +1 -0
  32. package/dist/csharp.d.cts +7 -0
  33. package/dist/csharp.d.ts +7 -0
  34. package/dist/csharp.js +984 -0
  35. package/dist/csharp.js.map +1 -0
  36. package/dist/index.cjs +3142 -1160
  37. package/dist/index.cjs.map +1 -1
  38. package/dist/index.d.cts +13 -5
  39. package/dist/index.d.ts +13 -5
  40. package/dist/index.js +3117 -1148
  41. package/dist/index.js.map +1 -1
  42. package/dist/internal/browser.cjs +1639 -30
  43. package/dist/internal/browser.cjs.map +1 -1
  44. package/dist/internal/browser.d.cts +6 -199
  45. package/dist/internal/browser.d.ts +6 -199
  46. package/dist/internal/browser.js +1636 -30
  47. package/dist/internal/browser.js.map +1 -1
  48. package/dist/java-worker-client-BOwKW-11.d.cts +72 -0
  49. package/dist/java-worker-client-C97DDnCp.d.ts +72 -0
  50. package/dist/java.cjs +1225 -0
  51. package/dist/java.cjs.map +1 -0
  52. package/dist/java.d.cts +7 -0
  53. package/dist/java.d.ts +7 -0
  54. package/dist/java.js +1197 -0
  55. package/dist/java.js.map +1 -0
  56. package/dist/javascript-worker-client-CYBGEEvc.d.cts +51 -0
  57. package/dist/javascript-worker-client-DIX1Mp21.d.ts +51 -0
  58. package/dist/javascript.cjs +1063 -19
  59. package/dist/javascript.cjs.map +1 -1
  60. package/dist/javascript.d.cts +7 -4
  61. package/dist/javascript.d.ts +7 -4
  62. package/dist/javascript.js +1061 -19
  63. package/dist/javascript.js.map +1 -1
  64. package/dist/pyodide-worker-client-C-2rfHj9.d.ts +111 -0
  65. package/dist/pyodide-worker-client-Cn0a8Uv3.d.cts +111 -0
  66. package/dist/python.cjs +1282 -74
  67. package/dist/python.cjs.map +1 -1
  68. package/dist/python.d.cts +20 -14
  69. package/dist/python.d.ts +20 -14
  70. package/dist/python.js +1279 -74
  71. package/dist/python.js.map +1 -1
  72. package/dist/runtime-language-info-BFUSti3-.d.ts +43 -0
  73. package/dist/runtime-language-info-Bxza1cI2.d.cts +43 -0
  74. package/dist/runtime-types-2qM0MukN.d.cts +244 -0
  75. package/dist/runtime-types-2qM0MukN.d.ts +244 -0
  76. package/package.json +73 -8
  77. package/workers/cpp/cpp-compiler-frame.html +82 -0
  78. package/workers/cpp/cpp-compiler-worker.js +131 -0
  79. package/workers/cpp/cpp-worker.js +5790 -0
  80. package/workers/cpp/tracecode_runtime.hpp +6147 -0
  81. package/workers/csharp/csharp-worker.js +301 -0
  82. package/workers/java/.build/classes/harness/browser/JavaRewriteLibrary.class +0 -0
  83. package/workers/java/java-source-augmentations.js +880 -0
  84. package/workers/java/java-worker.js +2149 -178
  85. package/workers/java/src/harness/browser/JavaRewriteLibrary.java +1645 -32
  86. package/workers/java/src/javafx/util/Pair.java +42 -0
  87. package/workers/java/src/tracecode/browser/BrowserCompileAndTraceLibrary.java +714 -0
  88. package/workers/java/src/tracecode/browser/BrowserCompileAndTraceMain.java +76 -0
  89. package/workers/java/src/tracecode/browser/RuntimeProbeMain.java +14 -0
  90. package/workers/java/src/tracecode/user/TraceHooks.java +1406 -0
  91. package/workers/javascript/javascript-libraries-entry.js +71 -0
  92. package/workers/javascript/javascript-worker.js +2054 -424
  93. package/workers/python/generated-python-harness-snippets.js +4 -4
  94. package/workers/python/pyodide-worker.js +222 -61
  95. package/workers/python/runtime-core.js +1387 -301
  96. package/workers/vendor/csharp/.stamp +0 -0
  97. package/workers/vendor/csharp/TraceCode.CSharpHost.runtimeconfig.json +32 -0
  98. package/workers/vendor/csharp/_framework/Microsoft.CSharp.wasm +0 -0
  99. package/workers/vendor/csharp/_framework/Microsoft.CodeAnalysis.CSharp.wasm +0 -0
  100. package/workers/vendor/csharp/_framework/Microsoft.CodeAnalysis.wasm +0 -0
  101. package/workers/vendor/csharp/_framework/Microsoft.VisualBasic.Core.wasm +0 -0
  102. package/workers/vendor/csharp/_framework/Microsoft.VisualBasic.wasm +0 -0
  103. package/workers/vendor/csharp/_framework/Microsoft.Win32.Primitives.wasm +0 -0
  104. package/workers/vendor/csharp/_framework/Microsoft.Win32.Registry.wasm +0 -0
  105. package/workers/vendor/csharp/_framework/System.AppContext.wasm +0 -0
  106. package/workers/vendor/csharp/_framework/System.Buffers.wasm +0 -0
  107. package/workers/vendor/csharp/_framework/System.Collections.Concurrent.wasm +0 -0
  108. package/workers/vendor/csharp/_framework/System.Collections.Immutable.wasm +0 -0
  109. package/workers/vendor/csharp/_framework/System.Collections.NonGeneric.wasm +0 -0
  110. package/workers/vendor/csharp/_framework/System.Collections.Specialized.wasm +0 -0
  111. package/workers/vendor/csharp/_framework/System.Collections.wasm +0 -0
  112. package/workers/vendor/csharp/_framework/System.ComponentModel.Annotations.wasm +0 -0
  113. package/workers/vendor/csharp/_framework/System.ComponentModel.DataAnnotations.wasm +0 -0
  114. package/workers/vendor/csharp/_framework/System.ComponentModel.EventBasedAsync.wasm +0 -0
  115. package/workers/vendor/csharp/_framework/System.ComponentModel.Primitives.wasm +0 -0
  116. package/workers/vendor/csharp/_framework/System.ComponentModel.TypeConverter.wasm +0 -0
  117. package/workers/vendor/csharp/_framework/System.ComponentModel.wasm +0 -0
  118. package/workers/vendor/csharp/_framework/System.Configuration.wasm +0 -0
  119. package/workers/vendor/csharp/_framework/System.Console.wasm +0 -0
  120. package/workers/vendor/csharp/_framework/System.Core.wasm +0 -0
  121. package/workers/vendor/csharp/_framework/System.Data.Common.wasm +0 -0
  122. package/workers/vendor/csharp/_framework/System.Data.DataSetExtensions.wasm +0 -0
  123. package/workers/vendor/csharp/_framework/System.Data.wasm +0 -0
  124. package/workers/vendor/csharp/_framework/System.Diagnostics.Contracts.wasm +0 -0
  125. package/workers/vendor/csharp/_framework/System.Diagnostics.Debug.wasm +0 -0
  126. package/workers/vendor/csharp/_framework/System.Diagnostics.DiagnosticSource.wasm +0 -0
  127. package/workers/vendor/csharp/_framework/System.Diagnostics.FileVersionInfo.wasm +0 -0
  128. package/workers/vendor/csharp/_framework/System.Diagnostics.Process.wasm +0 -0
  129. package/workers/vendor/csharp/_framework/System.Diagnostics.StackTrace.wasm +0 -0
  130. package/workers/vendor/csharp/_framework/System.Diagnostics.TextWriterTraceListener.wasm +0 -0
  131. package/workers/vendor/csharp/_framework/System.Diagnostics.Tools.wasm +0 -0
  132. package/workers/vendor/csharp/_framework/System.Diagnostics.TraceSource.wasm +0 -0
  133. package/workers/vendor/csharp/_framework/System.Diagnostics.Tracing.wasm +0 -0
  134. package/workers/vendor/csharp/_framework/System.Drawing.Primitives.wasm +0 -0
  135. package/workers/vendor/csharp/_framework/System.Drawing.wasm +0 -0
  136. package/workers/vendor/csharp/_framework/System.Dynamic.Runtime.wasm +0 -0
  137. package/workers/vendor/csharp/_framework/System.Formats.Asn1.wasm +0 -0
  138. package/workers/vendor/csharp/_framework/System.Formats.Tar.wasm +0 -0
  139. package/workers/vendor/csharp/_framework/System.Globalization.Calendars.wasm +0 -0
  140. package/workers/vendor/csharp/_framework/System.Globalization.Extensions.wasm +0 -0
  141. package/workers/vendor/csharp/_framework/System.Globalization.wasm +0 -0
  142. package/workers/vendor/csharp/_framework/System.IO.Compression.Brotli.wasm +0 -0
  143. package/workers/vendor/csharp/_framework/System.IO.Compression.FileSystem.wasm +0 -0
  144. package/workers/vendor/csharp/_framework/System.IO.Compression.ZipFile.wasm +0 -0
  145. package/workers/vendor/csharp/_framework/System.IO.Compression.wasm +0 -0
  146. package/workers/vendor/csharp/_framework/System.IO.FileSystem.AccessControl.wasm +0 -0
  147. package/workers/vendor/csharp/_framework/System.IO.FileSystem.DriveInfo.wasm +0 -0
  148. package/workers/vendor/csharp/_framework/System.IO.FileSystem.Primitives.wasm +0 -0
  149. package/workers/vendor/csharp/_framework/System.IO.FileSystem.Watcher.wasm +0 -0
  150. package/workers/vendor/csharp/_framework/System.IO.FileSystem.wasm +0 -0
  151. package/workers/vendor/csharp/_framework/System.IO.IsolatedStorage.wasm +0 -0
  152. package/workers/vendor/csharp/_framework/System.IO.MemoryMappedFiles.wasm +0 -0
  153. package/workers/vendor/csharp/_framework/System.IO.Pipelines.wasm +0 -0
  154. package/workers/vendor/csharp/_framework/System.IO.Pipes.AccessControl.wasm +0 -0
  155. package/workers/vendor/csharp/_framework/System.IO.Pipes.wasm +0 -0
  156. package/workers/vendor/csharp/_framework/System.IO.UnmanagedMemoryStream.wasm +0 -0
  157. package/workers/vendor/csharp/_framework/System.IO.wasm +0 -0
  158. package/workers/vendor/csharp/_framework/System.Linq.AsyncEnumerable.wasm +0 -0
  159. package/workers/vendor/csharp/_framework/System.Linq.Expressions.wasm +0 -0
  160. package/workers/vendor/csharp/_framework/System.Linq.Parallel.wasm +0 -0
  161. package/workers/vendor/csharp/_framework/System.Linq.Queryable.wasm +0 -0
  162. package/workers/vendor/csharp/_framework/System.Linq.wasm +0 -0
  163. package/workers/vendor/csharp/_framework/System.Memory.wasm +0 -0
  164. package/workers/vendor/csharp/_framework/System.Net.Http.Json.wasm +0 -0
  165. package/workers/vendor/csharp/_framework/System.Net.Http.wasm +0 -0
  166. package/workers/vendor/csharp/_framework/System.Net.HttpListener.wasm +0 -0
  167. package/workers/vendor/csharp/_framework/System.Net.Mail.wasm +0 -0
  168. package/workers/vendor/csharp/_framework/System.Net.NameResolution.wasm +0 -0
  169. package/workers/vendor/csharp/_framework/System.Net.NetworkInformation.wasm +0 -0
  170. package/workers/vendor/csharp/_framework/System.Net.Ping.wasm +0 -0
  171. package/workers/vendor/csharp/_framework/System.Net.Primitives.wasm +0 -0
  172. package/workers/vendor/csharp/_framework/System.Net.Quic.wasm +0 -0
  173. package/workers/vendor/csharp/_framework/System.Net.Requests.wasm +0 -0
  174. package/workers/vendor/csharp/_framework/System.Net.Security.wasm +0 -0
  175. package/workers/vendor/csharp/_framework/System.Net.ServerSentEvents.wasm +0 -0
  176. package/workers/vendor/csharp/_framework/System.Net.ServicePoint.wasm +0 -0
  177. package/workers/vendor/csharp/_framework/System.Net.Sockets.wasm +0 -0
  178. package/workers/vendor/csharp/_framework/System.Net.WebClient.wasm +0 -0
  179. package/workers/vendor/csharp/_framework/System.Net.WebHeaderCollection.wasm +0 -0
  180. package/workers/vendor/csharp/_framework/System.Net.WebProxy.wasm +0 -0
  181. package/workers/vendor/csharp/_framework/System.Net.WebSockets.Client.wasm +0 -0
  182. package/workers/vendor/csharp/_framework/System.Net.WebSockets.wasm +0 -0
  183. package/workers/vendor/csharp/_framework/System.Net.wasm +0 -0
  184. package/workers/vendor/csharp/_framework/System.Numerics.Vectors.wasm +0 -0
  185. package/workers/vendor/csharp/_framework/System.Numerics.wasm +0 -0
  186. package/workers/vendor/csharp/_framework/System.ObjectModel.wasm +0 -0
  187. package/workers/vendor/csharp/_framework/System.Private.CoreLib.wasm +0 -0
  188. package/workers/vendor/csharp/_framework/System.Private.DataContractSerialization.wasm +0 -0
  189. package/workers/vendor/csharp/_framework/System.Private.Uri.wasm +0 -0
  190. package/workers/vendor/csharp/_framework/System.Private.Xml.Linq.wasm +0 -0
  191. package/workers/vendor/csharp/_framework/System.Private.Xml.wasm +0 -0
  192. package/workers/vendor/csharp/_framework/System.Reflection.DispatchProxy.wasm +0 -0
  193. package/workers/vendor/csharp/_framework/System.Reflection.Emit.ILGeneration.wasm +0 -0
  194. package/workers/vendor/csharp/_framework/System.Reflection.Emit.Lightweight.wasm +0 -0
  195. package/workers/vendor/csharp/_framework/System.Reflection.Emit.wasm +0 -0
  196. package/workers/vendor/csharp/_framework/System.Reflection.Extensions.wasm +0 -0
  197. package/workers/vendor/csharp/_framework/System.Reflection.Metadata.wasm +0 -0
  198. package/workers/vendor/csharp/_framework/System.Reflection.Primitives.wasm +0 -0
  199. package/workers/vendor/csharp/_framework/System.Reflection.TypeExtensions.wasm +0 -0
  200. package/workers/vendor/csharp/_framework/System.Reflection.wasm +0 -0
  201. package/workers/vendor/csharp/_framework/System.Resources.Reader.wasm +0 -0
  202. package/workers/vendor/csharp/_framework/System.Resources.ResourceManager.wasm +0 -0
  203. package/workers/vendor/csharp/_framework/System.Resources.Writer.wasm +0 -0
  204. package/workers/vendor/csharp/_framework/System.Runtime.CompilerServices.Unsafe.wasm +0 -0
  205. package/workers/vendor/csharp/_framework/System.Runtime.CompilerServices.VisualC.wasm +0 -0
  206. package/workers/vendor/csharp/_framework/System.Runtime.Extensions.wasm +0 -0
  207. package/workers/vendor/csharp/_framework/System.Runtime.Handles.wasm +0 -0
  208. package/workers/vendor/csharp/_framework/System.Runtime.InteropServices.JavaScript.wasm +0 -0
  209. package/workers/vendor/csharp/_framework/System.Runtime.InteropServices.RuntimeInformation.wasm +0 -0
  210. package/workers/vendor/csharp/_framework/System.Runtime.InteropServices.wasm +0 -0
  211. package/workers/vendor/csharp/_framework/System.Runtime.Intrinsics.wasm +0 -0
  212. package/workers/vendor/csharp/_framework/System.Runtime.Loader.wasm +0 -0
  213. package/workers/vendor/csharp/_framework/System.Runtime.Numerics.wasm +0 -0
  214. package/workers/vendor/csharp/_framework/System.Runtime.Serialization.Formatters.wasm +0 -0
  215. package/workers/vendor/csharp/_framework/System.Runtime.Serialization.Json.wasm +0 -0
  216. package/workers/vendor/csharp/_framework/System.Runtime.Serialization.Primitives.wasm +0 -0
  217. package/workers/vendor/csharp/_framework/System.Runtime.Serialization.Xml.wasm +0 -0
  218. package/workers/vendor/csharp/_framework/System.Runtime.Serialization.wasm +0 -0
  219. package/workers/vendor/csharp/_framework/System.Runtime.wasm +0 -0
  220. package/workers/vendor/csharp/_framework/System.Security.AccessControl.wasm +0 -0
  221. package/workers/vendor/csharp/_framework/System.Security.Claims.wasm +0 -0
  222. package/workers/vendor/csharp/_framework/System.Security.Cryptography.Algorithms.wasm +0 -0
  223. package/workers/vendor/csharp/_framework/System.Security.Cryptography.Cng.wasm +0 -0
  224. package/workers/vendor/csharp/_framework/System.Security.Cryptography.Csp.wasm +0 -0
  225. package/workers/vendor/csharp/_framework/System.Security.Cryptography.Encoding.wasm +0 -0
  226. package/workers/vendor/csharp/_framework/System.Security.Cryptography.OpenSsl.wasm +0 -0
  227. package/workers/vendor/csharp/_framework/System.Security.Cryptography.Primitives.wasm +0 -0
  228. package/workers/vendor/csharp/_framework/System.Security.Cryptography.X509Certificates.wasm +0 -0
  229. package/workers/vendor/csharp/_framework/System.Security.Cryptography.wasm +0 -0
  230. package/workers/vendor/csharp/_framework/System.Security.Principal.Windows.wasm +0 -0
  231. package/workers/vendor/csharp/_framework/System.Security.Principal.wasm +0 -0
  232. package/workers/vendor/csharp/_framework/System.Security.SecureString.wasm +0 -0
  233. package/workers/vendor/csharp/_framework/System.Security.wasm +0 -0
  234. package/workers/vendor/csharp/_framework/System.ServiceModel.Web.wasm +0 -0
  235. package/workers/vendor/csharp/_framework/System.ServiceProcess.wasm +0 -0
  236. package/workers/vendor/csharp/_framework/System.Text.Encoding.CodePages.wasm +0 -0
  237. package/workers/vendor/csharp/_framework/System.Text.Encoding.Extensions.wasm +0 -0
  238. package/workers/vendor/csharp/_framework/System.Text.Encoding.wasm +0 -0
  239. package/workers/vendor/csharp/_framework/System.Text.Encodings.Web.wasm +0 -0
  240. package/workers/vendor/csharp/_framework/System.Text.Json.wasm +0 -0
  241. package/workers/vendor/csharp/_framework/System.Text.RegularExpressions.wasm +0 -0
  242. package/workers/vendor/csharp/_framework/System.Threading.AccessControl.wasm +0 -0
  243. package/workers/vendor/csharp/_framework/System.Threading.Channels.wasm +0 -0
  244. package/workers/vendor/csharp/_framework/System.Threading.Overlapped.wasm +0 -0
  245. package/workers/vendor/csharp/_framework/System.Threading.Tasks.Dataflow.wasm +0 -0
  246. package/workers/vendor/csharp/_framework/System.Threading.Tasks.Extensions.wasm +0 -0
  247. package/workers/vendor/csharp/_framework/System.Threading.Tasks.Parallel.wasm +0 -0
  248. package/workers/vendor/csharp/_framework/System.Threading.Tasks.wasm +0 -0
  249. package/workers/vendor/csharp/_framework/System.Threading.Thread.wasm +0 -0
  250. package/workers/vendor/csharp/_framework/System.Threading.ThreadPool.wasm +0 -0
  251. package/workers/vendor/csharp/_framework/System.Threading.Timer.wasm +0 -0
  252. package/workers/vendor/csharp/_framework/System.Threading.wasm +0 -0
  253. package/workers/vendor/csharp/_framework/System.Transactions.Local.wasm +0 -0
  254. package/workers/vendor/csharp/_framework/System.Transactions.wasm +0 -0
  255. package/workers/vendor/csharp/_framework/System.ValueTuple.wasm +0 -0
  256. package/workers/vendor/csharp/_framework/System.Web.HttpUtility.wasm +0 -0
  257. package/workers/vendor/csharp/_framework/System.Web.wasm +0 -0
  258. package/workers/vendor/csharp/_framework/System.Windows.wasm +0 -0
  259. package/workers/vendor/csharp/_framework/System.Xml.Linq.wasm +0 -0
  260. package/workers/vendor/csharp/_framework/System.Xml.ReaderWriter.wasm +0 -0
  261. package/workers/vendor/csharp/_framework/System.Xml.Serialization.wasm +0 -0
  262. package/workers/vendor/csharp/_framework/System.Xml.XDocument.wasm +0 -0
  263. package/workers/vendor/csharp/_framework/System.Xml.XPath.XDocument.wasm +0 -0
  264. package/workers/vendor/csharp/_framework/System.Xml.XPath.wasm +0 -0
  265. package/workers/vendor/csharp/_framework/System.Xml.XmlDocument.wasm +0 -0
  266. package/workers/vendor/csharp/_framework/System.Xml.XmlSerializer.wasm +0 -0
  267. package/workers/vendor/csharp/_framework/System.Xml.wasm +0 -0
  268. package/workers/vendor/csharp/_framework/System.wasm +0 -0
  269. package/workers/vendor/csharp/_framework/TraceCode.CSharpHost.wasm +0 -0
  270. package/workers/vendor/csharp/_framework/WindowsBase.wasm +0 -0
  271. package/workers/vendor/csharp/_framework/cs/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
  272. package/workers/vendor/csharp/_framework/cs/Microsoft.CodeAnalysis.resources.wasm +0 -0
  273. package/workers/vendor/csharp/_framework/de/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
  274. package/workers/vendor/csharp/_framework/de/Microsoft.CodeAnalysis.resources.wasm +0 -0
  275. package/workers/vendor/csharp/_framework/dotnet.boot.js +1958 -0
  276. package/workers/vendor/csharp/_framework/dotnet.js +4 -0
  277. package/workers/vendor/csharp/_framework/dotnet.js.map +1 -0
  278. package/workers/vendor/csharp/_framework/dotnet.native.js +6687 -0
  279. package/workers/vendor/csharp/_framework/dotnet.native.wasm +0 -0
  280. package/workers/vendor/csharp/_framework/dotnet.runtime.js +4 -0
  281. package/workers/vendor/csharp/_framework/dotnet.runtime.js.map +1 -0
  282. package/workers/vendor/csharp/_framework/es/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
  283. package/workers/vendor/csharp/_framework/es/Microsoft.CodeAnalysis.resources.wasm +0 -0
  284. package/workers/vendor/csharp/_framework/fr/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
  285. package/workers/vendor/csharp/_framework/fr/Microsoft.CodeAnalysis.resources.wasm +0 -0
  286. package/workers/vendor/csharp/_framework/it/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
  287. package/workers/vendor/csharp/_framework/it/Microsoft.CodeAnalysis.resources.wasm +0 -0
  288. package/workers/vendor/csharp/_framework/ja/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
  289. package/workers/vendor/csharp/_framework/ja/Microsoft.CodeAnalysis.resources.wasm +0 -0
  290. package/workers/vendor/csharp/_framework/ko/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
  291. package/workers/vendor/csharp/_framework/ko/Microsoft.CodeAnalysis.resources.wasm +0 -0
  292. package/workers/vendor/csharp/_framework/mscorlib.wasm +0 -0
  293. package/workers/vendor/csharp/_framework/netstandard.wasm +0 -0
  294. package/workers/vendor/csharp/_framework/pl/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
  295. package/workers/vendor/csharp/_framework/pl/Microsoft.CodeAnalysis.resources.wasm +0 -0
  296. package/workers/vendor/csharp/_framework/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
  297. package/workers/vendor/csharp/_framework/pt-BR/Microsoft.CodeAnalysis.resources.wasm +0 -0
  298. package/workers/vendor/csharp/_framework/ru/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
  299. package/workers/vendor/csharp/_framework/ru/Microsoft.CodeAnalysis.resources.wasm +0 -0
  300. package/workers/vendor/csharp/_framework/supportFiles/0_Microsoft.CodeAnalysis.CSharp.dll +0 -0
  301. package/workers/vendor/csharp/_framework/supportFiles/100_System.Reflection.Emit.ILGeneration.dll +0 -0
  302. package/workers/vendor/csharp/_framework/supportFiles/101_System.Reflection.Emit.Lightweight.dll +0 -0
  303. package/workers/vendor/csharp/_framework/supportFiles/102_System.Reflection.Extensions.dll +0 -0
  304. package/workers/vendor/csharp/_framework/supportFiles/103_System.Reflection.Metadata.dll +0 -0
  305. package/workers/vendor/csharp/_framework/supportFiles/104_System.Reflection.Primitives.dll +0 -0
  306. package/workers/vendor/csharp/_framework/supportFiles/105_System.Reflection.TypeExtensions.dll +0 -0
  307. package/workers/vendor/csharp/_framework/supportFiles/106_System.Resources.Reader.dll +0 -0
  308. package/workers/vendor/csharp/_framework/supportFiles/107_System.Resources.ResourceManager.dll +0 -0
  309. package/workers/vendor/csharp/_framework/supportFiles/108_System.Resources.Writer.dll +0 -0
  310. package/workers/vendor/csharp/_framework/supportFiles/109_System.Runtime.CompilerServices.Unsafe.dll +0 -0
  311. package/workers/vendor/csharp/_framework/supportFiles/10_System.Buffers.dll +0 -0
  312. package/workers/vendor/csharp/_framework/supportFiles/110_System.Runtime.CompilerServices.VisualC.dll +0 -0
  313. package/workers/vendor/csharp/_framework/supportFiles/111_System.Runtime.dll +0 -0
  314. package/workers/vendor/csharp/_framework/supportFiles/112_System.Runtime.Extensions.dll +0 -0
  315. package/workers/vendor/csharp/_framework/supportFiles/113_System.Runtime.Handles.dll +0 -0
  316. package/workers/vendor/csharp/_framework/supportFiles/114_System.Runtime.InteropServices.dll +0 -0
  317. package/workers/vendor/csharp/_framework/supportFiles/115_System.Runtime.InteropServices.JavaScript.dll +0 -0
  318. package/workers/vendor/csharp/_framework/supportFiles/116_System.Runtime.InteropServices.RuntimeInformation.dll +0 -0
  319. package/workers/vendor/csharp/_framework/supportFiles/117_System.Runtime.Intrinsics.dll +0 -0
  320. package/workers/vendor/csharp/_framework/supportFiles/118_System.Runtime.Loader.dll +0 -0
  321. package/workers/vendor/csharp/_framework/supportFiles/119_System.Runtime.Numerics.dll +0 -0
  322. package/workers/vendor/csharp/_framework/supportFiles/11_System.Collections.Concurrent.dll +0 -0
  323. package/workers/vendor/csharp/_framework/supportFiles/120_System.Runtime.Serialization.dll +0 -0
  324. package/workers/vendor/csharp/_framework/supportFiles/121_System.Runtime.Serialization.Formatters.dll +0 -0
  325. package/workers/vendor/csharp/_framework/supportFiles/122_System.Runtime.Serialization.Json.dll +0 -0
  326. package/workers/vendor/csharp/_framework/supportFiles/123_System.Runtime.Serialization.Primitives.dll +0 -0
  327. package/workers/vendor/csharp/_framework/supportFiles/124_System.Runtime.Serialization.Xml.dll +0 -0
  328. package/workers/vendor/csharp/_framework/supportFiles/125_System.Security.AccessControl.dll +0 -0
  329. package/workers/vendor/csharp/_framework/supportFiles/126_System.Security.Claims.dll +0 -0
  330. package/workers/vendor/csharp/_framework/supportFiles/127_System.Security.Cryptography.Algorithms.dll +0 -0
  331. package/workers/vendor/csharp/_framework/supportFiles/128_System.Security.Cryptography.Cng.dll +0 -0
  332. package/workers/vendor/csharp/_framework/supportFiles/129_System.Security.Cryptography.Csp.dll +0 -0
  333. package/workers/vendor/csharp/_framework/supportFiles/12_System.Collections.dll +0 -0
  334. package/workers/vendor/csharp/_framework/supportFiles/130_System.Security.Cryptography.dll +0 -0
  335. package/workers/vendor/csharp/_framework/supportFiles/131_System.Security.Cryptography.Encoding.dll +0 -0
  336. package/workers/vendor/csharp/_framework/supportFiles/132_System.Security.Cryptography.OpenSsl.dll +0 -0
  337. package/workers/vendor/csharp/_framework/supportFiles/133_System.Security.Cryptography.Primitives.dll +0 -0
  338. package/workers/vendor/csharp/_framework/supportFiles/134_System.Security.Cryptography.X509Certificates.dll +0 -0
  339. package/workers/vendor/csharp/_framework/supportFiles/135_System.Security.dll +0 -0
  340. package/workers/vendor/csharp/_framework/supportFiles/136_System.Security.Principal.dll +0 -0
  341. package/workers/vendor/csharp/_framework/supportFiles/137_System.Security.Principal.Windows.dll +0 -0
  342. package/workers/vendor/csharp/_framework/supportFiles/138_System.Security.SecureString.dll +0 -0
  343. package/workers/vendor/csharp/_framework/supportFiles/139_System.ServiceModel.Web.dll +0 -0
  344. package/workers/vendor/csharp/_framework/supportFiles/13_System.Collections.Immutable.dll +0 -0
  345. package/workers/vendor/csharp/_framework/supportFiles/140_System.ServiceProcess.dll +0 -0
  346. package/workers/vendor/csharp/_framework/supportFiles/141_System.Text.Encoding.CodePages.dll +0 -0
  347. package/workers/vendor/csharp/_framework/supportFiles/142_System.Text.Encoding.dll +0 -0
  348. package/workers/vendor/csharp/_framework/supportFiles/143_System.Text.Encoding.Extensions.dll +0 -0
  349. package/workers/vendor/csharp/_framework/supportFiles/144_System.Text.Encodings.Web.dll +0 -0
  350. package/workers/vendor/csharp/_framework/supportFiles/145_System.Text.Json.dll +0 -0
  351. package/workers/vendor/csharp/_framework/supportFiles/146_System.Text.RegularExpressions.dll +0 -0
  352. package/workers/vendor/csharp/_framework/supportFiles/147_System.Threading.AccessControl.dll +0 -0
  353. package/workers/vendor/csharp/_framework/supportFiles/148_System.Threading.Channels.dll +0 -0
  354. package/workers/vendor/csharp/_framework/supportFiles/149_System.Threading.dll +0 -0
  355. package/workers/vendor/csharp/_framework/supportFiles/14_System.Collections.NonGeneric.dll +0 -0
  356. package/workers/vendor/csharp/_framework/supportFiles/150_System.Threading.Overlapped.dll +0 -0
  357. package/workers/vendor/csharp/_framework/supportFiles/151_System.Threading.Tasks.Dataflow.dll +0 -0
  358. package/workers/vendor/csharp/_framework/supportFiles/152_System.Threading.Tasks.dll +0 -0
  359. package/workers/vendor/csharp/_framework/supportFiles/153_System.Threading.Tasks.Extensions.dll +0 -0
  360. package/workers/vendor/csharp/_framework/supportFiles/154_System.Threading.Tasks.Parallel.dll +0 -0
  361. package/workers/vendor/csharp/_framework/supportFiles/155_System.Threading.Thread.dll +0 -0
  362. package/workers/vendor/csharp/_framework/supportFiles/156_System.Threading.ThreadPool.dll +0 -0
  363. package/workers/vendor/csharp/_framework/supportFiles/157_System.Threading.Timer.dll +0 -0
  364. package/workers/vendor/csharp/_framework/supportFiles/158_System.Transactions.dll +0 -0
  365. package/workers/vendor/csharp/_framework/supportFiles/159_System.Transactions.Local.dll +0 -0
  366. package/workers/vendor/csharp/_framework/supportFiles/15_System.Collections.Specialized.dll +0 -0
  367. package/workers/vendor/csharp/_framework/supportFiles/160_System.ValueTuple.dll +0 -0
  368. package/workers/vendor/csharp/_framework/supportFiles/161_System.Web.dll +0 -0
  369. package/workers/vendor/csharp/_framework/supportFiles/162_System.Web.HttpUtility.dll +0 -0
  370. package/workers/vendor/csharp/_framework/supportFiles/163_System.Windows.dll +0 -0
  371. package/workers/vendor/csharp/_framework/supportFiles/164_System.Xml.dll +0 -0
  372. package/workers/vendor/csharp/_framework/supportFiles/165_System.Xml.Linq.dll +0 -0
  373. package/workers/vendor/csharp/_framework/supportFiles/166_System.Xml.ReaderWriter.dll +0 -0
  374. package/workers/vendor/csharp/_framework/supportFiles/167_System.Xml.Serialization.dll +0 -0
  375. package/workers/vendor/csharp/_framework/supportFiles/168_System.Xml.XDocument.dll +0 -0
  376. package/workers/vendor/csharp/_framework/supportFiles/169_System.Xml.XmlDocument.dll +0 -0
  377. package/workers/vendor/csharp/_framework/supportFiles/16_System.ComponentModel.Annotations.dll +0 -0
  378. package/workers/vendor/csharp/_framework/supportFiles/170_System.Xml.XmlSerializer.dll +0 -0
  379. package/workers/vendor/csharp/_framework/supportFiles/171_System.Xml.XPath.dll +0 -0
  380. package/workers/vendor/csharp/_framework/supportFiles/172_System.Xml.XPath.XDocument.dll +0 -0
  381. package/workers/vendor/csharp/_framework/supportFiles/173_TraceCode.CSharpHost.dll +0 -0
  382. package/workers/vendor/csharp/_framework/supportFiles/174_WindowsBase.dll +0 -0
  383. package/workers/vendor/csharp/_framework/supportFiles/17_System.ComponentModel.DataAnnotations.dll +0 -0
  384. package/workers/vendor/csharp/_framework/supportFiles/18_System.ComponentModel.dll +0 -0
  385. package/workers/vendor/csharp/_framework/supportFiles/19_System.ComponentModel.EventBasedAsync.dll +0 -0
  386. package/workers/vendor/csharp/_framework/supportFiles/1_Microsoft.CodeAnalysis.dll +0 -0
  387. package/workers/vendor/csharp/_framework/supportFiles/20_System.ComponentModel.Primitives.dll +0 -0
  388. package/workers/vendor/csharp/_framework/supportFiles/21_System.ComponentModel.TypeConverter.dll +0 -0
  389. package/workers/vendor/csharp/_framework/supportFiles/22_System.Configuration.dll +0 -0
  390. package/workers/vendor/csharp/_framework/supportFiles/23_System.Console.dll +0 -0
  391. package/workers/vendor/csharp/_framework/supportFiles/24_System.Core.dll +0 -0
  392. package/workers/vendor/csharp/_framework/supportFiles/25_System.Data.Common.dll +0 -0
  393. package/workers/vendor/csharp/_framework/supportFiles/26_System.Data.DataSetExtensions.dll +0 -0
  394. package/workers/vendor/csharp/_framework/supportFiles/27_System.Data.dll +0 -0
  395. package/workers/vendor/csharp/_framework/supportFiles/28_System.Diagnostics.Contracts.dll +0 -0
  396. package/workers/vendor/csharp/_framework/supportFiles/29_System.Diagnostics.Debug.dll +0 -0
  397. package/workers/vendor/csharp/_framework/supportFiles/2_Microsoft.CSharp.dll +0 -0
  398. package/workers/vendor/csharp/_framework/supportFiles/30_System.Diagnostics.DiagnosticSource.dll +0 -0
  399. package/workers/vendor/csharp/_framework/supportFiles/31_System.Diagnostics.FileVersionInfo.dll +0 -0
  400. package/workers/vendor/csharp/_framework/supportFiles/32_System.Diagnostics.Process.dll +0 -0
  401. package/workers/vendor/csharp/_framework/supportFiles/33_System.Diagnostics.StackTrace.dll +0 -0
  402. package/workers/vendor/csharp/_framework/supportFiles/34_System.Diagnostics.TextWriterTraceListener.dll +0 -0
  403. package/workers/vendor/csharp/_framework/supportFiles/35_System.Diagnostics.Tools.dll +0 -0
  404. package/workers/vendor/csharp/_framework/supportFiles/36_System.Diagnostics.TraceSource.dll +0 -0
  405. package/workers/vendor/csharp/_framework/supportFiles/37_System.Diagnostics.Tracing.dll +0 -0
  406. package/workers/vendor/csharp/_framework/supportFiles/38_System.dll +0 -0
  407. package/workers/vendor/csharp/_framework/supportFiles/39_System.Drawing.dll +0 -0
  408. package/workers/vendor/csharp/_framework/supportFiles/3_Microsoft.VisualBasic.Core.dll +0 -0
  409. package/workers/vendor/csharp/_framework/supportFiles/40_System.Drawing.Primitives.dll +0 -0
  410. package/workers/vendor/csharp/_framework/supportFiles/41_System.Dynamic.Runtime.dll +0 -0
  411. package/workers/vendor/csharp/_framework/supportFiles/42_System.Formats.Asn1.dll +0 -0
  412. package/workers/vendor/csharp/_framework/supportFiles/43_System.Formats.Tar.dll +0 -0
  413. package/workers/vendor/csharp/_framework/supportFiles/44_System.Globalization.Calendars.dll +0 -0
  414. package/workers/vendor/csharp/_framework/supportFiles/45_System.Globalization.dll +0 -0
  415. package/workers/vendor/csharp/_framework/supportFiles/46_System.Globalization.Extensions.dll +0 -0
  416. package/workers/vendor/csharp/_framework/supportFiles/47_System.IO.Compression.Brotli.dll +0 -0
  417. package/workers/vendor/csharp/_framework/supportFiles/48_System.IO.Compression.dll +0 -0
  418. package/workers/vendor/csharp/_framework/supportFiles/49_System.IO.Compression.FileSystem.dll +0 -0
  419. package/workers/vendor/csharp/_framework/supportFiles/4_Microsoft.VisualBasic.dll +0 -0
  420. package/workers/vendor/csharp/_framework/supportFiles/50_System.IO.Compression.ZipFile.dll +0 -0
  421. package/workers/vendor/csharp/_framework/supportFiles/51_System.IO.dll +0 -0
  422. package/workers/vendor/csharp/_framework/supportFiles/52_System.IO.FileSystem.AccessControl.dll +0 -0
  423. package/workers/vendor/csharp/_framework/supportFiles/53_System.IO.FileSystem.dll +0 -0
  424. package/workers/vendor/csharp/_framework/supportFiles/54_System.IO.FileSystem.DriveInfo.dll +0 -0
  425. package/workers/vendor/csharp/_framework/supportFiles/55_System.IO.FileSystem.Primitives.dll +0 -0
  426. package/workers/vendor/csharp/_framework/supportFiles/56_System.IO.FileSystem.Watcher.dll +0 -0
  427. package/workers/vendor/csharp/_framework/supportFiles/57_System.IO.IsolatedStorage.dll +0 -0
  428. package/workers/vendor/csharp/_framework/supportFiles/58_System.IO.MemoryMappedFiles.dll +0 -0
  429. package/workers/vendor/csharp/_framework/supportFiles/59_System.IO.Pipelines.dll +0 -0
  430. package/workers/vendor/csharp/_framework/supportFiles/5_Microsoft.Win32.Primitives.dll +0 -0
  431. package/workers/vendor/csharp/_framework/supportFiles/60_System.IO.Pipes.AccessControl.dll +0 -0
  432. package/workers/vendor/csharp/_framework/supportFiles/61_System.IO.Pipes.dll +0 -0
  433. package/workers/vendor/csharp/_framework/supportFiles/62_System.IO.UnmanagedMemoryStream.dll +0 -0
  434. package/workers/vendor/csharp/_framework/supportFiles/63_System.Linq.AsyncEnumerable.dll +0 -0
  435. package/workers/vendor/csharp/_framework/supportFiles/64_System.Linq.dll +0 -0
  436. package/workers/vendor/csharp/_framework/supportFiles/65_System.Linq.Expressions.dll +0 -0
  437. package/workers/vendor/csharp/_framework/supportFiles/66_System.Linq.Parallel.dll +0 -0
  438. package/workers/vendor/csharp/_framework/supportFiles/67_System.Linq.Queryable.dll +0 -0
  439. package/workers/vendor/csharp/_framework/supportFiles/68_System.Memory.dll +0 -0
  440. package/workers/vendor/csharp/_framework/supportFiles/69_System.Net.dll +0 -0
  441. package/workers/vendor/csharp/_framework/supportFiles/6_Microsoft.Win32.Registry.dll +0 -0
  442. package/workers/vendor/csharp/_framework/supportFiles/70_System.Net.Http.dll +0 -0
  443. package/workers/vendor/csharp/_framework/supportFiles/71_System.Net.Http.Json.dll +0 -0
  444. package/workers/vendor/csharp/_framework/supportFiles/72_System.Net.HttpListener.dll +0 -0
  445. package/workers/vendor/csharp/_framework/supportFiles/73_System.Net.Mail.dll +0 -0
  446. package/workers/vendor/csharp/_framework/supportFiles/74_System.Net.NameResolution.dll +0 -0
  447. package/workers/vendor/csharp/_framework/supportFiles/75_System.Net.NetworkInformation.dll +0 -0
  448. package/workers/vendor/csharp/_framework/supportFiles/76_System.Net.Ping.dll +0 -0
  449. package/workers/vendor/csharp/_framework/supportFiles/77_System.Net.Primitives.dll +0 -0
  450. package/workers/vendor/csharp/_framework/supportFiles/78_System.Net.Quic.dll +0 -0
  451. package/workers/vendor/csharp/_framework/supportFiles/79_System.Net.Requests.dll +0 -0
  452. package/workers/vendor/csharp/_framework/supportFiles/7_mscorlib.dll +0 -0
  453. package/workers/vendor/csharp/_framework/supportFiles/80_System.Net.Security.dll +0 -0
  454. package/workers/vendor/csharp/_framework/supportFiles/81_System.Net.ServerSentEvents.dll +0 -0
  455. package/workers/vendor/csharp/_framework/supportFiles/82_System.Net.ServicePoint.dll +0 -0
  456. package/workers/vendor/csharp/_framework/supportFiles/83_System.Net.Sockets.dll +0 -0
  457. package/workers/vendor/csharp/_framework/supportFiles/84_System.Net.WebClient.dll +0 -0
  458. package/workers/vendor/csharp/_framework/supportFiles/85_System.Net.WebHeaderCollection.dll +0 -0
  459. package/workers/vendor/csharp/_framework/supportFiles/86_System.Net.WebProxy.dll +0 -0
  460. package/workers/vendor/csharp/_framework/supportFiles/87_System.Net.WebSockets.Client.dll +0 -0
  461. package/workers/vendor/csharp/_framework/supportFiles/88_System.Net.WebSockets.dll +0 -0
  462. package/workers/vendor/csharp/_framework/supportFiles/89_System.Numerics.dll +0 -0
  463. package/workers/vendor/csharp/_framework/supportFiles/8_netstandard.dll +0 -0
  464. package/workers/vendor/csharp/_framework/supportFiles/90_System.Numerics.Vectors.dll +0 -0
  465. package/workers/vendor/csharp/_framework/supportFiles/91_System.ObjectModel.dll +0 -0
  466. package/workers/vendor/csharp/_framework/supportFiles/92_System.Private.CoreLib.dll +0 -0
  467. package/workers/vendor/csharp/_framework/supportFiles/93_System.Private.DataContractSerialization.dll +0 -0
  468. package/workers/vendor/csharp/_framework/supportFiles/94_System.Private.Uri.dll +0 -0
  469. package/workers/vendor/csharp/_framework/supportFiles/95_System.Private.Xml.dll +0 -0
  470. package/workers/vendor/csharp/_framework/supportFiles/96_System.Private.Xml.Linq.dll +0 -0
  471. package/workers/vendor/csharp/_framework/supportFiles/97_System.Reflection.DispatchProxy.dll +0 -0
  472. package/workers/vendor/csharp/_framework/supportFiles/98_System.Reflection.dll +0 -0
  473. package/workers/vendor/csharp/_framework/supportFiles/99_System.Reflection.Emit.dll +0 -0
  474. package/workers/vendor/csharp/_framework/supportFiles/9_System.AppContext.dll +0 -0
  475. package/workers/vendor/csharp/_framework/tr/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
  476. package/workers/vendor/csharp/_framework/tr/Microsoft.CodeAnalysis.resources.wasm +0 -0
  477. package/workers/vendor/csharp/_framework/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
  478. package/workers/vendor/csharp/_framework/zh-Hans/Microsoft.CodeAnalysis.resources.wasm +0 -0
  479. package/workers/vendor/csharp/_framework/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
  480. package/workers/vendor/csharp/_framework/zh-Hant/Microsoft.CodeAnalysis.resources.wasm +0 -0
  481. package/workers/vendor/csharp/main.mjs +5 -0
  482. package/workers/vendor/csharp/package.json +1 -0
  483. package/workers/vendor/java-browser-helper.jar +0 -0
  484. package/workers/vendor/java-rewriter.jar +0 -0
  485. package/workers/vendor/javascript-libraries.js +10106 -0
  486. package/dist/runtime-types-89nchXlY.d.cts +0 -89
  487. package/dist/runtime-types-CCQ-ZLc9.d.ts +0 -89
  488. package/dist/types-zyvpJKCi.d.cts +0 -100
  489. package/dist/types-zyvpJKCi.d.ts +0 -100
  490. package/workers/java/java-source-augmentations.cjs +0 -242
  491. package/workers/java/src/spike/user/TraceHooks.java +0 -619
  492. package/workers/vendor/java-browser-spike-helper.jar +0 -0
  493. package/workers/vendor/java-practice-rewriter.jar +0 -0
  494. package/workers/vendor/java-rewrite-bridge.jar +0 -0
@@ -14,6 +14,20 @@ const WORKER_DEBUG = (() => {
14
14
  }
15
15
  })();
16
16
 
17
+ function emitRuntimeDiagnostic(level, phase, message, detail) {
18
+ if (!WORKER_DEBUG && level !== 'error') return;
19
+ const method = level === 'error' ? 'error' : level === 'warn' ? 'warn' : level === 'debug' ? 'debug' : 'info';
20
+ console[method]('[TraceRuntime]', {
21
+ schema: 'tracecode.runtime-diagnostic.v1',
22
+ source: 'harness',
23
+ component: 'JavaScriptWorker',
24
+ runtime: 'javascript',
25
+ phase,
26
+ message,
27
+ ...(detail === undefined ? {} : { detail }),
28
+ });
29
+ }
30
+
17
31
  let isInitialized = false;
18
32
  let isLoading = false;
19
33
  let typeScriptLoadPromise = null;
@@ -28,12 +42,23 @@ const TYPESCRIPT_COMPILER_URLS = [
28
42
  'https://cdn.jsdelivr.net/npm/typescript@5.9.2/lib/typescript.js',
29
43
  'https://unpkg.com/typescript@5.9.2/lib/typescript.js',
30
44
  ];
45
+ const JAVASCRIPT_LIBRARY_URLS = [
46
+ './vendor/javascript-libraries.js',
47
+ ];
48
+ let javascriptLibrariesLoadAttempted = false;
31
49
 
32
50
  const JAVASCRIPT_RUNTIME_PRELUDE = `
51
+ if (typeof globalThis.module === 'undefined') {
52
+ globalThis.module = { exports: {} };
53
+ }
54
+ if (typeof globalThis.exports === 'undefined') {
55
+ globalThis.exports = globalThis.module.exports || {};
56
+ }
33
57
  if (typeof globalThis.ListNode !== 'function') {
34
58
  globalThis.ListNode = class ListNode {
35
59
  constructor(val = 0, next = null) {
36
60
  this.val = val;
61
+ this.value = val;
37
62
  this.next = next;
38
63
  }
39
64
  };
@@ -42,6 +67,7 @@ if (typeof globalThis.TreeNode !== 'function') {
42
67
  globalThis.TreeNode = class TreeNode {
43
68
  constructor(val = 0, left = null, right = null) {
44
69
  this.val = val;
70
+ this.value = val;
45
71
  this.left = left;
46
72
  this.right = right;
47
73
  }
@@ -49,9 +75,45 @@ if (typeof globalThis.TreeNode !== 'function') {
49
75
  }
50
76
  `;
51
77
 
78
+ function ensureJavaScriptLibraries() {
79
+ if (
80
+ typeof globalThis !== 'undefined' &&
81
+ globalThis.__TRACECODE_JAVASCRIPT_LIBRARIES__ &&
82
+ typeof globalThis.require === 'function'
83
+ ) {
84
+ return;
85
+ }
86
+ if (javascriptLibrariesLoadAttempted) return;
87
+ javascriptLibrariesLoadAttempted = true;
88
+ if (typeof importScripts !== 'function') return;
89
+
90
+ const errors = [];
91
+ for (const libraryUrl of JAVASCRIPT_LIBRARY_URLS) {
92
+ try {
93
+ importScripts(libraryUrl);
94
+ if (
95
+ typeof globalThis !== 'undefined' &&
96
+ globalThis.__TRACECODE_JAVASCRIPT_LIBRARIES__ &&
97
+ typeof globalThis.require === 'function'
98
+ ) {
99
+ return;
100
+ }
101
+ errors.push(`${libraryUrl} (loaded but module registry was missing)`);
102
+ } catch (error) {
103
+ const message = error instanceof Error ? error.message : String(error);
104
+ errors.push(`${libraryUrl} (${message})`);
105
+ }
106
+ }
107
+
108
+ if (errors.length > 0) {
109
+ emitRuntimeDiagnostic('warn', 'library-preload-skipped', 'JavaScript library preload skipped.', { errors });
110
+ }
111
+ }
112
+
52
113
  const TYPESCRIPT_RUNTIME_DECLARATIONS = `
53
114
  declare class ListNode {
54
115
  val: any;
116
+ value: any;
55
117
  next: ListNode | SerializedListNode | SerializedRef | null;
56
118
  prev?: ListNode | SerializedListNode | SerializedRef | null;
57
119
  constructor(val?: any, next?: ListNode | null);
@@ -59,6 +121,7 @@ declare class ListNode {
59
121
 
60
122
  declare class TreeNode {
61
123
  val: any;
124
+ value: any;
62
125
  left: TreeNode | SerializedTreeNode | SerializedRef | null;
63
126
  right: TreeNode | SerializedTreeNode | SerializedRef | null;
64
127
  constructor(val?: any, left?: TreeNode | null, right?: TreeNode | null);
@@ -70,6 +133,7 @@ type SerializedListNode = {
70
133
  __id__?: string;
71
134
  __type__?: 'ListNode';
72
135
  val?: any;
136
+ value?: any;
73
137
  next?: SerializedListNode | SerializedRef | ListNode | null;
74
138
  prev?: SerializedListNode | SerializedRef | ListNode | null;
75
139
  };
@@ -78,11 +142,48 @@ type SerializedTreeNode = {
78
142
  __id__?: string;
79
143
  __type__?: 'TreeNode';
80
144
  val?: any;
145
+ value?: any;
81
146
  left?: SerializedTreeNode | SerializedRef | TreeNode | null;
82
147
  right?: SerializedTreeNode | SerializedRef | TreeNode | null;
83
148
  };
84
149
  `;
85
150
 
151
+ const CUSTOM_OBJECT_MATERIALIZER_SOURCE = `
152
+ function __tracecodeMaterializeCustomObject(value) {
153
+ if (value === null || value === undefined) return value;
154
+ if (Array.isArray(value)) return value.map((item) => __tracecodeMaterializeCustomObject(item));
155
+ if (typeof value !== 'object') return value;
156
+ if (value.__type__ === 'TreeNode' || value.__type__ === 'ListNode' || value.__ref__) return value;
157
+ const __typeName = typeof value.__type__ === 'string'
158
+ ? value.__type__
159
+ : (typeof value.__class__ === 'string' ? value.__class__ : null);
160
+ if (!__typeName) return value;
161
+ const __fields = { __type__: __typeName };
162
+ if (typeof value.__class__ === 'string') __fields.__class__ = value.__class__;
163
+ for (const [__key, __child] of Object.entries(value)) {
164
+ if (__key === '__type__' || __key === '__class__' || __key === '__id__') continue;
165
+ __fields[__key] = __tracecodeMaterializeCustomObject(__child);
166
+ }
167
+ let __ctor;
168
+ try {
169
+ __ctor = eval(__typeName);
170
+ } catch (_err) {
171
+ __ctor = undefined;
172
+ }
173
+ if (typeof __ctor !== 'function') return __fields;
174
+ const __args = Object.entries(__fields)
175
+ .filter(([__key]) => __key !== '__type__' && __key !== '__class__')
176
+ .map(([, __value]) => __value);
177
+ try {
178
+ return new __ctor(...__args);
179
+ } catch (_err) {
180
+ const __instance = Object.create(__ctor.prototype);
181
+ Object.assign(__instance, __fields);
182
+ return __instance;
183
+ }
184
+ }
185
+ `;
186
+
86
187
  function performanceNow() {
87
188
  if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
88
189
  return performance.now();
@@ -139,17 +240,41 @@ function getCustomClassName(value) {
139
240
  return name;
140
241
  }
141
242
 
243
+ const RUNTIME_VALUE_MAX_DEPTH = 48;
244
+ const RUNTIME_VALUE_MAX_ITEMS = 64;
245
+ const RUNTIME_VALUE_MAX_OBJECT_FIELDS = 32;
246
+ const TRACE_SERIALIZATION_LIMITS = { maxItems: RUNTIME_VALUE_MAX_ITEMS, maxFields: RUNTIME_VALUE_MAX_OBJECT_FIELDS };
247
+ const OUTPUT_SERIALIZATION_LIMITS = { maxItems: Number.POSITIVE_INFINITY, maxFields: Number.POSITIVE_INFINITY };
248
+ let activeSerializationLimits = TRACE_SERIALIZATION_LIMITS;
249
+
250
+ function truncationMarker(total, emitted) {
251
+ return { __truncated__: true, remaining: Math.max(0, total - emitted) };
252
+ }
253
+
254
+ function limitedEntries(items, maxItems) {
255
+ return {
256
+ values: items.slice(0, maxItems),
257
+ remaining: Math.max(0, items.length - maxItems),
258
+ };
259
+ }
260
+
142
261
  function serializeValue(
143
262
  value,
144
263
  depth = 0,
145
264
  seen = new WeakSet(),
146
265
  nodeRefState = { ids: new Map(), nextId: 1 }
147
266
  ) {
148
- if (depth > 48) return '<max depth>';
267
+ if (depth > RUNTIME_VALUE_MAX_DEPTH) return '<max depth>';
149
268
  if (value === null || value === undefined) return value;
150
269
 
151
270
  const valueType = typeof value;
152
- if (valueType === 'string' || valueType === 'number' || valueType === 'boolean') {
271
+ if (valueType === 'number') {
272
+ if (Number.isNaN(value)) return 'NaN';
273
+ if (value === Infinity) return 'Infinity';
274
+ if (value === -Infinity) return '-Infinity';
275
+ return value;
276
+ }
277
+ if (valueType === 'string' || valueType === 'boolean') {
153
278
  return value;
154
279
  }
155
280
  if (valueType === 'bigint') {
@@ -159,22 +284,39 @@ function serializeValue(
159
284
  return '<function>';
160
285
  }
161
286
  if (Array.isArray(value)) {
162
- return value.map((item) => serializeValue(item, depth + 1, seen, nodeRefState));
287
+ const limited = limitedEntries(value, activeSerializationLimits.maxItems);
288
+ const result = limited.values.map((item) => serializeValue(item, depth + 1, seen, nodeRefState));
289
+ if (limited.remaining > 0) result.push(truncationMarker(value.length, limited.values.length));
290
+ return result;
163
291
  }
164
292
  if (value instanceof Set) {
165
- return {
293
+ const items = [...value];
294
+ const limited = limitedEntries(items, activeSerializationLimits.maxItems);
295
+ const result = {
166
296
  __type__: 'set',
167
- values: [...value].map((item) => serializeValue(item, depth + 1, seen, nodeRefState)),
297
+ values: limited.values.map((item) => serializeValue(item, depth + 1, seen, nodeRefState)),
168
298
  };
299
+ if (limited.remaining > 0) {
300
+ result.__truncated__ = true;
301
+ result.remaining = limited.remaining;
302
+ }
303
+ return result;
169
304
  }
170
305
  if (value instanceof Map) {
171
- return {
306
+ const entries = [...value.entries()];
307
+ const limited = limitedEntries(entries, activeSerializationLimits.maxItems);
308
+ const result = {
172
309
  __type__: 'map',
173
- entries: [...value.entries()].map(([k, v]) => [
310
+ entries: limited.values.map(([k, v]) => [
174
311
  serializeValue(k, depth + 1, seen, nodeRefState),
175
312
  serializeValue(v, depth + 1, seen, nodeRefState),
176
313
  ]),
177
314
  };
315
+ if (limited.remaining > 0) {
316
+ result.__truncated__ = true;
317
+ result.remaining = limited.remaining;
318
+ }
319
+ return result;
178
320
  }
179
321
  if (valueType === 'object') {
180
322
  if (isLikelyTreeNodeValue(value) || isLikelyListNodeValue(value)) {
@@ -182,12 +324,12 @@ function serializeValue(
182
324
  if (existingId) {
183
325
  return { __ref__: existingId };
184
326
  }
185
- const nodePrefix = isLikelyTreeNodeValue(value) ? 'tree' : 'list';
186
- const nodeId = `${nodePrefix}-${nodeRefState.nextId++}`;
327
+ const isTree = isLikelyTreeNodeValue(value);
328
+ const nodeId = `ref-${nodeRefState.nextId++}`;
187
329
  nodeRefState.ids.set(value, nodeId);
188
330
 
189
331
  const out =
190
- nodePrefix === 'tree'
332
+ isTree
191
333
  ? {
192
334
  __type__: 'TreeNode',
193
335
  __id__: nodeId,
@@ -205,13 +347,17 @@ function serializeValue(
205
347
  : {}),
206
348
  };
207
349
  const skipped =
208
- nodePrefix === 'tree'
350
+ isTree
209
351
  ? new Set(['__id__', '__type__', '__class__', 'val', 'value', 'left', 'right'])
210
352
  : new Set(['__id__', '__type__', '__class__', 'val', 'value', 'next', 'prev']);
211
- for (const [k, v] of Object.entries(value)) {
212
- if (skipped.has(k)) continue;
353
+ const fields = Object.entries(value).filter(([k]) => !skipped.has(k));
354
+ for (const [k, v] of fields.slice(0, activeSerializationLimits.maxFields)) {
213
355
  out[k] = serializeValue(v, depth + 1, seen, nodeRefState);
214
356
  }
357
+ if (fields.length > activeSerializationLimits.maxFields) {
358
+ out.__truncated__ = true;
359
+ out.remaining = fields.length - activeSerializationLimits.maxFields;
360
+ }
215
361
  return out;
216
362
  }
217
363
 
@@ -222,19 +368,24 @@ function serializeValue(
222
368
  return { __ref__: existingId };
223
369
  }
224
370
 
225
- const objectId = `object-${nodeRefState.nextId++}`;
371
+ const objectId = `ref-${nodeRefState.nextId++}`;
226
372
  nodeRefState.ids.set(value, objectId);
227
373
 
228
374
  if (seen.has(value)) return { __ref__: objectId };
229
375
  seen.add(value);
230
376
  const out = {
231
- __type__: 'object',
377
+ __type__: customClassName,
232
378
  __class__: customClassName,
233
379
  __id__: objectId,
234
380
  };
235
- for (const [k, v] of Object.entries(value)) {
381
+ const fields = Object.entries(value);
382
+ for (const [k, v] of fields.slice(0, activeSerializationLimits.maxFields)) {
236
383
  out[k] = serializeValue(v, depth + 1, seen, nodeRefState);
237
384
  }
385
+ if (fields.length > activeSerializationLimits.maxFields) {
386
+ out.__truncated__ = true;
387
+ out.remaining = fields.length - activeSerializationLimits.maxFields;
388
+ }
238
389
  seen.delete(value);
239
390
  return out;
240
391
  }
@@ -242,9 +393,14 @@ function serializeValue(
242
393
  if (seen.has(value)) return '<cycle>';
243
394
  seen.add(value);
244
395
  const out = {};
245
- for (const [k, v] of Object.entries(value)) {
396
+ const fields = Object.entries(value);
397
+ for (const [k, v] of fields.slice(0, activeSerializationLimits.maxFields)) {
246
398
  out[k] = serializeValue(v, depth + 1, seen, nodeRefState);
247
399
  }
400
+ if (fields.length > activeSerializationLimits.maxFields) {
401
+ out.__truncated__ = true;
402
+ out.remaining = fields.length - activeSerializationLimits.maxFields;
403
+ }
248
404
  seen.delete(value);
249
405
  return out;
250
406
  }
@@ -252,6 +408,20 @@ function serializeValue(
252
408
  return String(value);
253
409
  }
254
410
 
411
+ function withSerializationLimits(limits, serialize) {
412
+ const previous = activeSerializationLimits;
413
+ activeSerializationLimits = limits;
414
+ try {
415
+ return serialize();
416
+ } finally {
417
+ activeSerializationLimits = previous;
418
+ }
419
+ }
420
+
421
+ function serializeOutputValue(value) {
422
+ return withSerializationLimits(OUTPUT_SERIALIZATION_LIMITS, () => serializeValue(value));
423
+ }
424
+
255
425
  function serializeTopLevelValue(value, nodeRefState) {
256
426
  if (value === null || value === undefined) return value;
257
427
  if (typeof value !== 'object' || Array.isArray(value)) {
@@ -264,7 +434,7 @@ function serializeTopLevelValue(value, nodeRefState) {
264
434
  const isTree = isLikelyTreeNodeValue(value);
265
435
  let nodeId = nodeRefState.ids.get(objectValue);
266
436
  if (!nodeId) {
267
- nodeId = `${isTree ? 'tree' : 'list'}-${nodeRefState.nextId++}`;
437
+ nodeId = `ref-${nodeRefState.nextId++}`;
268
438
  nodeRefState.ids.set(objectValue, nodeId);
269
439
  }
270
440
 
@@ -289,10 +459,14 @@ function serializeTopLevelValue(value, nodeRefState) {
289
459
  const skipped = isTree
290
460
  ? new Set(['__id__', '__type__', '__class__', 'val', 'value', 'left', 'right'])
291
461
  : new Set(['__id__', '__type__', '__class__', 'val', 'value', 'next', 'prev']);
292
- for (const [k, v] of Object.entries(nodeValue)) {
293
- if (skipped.has(k)) continue;
462
+ const fields = Object.entries(nodeValue).filter(([k]) => !skipped.has(k));
463
+ for (const [k, v] of fields.slice(0, activeSerializationLimits.maxFields)) {
294
464
  out[k] = serializeValue(v, 1, new WeakSet(), nodeRefState);
295
465
  }
466
+ if (fields.length > activeSerializationLimits.maxFields) {
467
+ out.__truncated__ = true;
468
+ out.remaining = fields.length - activeSerializationLimits.maxFields;
469
+ }
296
470
  return out;
297
471
  }
298
472
 
@@ -301,7 +475,7 @@ function serializeTopLevelValue(value, nodeRefState) {
301
475
  const objectValue = value;
302
476
  let objectId = nodeRefState.ids.get(objectValue);
303
477
  if (!objectId) {
304
- objectId = `object-${nodeRefState.nextId++}`;
478
+ objectId = `ref-${nodeRefState.nextId++}`;
305
479
  nodeRefState.ids.set(objectValue, objectId);
306
480
  }
307
481
  const seen = new WeakSet();
@@ -311,9 +485,14 @@ function serializeTopLevelValue(value, nodeRefState) {
311
485
  __class__: customClassName,
312
486
  __id__: objectId,
313
487
  };
314
- for (const [k, v] of Object.entries(value)) {
488
+ const fields = Object.entries(value);
489
+ for (const [k, v] of fields.slice(0, activeSerializationLimits.maxFields)) {
315
490
  out[k] = serializeValue(v, 1, seen, nodeRefState);
316
491
  }
492
+ if (fields.length > activeSerializationLimits.maxFields) {
493
+ out.__truncated__ = true;
494
+ out.remaining = fields.length - activeSerializationLimits.maxFields;
495
+ }
317
496
  return out;
318
497
  }
319
498
 
@@ -398,16 +577,45 @@ function resolveReferenceGraph(value, byId, resolved) {
398
577
  return out;
399
578
  }
400
579
 
580
+ function cloneInputGraph(value, cloned = new WeakMap()) {
581
+ if (value === null || value === undefined) return value;
582
+ if (typeof value !== 'object') return value;
583
+
584
+ if (cloned.has(value)) {
585
+ return cloned.get(value);
586
+ }
587
+
588
+ if (Array.isArray(value)) {
589
+ const out = [];
590
+ cloned.set(value, out);
591
+ for (const item of value) {
592
+ out.push(cloneInputGraph(item, cloned));
593
+ }
594
+ return out;
595
+ }
596
+
597
+ if (!isPlainObjectRecord(value)) {
598
+ return value;
599
+ }
600
+
601
+ const out = {};
602
+ cloned.set(value, out);
603
+ for (const [key, nested] of Object.entries(value)) {
604
+ out[key] = cloneInputGraph(nested, cloned);
605
+ }
606
+ return out;
607
+ }
608
+
401
609
  function normalizeInputs(inputs) {
402
610
  if (!inputs || typeof inputs !== 'object' || Array.isArray(inputs)) return {};
403
611
  const byId = new Map();
404
612
  collectReferenceTargets(inputs, byId, new WeakSet());
405
613
  if (byId.size === 0) {
406
- return inputs;
614
+ return cloneInputGraph(inputs);
407
615
  }
408
616
  const hydrated = resolveReferenceGraph(inputs, byId, new WeakMap());
409
617
  if (!hydrated || typeof hydrated !== 'object' || Array.isArray(hydrated)) {
410
- return inputs;
618
+ return cloneInputGraph(inputs);
411
619
  }
412
620
  return hydrated;
413
621
  }
@@ -675,12 +883,168 @@ function findFunctionLikeNode(ts, sourceFile, functionName, executionStyle) {
675
883
  return found;
676
884
  }
677
885
 
886
+ function escapeRegExp(value) {
887
+ return String(value).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
888
+ }
889
+
890
+ function stripJavaScriptTriviaForSignatureScan(code) {
891
+ let output = '';
892
+ let i = 0;
893
+
894
+ while (i < code.length) {
895
+ const current = code[i];
896
+ const next = code[i + 1];
897
+
898
+ if (current === '/' && next === '/') {
899
+ output += ' ';
900
+ i += 2;
901
+ while (i < code.length && code[i] !== '\n') {
902
+ output += ' ';
903
+ i += 1;
904
+ }
905
+ continue;
906
+ }
907
+
908
+ if (current === '/' && next === '*') {
909
+ output += ' ';
910
+ i += 2;
911
+ while (i < code.length) {
912
+ if (code[i] === '*' && code[i + 1] === '/') {
913
+ output += ' ';
914
+ i += 2;
915
+ break;
916
+ }
917
+ output += code[i] === '\n' ? '\n' : ' ';
918
+ i += 1;
919
+ }
920
+ continue;
921
+ }
922
+
923
+ if (current === '"' || current === "'" || current === '`') {
924
+ const quote = current;
925
+ output += quote;
926
+ i += 1;
927
+ while (i < code.length) {
928
+ const char = code[i];
929
+ if (char === '\\') {
930
+ output += ' ';
931
+ if (i + 1 < code.length) output += code[i + 1] === '\n' ? '\n' : ' ';
932
+ i += 2;
933
+ continue;
934
+ }
935
+ output += char === '\n' ? '\n' : ' ';
936
+ i += 1;
937
+ if (char === quote) break;
938
+ }
939
+ continue;
940
+ }
941
+
942
+ output += current;
943
+ i += 1;
944
+ }
945
+
946
+ return output;
947
+ }
948
+
949
+ function findMatchingBraceIndex(code, openBraceIndex) {
950
+ let depth = 0;
951
+ for (let i = openBraceIndex; i < code.length; i += 1) {
952
+ const char = code[i];
953
+ if (char === '{') {
954
+ depth += 1;
955
+ } else if (char === '}') {
956
+ depth -= 1;
957
+ if (depth === 0) return i;
958
+ }
959
+ }
960
+ return -1;
961
+ }
962
+
963
+ function extractClassBodyForSignatureScan(code, className) {
964
+ const classMatch = new RegExp(`\\bclass\\s+${escapeRegExp(className)}\\b[^{}]*\\{`, 'm').exec(code);
965
+ if (!classMatch) return null;
966
+ const openBraceIndex = classMatch.index + classMatch[0].lastIndexOf('{');
967
+ const closeBraceIndex = findMatchingBraceIndex(code, openBraceIndex);
968
+ if (closeBraceIndex < 0) return null;
969
+ return code.slice(openBraceIndex + 1, closeBraceIndex);
970
+ }
971
+
972
+ function parseSimpleJavaScriptParameterNames(parameterText) {
973
+ const names = [];
974
+ const rawParameters = String(parameterText ?? '').split(',');
975
+
976
+ for (const rawParameter of rawParameters) {
977
+ const trimmed = rawParameter.trim();
978
+ if (!trimmed) continue;
979
+ const withoutDefault = trimmed.split('=')[0].trim();
980
+ const name = withoutDefault.startsWith('...') ? withoutDefault.slice(3).trim() : withoutDefault;
981
+ if (name === 'this') continue;
982
+ if (!/^[A-Za-z_$][\w$]*$/.test(name)) {
983
+ return null;
984
+ }
985
+ names.push(name);
986
+ }
987
+
988
+ return names;
989
+ }
990
+
991
+ function extractSimpleJavaScriptParameterNames(code, functionName, executionStyle) {
992
+ const strippedCode = stripJavaScriptTriviaForSignatureScan(code);
993
+ const escapedName = escapeRegExp(functionName);
994
+ const exportPrefix = String.raw`(?:export\s+default\s+|export\s+)?`;
995
+ const functionPatterns = [
996
+ new RegExp(String.raw`(?:^|[^\w$])${exportPrefix}(?:async\s+)?function\s+${escapedName}\s*\(([^)]*)\)`, 'm'),
997
+ new RegExp(String.raw`(?:^|[^\w$])${exportPrefix}(?:const|let|var)\s+${escapedName}\s*=\s*(?:async\s+)?function(?:\s+[A-Za-z_$][\w$]*)?\s*\(([^)]*)\)`, 'm'),
998
+ new RegExp(String.raw`(?:^|[^\w$])${exportPrefix}(?:const|let|var)\s+${escapedName}\s*=\s*(?:async\s+)?\(([^)]*)\)\s*=>`, 'm'),
999
+ new RegExp(String.raw`(?:^|[^\w$])${exportPrefix}(?:const|let|var)\s+${escapedName}\s*=\s*(?:async\s+)?([A-Za-z_$][\w$]*)\s*=>`, 'm'),
1000
+ ];
1001
+ const methodBody =
1002
+ executionStyle === 'solution-method'
1003
+ ? extractClassBodyForSignatureScan(strippedCode, 'Solution') ?? strippedCode
1004
+ : strippedCode;
1005
+ const methodPatterns = [
1006
+ new RegExp(String.raw`(?:^|[;{}\s])(?:async\s+)?${escapedName}\s*\(([^)]*)\)\s*\{`, 'm'),
1007
+ new RegExp(String.raw`(?:^|[;{}\s])${escapedName}\s*=\s*(?:async\s+)?\(([^)]*)\)\s*=>`, 'm'),
1008
+ new RegExp(String.raw`(?:^|[;{}\s])${escapedName}\s*=\s*(?:async\s+)?([A-Za-z_$][\w$]*)\s*=>`, 'm'),
1009
+ new RegExp(String.raw`(?:^|[;{}\s])${escapedName}\s*=\s*(?:async\s+)?function(?:\s+[A-Za-z_$][\w$]*)?\s*\(([^)]*)\)`, 'm'),
1010
+ ];
1011
+ const patterns = executionStyle === 'solution-method' ? methodPatterns : functionPatterns;
1012
+ const scanCode = executionStyle === 'solution-method' ? methodBody : strippedCode;
1013
+
1014
+ for (const pattern of patterns) {
1015
+ const match = pattern.exec(scanCode);
1016
+ if (!match) continue;
1017
+ return parseSimpleJavaScriptParameterNames(match[1] ?? '');
1018
+ }
1019
+
1020
+ return null;
1021
+ }
1022
+
1023
+ function orderInputKeysByParameterNames(parameterNames, inputs, fallbackKeys) {
1024
+ if (!parameterNames || parameterNames.length === 0) {
1025
+ return fallbackKeys;
1026
+ }
1027
+
1028
+ const matchedKeys = parameterNames.filter((name) => Object.prototype.hasOwnProperty.call(inputs, name));
1029
+ if (matchedKeys.length === 0) {
1030
+ return fallbackKeys;
1031
+ }
1032
+
1033
+ const extras = fallbackKeys.filter((key) => !matchedKeys.includes(key));
1034
+ return [...matchedKeys, ...extras];
1035
+ }
1036
+
678
1037
  async function resolveOrderedInputKeys(code, functionName, inputs, executionStyle, language = 'javascript') {
679
1038
  const fallbackKeys = Object.keys(inputs ?? {});
680
1039
  if (!functionName || executionStyle === 'ops-class' || fallbackKeys.length <= 1) {
681
1040
  return fallbackKeys;
682
1041
  }
683
1042
 
1043
+ if (language !== 'typescript') {
1044
+ const parameterNames = extractSimpleJavaScriptParameterNames(code, functionName, executionStyle);
1045
+ return orderInputKeysByParameterNames(parameterNames, inputs, fallbackKeys);
1046
+ }
1047
+
684
1048
  try {
685
1049
  await ensureTypeScriptCompiler();
686
1050
  const ts = getTypeScriptCompiler();
@@ -701,17 +1065,7 @@ async function resolveOrderedInputKeys(code, functionName, inputs, executionStyl
701
1065
  }
702
1066
 
703
1067
  const parameterNames = collectSimpleParameterNames(ts, target);
704
- if (!parameterNames || parameterNames.length === 0) {
705
- return fallbackKeys;
706
- }
707
-
708
- const matchedKeys = parameterNames.filter((name) => Object.prototype.hasOwnProperty.call(inputs, name));
709
- if (matchedKeys.length === 0) {
710
- return fallbackKeys;
711
- }
712
-
713
- const extras = fallbackKeys.filter((key) => !matchedKeys.includes(key));
714
- return [...matchedKeys, ...extras];
1068
+ return orderInputKeysByParameterNames(parameterNames, inputs, fallbackKeys);
715
1069
  } catch (_error) {
716
1070
  return fallbackKeys;
717
1071
  }
@@ -759,22 +1113,30 @@ function getNumericOption(value, fallback) {
759
1113
  return Math.floor(value);
760
1114
  }
761
1115
 
762
- function isTraceableIntegerIndex(value) {
763
- return typeof value === 'number' && Number.isInteger(value);
1116
+ function isTraceablePathSegment(value) {
1117
+ return (typeof value === 'number' && Number.isInteger(value)) ||
1118
+ (typeof value === 'string' && value.length > 0);
764
1119
  }
765
1120
 
766
1121
  function normalizeTraceIndices(indices, maxDepth = 2) {
767
1122
  if (!Array.isArray(indices) || indices.length === 0 || indices.length > maxDepth) {
768
1123
  return null;
769
1124
  }
770
- if (!indices.every(isTraceableIntegerIndex)) {
1125
+ if (!indices.every(isTraceablePathSegment)) {
1126
+ return null;
1127
+ }
1128
+ return indices.map((index) => typeof index === 'number' ? Math.trunc(index) : index);
1129
+ }
1130
+
1131
+ function normalizeTraceIndexSources(indexSources, maxDepth = 2) {
1132
+ if (!Array.isArray(indexSources) || indexSources.length === 0 || indexSources.length > maxDepth) {
771
1133
  return null;
772
1134
  }
773
- return indices.map((index) => Math.trunc(index));
1135
+ return indexSources.map((source) => typeof source === 'string' && source.length > 0 ? source : null);
774
1136
  }
775
1137
 
776
1138
  function isTraceableMutatingMethod(methodName) {
777
- return ['push', 'pop', 'shift', 'unshift', 'splice'].includes(methodName);
1139
+ return ['push', 'pop', 'shift', 'unshift', 'splice', 'set', 'get', 'has', 'add', 'delete', 'clear'].includes(methodName);
778
1140
  }
779
1141
 
780
1142
  function readValueAtIndices(container, indices) {
@@ -809,14 +1171,17 @@ function writeValueAtIndices(container, indices, value) {
809
1171
 
810
1172
  function createTraceRecorder(options = {}) {
811
1173
  const trace = [];
1174
+ const runtimeTraceEvents = [];
812
1175
  const callStack = [];
813
1176
  const pendingAccessesByFrame = new Map();
814
1177
  const deferredAccessesByFrame = new Map();
1178
+ const runtimeTraceAccessStatsByVariable = new Map();
815
1179
  const lineHitCount = new Map();
816
1180
  const stableNodeRefState = { ids: new Map(), nextId: 1 };
817
1181
  const maxTraceSteps = getNumericOption(options.maxTraceSteps, 4000);
818
1182
  const maxStoredEvents = getNumericOption(options.maxStoredEvents, maxTraceSteps);
819
1183
  const effectiveMaxTraceSteps = Math.min(maxTraceSteps, maxStoredEvents);
1184
+ const effectiveMaxRuntimeTraceEvents = maxStoredEvents;
820
1185
  const maxLineEvents = getNumericOption(options.maxLineEvents, 12000);
821
1186
  const maxSingleLineHits = getNumericOption(options.maxSingleLineHits, 1000);
822
1187
  const maxCallDepth = getNumericOption(options.maxCallDepth, 2000);
@@ -827,6 +1192,27 @@ function createTraceRecorder(options = {}) {
827
1192
  let timeoutRecorded = false;
828
1193
  let nextFrameId = 1;
829
1194
 
1195
+ function markTraceCaptureLimit(lineNumber, functionName) {
1196
+ if (!traceLimitExceeded) {
1197
+ traceLimitExceeded = true;
1198
+ timeoutReason = 'trace-limit';
1199
+ }
1200
+ pendingAccessesByFrame.clear();
1201
+ deferredAccessesByFrame.clear();
1202
+ if (!timeoutRecorded && trace.length < effectiveMaxTraceSteps && runtimeTraceEvents.length < effectiveMaxRuntimeTraceEvents) {
1203
+ const timeoutStep = {
1204
+ line: normalizeLine(lineNumber, 1),
1205
+ event: 'timeout',
1206
+ variables: { timeoutReason: 'trace-limit' },
1207
+ function: functionName ?? callStack[callStack.length - 1]?.function ?? '<module>',
1208
+ callStack: snapshotCallStack(),
1209
+ };
1210
+ timeoutRecorded = true;
1211
+ trace.push(timeoutStep);
1212
+ appendRuntimeTraceEventsForStep(timeoutStep);
1213
+ }
1214
+ }
1215
+
830
1216
  function normalizeLine(lineNumber, fallback = 1) {
831
1217
  const parsed = Number(lineNumber);
832
1218
  if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
@@ -835,6 +1221,7 @@ function createTraceRecorder(options = {}) {
835
1221
 
836
1222
  function snapshotCallStack() {
837
1223
  return callStack.map((frame) => ({
1224
+ id: frame.id,
838
1225
  function: frame.function,
839
1226
  args: frame.args,
840
1227
  line: frame.line,
@@ -848,11 +1235,7 @@ function createTraceRecorder(options = {}) {
848
1235
  if (variableValue === undefined) continue;
849
1236
  if (typeof variableValue === 'function') continue;
850
1237
  try {
851
- const refState =
852
- key === 'this' && variableValue && typeof variableValue === 'object'
853
- ? { ids: new Map(), nextId: 1 }
854
- : stableNodeRefState;
855
- result[key] = serializeTopLevelValue(variableValue, refState);
1238
+ result[key] = serializeTopLevelValue(variableValue, stableNodeRefState);
856
1239
  } catch {
857
1240
  // Skip variables that throw during serialization (e.g. transient proxy/getter failures).
858
1241
  }
@@ -860,6 +1243,24 @@ function createTraceRecorder(options = {}) {
860
1243
  return result;
861
1244
  }
862
1245
 
1246
+ function sanitizeCallArgs(value) {
1247
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return {};
1248
+ const result = {};
1249
+ for (const [key, variableValue] of Object.entries(value)) {
1250
+ if (typeof variableValue === 'function') continue;
1251
+ if (variableValue === undefined) {
1252
+ result[key] = '<undefined>';
1253
+ continue;
1254
+ }
1255
+ try {
1256
+ result[key] = serializeTopLevelValue(variableValue, stableNodeRefState);
1257
+ } catch {
1258
+ result[key] = '<unserializable>';
1259
+ }
1260
+ }
1261
+ return result;
1262
+ }
1263
+
863
1264
  function isLikelyTreeObject(value) {
864
1265
  if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
865
1266
  const hasValue = Object.prototype.hasOwnProperty.call(value, 'val') || Object.prototype.hasOwnProperty.call(value, 'value');
@@ -916,178 +1317,6 @@ function createTraceRecorder(options = {}) {
916
1317
  return true;
917
1318
  }
918
1319
 
919
- function shouldVisualizeObjectAsHashMap(name, value) {
920
- if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
921
- if (isLikelyTreeObject(value) || isLikelyLinkedListObject(value)) return false;
922
- if (value.__type__ === 'object') return false;
923
- if (Object.keys(value).length === 1 && typeof value.__ref__ === 'string') return false;
924
- if (isLikelyAdjacencyListObject(value)) return false;
925
-
926
- const lowerName = String(name).toLowerCase();
927
- if (lowerName.includes('map') || lowerName.includes('seen') || lowerName.includes('dict')) {
928
- return true;
929
- }
930
- return Object.keys(value).length > 0;
931
- }
932
-
933
- function collectRuntimeVisualizations(value) {
934
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
935
- return { hashMaps: [], objectKinds: {} };
936
- }
937
-
938
- const visualizations = [];
939
- const objectKinds = {};
940
- for (const [name, variableValue] of Object.entries(value)) {
941
- if (variableValue === undefined) continue;
942
-
943
- if (variableValue instanceof Map) {
944
- objectKinds[name] = 'map';
945
- visualizations.push({
946
- name,
947
- kind: 'map',
948
- entries: [...variableValue.entries()].map(([key, mapValue]) => ({
949
- key: serializeValue(key),
950
- value: serializeValue(mapValue),
951
- })),
952
- });
953
- continue;
954
- }
955
-
956
- if (variableValue instanceof Set) {
957
- objectKinds[name] = 'set';
958
- visualizations.push({
959
- name,
960
- kind: 'set',
961
- entries: [...variableValue.values()].map((item) => ({
962
- key: serializeValue(item),
963
- value: true,
964
- })),
965
- });
966
- continue;
967
- }
968
-
969
- if (isLikelyIndexedAdjacencyListArray(variableValue)) {
970
- objectKinds[name] = 'graph-adjacency';
971
- continue;
972
- }
973
-
974
- if (variableValue && typeof variableValue === 'object' && !Array.isArray(variableValue)) {
975
- const customClassName = getCustomClassName(variableValue);
976
- if (customClassName) {
977
- const serializedObject = serializeValue(variableValue);
978
- objectKinds[name] = 'object';
979
- visualizations.push({
980
- name,
981
- kind: 'object',
982
- objectClassName: customClassName,
983
- objectId:
984
- serializedObject && typeof serializedObject === 'object' && typeof serializedObject.__id__ === 'string'
985
- ? serializedObject.__id__
986
- : undefined,
987
- entries: Object.entries(serializedObject)
988
- .filter(([key]) => key !== '__type__' && key !== '__class__' && key !== '__id__')
989
- .map(([key, entryValue]) => ({
990
- key,
991
- value: entryValue,
992
- })),
993
- });
994
- continue;
995
- }
996
-
997
- const serializedValue = variableValue;
998
-
999
- if (serializedValue.__type__ === 'object') {
1000
- objectKinds[name] = 'object';
1001
- visualizations.push({
1002
- name,
1003
- kind: 'object',
1004
- objectClassName:
1005
- typeof serializedValue.__class__ === 'string' && serializedValue.__class__.length > 0
1006
- ? serializedValue.__class__
1007
- : undefined,
1008
- objectId:
1009
- typeof serializedValue.__id__ === 'string' && serializedValue.__id__.length > 0
1010
- ? serializedValue.__id__
1011
- : undefined,
1012
- entries: Object.entries(serializedValue)
1013
- .filter(([key]) => key !== '__type__' && key !== '__class__' && key !== '__id__')
1014
- .map(([key, entryValue]) => ({
1015
- key,
1016
- value: entryValue,
1017
- })),
1018
- });
1019
- continue;
1020
- }
1021
-
1022
- if (serializedValue.__type__ === 'map' && Array.isArray(serializedValue.entries)) {
1023
- objectKinds[name] = 'map';
1024
- visualizations.push({
1025
- name,
1026
- kind: 'map',
1027
- entries: serializedValue.entries
1028
- .filter((entry) => Array.isArray(entry) && entry.length >= 2)
1029
- .map((entry) => ({
1030
- key: entry[0],
1031
- value: entry[1],
1032
- })),
1033
- });
1034
- continue;
1035
- }
1036
-
1037
- if (serializedValue.__type__ === 'set' && Array.isArray(serializedValue.values)) {
1038
- objectKinds[name] = 'set';
1039
- visualizations.push({
1040
- name,
1041
- kind: 'set',
1042
- entries: serializedValue.values.map((item) => ({
1043
- key: item,
1044
- value: true,
1045
- })),
1046
- });
1047
- continue;
1048
- }
1049
-
1050
- if (isLikelyTreeObject(serializedValue)) {
1051
- objectKinds[name] = 'tree';
1052
- continue;
1053
- }
1054
-
1055
- if (isLikelyLinkedListObject(serializedValue)) {
1056
- objectKinds[name] = 'linked-list';
1057
- continue;
1058
- }
1059
-
1060
- if (isLikelyAdjacencyListObject(serializedValue)) {
1061
- objectKinds[name] = 'graph-adjacency';
1062
- continue;
1063
- }
1064
-
1065
- if (shouldVisualizeObjectAsHashMap(name, serializedValue)) {
1066
- objectKinds[name] = 'hashmap';
1067
- visualizations.push({
1068
- name,
1069
- kind: 'hashmap',
1070
- entries: Object.entries(serializedValue).map(([key, entryValue]) => ({
1071
- key,
1072
- value: serializeValue(entryValue),
1073
- })),
1074
- });
1075
- }
1076
- }
1077
- }
1078
-
1079
- return { hashMaps: visualizations, objectKinds };
1080
- }
1081
-
1082
- function buildVisualizationPayload(value) {
1083
- const { hashMaps, objectKinds } = collectRuntimeVisualizations(value);
1084
- if (hashMaps.length === 0 && Object.keys(objectKinds).length === 0) return undefined;
1085
- return {
1086
- ...(hashMaps.length > 0 ? { hashMaps } : {}),
1087
- ...(Object.keys(objectKinds).length > 0 ? { objectKinds } : {}),
1088
- };
1089
- }
1090
-
1091
1320
  function createLimitError(reason, lineNumber, message) {
1092
1321
  const error = new Error(message);
1093
1322
  error.__traceLimitExceeded = true;
@@ -1135,29 +1364,27 @@ function createTraceRecorder(options = {}) {
1135
1364
  ...(Array.isArray(access.indices) && access.indices.length > 0
1136
1365
  ? { indices: access.indices }
1137
1366
  : {}),
1367
+ ...(Array.isArray(access.indexSources) && access.indexSources.length > 0
1368
+ ? { indexSources: access.indexSources }
1369
+ : {}),
1138
1370
  ...(access.method ? { method: access.method } : {}),
1371
+ ...(Array.isArray(access.args) ? { args: access.args } : {}),
1139
1372
  ...(access.pathDepth ? { pathDepth: access.pathDepth } : {}),
1373
+ ...(access.scope ? { scope: access.scope } : {}),
1374
+ ...(access.binding ? { binding: access.binding } : {}),
1375
+ ...(Number.isFinite(access.line) && access.line > 0 ? { line: access.line } : {}),
1376
+ ...(Number.isFinite(access.column) && access.column >= 0 ? { column: access.column } : {}),
1377
+ ...(Object.prototype.hasOwnProperty.call(access, 'value') ? { value: access.value } : {}),
1140
1378
  }));
1141
1379
  }
1142
1380
 
1143
1381
  function appendTrace(step, frameId = getCurrentFrameId()) {
1382
+ if (traceLimitExceeded) {
1383
+ return;
1384
+ }
1144
1385
  if (trace.length >= effectiveMaxTraceSteps) {
1145
- const lineNumber = normalizeLine(step?.line, 1);
1146
- if (!traceLimitExceeded) {
1147
- traceLimitExceeded = true;
1148
- timeoutReason = 'trace-limit';
1149
- }
1150
- if (!timeoutRecorded && trace.length < effectiveMaxTraceSteps) {
1151
- trace.push({
1152
- line: lineNumber,
1153
- event: 'timeout',
1154
- variables: {},
1155
- function: step?.function ?? callStack[callStack.length - 1]?.function ?? '<module>',
1156
- callStack: snapshotCallStack(),
1157
- });
1158
- timeoutRecorded = true;
1159
- }
1160
- throw createLimitError('trace-limit', lineNumber, `Exceeded ${effectiveMaxTraceSteps} trace steps`);
1386
+ markTraceCaptureLimit(step?.line, step?.function);
1387
+ return;
1161
1388
  }
1162
1389
  const accesses = flushPendingAccesses(frameId);
1163
1390
  const nextStep = {
@@ -1173,35 +1400,185 @@ function createTraceRecorder(options = {}) {
1173
1400
  if (nextStep.accesses?.length) {
1174
1401
  previous.accesses = [...(previous.accesses || []), ...nextStep.accesses];
1175
1402
  }
1176
- if (nextStep.visualization !== undefined) {
1177
- previous.visualization = nextStep.visualization;
1178
- }
1179
1403
  previous.callStack = nextStep.callStack;
1180
1404
  previous.function = nextStep.function;
1405
+ appendRuntimeTraceEventsForStep({
1406
+ ...nextStep,
1407
+ event: '__merge_only__',
1408
+ });
1181
1409
  return;
1182
1410
  }
1183
1411
  trace.push(nextStep);
1412
+ appendRuntimeTraceEventsForStep(nextStep);
1184
1413
  }
1185
1414
 
1186
- function canMergeConsecutiveLineSteps(previous, nextStep) {
1187
- if (!previous || !nextStep) return false;
1188
- if (previous.event !== 'line' || nextStep.event !== 'line') return false;
1189
- if (previous.line !== nextStep.line) return false;
1190
- if (previous.function !== nextStep.function) return false;
1191
- return sameCallStackVisit(previous.callStack, nextStep.callStack);
1415
+ function runtimeTraceFrameIdForStep(step) {
1416
+ const stack = Array.isArray(step?.callStack) ? step.callStack : [];
1417
+ if (stack.length > 0) {
1418
+ const frame = stack[stack.length - 1];
1419
+ return `${frame.function}:${frame.line}:${frame.id ?? 'unknown'}`;
1420
+ }
1421
+ return `${step.function}:${step.line}:root`;
1192
1422
  }
1193
1423
 
1194
- function sameCallStackVisit(left, right) {
1195
- if (!Array.isArray(left) || !Array.isArray(right)) return false;
1196
- if (left.length !== right.length) return false;
1197
- for (let index = 0; index < left.length; index += 1) {
1198
- const leftFrame = left[index];
1199
- const rightFrame = right[index];
1200
- if (!leftFrame || !rightFrame) return false;
1201
- if (leftFrame.function !== rightFrame.function) return false;
1202
- if (leftFrame.line !== rightFrame.line) return false;
1424
+ function runtimeTraceTargetForAccess(access) {
1425
+ const indices = Array.isArray(access?.indices) ? access.indices : [];
1426
+ const indexSources = Array.isArray(access?.indexSources) ? access.indexSources : [];
1427
+ const scope = typeof access?.scope === 'string' && access.scope.length > 0
1428
+ ? access.scope
1429
+ : undefined;
1430
+ const base = {
1431
+ variable: access.variable,
1432
+ ...(scope ? { scope } : {}),
1433
+ };
1434
+ if (indices.length > 0) {
1435
+ return {
1436
+ ...base,
1437
+ path: indices,
1438
+ ...(indexSources.length > 0 ? { indexSources } : {}),
1439
+ };
1203
1440
  }
1204
- return true;
1441
+ return base;
1442
+ }
1443
+
1444
+ function runtimeTraceKindForAccess(access) {
1445
+ if (access.kind === 'indexed-read' || access.kind === 'cell-read') return 'read';
1446
+ if (access.kind === 'indexed-write' || access.kind === 'cell-write') return 'write';
1447
+ return 'mutate';
1448
+ }
1449
+
1450
+ function runtimeTraceAccessValue(step, access) {
1451
+ if (access && Object.prototype.hasOwnProperty.call(access, 'value')) return access.value;
1452
+ return valueAtPath(step?.variables?.[access.variable], access.indices);
1453
+ }
1454
+
1455
+ function traceStepFrameId(step) {
1456
+ const stack = Array.isArray(step?.callStack) ? step.callStack : [];
1457
+ return stack.length > 0 ? stack[stack.length - 1]?.id : undefined;
1458
+ }
1459
+
1460
+ function updateRuntimeTraceAccessStats(access) {
1461
+ const variable = access?.variable;
1462
+ if (typeof variable !== 'string' || variable.length === 0) return;
1463
+ const stats = runtimeTraceAccessStatsByVariable.get(variable) ?? {
1464
+ hasCellRead: false,
1465
+ hasCellWrite: false,
1466
+ hasMutatingCall: false,
1467
+ hasNestedMutatingCall: false,
1468
+ hasIndexedWrite: false,
1469
+ };
1470
+ if (access.kind === 'cell-read') stats.hasCellRead = true;
1471
+ if (access.kind === 'cell-write') stats.hasCellWrite = true;
1472
+ if (access.kind === 'mutating-call') stats.hasMutatingCall = true;
1473
+ if (access.kind === 'mutating-call' && (access.pathDepth ?? 0) > 0) stats.hasNestedMutatingCall = true;
1474
+ if (access.kind === 'indexed-write') stats.hasIndexedWrite = true;
1475
+ runtimeTraceAccessStatsByVariable.set(variable, stats);
1476
+ }
1477
+
1478
+ function appendRuntimeTraceEventsForStep(step) {
1479
+ if (traceLimitExceeded && timeoutReason === 'trace-limit' && step?.event !== 'timeout') {
1480
+ return;
1481
+ }
1482
+ const base = {
1483
+ runId: 'javascript:run',
1484
+ line: step.line,
1485
+ frameId: runtimeTraceFrameIdForStep(step),
1486
+ };
1487
+ const pushRuntimeTraceEvent = (event) => {
1488
+ if (runtimeTraceEvents.length >= effectiveMaxRuntimeTraceEvents) {
1489
+ markTraceCaptureLimit(step?.line, step?.function);
1490
+ return false;
1491
+ }
1492
+ runtimeTraceEvents.push(event);
1493
+ return true;
1494
+ };
1495
+
1496
+ if (step.event === 'line') {
1497
+ pushRuntimeTraceEvent({ ...base, kind: 'line', function: step.function });
1498
+ } else if (step.event === 'call') {
1499
+ const stack = Array.isArray(step.callStack) ? step.callStack : [];
1500
+ pushRuntimeTraceEvent({ ...base, kind: 'call', function: step.function, args: stack.at(-1)?.args });
1501
+ } else if (step.event === 'return') {
1502
+ pushRuntimeTraceEvent({
1503
+ ...base,
1504
+ kind: 'return',
1505
+ function: step.function,
1506
+ ...(step.returnValue !== undefined ? { value: step.returnValue } : {}),
1507
+ });
1508
+ } else if (step.event === 'exception') {
1509
+ pushRuntimeTraceEvent({ ...base, kind: 'exception', message: String(step.returnValue ?? 'Runtime exception') });
1510
+ } else if (step.event === 'timeout') {
1511
+ pushRuntimeTraceEvent({ ...base, kind: 'timeout', message: 'Runtime timeout' });
1512
+ } else if (step.event === 'stdout') {
1513
+ pushRuntimeTraceEvent({
1514
+ kind: 'stdout',
1515
+ runId: 'javascript:run',
1516
+ ...(step.line ? { line: step.line } : {}),
1517
+ text: String(step.returnValue ?? ''),
1518
+ });
1519
+ }
1520
+
1521
+ if (step.event !== '__merge_only__') {
1522
+ for (const [variable, value] of Object.entries(step.variables ?? {})) {
1523
+ if (!pushRuntimeTraceEvent({ ...base, kind: 'snapshot', target: { variable }, value })) return;
1524
+ }
1525
+ } else {
1526
+ for (const [variable, value] of Object.entries(step.variables ?? {})) {
1527
+ if (!pushRuntimeTraceEvent({ ...base, kind: 'snapshot', target: { variable }, value })) return;
1528
+ }
1529
+ }
1530
+
1531
+ for (const access of step.accesses ?? []) {
1532
+ updateRuntimeTraceAccessStats(access);
1533
+ const kind = runtimeTraceKindForAccess(access);
1534
+ const target = runtimeTraceTargetForAccess(access);
1535
+ const accessBase = {
1536
+ ...base,
1537
+ ...(Number.isFinite(access.line) && access.line > 0 ? { line: access.line } : {}),
1538
+ ...(Number.isFinite(access.column) && access.column >= 0 ? { column: access.column } : {}),
1539
+ };
1540
+ if (kind === 'mutate') {
1541
+ const event = {
1542
+ ...accessBase,
1543
+ kind,
1544
+ target,
1545
+ ...(access.method ? { method: access.method } : {}),
1546
+ ...(Array.isArray(access.args) ? { args: access.args } : {}),
1547
+ };
1548
+ if (!pushRuntimeTraceEvent(event)) return;
1549
+ } else {
1550
+ const event = {
1551
+ ...accessBase,
1552
+ kind,
1553
+ target,
1554
+ value: runtimeTraceAccessValue(step, access),
1555
+ ...(access.binding ? { binding: access.binding } : {}),
1556
+ };
1557
+ if (!pushRuntimeTraceEvent(event)) return;
1558
+ }
1559
+ }
1560
+ }
1561
+
1562
+ function canMergeConsecutiveLineSteps(previous, nextStep) {
1563
+ if (!previous || !nextStep) return false;
1564
+ if (previous.event !== 'line' || nextStep.event !== 'line') return false;
1565
+ if (previous.line !== nextStep.line) return false;
1566
+ if (previous.function !== nextStep.function) return false;
1567
+ if ((previous.accesses?.length ?? 0) > 0 || (nextStep.accesses?.length ?? 0) > 0) return false;
1568
+ return sameCallStackVisit(previous.callStack, nextStep.callStack);
1569
+ }
1570
+
1571
+ function sameCallStackVisit(left, right) {
1572
+ if (!Array.isArray(left) || !Array.isArray(right)) return false;
1573
+ if (left.length !== right.length) return false;
1574
+ for (let index = 0; index < left.length; index += 1) {
1575
+ const leftFrame = left[index];
1576
+ const rightFrame = right[index];
1577
+ if (!leftFrame || !rightFrame) return false;
1578
+ if (leftFrame.function !== rightFrame.function) return false;
1579
+ if (leftFrame.line !== rightFrame.line) return false;
1580
+ }
1581
+ return true;
1205
1582
  }
1206
1583
 
1207
1584
  function markTimeout(reason, lineNumber, message) {
@@ -1312,7 +1689,6 @@ function createTraceRecorder(options = {}) {
1312
1689
  variables: inferredFrame.args,
1313
1690
  function: normalizedFunctionName,
1314
1691
  callStack: snapshotCallStack(),
1315
- visualization: buildVisualizationPayload(inferredArgs),
1316
1692
  });
1317
1693
  return normalizedFunctionName;
1318
1694
  }
@@ -1333,7 +1709,6 @@ function createTraceRecorder(options = {}) {
1333
1709
  },
1334
1710
  pushCall(functionName, args, lineNumber) {
1335
1711
  const normalizedLine = normalizeLine(lineNumber, 1);
1336
- const normalizedArgs = sanitizeVariables(args);
1337
1712
  if (callStack.length + 1 > maxCallDepth) {
1338
1713
  markTimeout(
1339
1714
  'recursion-limit',
@@ -1341,6 +1716,11 @@ function createTraceRecorder(options = {}) {
1341
1716
  `Exceeded max call depth (${maxCallDepth})`
1342
1717
  );
1343
1718
  }
1719
+ if (traceLimitExceeded) {
1720
+ return;
1721
+ }
1722
+ this.attachPendingAccessesToPreviousLine();
1723
+ const normalizedArgs = sanitizeCallArgs(args);
1344
1724
  const frame = {
1345
1725
  id: nextFrameId++,
1346
1726
  function: functionName || '<module>',
@@ -1354,10 +1734,12 @@ function createTraceRecorder(options = {}) {
1354
1734
  variables: normalizedArgs,
1355
1735
  function: frame.function,
1356
1736
  callStack: snapshotCallStack(),
1357
- visualization: buildVisualizationPayload(args),
1358
1737
  });
1359
1738
  },
1360
1739
  recordAccess(event) {
1740
+ if (traceLimitExceeded) {
1741
+ return;
1742
+ }
1361
1743
  if (!event || typeof event !== 'object') {
1362
1744
  return;
1363
1745
  }
@@ -1377,12 +1759,41 @@ function createTraceRecorder(options = {}) {
1377
1759
  variable,
1378
1760
  kind,
1379
1761
  ...(Array.isArray(event.indices) && event.indices.length > 0
1380
- ? { indices: event.indices.map((index) => Math.trunc(index)) }
1762
+ ? { indices: normalizeTraceIndices(event.indices) ?? undefined }
1763
+ : {}),
1764
+ ...(Array.isArray(event.indexSources) && event.indexSources.length > 0
1765
+ ? { indexSources: normalizeTraceIndexSources(event.indexSources) ?? undefined }
1381
1766
  : {}),
1382
1767
  ...(typeof event.method === 'string' && event.method.length > 0
1383
1768
  ? { method: event.method }
1384
1769
  : {}),
1385
- ...(event.pathDepth === 1 || event.pathDepth === 2 ? { pathDepth: event.pathDepth } : {}),
1770
+ ...(Array.isArray(event.args)
1771
+ ? { args: event.args.map((arg) => this.serialize(arg)) }
1772
+ : {}),
1773
+ ...(event.pathDepth === 1 || event.pathDepth === 2 || event.pathDepth === 3 ? { pathDepth: event.pathDepth } : {}),
1774
+ ...(typeof event.scope === 'string' && event.scope.length > 0
1775
+ ? { scope: event.scope }
1776
+ : {}),
1777
+ ...(event.binding &&
1778
+ typeof event.binding === 'object' &&
1779
+ typeof event.binding.variable === 'string' &&
1780
+ event.binding.variable.length > 0
1781
+ ? {
1782
+ binding: {
1783
+ ...(event.binding.kind === 'iteration' ? { kind: 'iteration' } : {}),
1784
+ variable: event.binding.variable,
1785
+ },
1786
+ }
1787
+ : {}),
1788
+ ...(Number.isFinite(event.line) && event.line > 0
1789
+ ? { line: Math.trunc(event.line) }
1790
+ : {}),
1791
+ ...(Number.isFinite(event.column) && event.column >= 0
1792
+ ? { column: Math.trunc(event.column) }
1793
+ : {}),
1794
+ ...(Object.prototype.hasOwnProperty.call(event, 'value')
1795
+ ? { value: this.serialize(event.value) }
1796
+ : {}),
1386
1797
  };
1387
1798
 
1388
1799
  const existing = pendingAccessesByFrame.get(frameId) ?? [];
@@ -1390,6 +1801,9 @@ function createTraceRecorder(options = {}) {
1390
1801
  pendingAccessesByFrame.set(frameId, existing);
1391
1802
  },
1392
1803
  deferPendingAccesses(lineFlushes = 1) {
1804
+ if (traceLimitExceeded) {
1805
+ return;
1806
+ }
1393
1807
  const frameId = getCurrentFrameId();
1394
1808
  if (frameId === undefined) {
1395
1809
  return;
@@ -1408,9 +1822,54 @@ function createTraceRecorder(options = {}) {
1408
1822
  ),
1409
1823
  });
1410
1824
  },
1825
+ attachPendingAccessesToPreviousLine() {
1826
+ if (traceLimitExceeded) {
1827
+ return;
1828
+ }
1829
+ const frameId = getCurrentFrameId();
1830
+ if (frameId === undefined) {
1831
+ return;
1832
+ }
1833
+ const pending = pendingAccessesByFrame.get(frameId);
1834
+ if (!Array.isArray(pending) || pending.length === 0) {
1835
+ return;
1836
+ }
1837
+ const attachable = pending;
1838
+ pendingAccessesByFrame.delete(frameId);
1839
+ if (attachable.length === 0) {
1840
+ return;
1841
+ }
1842
+ for (let index = trace.length - 1; index >= 0; index -= 1) {
1843
+ const step = trace[index];
1844
+ if (!step || step.event !== 'line') continue;
1845
+ if (traceStepFrameId(step) !== frameId) continue;
1846
+ step.accesses = [...(step.accesses ?? []), ...attachable];
1847
+ appendRuntimeTraceEventsForStep({
1848
+ ...step,
1849
+ event: '__access_only__',
1850
+ accesses: attachable,
1851
+ });
1852
+ return;
1853
+ }
1854
+ pendingAccessesByFrame.set(frameId, attachable);
1855
+ },
1856
+ traceCondition(value) {
1857
+ this.attachPendingAccessesToPreviousLine();
1858
+ return value;
1859
+ },
1860
+ tracePostLineCondition(evaluate) {
1861
+ if (typeof evaluate !== 'function') {
1862
+ return evaluate;
1863
+ }
1864
+ return evaluate();
1865
+ },
1411
1866
  line(lineNumber, snapshotFactory, functionNameOverride, functionStartLine) {
1412
1867
  const normalizedLine = normalizeLine(lineNumber, callStack[callStack.length - 1]?.line ?? 1);
1413
1868
 
1869
+ if (traceLimitExceeded) {
1870
+ return;
1871
+ }
1872
+
1414
1873
  lineEventCount += 1;
1415
1874
  if (lineEventCount > maxLineEvents) {
1416
1875
  markTimeout('line-limit', normalizedLine, `Exceeded ${maxLineEvents} line events`);
@@ -1427,15 +1886,12 @@ function createTraceRecorder(options = {}) {
1427
1886
  }
1428
1887
 
1429
1888
  let variables = {};
1430
- let visualization;
1431
1889
  if (typeof snapshotFactory === 'function') {
1432
1890
  try {
1433
1891
  const snapshot = snapshotFactory();
1434
1892
  variables = sanitizeVariables(snapshot);
1435
- visualization = buildVisualizationPayload(snapshot);
1436
1893
  } catch {
1437
1894
  variables = {};
1438
- visualization = undefined;
1439
1895
  }
1440
1896
  }
1441
1897
 
@@ -1452,10 +1908,12 @@ function createTraceRecorder(options = {}) {
1452
1908
  variables,
1453
1909
  function: traceFunctionName,
1454
1910
  callStack: snapshotCallStack(),
1455
- visualization,
1456
1911
  });
1457
1912
  },
1458
1913
  recordReturn(lineNumber, returnValue, functionNameOverride) {
1914
+ if (traceLimitExceeded) {
1915
+ return;
1916
+ }
1459
1917
  const normalizedLine = normalizeLine(lineNumber, callStack[callStack.length - 1]?.line ?? 1);
1460
1918
  const functionName =
1461
1919
  typeof functionNameOverride === 'string' && functionNameOverride.length > 0
@@ -1463,9 +1921,6 @@ function createTraceRecorder(options = {}) {
1463
1921
  : callStack[callStack.length - 1]?.function ?? '<module>';
1464
1922
  const serializedReturnValue = serializeValue(returnValue);
1465
1923
  const variables = functionName === '<module>' ? { result: serializedReturnValue } : {};
1466
- const visualization = functionName === '<module>'
1467
- ? buildVisualizationPayload({ result: returnValue })
1468
- : undefined;
1469
1924
 
1470
1925
  appendTrace({
1471
1926
  line: normalizedLine,
@@ -1474,10 +1929,12 @@ function createTraceRecorder(options = {}) {
1474
1929
  function: functionName,
1475
1930
  callStack: snapshotCallStack(),
1476
1931
  returnValue: serializedReturnValue,
1477
- visualization,
1478
1932
  });
1479
1933
  },
1480
1934
  recordException(lineNumber, error, functionNameOverride) {
1935
+ if (traceLimitExceeded) {
1936
+ return;
1937
+ }
1481
1938
  const normalizedLine = normalizeLine(lineNumber, callStack[callStack.length - 1]?.line ?? 1);
1482
1939
  appendTrace({
1483
1940
  line: normalizedLine,
@@ -1491,6 +1948,21 @@ function createTraceRecorder(options = {}) {
1491
1948
  returnValue: error instanceof Error ? error.message : String(error),
1492
1949
  });
1493
1950
  },
1951
+ recordStdout(lineNumber, text) {
1952
+ if (traceLimitExceeded) {
1953
+ return;
1954
+ }
1955
+ const normalizedLine = normalizeLine(lineNumber, callStack[callStack.length - 1]?.line ?? 1);
1956
+ appendTrace({
1957
+ line: normalizedLine,
1958
+ event: 'stdout',
1959
+ variables: {},
1960
+ function: callStack[callStack.length - 1]?.function ?? '<module>',
1961
+ callStack: snapshotCallStack(),
1962
+ stdoutLineCount: 1,
1963
+ returnValue: String(text ?? ''),
1964
+ });
1965
+ },
1494
1966
  popCall() {
1495
1967
  if (callStack.length > 0) {
1496
1968
  const frame = callStack.pop();
@@ -1513,6 +1985,21 @@ function createTraceRecorder(options = {}) {
1513
1985
  getTrace() {
1514
1986
  return trace;
1515
1987
  },
1988
+ getRuntimeTrace(language, runId = `${language}:run`, file) {
1989
+ const events = runtimeTraceEvents.map((event) => ({
1990
+ ...event,
1991
+ runId,
1992
+ ...(file ? { file } : {}),
1993
+ }));
1994
+ return {
1995
+ schemaVersion: RUNTIME_TRACE_SCHEMA_VERSION,
1996
+ language,
1997
+ runId,
1998
+ events,
1999
+ lineEventCount: events.filter((event) => event.kind === 'line').length,
2000
+ traceStepCount: events.length,
2001
+ };
2002
+ },
1516
2003
  getLineEventCount() {
1517
2004
  return lineEventCount;
1518
2005
  },
@@ -1672,6 +2159,75 @@ function createSyntheticTrace(payload, codeResult) {
1672
2159
  ];
1673
2160
  }
1674
2161
 
2162
+ function createEmptyRuntimeTrace(language, runId = `${language}:run`) {
2163
+ return {
2164
+ schemaVersion: RUNTIME_TRACE_SCHEMA_VERSION,
2165
+ language,
2166
+ runId,
2167
+ events: [],
2168
+ lineEventCount: 0,
2169
+ traceStepCount: 0,
2170
+ };
2171
+ }
2172
+
2173
+ function defaultRuntimeTraceFile(language) {
2174
+ return language === 'typescript' ? 'solution.ts' : 'solution.js';
2175
+ }
2176
+
2177
+ function createSyntheticRuntimeTrace(payload, codeResult, language) {
2178
+ const syntheticTrace = createSyntheticTrace(payload, codeResult);
2179
+ const runId = `${language}:run`;
2180
+ const file = defaultRuntimeTraceFile(language);
2181
+ const events = [];
2182
+ for (const step of syntheticTrace) {
2183
+ const base = {
2184
+ runId,
2185
+ file,
2186
+ line: step.line,
2187
+ frameId: runtimeTraceFrameIdForSyntheticStep(step),
2188
+ };
2189
+ if (step.event === 'call') {
2190
+ events.push({ ...base, kind: 'call', function: step.function, args: step.callStack?.at(-1)?.args });
2191
+ } else if (step.event === 'line') {
2192
+ events.push({ ...base, kind: 'line', function: step.function });
2193
+ } else if (step.event === 'return') {
2194
+ events.push({ ...base, kind: 'return', function: step.function, value: step.returnValue });
2195
+ }
2196
+ for (const [variable, value] of Object.entries(step.variables ?? {})) {
2197
+ events.push({ ...base, kind: 'snapshot', target: { variable }, value });
2198
+ }
2199
+ }
2200
+ return {
2201
+ schemaVersion: RUNTIME_TRACE_SCHEMA_VERSION,
2202
+ language,
2203
+ runId,
2204
+ events,
2205
+ lineEventCount: events.filter((event) => event.kind === 'line').length,
2206
+ traceStepCount: events.length,
2207
+ };
2208
+ }
2209
+
2210
+ const RUNTIME_TRACE_SCHEMA_VERSION = 'runtime-trace-2026-04-28';
2211
+
2212
+ function runtimeTraceFrameIdForSyntheticStep(step) {
2213
+ const stack = Array.isArray(step?.callStack) ? step.callStack : [];
2214
+ if (stack.length > 0) {
2215
+ const frame = stack[stack.length - 1];
2216
+ return `${frame.function}:${frame.line}`;
2217
+ }
2218
+ return `${step.function}:${step.line}`;
2219
+ }
2220
+
2221
+ function valueAtPath(value, path) {
2222
+ if (!Array.isArray(path) || path.length === 0) return value;
2223
+ let current = value;
2224
+ for (const part of path) {
2225
+ if (current === null || current === undefined || typeof current !== 'object') return undefined;
2226
+ current = current[String(part)];
2227
+ }
2228
+ return current;
2229
+ }
2230
+
1675
2231
  function getTypeScriptCompiler() {
1676
2232
  const ts = self?.ts;
1677
2233
  if (ts && typeof ts.transpileModule === 'function') {
@@ -1755,6 +2311,7 @@ function transpileTypeScript(sourceCode) {
1755
2311
  }
1756
2312
 
1757
2313
  async function prepareExecutableCode(sourceCode, language) {
2314
+ ensureJavaScriptLibraries();
1758
2315
  if (language === 'typescript') {
1759
2316
  await ensureTypeScriptCompiler();
1760
2317
  return transpileTypeScript(sourceCode);
@@ -1780,6 +2337,51 @@ function addBindingNames(ts, nameNode, names) {
1780
2337
  }
1781
2338
  }
1782
2339
 
2340
+ function collectBindingNames(ts, nameNode) {
2341
+ const names = new Set();
2342
+ addBindingNames(ts, nameNode, names);
2343
+ return [...names];
2344
+ }
2345
+
2346
+ function addAssignmentTargetNames(ts, node, names) {
2347
+ if (!node) return;
2348
+ if (ts.isParenthesizedExpression(node)) {
2349
+ addAssignmentTargetNames(ts, node.expression, names);
2350
+ return;
2351
+ }
2352
+ if (ts.isIdentifier(node)) {
2353
+ if (!node.text.startsWith('__trace')) names.add(node.text);
2354
+ return;
2355
+ }
2356
+ if (ts.isArrayLiteralExpression(node)) {
2357
+ for (const element of node.elements) {
2358
+ if (ts.isSpreadElement(element)) {
2359
+ addAssignmentTargetNames(ts, element.expression, names);
2360
+ } else {
2361
+ addAssignmentTargetNames(ts, element, names);
2362
+ }
2363
+ }
2364
+ return;
2365
+ }
2366
+ if (ts.isObjectLiteralExpression(node)) {
2367
+ for (const property of node.properties) {
2368
+ if (ts.isShorthandPropertyAssignment(property)) {
2369
+ addAssignmentTargetNames(ts, property.name, names);
2370
+ } else if (ts.isPropertyAssignment(property)) {
2371
+ addAssignmentTargetNames(ts, property.initializer, names);
2372
+ } else if (ts.isSpreadAssignment(property)) {
2373
+ addAssignmentTargetNames(ts, property.expression, names);
2374
+ }
2375
+ }
2376
+ }
2377
+ }
2378
+
2379
+ function collectAssignmentTargetNames(ts, node) {
2380
+ const names = new Set();
2381
+ addAssignmentTargetNames(ts, node, names);
2382
+ return [...names];
2383
+ }
2384
+
1783
2385
  function collectTraceVariableNames(ts, sourceFile) {
1784
2386
  const names = new Set();
1785
2387
 
@@ -1793,11 +2395,10 @@ function collectTraceVariableNames(ts, sourceFile) {
1793
2395
  } else if (
1794
2396
  ts.isBinaryExpression(node) &&
1795
2397
  node.left &&
1796
- ts.isIdentifier(node.left) &&
1797
2398
  node.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
1798
2399
  node.operatorToken.kind <= ts.SyntaxKind.LastAssignment
1799
2400
  ) {
1800
- names.add(node.left.text);
2401
+ addAssignmentTargetNames(ts, node.left, names);
1801
2402
  }
1802
2403
  ts.forEachChild(node, visit);
1803
2404
  }
@@ -1817,6 +2418,95 @@ function shouldTraceStatement(ts, statement) {
1817
2418
  );
1818
2419
  }
1819
2420
 
2421
+ function shouldMapStatementLineForFunctionContext(ts, statement) {
2422
+ return (
2423
+ shouldTraceStatement(ts, statement) ||
2424
+ ts.isWhileStatement(statement) ||
2425
+ ts.isForStatement(statement) ||
2426
+ ts.isForOfStatement(statement)
2427
+ );
2428
+ }
2429
+
2430
+ function isSingleLineNode(sourceFile, node) {
2431
+ const start = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line;
2432
+ const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd()).line;
2433
+ return start === end;
2434
+ }
2435
+
2436
+ function statementBypassesFollowingTraceLine(ts, statement) {
2437
+ if (
2438
+ ts.isBreakStatement(statement) ||
2439
+ ts.isContinueStatement(statement) ||
2440
+ ts.isReturnStatement(statement) ||
2441
+ ts.isThrowStatement(statement)
2442
+ ) {
2443
+ return true;
2444
+ }
2445
+ if (ts.isBlock(statement)) {
2446
+ return statement.statements.some((nested) => statementBypassesFollowingTraceLine(ts, nested));
2447
+ }
2448
+ return false;
2449
+ }
2450
+
2451
+ function shouldTraceIfStatementPostLine(ts, sourceFile, statement) {
2452
+ if (!isSingleLineNode(sourceFile, statement)) {
2453
+ return false;
2454
+ }
2455
+ if (statementBypassesFollowingTraceLine(ts, statement.thenStatement)) {
2456
+ return false;
2457
+ }
2458
+ if (statement.elseStatement && statementBypassesFollowingTraceLine(ts, statement.elseStatement)) {
2459
+ return false;
2460
+ }
2461
+ return true;
2462
+ }
2463
+
2464
+ function isPostLineStateStatement(ts, sourceFile, statement) {
2465
+ if (ts.isVariableStatement(statement)) {
2466
+ return true;
2467
+ }
2468
+ if (ts.isIfStatement(statement) && shouldTraceIfStatementPostLine(ts, sourceFile, statement)) {
2469
+ return true;
2470
+ }
2471
+ if (!ts.isExpressionStatement(statement)) {
2472
+ return false;
2473
+ }
2474
+ const expression = statement.expression;
2475
+ if (
2476
+ (ts.isPrefixUnaryExpression(expression) || ts.isPostfixUnaryExpression(expression)) &&
2477
+ ts.isIdentifier(expression.operand) &&
2478
+ (expression.operator === ts.SyntaxKind.PlusPlusToken ||
2479
+ expression.operator === ts.SyntaxKind.MinusMinusToken)
2480
+ ) {
2481
+ return true;
2482
+ }
2483
+ if (
2484
+ ts.isBinaryExpression(expression) &&
2485
+ isAssignmentOperatorToken(ts, expression.operatorToken.kind) &&
2486
+ ts.isIdentifier(expression.left)
2487
+ ) {
2488
+ return true;
2489
+ }
2490
+ if (isTraceStateMutationHelperCall(ts, expression)) {
2491
+ return true;
2492
+ }
2493
+ return false;
2494
+ }
2495
+
2496
+ function isTraceStateMutationHelperCall(ts, expression) {
2497
+ let current = unwrapParenthesizedExpression(ts, expression);
2498
+ if (!current || !ts.isCallExpression(current) || !ts.isIdentifier(current.expression)) {
2499
+ return false;
2500
+ }
2501
+ return [
2502
+ '__traceMutatingCall',
2503
+ '__traceWriteIndex',
2504
+ '__traceAugAssignIndex',
2505
+ '__traceUpdateIndex',
2506
+ '__traceUpdateScalar',
2507
+ ].includes(current.expression.text);
2508
+ }
2509
+
1820
2510
  function getNodeNameText(ts, nameNode) {
1821
2511
  if (!nameNode) return null;
1822
2512
  if (ts.isIdentifier(nameNode) || ts.isPrivateIdentifier(nameNode)) {
@@ -1857,7 +2547,8 @@ function inferTraceFunctionName(ts, node, fallbackFunctionName) {
1857
2547
  }
1858
2548
 
1859
2549
  if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {
1860
- const parent = node.parent;
2550
+ const originalNode = ts.getOriginalNode(node);
2551
+ const parent = node.parent ?? originalNode?.parent;
1861
2552
  if (parent && ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)) {
1862
2553
  return parent.name.text;
1863
2554
  }
@@ -1918,7 +2609,7 @@ function buildLineFunctionMap(ts, sourceFile, defaultFunctionName) {
1918
2609
  return;
1919
2610
  }
1920
2611
 
1921
- if (ts.isStatement(node) && shouldTraceStatement(ts, node)) {
2612
+ if (ts.isStatement(node) && shouldMapStatementLineForFunctionContext(ts, node)) {
1922
2613
  mapStatementLine(node, currentFunctionName, currentFunctionStartLine, includeThisSnapshot);
1923
2614
  }
1924
2615
 
@@ -1931,7 +2622,14 @@ function buildLineFunctionMap(ts, sourceFile, defaultFunctionName) {
1931
2622
 
1932
2623
  function unwrapParenthesizedExpression(ts, node) {
1933
2624
  let current = node;
1934
- while (current && ts.isParenthesizedExpression(current)) {
2625
+ while (
2626
+ current &&
2627
+ (ts.isParenthesizedExpression(current) ||
2628
+ (typeof ts.isAsExpression === 'function' && ts.isAsExpression(current)) ||
2629
+ (typeof ts.isTypeAssertionExpression === 'function' && ts.isTypeAssertionExpression(current)) ||
2630
+ (typeof ts.isSatisfiesExpression === 'function' && ts.isSatisfiesExpression(current)) ||
2631
+ (typeof ts.isNonNullExpression === 'function' && ts.isNonNullExpression(current)))
2632
+ ) {
1935
2633
  current = current.expression;
1936
2634
  }
1937
2635
  return current;
@@ -1951,6 +2649,16 @@ function isAssignmentLikeLeftOperand(ts, node) {
1951
2649
  );
1952
2650
  }
1953
2651
 
2652
+ function isTraceablePropertyWriteLeftOperand(ts, node) {
2653
+ const parent = node?.parent;
2654
+ return Boolean(
2655
+ parent &&
2656
+ ts.isBinaryExpression(parent) &&
2657
+ parent.left === node &&
2658
+ parent.operatorToken.kind === ts.SyntaxKind.EqualsToken
2659
+ );
2660
+ }
2661
+
1954
2662
  function isUpdateExpressionOperand(ts, node) {
1955
2663
  const parent = node?.parent;
1956
2664
  if (!parent) return false;
@@ -2006,21 +2714,71 @@ function extractTraceableElementAccess(ts, node) {
2006
2714
  const indices = [];
2007
2715
  let current = unwrapParenthesizedExpression(ts, node);
2008
2716
 
2009
- while (current && ts.isElementAccessExpression(current) && indices.length < 3) {
2010
- indices.unshift(current.argumentExpression);
2011
- current = unwrapParenthesizedExpression(ts, current.expression);
2717
+ while (current && indices.length < 3) {
2718
+ if (ts.isElementAccessExpression(current)) {
2719
+ indices.unshift(current.argumentExpression);
2720
+ current = unwrapParenthesizedExpression(ts, current.expression);
2721
+ continue;
2722
+ }
2723
+ if (ts.isPropertyAccessExpression(current)) {
2724
+ indices.unshift(ts.factory.createStringLiteral(current.name.text));
2725
+ current = unwrapParenthesizedExpression(ts, current.expression);
2726
+ continue;
2727
+ }
2728
+ break;
2012
2729
  }
2013
2730
 
2014
- if (!current || !ts.isIdentifier(current) || indices.length === 0 || indices.length > 2) {
2731
+ if (!current || indices.length === 0 || indices.length > 2) {
2732
+ return null;
2733
+ }
2734
+ if (ts.isThis(current)) {
2735
+ return {
2736
+ variableName: 'this',
2737
+ receiverExpression: ts.factory.createThis(),
2738
+ indices,
2739
+ };
2740
+ }
2741
+ if (!ts.isIdentifier(current)) {
2015
2742
  return null;
2016
2743
  }
2017
2744
 
2018
2745
  return {
2019
2746
  variableName: current.text,
2747
+ receiverExpression: ts.factory.createIdentifier(current.text),
2020
2748
  indices,
2021
2749
  };
2022
2750
  }
2023
2751
 
2752
+ function extractTraceablePropertyAccess(ts, node) {
2753
+ const current = unwrapParenthesizedExpression(ts, node);
2754
+ if (!current || !ts.isPropertyAccessExpression(current)) {
2755
+ return null;
2756
+ }
2757
+ const receiver = unwrapParenthesizedExpression(ts, current.expression);
2758
+ if (!receiver) {
2759
+ return null;
2760
+ }
2761
+ if (ts.isThis(receiver)) {
2762
+ return {
2763
+ variableName: 'this',
2764
+ propertyName: current.name.text,
2765
+ scope: 'receiver',
2766
+ };
2767
+ }
2768
+ if (!ts.isIdentifier(receiver)) {
2769
+ return null;
2770
+ }
2771
+ return {
2772
+ variableName: receiver.text,
2773
+ propertyName: current.name.text,
2774
+ };
2775
+ }
2776
+
2777
+ function runtimeScopeForTraceableReceiver(receiverName, localVariableNames) {
2778
+ if (receiverName === 'this') return 'receiver';
2779
+ return localVariableNames.has(receiverName) ? 'local' : 'global';
2780
+ }
2781
+
2024
2782
  function extractTraceableMutatingCall(ts, node) {
2025
2783
  if (!ts.isCallExpression(node) || !ts.isPropertyAccessExpression(node.expression)) {
2026
2784
  return null;
@@ -2028,14 +2786,68 @@ function extractTraceableMutatingCall(ts, node) {
2028
2786
 
2029
2787
  const receiver = unwrapParenthesizedExpression(ts, node.expression.expression);
2030
2788
  const methodName = node.expression.name.text;
2031
- if (!receiver || !ts.isIdentifier(receiver) || !isTraceableMutatingMethod(methodName)) {
2789
+ if (!receiver || !isTraceableMutatingMethod(methodName)) {
2032
2790
  return null;
2033
2791
  }
2034
2792
 
2035
- return {
2036
- variableName: receiver.text,
2037
- methodName,
2038
- };
2793
+ if (ts.isIdentifier(receiver)) {
2794
+ return {
2795
+ variableName: receiver.text,
2796
+ receiverExpression: ts.factory.createIdentifier(receiver.text),
2797
+ methodName,
2798
+ indices: [],
2799
+ };
2800
+ }
2801
+
2802
+ if (
2803
+ ts.isPropertyAccessExpression(receiver) &&
2804
+ ts.isThis(unwrapParenthesizedExpression(ts, receiver.expression))
2805
+ ) {
2806
+ return {
2807
+ variableName: 'this',
2808
+ receiverExpression: ts.factory.createThis(),
2809
+ methodName,
2810
+ indices: [ts.factory.createStringLiteral(receiver.name.text)],
2811
+ };
2812
+ }
2813
+
2814
+ const indexedReceiver = extractTraceableElementAccess(ts, receiver);
2815
+ if (indexedReceiver) {
2816
+ return {
2817
+ variableName: indexedReceiver.variableName,
2818
+ receiverExpression: indexedReceiver.receiverExpression,
2819
+ methodName,
2820
+ indices: indexedReceiver.indices,
2821
+ };
2822
+ }
2823
+
2824
+ if (
2825
+ ts.isCallExpression(receiver) &&
2826
+ ts.isPropertyAccessExpression(receiver.expression) &&
2827
+ receiver.expression.name.text === 'get' &&
2828
+ receiver.arguments.length === 1
2829
+ ) {
2830
+ const mapReceiver = unwrapParenthesizedExpression(ts, receiver.expression.expression);
2831
+ if (ts.isIdentifier(mapReceiver)) {
2832
+ return {
2833
+ variableName: mapReceiver.text,
2834
+ receiverExpression: ts.factory.createIdentifier(mapReceiver.text),
2835
+ methodName,
2836
+ indices: [receiver.arguments[0]],
2837
+ };
2838
+ }
2839
+ const tracedMapReceiver = extractTraceableElementAccess(ts, mapReceiver);
2840
+ if (tracedMapReceiver) {
2841
+ return {
2842
+ variableName: tracedMapReceiver.variableName,
2843
+ receiverExpression: tracedMapReceiver.receiverExpression,
2844
+ methodName,
2845
+ indices: [...tracedMapReceiver.indices, receiver.arguments[0]],
2846
+ };
2847
+ }
2848
+ }
2849
+
2850
+ return null;
2039
2851
  }
2040
2852
 
2041
2853
  function getCompoundAssignmentOperatorName(ts, tokenKind) {
@@ -2071,24 +2883,275 @@ function createIndicesArrayExpression(ts, indices) {
2071
2883
  return ts.factory.createArrayLiteralExpression(indices, false);
2072
2884
  }
2073
2885
 
2074
- function createTraceReadIndexExpression(ts, variableName, indices) {
2886
+ function createIndexSourcesArrayExpression(ts, sourceFile, indices) {
2887
+ return ts.factory.createArrayLiteralExpression(
2888
+ indices.map((index) => {
2889
+ const source = indexSourceExpressionText(ts, sourceFile, index);
2890
+ return source ? ts.factory.createStringLiteral(source) : ts.factory.createNull();
2891
+ }),
2892
+ false
2893
+ );
2894
+ }
2895
+
2896
+ function indexSourceExpressionText(ts, sourceFile, index) {
2897
+ if (ts.isIdentifier(index)) return index.text;
2898
+ if (typeof index.pos === 'number' && index.pos < 0) return null;
2899
+ let text = '';
2900
+ try {
2901
+ text = typeof index.getText === 'function' ? index.getText(sourceFile).trim().replace(/\s+/g, ' ') : '';
2902
+ } catch {
2903
+ text = '';
2904
+ }
2905
+ if (!text) return null;
2906
+ return isSafeIndexSourceExpression(ts, index) ? text : null;
2907
+ }
2908
+
2909
+ function isSafeIndexSourceExpression(ts, node) {
2910
+ const unwrapped = unwrapParenthesizedExpression(ts, node);
2911
+ if (!unwrapped) return false;
2912
+ if (ts.isIdentifier(unwrapped) || ts.isNumericLiteral(unwrapped) || ts.isStringLiteral(unwrapped)) {
2913
+ return true;
2914
+ }
2915
+ if (unwrapped.kind === ts.SyntaxKind.ThisKeyword) {
2916
+ return true;
2917
+ }
2918
+ if (ts.isPrefixUnaryExpression(unwrapped)) {
2919
+ if (
2920
+ (unwrapped.operator === ts.SyntaxKind.PlusPlusToken || unwrapped.operator === ts.SyntaxKind.MinusMinusToken) &&
2921
+ ts.isIdentifier(unwrapped.operand)
2922
+ ) {
2923
+ return true;
2924
+ }
2925
+ return (
2926
+ (unwrapped.operator === ts.SyntaxKind.PlusToken || unwrapped.operator === ts.SyntaxKind.MinusToken) &&
2927
+ isSafeIndexSourceExpression(ts, unwrapped.operand)
2928
+ );
2929
+ }
2930
+ if (ts.isPostfixUnaryExpression(unwrapped)) {
2931
+ return (
2932
+ (unwrapped.operator === ts.SyntaxKind.PlusPlusToken || unwrapped.operator === ts.SyntaxKind.MinusMinusToken) &&
2933
+ ts.isIdentifier(unwrapped.operand)
2934
+ );
2935
+ }
2936
+ if (ts.isPropertyAccessExpression(unwrapped)) {
2937
+ return isSafeIndexSourceExpression(ts, unwrapped.expression);
2938
+ }
2939
+ if (ts.isElementAccessExpression(unwrapped)) {
2940
+ return (
2941
+ isSafeIndexSourceExpression(ts, unwrapped.expression) &&
2942
+ Boolean(unwrapped.argumentExpression) &&
2943
+ isSafeIndexSourceExpression(ts, unwrapped.argumentExpression)
2944
+ );
2945
+ }
2946
+ if (ts.isCallExpression(unwrapped)) {
2947
+ const expression = unwrapParenthesizedExpression(ts, unwrapped.expression);
2948
+ if (!expression || !ts.isPropertyAccessExpression(expression)) return false;
2949
+ const safeIndexMethods = new Set(['at', 'charAt', 'charCodeAt', 'codePointAt']);
2950
+ return (
2951
+ safeIndexMethods.has(expression.name.text) &&
2952
+ isSafeIndexSourceExpression(ts, expression.expression) &&
2953
+ unwrapped.arguments.every((argument) => isSafeIndexSourceExpression(ts, argument))
2954
+ );
2955
+ }
2956
+ if (ts.isBinaryExpression(unwrapped)) {
2957
+ const allowedOperators = new Set([
2958
+ ts.SyntaxKind.PlusToken,
2959
+ ts.SyntaxKind.MinusToken,
2960
+ ts.SyntaxKind.AsteriskToken,
2961
+ ts.SyntaxKind.SlashToken,
2962
+ ts.SyntaxKind.PercentToken,
2963
+ ]);
2964
+ return (
2965
+ allowedOperators.has(unwrapped.operatorToken.kind) &&
2966
+ isSafeIndexSourceExpression(ts, unwrapped.left) &&
2967
+ isSafeIndexSourceExpression(ts, unwrapped.right)
2968
+ );
2969
+ }
2970
+ return false;
2971
+ }
2972
+
2973
+ function createTraceReadIndexExpression(ts, sourceFile, node, variableName, indices, indexSourceExpressions = indices) {
2974
+ const receiverExpression = variableName === 'this'
2975
+ ? ts.factory.createThis()
2976
+ : ts.factory.createIdentifier(variableName);
2977
+ return createTraceReadIndexExpressionForReceiver(
2978
+ ts,
2979
+ sourceFile,
2980
+ node,
2981
+ variableName,
2982
+ receiverExpression,
2983
+ indices,
2984
+ indexSourceExpressions
2985
+ );
2986
+ }
2987
+
2988
+ function createTraceReadIndexExpressionForReceiver(
2989
+ ts,
2990
+ sourceFile,
2991
+ node,
2992
+ variableName,
2993
+ receiverExpression,
2994
+ indices,
2995
+ indexSourceExpressions = indices
2996
+ ) {
2075
2997
  return ts.factory.createCallExpression(ts.factory.createIdentifier('__traceReadIndex'), undefined, [
2076
2998
  ts.factory.createStringLiteral(variableName),
2077
- ts.factory.createIdentifier(variableName),
2999
+ receiverExpression,
2078
3000
  createIndicesArrayExpression(ts, indices),
3001
+ createIndexSourcesArrayExpression(ts, sourceFile, indexSourceExpressions),
3002
+ createSourceLocationObject(ts, sourceFile, node),
2079
3003
  ]);
2080
3004
  }
2081
3005
 
2082
- function createTraceWriteIndexExpression(ts, variableName, indices, value) {
3006
+ function createTraceWriteIndexExpression(ts, sourceFile, node, variableName, indices, value, indexSourceExpressions = indices) {
3007
+ const receiverExpression = variableName === 'this'
3008
+ ? ts.factory.createThis()
3009
+ : ts.factory.createIdentifier(variableName);
2083
3010
  return ts.factory.createCallExpression(ts.factory.createIdentifier('__traceWriteIndex'), undefined, [
2084
3011
  ts.factory.createStringLiteral(variableName),
2085
- ts.factory.createIdentifier(variableName),
3012
+ receiverExpression,
2086
3013
  createIndicesArrayExpression(ts, indices),
3014
+ createIndexSourcesArrayExpression(ts, sourceFile, indexSourceExpressions),
2087
3015
  value,
3016
+ createSourceLocationObject(ts, sourceFile, node),
2088
3017
  ]);
2089
3018
  }
2090
3019
 
2091
- function createTraceAugAssignExpression(ts, variableName, indices, operatorName, rhs) {
3020
+ function createSourceLocationObject(ts, sourceFile, node) {
3021
+ const position = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
3022
+ return ts.factory.createObjectLiteralExpression(
3023
+ [
3024
+ ts.factory.createPropertyAssignment('line', ts.factory.createNumericLiteral(position.line + 1)),
3025
+ ts.factory.createPropertyAssignment('column', ts.factory.createNumericLiteral(position.character + 1)),
3026
+ ],
3027
+ false
3028
+ );
3029
+ }
3030
+
3031
+ function createTraceReadPropertyExpression(ts, sourceFile, node, variableName, propertyName, scope) {
3032
+ const receiverExpression = variableName === 'this'
3033
+ ? ts.factory.createThis()
3034
+ : ts.factory.createIdentifier(variableName);
3035
+ const args = [
3036
+ ts.factory.createStringLiteral(variableName),
3037
+ receiverExpression,
3038
+ ts.factory.createStringLiteral(propertyName),
3039
+ ];
3040
+ if (scope) {
3041
+ args.push(ts.factory.createStringLiteral(scope));
3042
+ }
3043
+ args.push(createSourceLocationObject(ts, sourceFile, node));
3044
+ return ts.factory.createCallExpression(ts.factory.createIdentifier('__traceReadProperty'), undefined, args);
3045
+ }
3046
+
3047
+ function createTraceWritePropertyExpression(ts, sourceFile, node, variableName, propertyName, value) {
3048
+ const receiverExpression = variableName === 'this'
3049
+ ? ts.factory.createThis()
3050
+ : ts.factory.createIdentifier(variableName);
3051
+ return ts.factory.createCallExpression(ts.factory.createIdentifier('__traceWriteIndex'), undefined, [
3052
+ ts.factory.createStringLiteral(variableName),
3053
+ receiverExpression,
3054
+ createIndicesArrayExpression(ts, [ts.factory.createStringLiteral(propertyName)]),
3055
+ ts.factory.createArrayLiteralExpression([ts.factory.createNull()], false),
3056
+ value,
3057
+ createSourceLocationObject(ts, sourceFile, node),
3058
+ ]);
3059
+ }
3060
+
3061
+ function createTraceScalarWriteExpression(ts, sourceFile, node, variableName, value) {
3062
+ return ts.factory.createCallExpression(ts.factory.createIdentifier('__traceAssignScalar'), undefined, [
3063
+ ts.factory.createStringLiteral(variableName),
3064
+ value,
3065
+ createSourceLocationObject(ts, sourceFile, node),
3066
+ ]);
3067
+ }
3068
+
3069
+ function createTraceScalarUpdateExpression(ts, sourceFile, node, variableName, operatorName, isPrefix) {
3070
+ return ts.factory.createCallExpression(ts.factory.createIdentifier('__traceUpdateScalar'), undefined, [
3071
+ ts.factory.createStringLiteral(variableName),
3072
+ ts.factory.createArrowFunction(
3073
+ undefined,
3074
+ undefined,
3075
+ [],
3076
+ undefined,
3077
+ ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
3078
+ isPrefix
3079
+ ? ts.factory.createPrefixUnaryExpression(
3080
+ operatorName === 'inc' ? ts.SyntaxKind.PlusPlusToken : ts.SyntaxKind.MinusMinusToken,
3081
+ ts.factory.createIdentifier(variableName)
3082
+ )
3083
+ : ts.factory.createPostfixUnaryExpression(
3084
+ ts.factory.createIdentifier(variableName),
3085
+ operatorName === 'inc' ? ts.SyntaxKind.PlusPlusToken : ts.SyntaxKind.MinusMinusToken
3086
+ )
3087
+ ),
3088
+ ts.factory.createArrowFunction(
3089
+ undefined,
3090
+ undefined,
3091
+ [],
3092
+ undefined,
3093
+ ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
3094
+ ts.factory.createIdentifier(variableName)
3095
+ ),
3096
+ isPrefix ? ts.factory.createTrue() : ts.factory.createFalse(),
3097
+ createSourceLocationObject(ts, sourceFile, node),
3098
+ ]);
3099
+ }
3100
+
3101
+ function createTraceScalarWriteStatement(ts, sourceFile, node, variableName) {
3102
+ return ts.factory.createExpressionStatement(
3103
+ ts.factory.createCallExpression(ts.factory.createIdentifier('__traceScalarWrite'), undefined, [
3104
+ ts.factory.createStringLiteral(variableName),
3105
+ ts.factory.createIdentifier(variableName),
3106
+ createSourceLocationObject(ts, sourceFile, node),
3107
+ ])
3108
+ );
3109
+ }
3110
+
3111
+ function traceScalarWriteStatementsForVariableStatement(ts, sourceFile, statement) {
3112
+ if (!ts.isVariableStatement(statement)) return [];
3113
+ const statements = [];
3114
+ for (const declaration of statement.declarationList.declarations) {
3115
+ if (!declaration.initializer) continue;
3116
+ if (
3117
+ ts.isArrowFunction(declaration.initializer) ||
3118
+ ts.isFunctionExpression(declaration.initializer) ||
3119
+ ts.isClassExpression(declaration.initializer)
3120
+ ) {
3121
+ continue;
3122
+ }
3123
+ for (const variableName of collectBindingNames(ts, declaration.name)) {
3124
+ statements.push(createTraceScalarWriteStatement(ts, sourceFile, declaration.name, variableName));
3125
+ }
3126
+ }
3127
+ return statements;
3128
+ }
3129
+
3130
+ function traceScalarWriteStatementsForDestructuringAssignmentStatement(ts, sourceFile, statement) {
3131
+ if (!ts.isExpressionStatement(statement)) return [];
3132
+ const expression = ts.isParenthesizedExpression(statement.expression)
3133
+ ? statement.expression.expression
3134
+ : statement.expression;
3135
+ if (!ts.isBinaryExpression(expression) || expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken) {
3136
+ return [];
3137
+ }
3138
+ if (!ts.isArrayLiteralExpression(expression.left) && !ts.isObjectLiteralExpression(expression.left)) {
3139
+ return [];
3140
+ }
3141
+ return collectAssignmentTargetNames(ts, expression.left)
3142
+ .map((variableName) => createTraceScalarWriteStatement(ts, sourceFile, expression.left, variableName));
3143
+ }
3144
+
3145
+ function createTraceAugAssignExpression(
3146
+ ts,
3147
+ sourceFile,
3148
+ node,
3149
+ variableName,
3150
+ indices,
3151
+ operatorName,
3152
+ rhs,
3153
+ indexSourceExpressions = indices
3154
+ ) {
2092
3155
  return ts.factory.createCallExpression(
2093
3156
  ts.factory.createIdentifier('__traceAugAssignIndex'),
2094
3157
  undefined,
@@ -2096,13 +3159,24 @@ function createTraceAugAssignExpression(ts, variableName, indices, operatorName,
2096
3159
  ts.factory.createStringLiteral(variableName),
2097
3160
  ts.factory.createIdentifier(variableName),
2098
3161
  createIndicesArrayExpression(ts, indices),
3162
+ createIndexSourcesArrayExpression(ts, sourceFile, indexSourceExpressions),
2099
3163
  ts.factory.createStringLiteral(operatorName),
2100
3164
  rhs,
3165
+ createSourceLocationObject(ts, sourceFile, node),
2101
3166
  ]
2102
3167
  );
2103
3168
  }
2104
3169
 
2105
- function createTraceUpdateExpression(ts, variableName, indices, operatorName, isPrefix) {
3170
+ function createTraceUpdateExpression(
3171
+ ts,
3172
+ sourceFile,
3173
+ node,
3174
+ variableName,
3175
+ indices,
3176
+ operatorName,
3177
+ isPrefix,
3178
+ indexSourceExpressions = indices
3179
+ ) {
2106
3180
  return ts.factory.createCallExpression(
2107
3181
  ts.factory.createIdentifier('__traceUpdateIndex'),
2108
3182
  undefined,
@@ -2110,25 +3184,106 @@ function createTraceUpdateExpression(ts, variableName, indices, operatorName, is
2110
3184
  ts.factory.createStringLiteral(variableName),
2111
3185
  ts.factory.createIdentifier(variableName),
2112
3186
  createIndicesArrayExpression(ts, indices),
3187
+ createIndexSourcesArrayExpression(ts, sourceFile, indexSourceExpressions),
2113
3188
  ts.factory.createStringLiteral(operatorName),
2114
3189
  isPrefix ? ts.factory.createTrue() : ts.factory.createFalse(),
3190
+ createSourceLocationObject(ts, sourceFile, node),
2115
3191
  ]
2116
3192
  );
2117
3193
  }
2118
3194
 
2119
- function createTraceMutatingCallExpression(ts, variableName, methodName, args) {
3195
+ function createTraceMutatingCallExpression(
3196
+ ts,
3197
+ sourceFile,
3198
+ node,
3199
+ variableName,
3200
+ methodName,
3201
+ args,
3202
+ indices = [],
3203
+ indexSourceExpressions = indices
3204
+ ) {
3205
+ const receiverExpression = variableName === 'this'
3206
+ ? ts.factory.createThis()
3207
+ : ts.factory.createIdentifier(variableName);
3208
+ return createTraceMutatingCallExpressionForReceiver(
3209
+ ts,
3210
+ sourceFile,
3211
+ node,
3212
+ variableName,
3213
+ receiverExpression,
3214
+ methodName,
3215
+ args,
3216
+ indices,
3217
+ indexSourceExpressions
3218
+ );
3219
+ }
3220
+
3221
+ function createTraceMutatingCallExpressionForReceiver(
3222
+ ts,
3223
+ sourceFile,
3224
+ node,
3225
+ variableName,
3226
+ receiverExpression,
3227
+ methodName,
3228
+ args,
3229
+ indices = [],
3230
+ indexSourceExpressions = indices
3231
+ ) {
3232
+ const effectiveIndexSourceExpressions = ['set', 'get', 'has'].includes(methodName) && args.length > 0
3233
+ ? [...indexSourceExpressions, args[0]]
3234
+ : indexSourceExpressions;
2120
3235
  return ts.factory.createCallExpression(
2121
3236
  ts.factory.createIdentifier('__traceMutatingCall'),
2122
3237
  undefined,
2123
3238
  [
2124
3239
  ts.factory.createStringLiteral(variableName),
2125
- ts.factory.createIdentifier(variableName),
3240
+ receiverExpression,
3241
+ createIndicesArrayExpression(ts, indices),
3242
+ createIndexSourcesArrayExpression(ts, sourceFile, effectiveIndexSourceExpressions),
2126
3243
  ts.factory.createStringLiteral(methodName),
3244
+ createSourceLocationObject(ts, sourceFile, node),
2127
3245
  ...args,
2128
3246
  ]
2129
3247
  );
2130
3248
  }
2131
3249
 
3250
+ function isConsoleLogCall(ts, node) {
3251
+ return Boolean(
3252
+ ts.isCallExpression(node) &&
3253
+ ts.isPropertyAccessExpression(node.expression) &&
3254
+ ts.isIdentifier(node.expression.expression) &&
3255
+ node.expression.expression.text === 'console' &&
3256
+ node.expression.name.text === 'log'
3257
+ );
3258
+ }
3259
+
3260
+ function createTraceStdoutExpression(ts, sourceFile, node) {
3261
+ const lineNumber = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1;
3262
+ return ts.factory.createCallExpression(
3263
+ ts.factory.createIdentifier('__traceStdout'),
3264
+ undefined,
3265
+ [
3266
+ ts.factory.createNumericLiteral(lineNumber),
3267
+ ...node.arguments,
3268
+ ]
3269
+ );
3270
+ }
3271
+
3272
+ function createTraceThrowExpression(ts, sourceFile, node) {
3273
+ const lineNumber = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1;
3274
+ return ts.factory.updateThrowStatement(
3275
+ node,
3276
+ ts.factory.createCallExpression(
3277
+ ts.factory.createIdentifier('__traceExceptionValue'),
3278
+ undefined,
3279
+ [
3280
+ ts.factory.createNumericLiteral(lineNumber),
3281
+ node.expression ?? ts.factory.createIdentifier('undefined'),
3282
+ ]
3283
+ )
3284
+ );
3285
+ }
3286
+
2132
3287
  function createSnapshotFactory(ts, variableNames, includeThis = false) {
2133
3288
  const properties = variableNames.map((name) =>
2134
3289
  ts.factory.createPropertyAssignment(
@@ -2222,6 +3377,19 @@ function createTraceLineStatement(ts, sourceFile, statement, variableNames, line
2222
3377
  );
2223
3378
  }
2224
3379
 
3380
+ function createAttachPendingAccessesStatement(ts) {
3381
+ return ts.factory.createExpressionStatement(
3382
+ ts.factory.createCallExpression(
3383
+ ts.factory.createPropertyAccessExpression(
3384
+ ts.factory.createIdentifier('__traceRecorder'),
3385
+ ts.factory.createIdentifier('attachPendingAccessesToPreviousLine')
3386
+ ),
3387
+ undefined,
3388
+ []
3389
+ )
3390
+ );
3391
+ }
3392
+
2225
3393
  function ensureBlockStatement(ts, statement) {
2226
3394
  if (ts.isBlock(statement)) {
2227
3395
  return statement;
@@ -2229,6 +3397,28 @@ function ensureBlockStatement(ts, statement) {
2229
3397
  return ts.factory.createBlock([statement], true);
2230
3398
  }
2231
3399
 
3400
+ function wrapTraceCondition(ts, expression, deferAccessesToNextLine = false) {
3401
+ const recorderMethod = deferAccessesToNextLine ? 'tracePostLineCondition' : 'traceCondition';
3402
+ const argument = deferAccessesToNextLine
3403
+ ? ts.factory.createArrowFunction(
3404
+ undefined,
3405
+ undefined,
3406
+ [],
3407
+ undefined,
3408
+ ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
3409
+ expression
3410
+ )
3411
+ : expression;
3412
+ return ts.factory.createCallExpression(
3413
+ ts.factory.createPropertyAccessExpression(
3414
+ ts.factory.createIdentifier('__traceRecorder'),
3415
+ ts.factory.createIdentifier(recorderMethod)
3416
+ ),
3417
+ undefined,
3418
+ [argument]
3419
+ );
3420
+ }
3421
+
2232
3422
  function rewriteWhileStatementForTracing(ts, sourceFile, whileStatement, variableNames, lineFunctionMap, defaultFunctionName) {
2233
3423
  const originalNode = ts.getOriginalNode(whileStatement) ?? whileStatement;
2234
3424
  const tracedLine = createTraceLineStatement(
@@ -2243,7 +3433,7 @@ function rewriteWhileStatementForTracing(ts, sourceFile, whileStatement, variabl
2243
3433
  const guardedBreak = ts.factory.createIfStatement(
2244
3434
  ts.factory.createPrefixUnaryExpression(
2245
3435
  ts.SyntaxKind.ExclamationToken,
2246
- whileStatement.expression
3436
+ wrapTraceCondition(ts, whileStatement.expression)
2247
3437
  ),
2248
3438
  ts.factory.createBreakStatement(),
2249
3439
  undefined
@@ -2276,27 +3466,82 @@ function rewriteForStatementForTracing(ts, sourceFile, forStatement, variableNam
2276
3466
  ts.factory.createBinaryExpression(
2277
3467
  tracedLineCall,
2278
3468
  ts.SyntaxKind.CommaToken,
2279
- condition
3469
+ wrapTraceCondition(ts, condition)
2280
3470
  )
2281
3471
  );
2282
- return ts.factory.updateForStatement(
3472
+ const initializerWriteStatements = [];
3473
+ if (forStatement.initializer && ts.isVariableDeclarationList(forStatement.initializer)) {
3474
+ for (const declaration of forStatement.initializer.declarations) {
3475
+ if (!ts.isIdentifier(declaration.name)) continue;
3476
+ initializerWriteStatements.push(createTraceScalarWriteStatement(ts, sourceFile, originalNode, declaration.name.text));
3477
+ }
3478
+ }
3479
+ const rewrittenFor = ts.factory.updateForStatement(
2283
3480
  forStatement,
2284
- forStatement.initializer,
3481
+ initializerWriteStatements.length > 0 ? undefined : forStatement.initializer,
2285
3482
  tracedCondition,
2286
3483
  forStatement.incrementor,
2287
3484
  forStatement.statement
2288
3485
  );
3486
+ if (initializerWriteStatements.length === 0 || !forStatement.initializer || !ts.isVariableDeclarationList(forStatement.initializer)) {
3487
+ return rewrittenFor;
3488
+ }
3489
+ return ts.factory.createBlock(
3490
+ [
3491
+ ts.factory.createVariableStatement(undefined, forStatement.initializer),
3492
+ ...initializerWriteStatements,
3493
+ rewrittenFor,
3494
+ ],
3495
+ true
3496
+ );
2289
3497
  }
2290
3498
 
2291
- function rewriteForOfStatementForTracing(ts, sourceFile, forOfStatement, variableNames, lineFunctionMap, defaultFunctionName) {
3499
+ function rewriteForOfStatementForTracing(ts, sourceFile, context, forOfStatement, variableNames, lineFunctionMap, defaultFunctionName) {
2292
3500
  const originalNode = ts.getOriginalNode(forOfStatement) ?? forOfStatement;
2293
- const lineNumber = ts.getLineAndCharacterOfPosition(sourceFile, originalNode.getStart(sourceFile)).line + 1;
2294
- const tempIndexName = `__traceForOfIndex_${lineNumber}_${originalNode.pos < 0 ? 0 : originalNode.pos}`;
2295
- const tempArrayName = `__traceForOfArray_${lineNumber}_${originalNode.pos < 0 ? 0 : originalNode.pos}`;
2296
- const arrayId = ts.factory.createIdentifier(tempArrayName);
2297
- const indexId = ts.factory.createIdentifier(tempIndexName);
2298
3501
  const visitedBodyBlock = ensureBlockStatement(ts, forOfStatement.statement);
2299
- const tracedLine = createTraceLineStatement(
3502
+ const originalExpression = originalNode.expression ?? forOfStatement.expression;
3503
+ const indexedSource = extractTraceableElementAccess(ts, originalExpression);
3504
+ const sourceName = ts.isIdentifier(forOfStatement.expression) ? forOfStatement.expression.text : null;
3505
+ const bindingName =
3506
+ ts.isVariableDeclarationList(forOfStatement.initializer) &&
3507
+ forOfStatement.initializer.declarations.length === 1 &&
3508
+ collectBindingNames(ts, forOfStatement.initializer.declarations[0].name).length > 0
3509
+ ? collectBindingNames(ts, forOfStatement.initializer.declarations[0].name).join(',')
3510
+ : ts.isIdentifier(forOfStatement.initializer)
3511
+ ? forOfStatement.initializer.text
3512
+ : null;
3513
+ const lineNumber = sourceFile.getLineAndCharacterOfPosition(originalNode.getStart(sourceFile)).line + 1;
3514
+ const tracedExpression =
3515
+ indexedSource && bindingName
3516
+ ? ts.factory.createCallExpression(
3517
+ ts.factory.createIdentifier('__traceIterableBindIndexed'),
3518
+ undefined,
3519
+ [
3520
+ ts.factory.createStringLiteral(indexedSource.variableName),
3521
+ forOfStatement.expression,
3522
+ createIndicesArrayExpression(ts, indexedSource.indices),
3523
+ createIndexSourcesArrayExpression(ts, sourceFile, indexedSource.indices),
3524
+ ts.factory.createStringLiteral(bindingName),
3525
+ ts.factory.createObjectLiteralExpression([
3526
+ ts.factory.createPropertyAssignment('line', ts.factory.createNumericLiteral(lineNumber)),
3527
+ ]),
3528
+ ]
3529
+ )
3530
+ : sourceName && bindingName
3531
+ ? ts.factory.createCallExpression(
3532
+ ts.factory.createIdentifier('__traceIterableBind'),
3533
+ undefined,
3534
+ [
3535
+ ts.factory.createStringLiteral(sourceName),
3536
+ forOfStatement.expression,
3537
+ ts.factory.createStringLiteral(bindingName),
3538
+ ts.factory.createObjectLiteralExpression([
3539
+ ts.factory.createPropertyAssignment('line', ts.factory.createNumericLiteral(lineNumber)),
3540
+ ]),
3541
+ ]
3542
+ )
3543
+ : forOfStatement.expression;
3544
+ const createHeaderLine = () => createTraceLineStatement(
2300
3545
  ts,
2301
3546
  sourceFile,
2302
3547
  originalNode,
@@ -2304,75 +3549,40 @@ function rewriteForOfStatementForTracing(ts, sourceFile, forOfStatement, variabl
2304
3549
  lineFunctionMap,
2305
3550
  defaultFunctionName
2306
3551
  );
2307
- const tracedLineCall = createTraceLineStatement(
2308
- ts,
2309
- sourceFile,
2310
- originalNode,
2311
- variableNames,
2312
- lineFunctionMap,
2313
- defaultFunctionName
2314
- ).expression;
2315
-
2316
- let bindingStatement;
2317
- if (ts.isVariableDeclarationList(forOfStatement.initializer)) {
2318
- const declaration = forOfStatement.initializer.declarations[0];
2319
- bindingStatement = ts.factory.createVariableStatement(
2320
- undefined,
2321
- ts.factory.updateVariableDeclarationList(forOfStatement.initializer, [
2322
- ts.factory.updateVariableDeclaration(
2323
- declaration,
2324
- declaration.name,
2325
- declaration.exclamationToken,
2326
- declaration.type,
2327
- ts.factory.createElementAccessExpression(arrayId, indexId)
2328
- ),
2329
- ])
2330
- );
2331
- } else {
2332
- bindingStatement = ts.factory.createExpressionStatement(
2333
- ts.factory.createAssignment(forOfStatement.initializer, ts.factory.createElementAccessExpression(arrayId, indexId))
2334
- );
2335
- }
3552
+ const bodyTracedLine = createHeaderLine();
3553
+ const rewriteContinueForHeader = (node) => {
3554
+ if (ts.isFunctionLike(node)) return node;
3555
+ if (
3556
+ node !== visitedBodyBlock &&
3557
+ (ts.isForStatement(node) ||
3558
+ ts.isForInStatement(node) ||
3559
+ ts.isForOfStatement(node) ||
3560
+ ts.isWhileStatement(node) ||
3561
+ ts.isDoStatement(node))
3562
+ ) {
3563
+ return node;
3564
+ }
3565
+ if (ts.isContinueStatement(node) && !node.label) {
3566
+ return ts.factory.createBlock([createHeaderLine(), node], true);
3567
+ }
3568
+ return ts.visitEachChild(node, rewriteContinueForHeader, context);
3569
+ };
3570
+ const bodyStatements = visitedBodyBlock.statements.map((statement) => ts.visitNode(statement, rewriteContinueForHeader));
3571
+ const bodyBlock = ts.factory.updateBlock(visitedBodyBlock, [
3572
+ bodyTracedLine,
3573
+ ...bodyStatements,
3574
+ ]);
2336
3575
 
2337
3576
  return ts.factory.createBlock(
2338
3577
  [
2339
- tracedLine,
2340
- ts.factory.createVariableStatement(
2341
- undefined,
2342
- ts.factory.createVariableDeclarationList(
2343
- [ts.factory.createVariableDeclaration(arrayId, undefined, undefined, forOfStatement.expression)],
2344
- ts.NodeFlags.Const
2345
- )
2346
- ),
2347
- ts.factory.createExpressionStatement(
2348
- ts.factory.createCallExpression(
2349
- ts.factory.createPropertyAccessExpression(
2350
- ts.factory.createIdentifier('__traceRecorder'),
2351
- ts.factory.createIdentifier('deferPendingAccesses')
2352
- ),
2353
- undefined,
2354
- [ts.factory.createNumericLiteral(1)]
2355
- )
2356
- ),
2357
- ts.factory.createForStatement(
2358
- ts.factory.createVariableDeclarationList(
2359
- [ts.factory.createVariableDeclaration(indexId, undefined, undefined, ts.factory.createNumericLiteral(0))],
2360
- ts.NodeFlags.Let
2361
- ),
2362
- ts.factory.createParenthesizedExpression(
2363
- ts.factory.createBinaryExpression(
2364
- tracedLineCall,
2365
- ts.SyntaxKind.CommaToken,
2366
- ts.factory.createBinaryExpression(
2367
- indexId,
2368
- ts.SyntaxKind.LessThanToken,
2369
- ts.factory.createPropertyAccessExpression(arrayId, 'length')
2370
- )
2371
- )
2372
- ),
2373
- ts.factory.createPostfixIncrement(indexId),
2374
- ts.factory.createBlock([bindingStatement, ...visitedBodyBlock.statements], true)
3578
+ ts.factory.updateForOfStatement(
3579
+ forOfStatement,
3580
+ forOfStatement.awaitModifier,
3581
+ forOfStatement.initializer,
3582
+ tracedExpression,
3583
+ bodyBlock
2375
3584
  ),
3585
+ createAttachPendingAccessesStatement(ts),
2376
3586
  ],
2377
3587
  true
2378
3588
  );
@@ -2395,16 +3605,28 @@ function instrumentStatementList(
2395
3605
  ts.getOriginalNode(visitedStatement) ??
2396
3606
  visitedStatement;
2397
3607
  if (shouldTraceStatement(ts, visitedStatement)) {
3608
+ const tracedLineStatement = createTraceLineStatement(
3609
+ ts,
3610
+ sourceFile,
3611
+ originalStatement,
3612
+ variableNames,
3613
+ lineFunctionMap,
3614
+ defaultFunctionName
3615
+ );
3616
+ if (isPostLineStateStatement(ts, sourceFile, originalStatement)) {
3617
+ nextStatements.push(visitedStatement);
3618
+ nextStatements.push(...traceScalarWriteStatementsForVariableStatement(ts, sourceFile, originalStatement));
3619
+ nextStatements.push(tracedLineStatement);
3620
+ continue;
3621
+ }
2398
3622
  nextStatements.push(
2399
- createTraceLineStatement(
2400
- ts,
2401
- sourceFile,
2402
- originalStatement,
2403
- variableNames,
2404
- lineFunctionMap,
2405
- defaultFunctionName
2406
- )
3623
+ tracedLineStatement
2407
3624
  );
3625
+ nextStatements.push(visitedStatement);
3626
+ nextStatements.push(...traceScalarWriteStatementsForVariableStatement(ts, sourceFile, originalStatement));
3627
+ nextStatements.push(...traceScalarWriteStatementsForDestructuringAssignmentStatement(ts, sourceFile, originalStatement));
3628
+ nextStatements.push(createAttachPendingAccessesStatement(ts));
3629
+ continue;
2408
3630
  }
2409
3631
  nextStatements.push(visitedStatement);
2410
3632
  }
@@ -2642,6 +3864,7 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
2642
3864
  );
2643
3865
 
2644
3866
  const variableNames = collectTraceVariableNames(ts, sourceFile);
3867
+ const localVariableNames = new Set(variableNames);
2645
3868
  const effectiveFunctionName =
2646
3869
  typeof traceFunctionName === 'string' && traceFunctionName.length > 0
2647
3870
  ? traceFunctionName
@@ -2662,14 +3885,31 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
2662
3885
  const visitedIndices = tracedOperand.indices.map((indexExpr) => ts.visitNode(indexExpr, visit));
2663
3886
  return createTraceUpdateExpression(
2664
3887
  ts,
3888
+ sourceFile,
3889
+ node,
2665
3890
  tracedOperand.variableName,
2666
3891
  visitedIndices,
2667
3892
  operatorName,
3893
+ ts.isPrefixUnaryExpression(node),
3894
+ tracedOperand.indices
3895
+ );
3896
+ }
3897
+ if (ts.isIdentifier(node.operand) && operatorName) {
3898
+ return createTraceScalarUpdateExpression(
3899
+ ts,
3900
+ sourceFile,
3901
+ node,
3902
+ node.operand.text,
3903
+ operatorName,
2668
3904
  ts.isPrefixUnaryExpression(node)
2669
3905
  );
2670
3906
  }
2671
3907
  }
2672
3908
 
3909
+ if (ts.isThrowStatement(node)) {
3910
+ return createTraceThrowExpression(ts, sourceFile, node);
3911
+ }
3912
+
2673
3913
  if (ts.isBinaryExpression(node)) {
2674
3914
  const tracedLeft = extractTraceableElementAccess(ts, node.left);
2675
3915
  if (tracedLeft && isAssignmentOperatorToken(ts, node.operatorToken.kind)) {
@@ -2678,9 +3918,12 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
2678
3918
  if (node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
2679
3919
  return createTraceWriteIndexExpression(
2680
3920
  ts,
3921
+ sourceFile,
3922
+ node.left,
2681
3923
  tracedLeft.variableName,
2682
3924
  visitedIndices,
2683
- visitedRight
3925
+ visitedRight,
3926
+ tracedLeft.indices
2684
3927
  );
2685
3928
  }
2686
3929
 
@@ -2688,34 +3931,87 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
2688
3931
  if (operatorName) {
2689
3932
  return createTraceAugAssignExpression(
2690
3933
  ts,
3934
+ sourceFile,
3935
+ node.left,
2691
3936
  tracedLeft.variableName,
2692
3937
  visitedIndices,
2693
3938
  operatorName,
2694
- visitedRight
3939
+ visitedRight,
3940
+ tracedLeft.indices
2695
3941
  );
2696
3942
  }
2697
3943
  }
3944
+
3945
+ if (ts.isIdentifier(node.left) && isAssignmentOperatorToken(ts, node.operatorToken.kind)) {
3946
+ const visitedRight = ts.visitNode(node.right, visit);
3947
+ const rewrittenAssignment = ts.factory.updateBinaryExpression(
3948
+ node,
3949
+ node.left,
3950
+ node.operatorToken,
3951
+ visitedRight
3952
+ );
3953
+ return createTraceScalarWriteExpression(
3954
+ ts,
3955
+ sourceFile,
3956
+ node.left,
3957
+ node.left.text,
3958
+ rewrittenAssignment
3959
+ );
3960
+ }
3961
+
3962
+ const tracedPropertyLeft = extractTraceablePropertyAccess(ts, node.left);
3963
+ if (tracedPropertyLeft && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
3964
+ const visitedRight = ts.visitNode(node.right, visit);
3965
+ return createTraceWritePropertyExpression(
3966
+ ts,
3967
+ sourceFile,
3968
+ node.left,
3969
+ tracedPropertyLeft.variableName,
3970
+ tracedPropertyLeft.propertyName,
3971
+ visitedRight
3972
+ );
3973
+ }
2698
3974
  }
2699
3975
 
2700
3976
  if (ts.isCallExpression(node)) {
3977
+ if (isConsoleLogCall(ts, node)) {
3978
+ return createTraceStdoutExpression(ts, sourceFile, node);
3979
+ }
2701
3980
  const tracedCall = extractTraceableMutatingCall(ts, node);
2702
3981
  if (tracedCall) {
2703
3982
  const visitedArgs = node.arguments.map((arg) => ts.visitNode(arg, visit));
2704
- return createTraceMutatingCallExpression(
3983
+ return createTraceMutatingCallExpressionForReceiver(
2705
3984
  ts,
3985
+ sourceFile,
3986
+ node,
2706
3987
  tracedCall.variableName,
3988
+ tracedCall.receiverExpression,
2707
3989
  tracedCall.methodName,
2708
- visitedArgs
3990
+ visitedArgs,
3991
+ tracedCall.indices?.map((indexExpr) => ts.visitNode(indexExpr, visit)) ?? [],
3992
+ tracedCall.indices ?? []
2709
3993
  );
2710
3994
  }
2711
3995
  }
2712
3996
 
3997
+ if (ts.isIfStatement(node)) {
3998
+ const visited = ts.visitEachChild(node, visit, context);
3999
+ return ts.factory.updateIfStatement(
4000
+ visited,
4001
+ wrapTraceCondition(ts, visited.expression, shouldTraceIfStatementPostLine(ts, sourceFile, node)),
4002
+ visited.thenStatement,
4003
+ visited.elseStatement
4004
+ );
4005
+ }
4006
+
2713
4007
  if (ts.isElementAccessExpression(node)) {
4008
+ const parent = node.parent;
2714
4009
  if (
2715
4010
  isNestedElementAccessExpression(ts, node) ||
2716
4011
  isAssignmentLikeLeftOperand(ts, node) ||
2717
4012
  isUpdateExpressionOperand(ts, node) ||
2718
- isDestructuringAssignmentTarget(ts, node)
4013
+ isDestructuringAssignmentTarget(ts, node) ||
4014
+ (parent && ts.isCallExpression(parent) && parent.expression === node)
2719
4015
  ) {
2720
4016
  return ts.visitEachChild(node, visit, context);
2721
4017
  }
@@ -2723,7 +4019,57 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
2723
4019
  const tracedAccess = extractTraceableElementAccess(ts, node);
2724
4020
  if (tracedAccess) {
2725
4021
  const visitedIndices = tracedAccess.indices.map((indexExpr) => ts.visitNode(indexExpr, visit));
2726
- return createTraceReadIndexExpression(ts, tracedAccess.variableName, visitedIndices);
4022
+ return createTraceReadIndexExpression(
4023
+ ts,
4024
+ sourceFile,
4025
+ node,
4026
+ tracedAccess.variableName,
4027
+ visitedIndices,
4028
+ tracedAccess.indices
4029
+ );
4030
+ }
4031
+ }
4032
+
4033
+ if (ts.isPropertyAccessExpression(node)) {
4034
+ const parent = node.parent;
4035
+ const grandparent = parent?.parent;
4036
+ if (
4037
+ isTraceablePropertyWriteLeftOperand(ts, node) ||
4038
+ isDestructuringAssignmentTarget(ts, node) ||
4039
+ (parent && ts.isCallExpression(parent) && parent.expression === node) ||
4040
+ (parent &&
4041
+ ts.isPropertyAccessExpression(parent) &&
4042
+ parent.expression === node &&
4043
+ grandparent &&
4044
+ ts.isCallExpression(grandparent) &&
4045
+ grandparent.expression === parent)
4046
+ ) {
4047
+ return ts.visitEachChild(node, visit, context);
4048
+ }
4049
+
4050
+ const tracedIndexedPropertyAccess = extractTraceableElementAccess(ts, node);
4051
+ if (tracedIndexedPropertyAccess && tracedIndexedPropertyAccess.indices.length > 1) {
4052
+ const visitedIndices = tracedIndexedPropertyAccess.indices.map((indexExpr) => ts.visitNode(indexExpr, visit));
4053
+ return createTraceReadIndexExpression(
4054
+ ts,
4055
+ sourceFile,
4056
+ node,
4057
+ tracedIndexedPropertyAccess.variableName,
4058
+ visitedIndices,
4059
+ tracedIndexedPropertyAccess.indices
4060
+ );
4061
+ }
4062
+
4063
+ const tracedAccess = extractTraceablePropertyAccess(ts, node);
4064
+ if (tracedAccess) {
4065
+ return createTraceReadPropertyExpression(
4066
+ ts,
4067
+ sourceFile,
4068
+ node,
4069
+ tracedAccess.variableName,
4070
+ tracedAccess.propertyName,
4071
+ tracedAccess.scope ?? runtimeScopeForTraceableReceiver(tracedAccess.variableName, localVariableNames)
4072
+ );
2727
4073
  }
2728
4074
  }
2729
4075
 
@@ -2803,6 +4149,7 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
2803
4149
  return rewriteForOfStatementForTracing(
2804
4150
  ts,
2805
4151
  sourceFile,
4152
+ context,
2806
4153
  visited,
2807
4154
  variableNames,
2808
4155
  lineFunctionMap,
@@ -2865,9 +4212,7 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
2865
4212
  function buildScriptExecutionRunner(code) {
2866
4213
  return new Function(
2867
4214
  'console',
2868
- `"use strict";
2869
- ${JAVASCRIPT_RUNTIME_PRELUDE}
2870
- let result;
4215
+ `${JAVASCRIPT_RUNTIME_PRELUDE}
2871
4216
  ${code}
2872
4217
  if (typeof result === 'undefined') {
2873
4218
  return null;
@@ -2879,19 +4224,41 @@ return result;`
2879
4224
  const TRACING_RUNTIME_HELPERS_SOURCE = `
2880
4225
  function __traceNormalizeIndices(__indices, __maxDepth = 2) {
2881
4226
  if (!Array.isArray(__indices) || __indices.length === 0 || __indices.length > __maxDepth) return null;
2882
- if (!__indices.every((__index) => typeof __index === 'number' && Number.isInteger(__index))) return null;
2883
- return __indices.map((__index) => Math.trunc(__index));
4227
+ if (!__indices.every((__index) =>
4228
+ (typeof __index === 'number' && Number.isInteger(__index)) ||
4229
+ (typeof __index === 'string' && __index.length > 0)
4230
+ )) return null;
4231
+ return __indices.map((__index) => typeof __index === 'number' ? Math.trunc(__index) : __index);
4232
+ }
4233
+
4234
+ function __traceNormalizeIndexSources(__indexSources, __pathLength) {
4235
+ if (!Array.isArray(__indexSources) || !Number.isInteger(__pathLength) || __pathLength <= 0) return null;
4236
+ const __normalized = __indexSources.slice(0, __pathLength).map((__source) =>
4237
+ typeof __source === 'string' && __source.length > 0 ? __source : null
4238
+ );
4239
+ while (__normalized.length < __pathLength) __normalized.push(null);
4240
+ return __normalized.some((__source) => __source !== null) ? __normalized : null;
2884
4241
  }
2885
4242
 
2886
4243
  function __traceReadValueAtIndices(__container, __indices) {
2887
4244
  let __current = __container;
2888
4245
  for (const __index of __indices) {
2889
4246
  if (__current === null || __current === undefined) return undefined;
2890
- __current = __current[__index];
4247
+ __current = __traceIsMapLike(__current) ? __current.get(__index) : __current[__index];
2891
4248
  }
2892
4249
  return __current;
2893
4250
  }
2894
4251
 
4252
+ function __traceIsMapLike(__value) {
4253
+ return __value instanceof Map ||
4254
+ (!!__value &&
4255
+ typeof __value === 'object' &&
4256
+ typeof __value.get === 'function' &&
4257
+ typeof __value.set === 'function' &&
4258
+ typeof __value.has === 'function' &&
4259
+ typeof __value.delete === 'function');
4260
+ }
4261
+
2895
4262
  function __traceWriteValueAtIndices(__container, __indices, __value) {
2896
4263
  if (__indices.length === 1) {
2897
4264
  __container[__indices[0]] = __value;
@@ -2907,33 +4274,156 @@ function __traceWriteValueAtIndices(__container, __indices, __value) {
2907
4274
  return __value;
2908
4275
  }
2909
4276
 
2910
- function __traceReadIndex(__varName, __container, __indices) {
4277
+ function __traceReadIndex(__varName, __container, __indices, __indexSources, __location) {
2911
4278
  const __normalized = __traceNormalizeIndices(__indices);
4279
+ const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __normalized?.length ?? 0);
4280
+ const __value = __traceReadValueAtIndices(__container, Array.isArray(__indices) ? __indices : []);
2912
4281
  if (__normalized) {
2913
4282
  __traceRecorder.recordAccess({
2914
4283
  variable: __varName,
2915
4284
  kind: __normalized.length === 2 ? 'cell-read' : 'indexed-read',
2916
4285
  indices: __normalized,
4286
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
2917
4287
  pathDepth: __normalized.length,
4288
+ value: __value,
4289
+ ...__traceNormalizeSourceLocation(__location),
4290
+ });
4291
+ }
4292
+ return __value;
4293
+ }
4294
+
4295
+ function* __traceIterableBind(__varName, __iterable, __bindingName, __location) {
4296
+ if (
4297
+ typeof __varName !== 'string' ||
4298
+ typeof __bindingName !== 'string' ||
4299
+ (__iterable === null || __iterable === undefined) ||
4300
+ typeof __iterable[Symbol.iterator] !== 'function'
4301
+ ) {
4302
+ yield* __iterable;
4303
+ return;
4304
+ }
4305
+ let __index = 0;
4306
+ for (const __value of __iterable) {
4307
+ __traceRecorder.recordAccess({
4308
+ variable: __varName,
4309
+ kind: 'indexed-read',
4310
+ indices: [__index],
4311
+ pathDepth: 1,
4312
+ value: __value,
4313
+ binding: { kind: 'iteration', variable: __bindingName },
4314
+ ...__traceNormalizeSourceLocation(__location),
2918
4315
  });
4316
+ __index += 1;
4317
+ yield __value;
4318
+ }
4319
+ }
4320
+
4321
+ function* __traceIterableBindIndexed(__varName, __iterable, __baseIndices, __indexSources, __bindingName, __location) {
4322
+ if (
4323
+ typeof __varName !== 'string' ||
4324
+ typeof __bindingName !== 'string' ||
4325
+ (__iterable === null || __iterable === undefined) ||
4326
+ typeof __iterable[Symbol.iterator] !== 'function'
4327
+ ) {
4328
+ yield* __iterable;
4329
+ return;
4330
+ }
4331
+ const __base = __traceNormalizeIndices(__baseIndices);
4332
+ const __baseSources = __traceNormalizeIndexSources(__indexSources, __base?.length ?? 0);
4333
+ let __index = 0;
4334
+ for (const __value of __iterable) {
4335
+ if (__base) {
4336
+ const __path = [...__base, __index];
4337
+ const __sources = Array.isArray(__baseSources) ? [...__baseSources, null] : null;
4338
+ __traceRecorder.recordAccess({
4339
+ variable: __varName,
4340
+ kind: __path.length === 2 ? 'cell-read' : 'indexed-read',
4341
+ indices: __path,
4342
+ pathDepth: __path.length,
4343
+ value: __value,
4344
+ ...(Array.isArray(__sources) ? { indexSources: __sources } : {}),
4345
+ binding: { kind: 'iteration', variable: __bindingName },
4346
+ ...__traceNormalizeSourceLocation(__location),
4347
+ });
4348
+ }
4349
+ __index += 1;
4350
+ yield __value;
4351
+ }
4352
+ }
4353
+
4354
+ function __traceIsMetadataProperty(__container, __propertyName) {
4355
+ if (__propertyName === 'length') {
4356
+ return Array.isArray(__container) || typeof __container === 'string';
4357
+ }
4358
+ if (__propertyName === 'size') {
4359
+ return __traceIsMapLike(__container) || __container instanceof Set;
2919
4360
  }
2920
- return __traceReadValueAtIndices(__container, Array.isArray(__indices) ? __indices : []);
4361
+ return false;
4362
+ }
4363
+
4364
+ function __traceNormalizeSourceLocation(__location) {
4365
+ if (!__location || typeof __location !== 'object') return {};
4366
+ const __line = Number(__location.line);
4367
+ const __column = Number(__location.column);
4368
+ return {
4369
+ ...(Number.isFinite(__line) && __line > 0 ? { line: Math.trunc(__line) } : {}),
4370
+ ...(Number.isFinite(__column) && __column >= 0 ? { column: Math.trunc(__column) } : {}),
4371
+ };
4372
+ }
4373
+
4374
+ function __traceReadProperty(__varName, __container, __propertyName, __scopeOrLocation, __maybeLocation) {
4375
+ const __scope = typeof __scopeOrLocation === 'string' ? __scopeOrLocation : undefined;
4376
+ const __location = typeof __scopeOrLocation === 'string' ? __maybeLocation : __scopeOrLocation;
4377
+ __traceRecorder.recordAccess({
4378
+ variable: __varName,
4379
+ kind: 'indexed-read',
4380
+ indices: [__propertyName],
4381
+ pathDepth: 1,
4382
+ ...(__scope ? { scope: __scope } : {}),
4383
+ ...__traceNormalizeSourceLocation(__location),
4384
+ });
4385
+ return __container?.[__propertyName];
2921
4386
  }
2922
4387
 
2923
- function __traceWriteIndex(__varName, __container, __indices, __value) {
4388
+ function __traceWriteIndex(__varName, __container, __indices, __indexSources, __value, __location) {
2924
4389
  const __normalized = __traceNormalizeIndices(__indices);
4390
+ const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __normalized?.length ?? 0);
2925
4391
  const __result = __traceWriteValueAtIndices(__container, Array.isArray(__indices) ? __indices : [], __value);
2926
4392
  if (__normalized) {
2927
4393
  __traceRecorder.recordAccess({
2928
4394
  variable: __varName,
2929
4395
  kind: __normalized.length === 2 ? 'cell-write' : 'indexed-write',
2930
4396
  indices: __normalized,
4397
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
2931
4398
  pathDepth: __normalized.length,
4399
+ value: __result,
4400
+ ...__traceNormalizeSourceLocation(__location),
2932
4401
  });
2933
4402
  }
2934
4403
  return __result;
2935
4404
  }
2936
4405
 
4406
+ function __traceScalarWrite(__varName, __value, __location) {
4407
+ __traceRecorder.recordAccess({
4408
+ variable: __varName,
4409
+ kind: 'indexed-write',
4410
+ value: __value,
4411
+ ...__traceNormalizeSourceLocation(__location),
4412
+ });
4413
+ return __value;
4414
+ }
4415
+
4416
+ function __traceAssignScalar(__varName, __value, __location) {
4417
+ return __traceScalarWrite(__varName, __value, __location);
4418
+ }
4419
+
4420
+ function __traceUpdateScalar(__varName, __update, __current, __isPrefix, __location) {
4421
+ const __result = typeof __update === 'function' ? __update() : undefined;
4422
+ const __value = typeof __current === 'function' ? __current() : __result;
4423
+ __traceScalarWrite(__varName, __value, __location);
4424
+ return __isPrefix ? __value : __result;
4425
+ }
4426
+
2937
4427
  function __traceApplyAugmentedValue(__current, __op, __rhs) {
2938
4428
  switch (__op) {
2939
4429
  case 'add': return __current + __rhs;
@@ -2951,8 +4441,9 @@ function __traceApplyAugmentedValue(__current, __op, __rhs) {
2951
4441
  }
2952
4442
  }
2953
4443
 
2954
- function __traceAugAssignIndex(__varName, __container, __indices, __op, __rhs) {
4444
+ function __traceAugAssignIndex(__varName, __container, __indices, __indexSources, __op, __rhs, __location) {
2955
4445
  const __normalized = __traceNormalizeIndices(__indices);
4446
+ const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __normalized?.length ?? 0);
2956
4447
  const __effectiveIndices = Array.isArray(__indices) ? __indices : [];
2957
4448
  const __current = __traceReadValueAtIndices(__container, __effectiveIndices);
2958
4449
  if (__normalized) {
@@ -2960,7 +4451,9 @@ function __traceAugAssignIndex(__varName, __container, __indices, __op, __rhs) {
2960
4451
  variable: __varName,
2961
4452
  kind: __normalized.length === 2 ? 'cell-read' : 'indexed-read',
2962
4453
  indices: __normalized,
4454
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
2963
4455
  pathDepth: __normalized.length,
4456
+ ...__traceNormalizeSourceLocation(__location),
2964
4457
  });
2965
4458
  }
2966
4459
  const __next = __traceApplyAugmentedValue(__current, __op, __rhs);
@@ -2970,14 +4463,18 @@ function __traceAugAssignIndex(__varName, __container, __indices, __op, __rhs) {
2970
4463
  variable: __varName,
2971
4464
  kind: __normalized.length === 2 ? 'cell-write' : 'indexed-write',
2972
4465
  indices: __normalized,
4466
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
2973
4467
  pathDepth: __normalized.length,
4468
+ value: __next,
4469
+ ...__traceNormalizeSourceLocation(__location),
2974
4470
  });
2975
4471
  }
2976
4472
  return __next;
2977
4473
  }
2978
4474
 
2979
- function __traceUpdateIndex(__varName, __container, __indices, __op, __isPrefix) {
4475
+ function __traceUpdateIndex(__varName, __container, __indices, __indexSources, __op, __isPrefix, __location) {
2980
4476
  const __normalized = __traceNormalizeIndices(__indices);
4477
+ const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __normalized?.length ?? 0);
2981
4478
  const __effectiveIndices = Array.isArray(__indices) ? __indices : [];
2982
4479
  const __current = __traceReadValueAtIndices(__container, __effectiveIndices);
2983
4480
  if (__normalized) {
@@ -2985,7 +4482,9 @@ function __traceUpdateIndex(__varName, __container, __indices, __op, __isPrefix)
2985
4482
  variable: __varName,
2986
4483
  kind: __normalized.length === 2 ? 'cell-read' : 'indexed-read',
2987
4484
  indices: __normalized,
4485
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
2988
4486
  pathDepth: __normalized.length,
4487
+ ...__traceNormalizeSourceLocation(__location),
2989
4488
  });
2990
4489
  }
2991
4490
  const __delta = __op === 'dec' ? -1 : 1;
@@ -2996,20 +4495,111 @@ function __traceUpdateIndex(__varName, __container, __indices, __op, __isPrefix)
2996
4495
  variable: __varName,
2997
4496
  kind: __normalized.length === 2 ? 'cell-write' : 'indexed-write',
2998
4497
  indices: __normalized,
4498
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
2999
4499
  pathDepth: __normalized.length,
4500
+ value: __next,
4501
+ ...__traceNormalizeSourceLocation(__location),
3000
4502
  });
3001
4503
  }
3002
4504
  return __isPrefix ? __next : __current;
3003
4505
  }
3004
4506
 
3005
- function __traceMutatingCall(__varName, __container, __method, ...__args) {
3006
- const __result = __container[__method](...__args);
3007
- if (['push', 'pop', 'shift', 'unshift', 'splice'].includes(__method)) {
4507
+ function __traceNormalizeMethodName(__container, __method, __args) {
4508
+ void __container;
4509
+ void __args;
4510
+ return __method;
4511
+ }
4512
+
4513
+ function __traceStdout(__line, ...__args) {
4514
+ console.log(...__args);
4515
+ __traceRecorder.recordStdout(__line, __args.map((__arg) => String(__arg)).join(' '));
4516
+ }
4517
+
4518
+ function __traceExceptionValue(__line, __error) {
4519
+ __traceRecorder.recordException(__line, __error);
4520
+ return __error;
4521
+ }
4522
+
4523
+ function __traceMutatingCall(__varName, __container, __indices, __indexSources, __method, __location, ...__args) {
4524
+ const __sourceLocation = __traceNormalizeSourceLocation(__location);
4525
+ let __target = __container;
4526
+ for (const __index of __indices || []) {
4527
+ __target = __traceIsMapLike(__target) ? __target.get(__index) : __target?.[__index];
4528
+ }
4529
+ const __mayMutate = ['push', 'pop', 'shift', 'unshift', 'splice', 'set', 'add', 'delete', 'clear'].includes(__method);
4530
+ const __result = __target[__method](...__args);
4531
+ if (['push', 'pop', 'shift', 'unshift', 'splice', 'set', 'get', 'has', 'add', 'delete', 'clear'].includes(__method)) {
4532
+ const __path = __indices || [];
4533
+ const __isMapLike = __traceIsMapLike(__target);
4534
+ const __isNestedMap = __path.length > 0 && __traceIsMapLike(__target);
4535
+ if (__isMapLike && __method === 'set') {
4536
+ const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __path.length + 1);
4537
+ const __targetPath = [...__path, __args[0]];
4538
+ __traceRecorder.recordAccess({
4539
+ variable: __varName,
4540
+ kind: 'indexed-write',
4541
+ indices: __targetPath,
4542
+ pathDepth: __path.length + 1,
4543
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
4544
+ value: serializeValue(__args[1]),
4545
+ ...__sourceLocation,
4546
+ });
4547
+ __traceRecorder.recordAccess({
4548
+ variable: __varName,
4549
+ kind: 'mutating-call',
4550
+ method: __traceNormalizeMethodName(__target, __method, __args),
4551
+ args: __args,
4552
+ indices: __targetPath,
4553
+ pathDepth: __path.length + 1,
4554
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
4555
+ ...__sourceLocation,
4556
+ });
4557
+ return __result;
4558
+ }
4559
+ if (__isMapLike && (__method === 'get' || __method === 'has')) {
4560
+ const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __path.length + 1);
4561
+ __traceRecorder.recordAccess({
4562
+ variable: __varName,
4563
+ kind: 'indexed-read',
4564
+ indices: [...__path, __args[0]],
4565
+ pathDepth: __path.length + 1,
4566
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
4567
+ value: serializeValue(__result),
4568
+ ...__sourceLocation,
4569
+ });
4570
+ return __result;
4571
+ }
4572
+ if (__target instanceof Set && __method === 'has') {
4573
+ __traceRecorder.recordAccess({
4574
+ variable: __varName,
4575
+ kind: 'indexed-read',
4576
+ indices: [...__path, __args[0]],
4577
+ pathDepth: __path.length + 1,
4578
+ ...__sourceLocation,
4579
+ });
4580
+ return __result;
4581
+ }
4582
+ if (__path.length > 0) {
4583
+ const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __path.length);
4584
+ __traceRecorder.recordAccess({
4585
+ variable: __varName,
4586
+ kind: 'indexed-read',
4587
+ indices: __path,
4588
+ pathDepth: __path.length,
4589
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
4590
+ ...__sourceLocation,
4591
+ });
4592
+ }
4593
+ const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __path.length);
3008
4594
  __traceRecorder.recordAccess({
3009
4595
  variable: __varName,
3010
4596
  kind: 'mutating-call',
3011
- method: __method,
3012
- pathDepth: 1,
4597
+ method: __traceNormalizeMethodName(__target, __method, __args),
4598
+ args: __args,
4599
+ indices: __path,
4600
+ pathDepth: __path.length,
4601
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
4602
+ ...__sourceLocation,
3013
4603
  });
3014
4604
  }
3015
4605
  return __result;
@@ -3021,10 +4611,8 @@ function buildScriptTracingRunner(code) {
3021
4611
  'console',
3022
4612
  '__traceRecorder',
3023
4613
  '__traceCtx',
3024
- `"use strict";
3025
- ${JAVASCRIPT_RUNTIME_PRELUDE}
4614
+ `${JAVASCRIPT_RUNTIME_PRELUDE}
3026
4615
  ${TRACING_RUNTIME_HELPERS_SOURCE}
3027
- let result;
3028
4616
  ${code}
3029
4617
  if (typeof result === 'undefined') {
3030
4618
  return null;
@@ -3042,6 +4630,7 @@ function buildFunctionExecutionRunner(code, executionStyle, argNames) {
3042
4630
  `"use strict";
3043
4631
  ${JAVASCRIPT_RUNTIME_PRELUDE}
3044
4632
  ${code}
4633
+ ${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
3045
4634
  let __target;
3046
4635
  try {
3047
4636
  __target = eval(__functionName);
@@ -3051,7 +4640,7 @@ try {
3051
4640
  if (typeof __target !== 'function') {
3052
4641
  throw new Error('Function "' + __functionName + '" not found');
3053
4642
  }
3054
- return __target(${argNames.join(', ')});`
4643
+ return __target(${argNames.map((name) => `__tracecodeMaterializeCustomObject(${name})`).join(', ')});`
3055
4644
  );
3056
4645
  }
3057
4646
 
@@ -3063,6 +4652,7 @@ return __target(${argNames.join(', ')});`
3063
4652
  `"use strict";
3064
4653
  ${JAVASCRIPT_RUNTIME_PRELUDE}
3065
4654
  ${code}
4655
+ ${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
3066
4656
  if (typeof Solution !== 'function') {
3067
4657
  throw new Error('Class "Solution" not found');
3068
4658
  }
@@ -3071,7 +4661,7 @@ const __method = __solver[__functionName];
3071
4661
  if (typeof __method !== 'function') {
3072
4662
  throw new Error('Method "Solution.' + __functionName + '" not found');
3073
4663
  }
3074
- return __method.call(__solver, ${argNames.join(', ')});`
4664
+ return __method.call(__solver, ${argNames.map((name) => `__tracecodeMaterializeCustomObject(${name})`).join(', ')});`
3075
4665
  );
3076
4666
  }
3077
4667
 
@@ -3084,6 +4674,7 @@ return __method.call(__solver, ${argNames.join(', ')});`
3084
4674
  `"use strict";
3085
4675
  ${JAVASCRIPT_RUNTIME_PRELUDE}
3086
4676
  ${code}
4677
+ ${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
3087
4678
  if (!Array.isArray(__operations) || !Array.isArray(__arguments)) {
3088
4679
  throw new Error('ops-class execution requires inputs.operations and inputs.arguments (or ops/args)');
3089
4680
  }
@@ -3110,6 +4701,7 @@ for (let __i = 0; __i < __operations.length; __i++) {
3110
4701
  if (!Array.isArray(__callArgs)) {
3111
4702
  __callArgs = [__callArgs];
3112
4703
  }
4704
+ __callArgs = __callArgs.map((__arg) => __tracecodeMaterializeCustomObject(__arg));
3113
4705
  if (__i === 0) {
3114
4706
  __instance = new __targetClass(...__callArgs);
3115
4707
  __out.push(null);
@@ -3139,6 +4731,7 @@ function buildFunctionTracingRunner(code, executionStyle, argNames) {
3139
4731
  ${JAVASCRIPT_RUNTIME_PRELUDE}
3140
4732
  ${TRACING_RUNTIME_HELPERS_SOURCE}
3141
4733
  ${code}
4734
+ ${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
3142
4735
  let __target;
3143
4736
  try {
3144
4737
  __target = eval(__functionName);
@@ -3148,7 +4741,7 @@ try {
3148
4741
  if (typeof __target !== 'function') {
3149
4742
  throw new Error('Function "' + __functionName + '" not found');
3150
4743
  }
3151
- return __target(${argNames.join(', ')});`
4744
+ return __target(${argNames.map((name) => `__tracecodeMaterializeCustomObject(${name})`).join(', ')});`
3152
4745
  );
3153
4746
  }
3154
4747
 
@@ -3163,6 +4756,7 @@ return __target(${argNames.join(', ')});`
3163
4756
  ${JAVASCRIPT_RUNTIME_PRELUDE}
3164
4757
  ${TRACING_RUNTIME_HELPERS_SOURCE}
3165
4758
  ${code}
4759
+ ${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
3166
4760
  if (typeof Solution !== 'function') {
3167
4761
  throw new Error('Class "Solution" not found');
3168
4762
  }
@@ -3171,7 +4765,7 @@ const __method = __solver[__functionName];
3171
4765
  if (typeof __method !== 'function') {
3172
4766
  throw new Error('Method "Solution.' + __functionName + '" not found');
3173
4767
  }
3174
- return __method.call(__solver, ${argNames.join(', ')});`
4768
+ return __method.call(__solver, ${argNames.map((name) => `__tracecodeMaterializeCustomObject(${name})`).join(', ')});`
3175
4769
  );
3176
4770
  }
3177
4771
 
@@ -3187,6 +4781,7 @@ return __method.call(__solver, ${argNames.join(', ')});`
3187
4781
  ${JAVASCRIPT_RUNTIME_PRELUDE}
3188
4782
  ${TRACING_RUNTIME_HELPERS_SOURCE}
3189
4783
  ${code}
4784
+ ${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
3190
4785
  if (!Array.isArray(__operations) || !Array.isArray(__arguments)) {
3191
4786
  throw new Error('ops-class execution requires inputs.operations and inputs.arguments (or ops/args)');
3192
4787
  }
@@ -3213,6 +4808,7 @@ for (let __i = 0; __i < __operations.length; __i++) {
3213
4808
  if (!Array.isArray(__callArgs)) {
3214
4809
  __callArgs = [__callArgs];
3215
4810
  }
4811
+ __callArgs = __callArgs.map((__arg) => __tracecodeMaterializeCustomObject(__arg));
3216
4812
  if (__i === 0) {
3217
4813
  __instance = new __targetClass(...__callArgs);
3218
4814
  __out.push(null);
@@ -3291,7 +4887,7 @@ async function executeCode(payload) {
3291
4887
 
3292
4888
  return {
3293
4889
  success: true,
3294
- output: serializeValue(output),
4890
+ output: serializeOutputValue(output),
3295
4891
  consoleOutput,
3296
4892
  };
3297
4893
  } catch (error) {
@@ -3347,11 +4943,11 @@ async function executeWithTracing(payload) {
3347
4943
  instrumentedCode = await instrumentCodeForTracing(executableCode, language, traceFunctionName);
3348
4944
  }
3349
4945
  } catch (instrumentationError) {
3350
- if (WORKER_DEBUG) {
3351
- const message =
3352
- instrumentationError instanceof Error ? instrumentationError.message : String(instrumentationError);
3353
- console.warn('[JavaScriptWorker] trace instrumentation failed, using synthetic fallback:', message);
3354
- }
4946
+ const message =
4947
+ instrumentationError instanceof Error ? instrumentationError.message : String(instrumentationError);
4948
+ emitRuntimeDiagnostic('warn', 'trace-instrumentation-fallback', 'Trace instrumentation failed; using synthetic fallback.', {
4949
+ message,
4950
+ });
3355
4951
  }
3356
4952
 
3357
4953
  if (!instrumentedCode) {
@@ -3359,27 +4955,28 @@ async function executeWithTracing(payload) {
3359
4955
  const executionTimeMs = performanceNow() - startedAt;
3360
4956
 
3361
4957
  if (!fallbackResult.success) {
4958
+ const trace = createEmptyRuntimeTrace(language);
3362
4959
  return {
3363
4960
  success: false,
3364
4961
  error: fallbackResult.error,
3365
4962
  errorLine: fallbackResult.errorLine,
3366
- trace: [],
4963
+ trace,
3367
4964
  executionTimeMs,
3368
4965
  consoleOutput: fallbackResult.consoleOutput ?? [],
3369
- lineEventCount: 0,
3370
- traceStepCount: 0,
4966
+ lineEventCount: trace.lineEventCount,
4967
+ traceStepCount: trace.traceStepCount,
3371
4968
  };
3372
4969
  }
3373
4970
 
3374
- const syntheticTrace = createSyntheticTrace(payload, fallbackResult);
4971
+ const trace = createSyntheticRuntimeTrace(payload, fallbackResult, language);
3375
4972
  return {
3376
4973
  success: true,
3377
4974
  output: fallbackResult.output,
3378
- trace: syntheticTrace,
4975
+ trace,
3379
4976
  executionTimeMs,
3380
4977
  consoleOutput: fallbackResult.consoleOutput ?? [],
3381
- lineEventCount: syntheticTrace.filter((step) => step.event === 'line').length,
3382
- traceStepCount: syntheticTrace.length,
4978
+ lineEventCount: trace.lineEventCount,
4979
+ traceStepCount: trace.traceStepCount,
3383
4980
  };
3384
4981
  }
3385
4982
 
@@ -3422,21 +5019,23 @@ async function executeWithTracing(payload) {
3422
5019
  );
3423
5020
  }
3424
5021
 
3425
- const serializedOutput = serializeValue(output);
5022
+ const serializedTraceOutput = serializeValue(output);
5023
+ const serializedOutput = serializeOutputValue(output);
3426
5024
  if (!hasNamedFunction) {
3427
5025
  traceRecorder.popToFunction(traceFunctionName);
3428
- traceRecorder.recordReturn(traceLineBounds.endLine, serializedOutput, traceFunctionName);
5026
+ traceRecorder.recordReturn(traceLineBounds.endLine, serializedTraceOutput, traceFunctionName);
3429
5027
  }
3430
5028
 
3431
5029
  const executionTimeMs = performanceNow() - startedAt;
5030
+ const trace = traceRecorder.getRuntimeTrace(language, `${language}:run`, defaultRuntimeTraceFile(language));
3432
5031
  return {
3433
5032
  success: true,
3434
5033
  output: serializedOutput,
3435
- trace: traceRecorder.getTrace(),
5034
+ trace,
3436
5035
  executionTimeMs,
3437
5036
  consoleOutput,
3438
- lineEventCount: traceRecorder.getLineEventCount(),
3439
- traceStepCount: traceRecorder.getTraceStepCount(),
5037
+ lineEventCount: trace.lineEventCount,
5038
+ traceStepCount: trace.traceStepCount,
3440
5039
  traceLimitExceeded: traceRecorder.isTraceLimitExceeded(),
3441
5040
  timeoutReason: traceRecorder.getTimeoutReason(),
3442
5041
  };
@@ -3461,16 +5060,17 @@ async function executeWithTracing(payload) {
3461
5060
  traceRecorder.recordException(traceErrorLine, message, traceFunctionName);
3462
5061
  }
3463
5062
 
5063
+ const trace = traceRecorder.getRuntimeTrace(language, `${language}:run`, defaultRuntimeTraceFile(language));
3464
5064
  return {
3465
5065
  success: false,
3466
5066
  output: null,
3467
5067
  error: message,
3468
5068
  errorLine,
3469
- trace: traceRecorder.getTrace(),
5069
+ trace,
3470
5070
  executionTimeMs,
3471
5071
  consoleOutput,
3472
- lineEventCount: traceRecorder.getLineEventCount(),
3473
- traceStepCount: traceRecorder.getTraceStepCount(),
5072
+ lineEventCount: trace.lineEventCount,
5073
+ traceStepCount: trace.traceStepCount,
3474
5074
  traceLimitExceeded,
3475
5075
  timeoutReason,
3476
5076
  };
@@ -3537,11 +5137,37 @@ async function initRuntime() {
3537
5137
 
3538
5138
  isLoading = true;
3539
5139
  const startedAt = performanceNow();
5140
+ ensureJavaScriptLibraries();
3540
5141
  isInitialized = true;
3541
5142
  isLoading = false;
3542
5143
  return { success: true, loadTimeMs: performanceNow() - startedAt };
3543
5144
  }
3544
5145
 
5146
+ async function warmRuntime(payload = {}) {
5147
+ const startedAt = performanceNow();
5148
+ const initStartedAt = performanceNow();
5149
+ await initRuntime();
5150
+ const initMs = performanceNow() - initStartedAt;
5151
+ let compilerWarmupMs = 0;
5152
+
5153
+ if (payload?.language === 'typescript' || payload?.preloadTypeScriptCompiler === true) {
5154
+ const compilerStartedAt = performanceNow();
5155
+ await ensureTypeScriptCompiler();
5156
+ compilerWarmupMs = performanceNow() - compilerStartedAt;
5157
+ }
5158
+
5159
+ const totalMs = performanceNow() - startedAt;
5160
+ return {
5161
+ success: true,
5162
+ loadTimeMs: totalMs,
5163
+ timings: {
5164
+ totalMs,
5165
+ initMs,
5166
+ warmupMs: compilerWarmupMs,
5167
+ },
5168
+ };
5169
+ }
5170
+
3545
5171
  async function processMessage(data) {
3546
5172
  const { id, type, payload } = data;
3547
5173
 
@@ -3553,6 +5179,12 @@ async function processMessage(data) {
3553
5179
  break;
3554
5180
  }
3555
5181
 
5182
+ case 'warmup': {
5183
+ const result = await warmRuntime(payload);
5184
+ self.postMessage({ id, type: 'warmup-result', payload: result });
5185
+ break;
5186
+ }
5187
+
3556
5188
  case 'execute-with-tracing': {
3557
5189
  const result = await executeWithTracing(payload);
3558
5190
  self.postMessage({ id, type: 'execute-result', payload: result });
@@ -3616,7 +5248,5 @@ self.onmessage = function(event) {
3616
5248
  });
3617
5249
  };
3618
5250
 
3619
- if (WORKER_DEBUG) {
3620
- console.log('[JavaScriptWorker] ready');
3621
- }
5251
+ emitRuntimeDiagnostic('info', 'worker-ready', 'JavaScript worker is ready.');
3622
5252
  self.postMessage({ type: 'worker-ready' });