@tracecode/harness 0.6.6 → 0.7.0-beta8

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 +6169 -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 +907 -0
  84. package/workers/java/java-worker.js +2161 -177
  85. package/workers/java/src/harness/browser/JavaRewriteLibrary.java +1659 -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 +1414 -0
  91. package/workers/javascript/javascript-libraries-entry.js +71 -0
  92. package/workers/javascript/javascript-worker.js +2055 -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,41 @@ 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
+ createHeaderLine(),
3586
+ createAttachPendingAccessesStatement(ts),
2376
3587
  ],
2377
3588
  true
2378
3589
  );
@@ -2395,16 +3606,28 @@ function instrumentStatementList(
2395
3606
  ts.getOriginalNode(visitedStatement) ??
2396
3607
  visitedStatement;
2397
3608
  if (shouldTraceStatement(ts, visitedStatement)) {
3609
+ const tracedLineStatement = createTraceLineStatement(
3610
+ ts,
3611
+ sourceFile,
3612
+ originalStatement,
3613
+ variableNames,
3614
+ lineFunctionMap,
3615
+ defaultFunctionName
3616
+ );
3617
+ if (isPostLineStateStatement(ts, sourceFile, originalStatement)) {
3618
+ nextStatements.push(visitedStatement);
3619
+ nextStatements.push(...traceScalarWriteStatementsForVariableStatement(ts, sourceFile, originalStatement));
3620
+ nextStatements.push(tracedLineStatement);
3621
+ continue;
3622
+ }
2398
3623
  nextStatements.push(
2399
- createTraceLineStatement(
2400
- ts,
2401
- sourceFile,
2402
- originalStatement,
2403
- variableNames,
2404
- lineFunctionMap,
2405
- defaultFunctionName
2406
- )
3624
+ tracedLineStatement
2407
3625
  );
3626
+ nextStatements.push(visitedStatement);
3627
+ nextStatements.push(...traceScalarWriteStatementsForVariableStatement(ts, sourceFile, originalStatement));
3628
+ nextStatements.push(...traceScalarWriteStatementsForDestructuringAssignmentStatement(ts, sourceFile, originalStatement));
3629
+ nextStatements.push(createAttachPendingAccessesStatement(ts));
3630
+ continue;
2408
3631
  }
2409
3632
  nextStatements.push(visitedStatement);
2410
3633
  }
@@ -2642,6 +3865,7 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
2642
3865
  );
2643
3866
 
2644
3867
  const variableNames = collectTraceVariableNames(ts, sourceFile);
3868
+ const localVariableNames = new Set(variableNames);
2645
3869
  const effectiveFunctionName =
2646
3870
  typeof traceFunctionName === 'string' && traceFunctionName.length > 0
2647
3871
  ? traceFunctionName
@@ -2662,14 +3886,31 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
2662
3886
  const visitedIndices = tracedOperand.indices.map((indexExpr) => ts.visitNode(indexExpr, visit));
2663
3887
  return createTraceUpdateExpression(
2664
3888
  ts,
3889
+ sourceFile,
3890
+ node,
2665
3891
  tracedOperand.variableName,
2666
3892
  visitedIndices,
2667
3893
  operatorName,
3894
+ ts.isPrefixUnaryExpression(node),
3895
+ tracedOperand.indices
3896
+ );
3897
+ }
3898
+ if (ts.isIdentifier(node.operand) && operatorName) {
3899
+ return createTraceScalarUpdateExpression(
3900
+ ts,
3901
+ sourceFile,
3902
+ node,
3903
+ node.operand.text,
3904
+ operatorName,
2668
3905
  ts.isPrefixUnaryExpression(node)
2669
3906
  );
2670
3907
  }
2671
3908
  }
2672
3909
 
3910
+ if (ts.isThrowStatement(node)) {
3911
+ return createTraceThrowExpression(ts, sourceFile, node);
3912
+ }
3913
+
2673
3914
  if (ts.isBinaryExpression(node)) {
2674
3915
  const tracedLeft = extractTraceableElementAccess(ts, node.left);
2675
3916
  if (tracedLeft && isAssignmentOperatorToken(ts, node.operatorToken.kind)) {
@@ -2678,9 +3919,12 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
2678
3919
  if (node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
2679
3920
  return createTraceWriteIndexExpression(
2680
3921
  ts,
3922
+ sourceFile,
3923
+ node.left,
2681
3924
  tracedLeft.variableName,
2682
3925
  visitedIndices,
2683
- visitedRight
3926
+ visitedRight,
3927
+ tracedLeft.indices
2684
3928
  );
2685
3929
  }
2686
3930
 
@@ -2688,34 +3932,87 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
2688
3932
  if (operatorName) {
2689
3933
  return createTraceAugAssignExpression(
2690
3934
  ts,
3935
+ sourceFile,
3936
+ node.left,
2691
3937
  tracedLeft.variableName,
2692
3938
  visitedIndices,
2693
3939
  operatorName,
2694
- visitedRight
3940
+ visitedRight,
3941
+ tracedLeft.indices
2695
3942
  );
2696
3943
  }
2697
3944
  }
3945
+
3946
+ if (ts.isIdentifier(node.left) && isAssignmentOperatorToken(ts, node.operatorToken.kind)) {
3947
+ const visitedRight = ts.visitNode(node.right, visit);
3948
+ const rewrittenAssignment = ts.factory.updateBinaryExpression(
3949
+ node,
3950
+ node.left,
3951
+ node.operatorToken,
3952
+ visitedRight
3953
+ );
3954
+ return createTraceScalarWriteExpression(
3955
+ ts,
3956
+ sourceFile,
3957
+ node.left,
3958
+ node.left.text,
3959
+ rewrittenAssignment
3960
+ );
3961
+ }
3962
+
3963
+ const tracedPropertyLeft = extractTraceablePropertyAccess(ts, node.left);
3964
+ if (tracedPropertyLeft && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
3965
+ const visitedRight = ts.visitNode(node.right, visit);
3966
+ return createTraceWritePropertyExpression(
3967
+ ts,
3968
+ sourceFile,
3969
+ node.left,
3970
+ tracedPropertyLeft.variableName,
3971
+ tracedPropertyLeft.propertyName,
3972
+ visitedRight
3973
+ );
3974
+ }
2698
3975
  }
2699
3976
 
2700
3977
  if (ts.isCallExpression(node)) {
3978
+ if (isConsoleLogCall(ts, node)) {
3979
+ return createTraceStdoutExpression(ts, sourceFile, node);
3980
+ }
2701
3981
  const tracedCall = extractTraceableMutatingCall(ts, node);
2702
3982
  if (tracedCall) {
2703
3983
  const visitedArgs = node.arguments.map((arg) => ts.visitNode(arg, visit));
2704
- return createTraceMutatingCallExpression(
3984
+ return createTraceMutatingCallExpressionForReceiver(
2705
3985
  ts,
3986
+ sourceFile,
3987
+ node,
2706
3988
  tracedCall.variableName,
3989
+ tracedCall.receiverExpression,
2707
3990
  tracedCall.methodName,
2708
- visitedArgs
3991
+ visitedArgs,
3992
+ tracedCall.indices?.map((indexExpr) => ts.visitNode(indexExpr, visit)) ?? [],
3993
+ tracedCall.indices ?? []
2709
3994
  );
2710
3995
  }
2711
3996
  }
2712
3997
 
3998
+ if (ts.isIfStatement(node)) {
3999
+ const visited = ts.visitEachChild(node, visit, context);
4000
+ return ts.factory.updateIfStatement(
4001
+ visited,
4002
+ wrapTraceCondition(ts, visited.expression, shouldTraceIfStatementPostLine(ts, sourceFile, node)),
4003
+ visited.thenStatement,
4004
+ visited.elseStatement
4005
+ );
4006
+ }
4007
+
2713
4008
  if (ts.isElementAccessExpression(node)) {
4009
+ const parent = node.parent;
2714
4010
  if (
2715
4011
  isNestedElementAccessExpression(ts, node) ||
2716
4012
  isAssignmentLikeLeftOperand(ts, node) ||
2717
4013
  isUpdateExpressionOperand(ts, node) ||
2718
- isDestructuringAssignmentTarget(ts, node)
4014
+ isDestructuringAssignmentTarget(ts, node) ||
4015
+ (parent && ts.isCallExpression(parent) && parent.expression === node)
2719
4016
  ) {
2720
4017
  return ts.visitEachChild(node, visit, context);
2721
4018
  }
@@ -2723,7 +4020,57 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
2723
4020
  const tracedAccess = extractTraceableElementAccess(ts, node);
2724
4021
  if (tracedAccess) {
2725
4022
  const visitedIndices = tracedAccess.indices.map((indexExpr) => ts.visitNode(indexExpr, visit));
2726
- return createTraceReadIndexExpression(ts, tracedAccess.variableName, visitedIndices);
4023
+ return createTraceReadIndexExpression(
4024
+ ts,
4025
+ sourceFile,
4026
+ node,
4027
+ tracedAccess.variableName,
4028
+ visitedIndices,
4029
+ tracedAccess.indices
4030
+ );
4031
+ }
4032
+ }
4033
+
4034
+ if (ts.isPropertyAccessExpression(node)) {
4035
+ const parent = node.parent;
4036
+ const grandparent = parent?.parent;
4037
+ if (
4038
+ isTraceablePropertyWriteLeftOperand(ts, node) ||
4039
+ isDestructuringAssignmentTarget(ts, node) ||
4040
+ (parent && ts.isCallExpression(parent) && parent.expression === node) ||
4041
+ (parent &&
4042
+ ts.isPropertyAccessExpression(parent) &&
4043
+ parent.expression === node &&
4044
+ grandparent &&
4045
+ ts.isCallExpression(grandparent) &&
4046
+ grandparent.expression === parent)
4047
+ ) {
4048
+ return ts.visitEachChild(node, visit, context);
4049
+ }
4050
+
4051
+ const tracedIndexedPropertyAccess = extractTraceableElementAccess(ts, node);
4052
+ if (tracedIndexedPropertyAccess && tracedIndexedPropertyAccess.indices.length > 1) {
4053
+ const visitedIndices = tracedIndexedPropertyAccess.indices.map((indexExpr) => ts.visitNode(indexExpr, visit));
4054
+ return createTraceReadIndexExpression(
4055
+ ts,
4056
+ sourceFile,
4057
+ node,
4058
+ tracedIndexedPropertyAccess.variableName,
4059
+ visitedIndices,
4060
+ tracedIndexedPropertyAccess.indices
4061
+ );
4062
+ }
4063
+
4064
+ const tracedAccess = extractTraceablePropertyAccess(ts, node);
4065
+ if (tracedAccess) {
4066
+ return createTraceReadPropertyExpression(
4067
+ ts,
4068
+ sourceFile,
4069
+ node,
4070
+ tracedAccess.variableName,
4071
+ tracedAccess.propertyName,
4072
+ tracedAccess.scope ?? runtimeScopeForTraceableReceiver(tracedAccess.variableName, localVariableNames)
4073
+ );
2727
4074
  }
2728
4075
  }
2729
4076
 
@@ -2803,6 +4150,7 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
2803
4150
  return rewriteForOfStatementForTracing(
2804
4151
  ts,
2805
4152
  sourceFile,
4153
+ context,
2806
4154
  visited,
2807
4155
  variableNames,
2808
4156
  lineFunctionMap,
@@ -2865,9 +4213,7 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
2865
4213
  function buildScriptExecutionRunner(code) {
2866
4214
  return new Function(
2867
4215
  'console',
2868
- `"use strict";
2869
- ${JAVASCRIPT_RUNTIME_PRELUDE}
2870
- let result;
4216
+ `${JAVASCRIPT_RUNTIME_PRELUDE}
2871
4217
  ${code}
2872
4218
  if (typeof result === 'undefined') {
2873
4219
  return null;
@@ -2879,19 +4225,41 @@ return result;`
2879
4225
  const TRACING_RUNTIME_HELPERS_SOURCE = `
2880
4226
  function __traceNormalizeIndices(__indices, __maxDepth = 2) {
2881
4227
  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));
4228
+ if (!__indices.every((__index) =>
4229
+ (typeof __index === 'number' && Number.isInteger(__index)) ||
4230
+ (typeof __index === 'string' && __index.length > 0)
4231
+ )) return null;
4232
+ return __indices.map((__index) => typeof __index === 'number' ? Math.trunc(__index) : __index);
4233
+ }
4234
+
4235
+ function __traceNormalizeIndexSources(__indexSources, __pathLength) {
4236
+ if (!Array.isArray(__indexSources) || !Number.isInteger(__pathLength) || __pathLength <= 0) return null;
4237
+ const __normalized = __indexSources.slice(0, __pathLength).map((__source) =>
4238
+ typeof __source === 'string' && __source.length > 0 ? __source : null
4239
+ );
4240
+ while (__normalized.length < __pathLength) __normalized.push(null);
4241
+ return __normalized.some((__source) => __source !== null) ? __normalized : null;
2884
4242
  }
2885
4243
 
2886
4244
  function __traceReadValueAtIndices(__container, __indices) {
2887
4245
  let __current = __container;
2888
4246
  for (const __index of __indices) {
2889
4247
  if (__current === null || __current === undefined) return undefined;
2890
- __current = __current[__index];
4248
+ __current = __traceIsMapLike(__current) ? __current.get(__index) : __current[__index];
2891
4249
  }
2892
4250
  return __current;
2893
4251
  }
2894
4252
 
4253
+ function __traceIsMapLike(__value) {
4254
+ return __value instanceof Map ||
4255
+ (!!__value &&
4256
+ typeof __value === 'object' &&
4257
+ typeof __value.get === 'function' &&
4258
+ typeof __value.set === 'function' &&
4259
+ typeof __value.has === 'function' &&
4260
+ typeof __value.delete === 'function');
4261
+ }
4262
+
2895
4263
  function __traceWriteValueAtIndices(__container, __indices, __value) {
2896
4264
  if (__indices.length === 1) {
2897
4265
  __container[__indices[0]] = __value;
@@ -2907,33 +4275,156 @@ function __traceWriteValueAtIndices(__container, __indices, __value) {
2907
4275
  return __value;
2908
4276
  }
2909
4277
 
2910
- function __traceReadIndex(__varName, __container, __indices) {
4278
+ function __traceReadIndex(__varName, __container, __indices, __indexSources, __location) {
2911
4279
  const __normalized = __traceNormalizeIndices(__indices);
4280
+ const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __normalized?.length ?? 0);
4281
+ const __value = __traceReadValueAtIndices(__container, Array.isArray(__indices) ? __indices : []);
2912
4282
  if (__normalized) {
2913
4283
  __traceRecorder.recordAccess({
2914
4284
  variable: __varName,
2915
4285
  kind: __normalized.length === 2 ? 'cell-read' : 'indexed-read',
2916
4286
  indices: __normalized,
4287
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
2917
4288
  pathDepth: __normalized.length,
4289
+ value: __value,
4290
+ ...__traceNormalizeSourceLocation(__location),
4291
+ });
4292
+ }
4293
+ return __value;
4294
+ }
4295
+
4296
+ function* __traceIterableBind(__varName, __iterable, __bindingName, __location) {
4297
+ if (
4298
+ typeof __varName !== 'string' ||
4299
+ typeof __bindingName !== 'string' ||
4300
+ (__iterable === null || __iterable === undefined) ||
4301
+ typeof __iterable[Symbol.iterator] !== 'function'
4302
+ ) {
4303
+ yield* __iterable;
4304
+ return;
4305
+ }
4306
+ let __index = 0;
4307
+ for (const __value of __iterable) {
4308
+ __traceRecorder.recordAccess({
4309
+ variable: __varName,
4310
+ kind: 'indexed-read',
4311
+ indices: [__index],
4312
+ pathDepth: 1,
4313
+ value: __value,
4314
+ binding: { kind: 'iteration', variable: __bindingName },
4315
+ ...__traceNormalizeSourceLocation(__location),
2918
4316
  });
4317
+ __index += 1;
4318
+ yield __value;
4319
+ }
4320
+ }
4321
+
4322
+ function* __traceIterableBindIndexed(__varName, __iterable, __baseIndices, __indexSources, __bindingName, __location) {
4323
+ if (
4324
+ typeof __varName !== 'string' ||
4325
+ typeof __bindingName !== 'string' ||
4326
+ (__iterable === null || __iterable === undefined) ||
4327
+ typeof __iterable[Symbol.iterator] !== 'function'
4328
+ ) {
4329
+ yield* __iterable;
4330
+ return;
4331
+ }
4332
+ const __base = __traceNormalizeIndices(__baseIndices);
4333
+ const __baseSources = __traceNormalizeIndexSources(__indexSources, __base?.length ?? 0);
4334
+ let __index = 0;
4335
+ for (const __value of __iterable) {
4336
+ if (__base) {
4337
+ const __path = [...__base, __index];
4338
+ const __sources = Array.isArray(__baseSources) ? [...__baseSources, null] : null;
4339
+ __traceRecorder.recordAccess({
4340
+ variable: __varName,
4341
+ kind: __path.length === 2 ? 'cell-read' : 'indexed-read',
4342
+ indices: __path,
4343
+ pathDepth: __path.length,
4344
+ value: __value,
4345
+ ...(Array.isArray(__sources) ? { indexSources: __sources } : {}),
4346
+ binding: { kind: 'iteration', variable: __bindingName },
4347
+ ...__traceNormalizeSourceLocation(__location),
4348
+ });
4349
+ }
4350
+ __index += 1;
4351
+ yield __value;
4352
+ }
4353
+ }
4354
+
4355
+ function __traceIsMetadataProperty(__container, __propertyName) {
4356
+ if (__propertyName === 'length') {
4357
+ return Array.isArray(__container) || typeof __container === 'string';
4358
+ }
4359
+ if (__propertyName === 'size') {
4360
+ return __traceIsMapLike(__container) || __container instanceof Set;
2919
4361
  }
2920
- return __traceReadValueAtIndices(__container, Array.isArray(__indices) ? __indices : []);
4362
+ return false;
4363
+ }
4364
+
4365
+ function __traceNormalizeSourceLocation(__location) {
4366
+ if (!__location || typeof __location !== 'object') return {};
4367
+ const __line = Number(__location.line);
4368
+ const __column = Number(__location.column);
4369
+ return {
4370
+ ...(Number.isFinite(__line) && __line > 0 ? { line: Math.trunc(__line) } : {}),
4371
+ ...(Number.isFinite(__column) && __column >= 0 ? { column: Math.trunc(__column) } : {}),
4372
+ };
4373
+ }
4374
+
4375
+ function __traceReadProperty(__varName, __container, __propertyName, __scopeOrLocation, __maybeLocation) {
4376
+ const __scope = typeof __scopeOrLocation === 'string' ? __scopeOrLocation : undefined;
4377
+ const __location = typeof __scopeOrLocation === 'string' ? __maybeLocation : __scopeOrLocation;
4378
+ __traceRecorder.recordAccess({
4379
+ variable: __varName,
4380
+ kind: 'indexed-read',
4381
+ indices: [__propertyName],
4382
+ pathDepth: 1,
4383
+ ...(__scope ? { scope: __scope } : {}),
4384
+ ...__traceNormalizeSourceLocation(__location),
4385
+ });
4386
+ return __container?.[__propertyName];
2921
4387
  }
2922
4388
 
2923
- function __traceWriteIndex(__varName, __container, __indices, __value) {
4389
+ function __traceWriteIndex(__varName, __container, __indices, __indexSources, __value, __location) {
2924
4390
  const __normalized = __traceNormalizeIndices(__indices);
4391
+ const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __normalized?.length ?? 0);
2925
4392
  const __result = __traceWriteValueAtIndices(__container, Array.isArray(__indices) ? __indices : [], __value);
2926
4393
  if (__normalized) {
2927
4394
  __traceRecorder.recordAccess({
2928
4395
  variable: __varName,
2929
4396
  kind: __normalized.length === 2 ? 'cell-write' : 'indexed-write',
2930
4397
  indices: __normalized,
4398
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
2931
4399
  pathDepth: __normalized.length,
4400
+ value: __result,
4401
+ ...__traceNormalizeSourceLocation(__location),
2932
4402
  });
2933
4403
  }
2934
4404
  return __result;
2935
4405
  }
2936
4406
 
4407
+ function __traceScalarWrite(__varName, __value, __location) {
4408
+ __traceRecorder.recordAccess({
4409
+ variable: __varName,
4410
+ kind: 'indexed-write',
4411
+ value: __value,
4412
+ ...__traceNormalizeSourceLocation(__location),
4413
+ });
4414
+ return __value;
4415
+ }
4416
+
4417
+ function __traceAssignScalar(__varName, __value, __location) {
4418
+ return __traceScalarWrite(__varName, __value, __location);
4419
+ }
4420
+
4421
+ function __traceUpdateScalar(__varName, __update, __current, __isPrefix, __location) {
4422
+ const __result = typeof __update === 'function' ? __update() : undefined;
4423
+ const __value = typeof __current === 'function' ? __current() : __result;
4424
+ __traceScalarWrite(__varName, __value, __location);
4425
+ return __isPrefix ? __value : __result;
4426
+ }
4427
+
2937
4428
  function __traceApplyAugmentedValue(__current, __op, __rhs) {
2938
4429
  switch (__op) {
2939
4430
  case 'add': return __current + __rhs;
@@ -2951,8 +4442,9 @@ function __traceApplyAugmentedValue(__current, __op, __rhs) {
2951
4442
  }
2952
4443
  }
2953
4444
 
2954
- function __traceAugAssignIndex(__varName, __container, __indices, __op, __rhs) {
4445
+ function __traceAugAssignIndex(__varName, __container, __indices, __indexSources, __op, __rhs, __location) {
2955
4446
  const __normalized = __traceNormalizeIndices(__indices);
4447
+ const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __normalized?.length ?? 0);
2956
4448
  const __effectiveIndices = Array.isArray(__indices) ? __indices : [];
2957
4449
  const __current = __traceReadValueAtIndices(__container, __effectiveIndices);
2958
4450
  if (__normalized) {
@@ -2960,7 +4452,9 @@ function __traceAugAssignIndex(__varName, __container, __indices, __op, __rhs) {
2960
4452
  variable: __varName,
2961
4453
  kind: __normalized.length === 2 ? 'cell-read' : 'indexed-read',
2962
4454
  indices: __normalized,
4455
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
2963
4456
  pathDepth: __normalized.length,
4457
+ ...__traceNormalizeSourceLocation(__location),
2964
4458
  });
2965
4459
  }
2966
4460
  const __next = __traceApplyAugmentedValue(__current, __op, __rhs);
@@ -2970,14 +4464,18 @@ function __traceAugAssignIndex(__varName, __container, __indices, __op, __rhs) {
2970
4464
  variable: __varName,
2971
4465
  kind: __normalized.length === 2 ? 'cell-write' : 'indexed-write',
2972
4466
  indices: __normalized,
4467
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
2973
4468
  pathDepth: __normalized.length,
4469
+ value: __next,
4470
+ ...__traceNormalizeSourceLocation(__location),
2974
4471
  });
2975
4472
  }
2976
4473
  return __next;
2977
4474
  }
2978
4475
 
2979
- function __traceUpdateIndex(__varName, __container, __indices, __op, __isPrefix) {
4476
+ function __traceUpdateIndex(__varName, __container, __indices, __indexSources, __op, __isPrefix, __location) {
2980
4477
  const __normalized = __traceNormalizeIndices(__indices);
4478
+ const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __normalized?.length ?? 0);
2981
4479
  const __effectiveIndices = Array.isArray(__indices) ? __indices : [];
2982
4480
  const __current = __traceReadValueAtIndices(__container, __effectiveIndices);
2983
4481
  if (__normalized) {
@@ -2985,7 +4483,9 @@ function __traceUpdateIndex(__varName, __container, __indices, __op, __isPrefix)
2985
4483
  variable: __varName,
2986
4484
  kind: __normalized.length === 2 ? 'cell-read' : 'indexed-read',
2987
4485
  indices: __normalized,
4486
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
2988
4487
  pathDepth: __normalized.length,
4488
+ ...__traceNormalizeSourceLocation(__location),
2989
4489
  });
2990
4490
  }
2991
4491
  const __delta = __op === 'dec' ? -1 : 1;
@@ -2996,20 +4496,111 @@ function __traceUpdateIndex(__varName, __container, __indices, __op, __isPrefix)
2996
4496
  variable: __varName,
2997
4497
  kind: __normalized.length === 2 ? 'cell-write' : 'indexed-write',
2998
4498
  indices: __normalized,
4499
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
2999
4500
  pathDepth: __normalized.length,
4501
+ value: __next,
4502
+ ...__traceNormalizeSourceLocation(__location),
3000
4503
  });
3001
4504
  }
3002
4505
  return __isPrefix ? __next : __current;
3003
4506
  }
3004
4507
 
3005
- function __traceMutatingCall(__varName, __container, __method, ...__args) {
3006
- const __result = __container[__method](...__args);
3007
- if (['push', 'pop', 'shift', 'unshift', 'splice'].includes(__method)) {
4508
+ function __traceNormalizeMethodName(__container, __method, __args) {
4509
+ void __container;
4510
+ void __args;
4511
+ return __method;
4512
+ }
4513
+
4514
+ function __traceStdout(__line, ...__args) {
4515
+ console.log(...__args);
4516
+ __traceRecorder.recordStdout(__line, __args.map((__arg) => String(__arg)).join(' '));
4517
+ }
4518
+
4519
+ function __traceExceptionValue(__line, __error) {
4520
+ __traceRecorder.recordException(__line, __error);
4521
+ return __error;
4522
+ }
4523
+
4524
+ function __traceMutatingCall(__varName, __container, __indices, __indexSources, __method, __location, ...__args) {
4525
+ const __sourceLocation = __traceNormalizeSourceLocation(__location);
4526
+ let __target = __container;
4527
+ for (const __index of __indices || []) {
4528
+ __target = __traceIsMapLike(__target) ? __target.get(__index) : __target?.[__index];
4529
+ }
4530
+ const __mayMutate = ['push', 'pop', 'shift', 'unshift', 'splice', 'set', 'add', 'delete', 'clear'].includes(__method);
4531
+ const __result = __target[__method](...__args);
4532
+ if (['push', 'pop', 'shift', 'unshift', 'splice', 'set', 'get', 'has', 'add', 'delete', 'clear'].includes(__method)) {
4533
+ const __path = __indices || [];
4534
+ const __isMapLike = __traceIsMapLike(__target);
4535
+ const __isNestedMap = __path.length > 0 && __traceIsMapLike(__target);
4536
+ if (__isMapLike && __method === 'set') {
4537
+ const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __path.length + 1);
4538
+ const __targetPath = [...__path, __args[0]];
4539
+ __traceRecorder.recordAccess({
4540
+ variable: __varName,
4541
+ kind: 'indexed-write',
4542
+ indices: __targetPath,
4543
+ pathDepth: __path.length + 1,
4544
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
4545
+ value: serializeValue(__args[1]),
4546
+ ...__sourceLocation,
4547
+ });
4548
+ __traceRecorder.recordAccess({
4549
+ variable: __varName,
4550
+ kind: 'mutating-call',
4551
+ method: __traceNormalizeMethodName(__target, __method, __args),
4552
+ args: __args,
4553
+ indices: __targetPath,
4554
+ pathDepth: __path.length + 1,
4555
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
4556
+ ...__sourceLocation,
4557
+ });
4558
+ return __result;
4559
+ }
4560
+ if (__isMapLike && (__method === 'get' || __method === 'has')) {
4561
+ const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __path.length + 1);
4562
+ __traceRecorder.recordAccess({
4563
+ variable: __varName,
4564
+ kind: 'indexed-read',
4565
+ indices: [...__path, __args[0]],
4566
+ pathDepth: __path.length + 1,
4567
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
4568
+ value: serializeValue(__result),
4569
+ ...__sourceLocation,
4570
+ });
4571
+ return __result;
4572
+ }
4573
+ if (__target instanceof Set && __method === 'has') {
4574
+ __traceRecorder.recordAccess({
4575
+ variable: __varName,
4576
+ kind: 'indexed-read',
4577
+ indices: [...__path, __args[0]],
4578
+ pathDepth: __path.length + 1,
4579
+ ...__sourceLocation,
4580
+ });
4581
+ return __result;
4582
+ }
4583
+ if (__path.length > 0) {
4584
+ const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __path.length);
4585
+ __traceRecorder.recordAccess({
4586
+ variable: __varName,
4587
+ kind: 'indexed-read',
4588
+ indices: __path,
4589
+ pathDepth: __path.length,
4590
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
4591
+ ...__sourceLocation,
4592
+ });
4593
+ }
4594
+ const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __path.length);
3008
4595
  __traceRecorder.recordAccess({
3009
4596
  variable: __varName,
3010
4597
  kind: 'mutating-call',
3011
- method: __method,
3012
- pathDepth: 1,
4598
+ method: __traceNormalizeMethodName(__target, __method, __args),
4599
+ args: __args,
4600
+ indices: __path,
4601
+ pathDepth: __path.length,
4602
+ ...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
4603
+ ...__sourceLocation,
3013
4604
  });
3014
4605
  }
3015
4606
  return __result;
@@ -3021,10 +4612,8 @@ function buildScriptTracingRunner(code) {
3021
4612
  'console',
3022
4613
  '__traceRecorder',
3023
4614
  '__traceCtx',
3024
- `"use strict";
3025
- ${JAVASCRIPT_RUNTIME_PRELUDE}
4615
+ `${JAVASCRIPT_RUNTIME_PRELUDE}
3026
4616
  ${TRACING_RUNTIME_HELPERS_SOURCE}
3027
- let result;
3028
4617
  ${code}
3029
4618
  if (typeof result === 'undefined') {
3030
4619
  return null;
@@ -3042,6 +4631,7 @@ function buildFunctionExecutionRunner(code, executionStyle, argNames) {
3042
4631
  `"use strict";
3043
4632
  ${JAVASCRIPT_RUNTIME_PRELUDE}
3044
4633
  ${code}
4634
+ ${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
3045
4635
  let __target;
3046
4636
  try {
3047
4637
  __target = eval(__functionName);
@@ -3051,7 +4641,7 @@ try {
3051
4641
  if (typeof __target !== 'function') {
3052
4642
  throw new Error('Function "' + __functionName + '" not found');
3053
4643
  }
3054
- return __target(${argNames.join(', ')});`
4644
+ return __target(${argNames.map((name) => `__tracecodeMaterializeCustomObject(${name})`).join(', ')});`
3055
4645
  );
3056
4646
  }
3057
4647
 
@@ -3063,6 +4653,7 @@ return __target(${argNames.join(', ')});`
3063
4653
  `"use strict";
3064
4654
  ${JAVASCRIPT_RUNTIME_PRELUDE}
3065
4655
  ${code}
4656
+ ${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
3066
4657
  if (typeof Solution !== 'function') {
3067
4658
  throw new Error('Class "Solution" not found');
3068
4659
  }
@@ -3071,7 +4662,7 @@ const __method = __solver[__functionName];
3071
4662
  if (typeof __method !== 'function') {
3072
4663
  throw new Error('Method "Solution.' + __functionName + '" not found');
3073
4664
  }
3074
- return __method.call(__solver, ${argNames.join(', ')});`
4665
+ return __method.call(__solver, ${argNames.map((name) => `__tracecodeMaterializeCustomObject(${name})`).join(', ')});`
3075
4666
  );
3076
4667
  }
3077
4668
 
@@ -3084,6 +4675,7 @@ return __method.call(__solver, ${argNames.join(', ')});`
3084
4675
  `"use strict";
3085
4676
  ${JAVASCRIPT_RUNTIME_PRELUDE}
3086
4677
  ${code}
4678
+ ${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
3087
4679
  if (!Array.isArray(__operations) || !Array.isArray(__arguments)) {
3088
4680
  throw new Error('ops-class execution requires inputs.operations and inputs.arguments (or ops/args)');
3089
4681
  }
@@ -3110,6 +4702,7 @@ for (let __i = 0; __i < __operations.length; __i++) {
3110
4702
  if (!Array.isArray(__callArgs)) {
3111
4703
  __callArgs = [__callArgs];
3112
4704
  }
4705
+ __callArgs = __callArgs.map((__arg) => __tracecodeMaterializeCustomObject(__arg));
3113
4706
  if (__i === 0) {
3114
4707
  __instance = new __targetClass(...__callArgs);
3115
4708
  __out.push(null);
@@ -3139,6 +4732,7 @@ function buildFunctionTracingRunner(code, executionStyle, argNames) {
3139
4732
  ${JAVASCRIPT_RUNTIME_PRELUDE}
3140
4733
  ${TRACING_RUNTIME_HELPERS_SOURCE}
3141
4734
  ${code}
4735
+ ${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
3142
4736
  let __target;
3143
4737
  try {
3144
4738
  __target = eval(__functionName);
@@ -3148,7 +4742,7 @@ try {
3148
4742
  if (typeof __target !== 'function') {
3149
4743
  throw new Error('Function "' + __functionName + '" not found');
3150
4744
  }
3151
- return __target(${argNames.join(', ')});`
4745
+ return __target(${argNames.map((name) => `__tracecodeMaterializeCustomObject(${name})`).join(', ')});`
3152
4746
  );
3153
4747
  }
3154
4748
 
@@ -3163,6 +4757,7 @@ return __target(${argNames.join(', ')});`
3163
4757
  ${JAVASCRIPT_RUNTIME_PRELUDE}
3164
4758
  ${TRACING_RUNTIME_HELPERS_SOURCE}
3165
4759
  ${code}
4760
+ ${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
3166
4761
  if (typeof Solution !== 'function') {
3167
4762
  throw new Error('Class "Solution" not found');
3168
4763
  }
@@ -3171,7 +4766,7 @@ const __method = __solver[__functionName];
3171
4766
  if (typeof __method !== 'function') {
3172
4767
  throw new Error('Method "Solution.' + __functionName + '" not found');
3173
4768
  }
3174
- return __method.call(__solver, ${argNames.join(', ')});`
4769
+ return __method.call(__solver, ${argNames.map((name) => `__tracecodeMaterializeCustomObject(${name})`).join(', ')});`
3175
4770
  );
3176
4771
  }
3177
4772
 
@@ -3187,6 +4782,7 @@ return __method.call(__solver, ${argNames.join(', ')});`
3187
4782
  ${JAVASCRIPT_RUNTIME_PRELUDE}
3188
4783
  ${TRACING_RUNTIME_HELPERS_SOURCE}
3189
4784
  ${code}
4785
+ ${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
3190
4786
  if (!Array.isArray(__operations) || !Array.isArray(__arguments)) {
3191
4787
  throw new Error('ops-class execution requires inputs.operations and inputs.arguments (or ops/args)');
3192
4788
  }
@@ -3213,6 +4809,7 @@ for (let __i = 0; __i < __operations.length; __i++) {
3213
4809
  if (!Array.isArray(__callArgs)) {
3214
4810
  __callArgs = [__callArgs];
3215
4811
  }
4812
+ __callArgs = __callArgs.map((__arg) => __tracecodeMaterializeCustomObject(__arg));
3216
4813
  if (__i === 0) {
3217
4814
  __instance = new __targetClass(...__callArgs);
3218
4815
  __out.push(null);
@@ -3291,7 +4888,7 @@ async function executeCode(payload) {
3291
4888
 
3292
4889
  return {
3293
4890
  success: true,
3294
- output: serializeValue(output),
4891
+ output: serializeOutputValue(output),
3295
4892
  consoleOutput,
3296
4893
  };
3297
4894
  } catch (error) {
@@ -3347,11 +4944,11 @@ async function executeWithTracing(payload) {
3347
4944
  instrumentedCode = await instrumentCodeForTracing(executableCode, language, traceFunctionName);
3348
4945
  }
3349
4946
  } 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
- }
4947
+ const message =
4948
+ instrumentationError instanceof Error ? instrumentationError.message : String(instrumentationError);
4949
+ emitRuntimeDiagnostic('warn', 'trace-instrumentation-fallback', 'Trace instrumentation failed; using synthetic fallback.', {
4950
+ message,
4951
+ });
3355
4952
  }
3356
4953
 
3357
4954
  if (!instrumentedCode) {
@@ -3359,27 +4956,28 @@ async function executeWithTracing(payload) {
3359
4956
  const executionTimeMs = performanceNow() - startedAt;
3360
4957
 
3361
4958
  if (!fallbackResult.success) {
4959
+ const trace = createEmptyRuntimeTrace(language);
3362
4960
  return {
3363
4961
  success: false,
3364
4962
  error: fallbackResult.error,
3365
4963
  errorLine: fallbackResult.errorLine,
3366
- trace: [],
4964
+ trace,
3367
4965
  executionTimeMs,
3368
4966
  consoleOutput: fallbackResult.consoleOutput ?? [],
3369
- lineEventCount: 0,
3370
- traceStepCount: 0,
4967
+ lineEventCount: trace.lineEventCount,
4968
+ traceStepCount: trace.traceStepCount,
3371
4969
  };
3372
4970
  }
3373
4971
 
3374
- const syntheticTrace = createSyntheticTrace(payload, fallbackResult);
4972
+ const trace = createSyntheticRuntimeTrace(payload, fallbackResult, language);
3375
4973
  return {
3376
4974
  success: true,
3377
4975
  output: fallbackResult.output,
3378
- trace: syntheticTrace,
4976
+ trace,
3379
4977
  executionTimeMs,
3380
4978
  consoleOutput: fallbackResult.consoleOutput ?? [],
3381
- lineEventCount: syntheticTrace.filter((step) => step.event === 'line').length,
3382
- traceStepCount: syntheticTrace.length,
4979
+ lineEventCount: trace.lineEventCount,
4980
+ traceStepCount: trace.traceStepCount,
3383
4981
  };
3384
4982
  }
3385
4983
 
@@ -3422,21 +5020,23 @@ async function executeWithTracing(payload) {
3422
5020
  );
3423
5021
  }
3424
5022
 
3425
- const serializedOutput = serializeValue(output);
5023
+ const serializedTraceOutput = serializeValue(output);
5024
+ const serializedOutput = serializeOutputValue(output);
3426
5025
  if (!hasNamedFunction) {
3427
5026
  traceRecorder.popToFunction(traceFunctionName);
3428
- traceRecorder.recordReturn(traceLineBounds.endLine, serializedOutput, traceFunctionName);
5027
+ traceRecorder.recordReturn(traceLineBounds.endLine, serializedTraceOutput, traceFunctionName);
3429
5028
  }
3430
5029
 
3431
5030
  const executionTimeMs = performanceNow() - startedAt;
5031
+ const trace = traceRecorder.getRuntimeTrace(language, `${language}:run`, defaultRuntimeTraceFile(language));
3432
5032
  return {
3433
5033
  success: true,
3434
5034
  output: serializedOutput,
3435
- trace: traceRecorder.getTrace(),
5035
+ trace,
3436
5036
  executionTimeMs,
3437
5037
  consoleOutput,
3438
- lineEventCount: traceRecorder.getLineEventCount(),
3439
- traceStepCount: traceRecorder.getTraceStepCount(),
5038
+ lineEventCount: trace.lineEventCount,
5039
+ traceStepCount: trace.traceStepCount,
3440
5040
  traceLimitExceeded: traceRecorder.isTraceLimitExceeded(),
3441
5041
  timeoutReason: traceRecorder.getTimeoutReason(),
3442
5042
  };
@@ -3461,16 +5061,17 @@ async function executeWithTracing(payload) {
3461
5061
  traceRecorder.recordException(traceErrorLine, message, traceFunctionName);
3462
5062
  }
3463
5063
 
5064
+ const trace = traceRecorder.getRuntimeTrace(language, `${language}:run`, defaultRuntimeTraceFile(language));
3464
5065
  return {
3465
5066
  success: false,
3466
5067
  output: null,
3467
5068
  error: message,
3468
5069
  errorLine,
3469
- trace: traceRecorder.getTrace(),
5070
+ trace,
3470
5071
  executionTimeMs,
3471
5072
  consoleOutput,
3472
- lineEventCount: traceRecorder.getLineEventCount(),
3473
- traceStepCount: traceRecorder.getTraceStepCount(),
5073
+ lineEventCount: trace.lineEventCount,
5074
+ traceStepCount: trace.traceStepCount,
3474
5075
  traceLimitExceeded,
3475
5076
  timeoutReason,
3476
5077
  };
@@ -3537,11 +5138,37 @@ async function initRuntime() {
3537
5138
 
3538
5139
  isLoading = true;
3539
5140
  const startedAt = performanceNow();
5141
+ ensureJavaScriptLibraries();
3540
5142
  isInitialized = true;
3541
5143
  isLoading = false;
3542
5144
  return { success: true, loadTimeMs: performanceNow() - startedAt };
3543
5145
  }
3544
5146
 
5147
+ async function warmRuntime(payload = {}) {
5148
+ const startedAt = performanceNow();
5149
+ const initStartedAt = performanceNow();
5150
+ await initRuntime();
5151
+ const initMs = performanceNow() - initStartedAt;
5152
+ let compilerWarmupMs = 0;
5153
+
5154
+ if (payload?.language === 'typescript' || payload?.preloadTypeScriptCompiler === true) {
5155
+ const compilerStartedAt = performanceNow();
5156
+ await ensureTypeScriptCompiler();
5157
+ compilerWarmupMs = performanceNow() - compilerStartedAt;
5158
+ }
5159
+
5160
+ const totalMs = performanceNow() - startedAt;
5161
+ return {
5162
+ success: true,
5163
+ loadTimeMs: totalMs,
5164
+ timings: {
5165
+ totalMs,
5166
+ initMs,
5167
+ warmupMs: compilerWarmupMs,
5168
+ },
5169
+ };
5170
+ }
5171
+
3545
5172
  async function processMessage(data) {
3546
5173
  const { id, type, payload } = data;
3547
5174
 
@@ -3553,6 +5180,12 @@ async function processMessage(data) {
3553
5180
  break;
3554
5181
  }
3555
5182
 
5183
+ case 'warmup': {
5184
+ const result = await warmRuntime(payload);
5185
+ self.postMessage({ id, type: 'warmup-result', payload: result });
5186
+ break;
5187
+ }
5188
+
3556
5189
  case 'execute-with-tracing': {
3557
5190
  const result = await executeWithTracing(payload);
3558
5191
  self.postMessage({ id, type: 'execute-result', payload: result });
@@ -3616,7 +5249,5 @@ self.onmessage = function(event) {
3616
5249
  });
3617
5250
  };
3618
5251
 
3619
- if (WORKER_DEBUG) {
3620
- console.log('[JavaScriptWorker] ready');
3621
- }
5252
+ emitRuntimeDiagnostic('info', 'worker-ready', 'JavaScript worker is ready.');
3622
5253
  self.postMessage({ type: 'worker-ready' });