SyncValsverifier → artifact → classifier → verdict
SyncVals · Trajectory

evanw-esbuild-4417

codex gpt-5.5 ✓ resolved GOOD_SUCCESS ↑ View task
Solved from the instruction alone, tests/ and solution/ were withheld from the agent's workspace and restored only for grading.
Reward = tests/test.sh exit code (0 → resolved); the classification below is post-hoc and cannot change it.
Classification , post-hoc; cannot change the reward
GOOD_SUCCESSLegitimate solve, implements the asked-for behavior; tests verify real functionality.
SubtypeLegitimate Solution
EvidenceAll 6 tests passed: test_async_generator_lowering_matches_native, test_bundled_output_uses_lowered_async_generator_helpers, test_case_roster_actually_ran, test_output_is_json_trace, test_async_generator_compatibility_targets_still_require_lowering, and test_no_hardcoded_hidden_literals. Agent's trajectory shows systematic exploration of runtime.go, implementation of promise-based queuing for iterator methods, and comprehensive test verification (go build ./cmd/... succeeded, go test ./... passed all packages). Implementation correctly addresses async generator semantics including queued next/throw/return calls, delegated iteration, cleanup yields from finally blocks, and synchronous side-effect ordering as specified in instruction.
Root causeAgent successfully understood and implemented a complex fix to async generator lowering in a JavaScript-to-JavaScript transpiler. The implementation correctly sequences iterator method calls through promise-valued gates to preserve native JavaScript semantics for concurrent calls, delegated generators, and finally-block cleanup ordering.
RecommendationN/A - task is fine
Trajectory
Tool-by-tool agent trajectory
45 tool calls · 2 tool types · 59 steps
<permissions instructions> Filesystem sandboxing defines which files can be read or written. `sandbox_mode` is `danger-full-access`: No filesystem sandboxing - all commands are permitted. Network access is enabled. Approval policy is currently never. Do not provide the `sandbox_permissions` for any reason, commands will be rejected. </permissions instructions><apps_instructions> ## Apps (Connectors) Apps (Connectors) can be explicitly triggered in user messages in the format `[$app-name](app://{connector_id})`. Apps can also be implicitly triggered as long as the context suggests usage of available apps. An app is equivalent to a set of MCP tools within the `codex_apps` MCP. An installed app's MCP tools are either provided to you already, or can be lazy-loaded through the `tool_search` tool. If `tool_search` is available, the apps that are searchable by `tools_search` will be listed by it. Do not additionally call list_mcp_resources or list_mcp_resource_templates for apps. </apps_instructions><skills_instructions> ## Skills A skill is a set of instructions provided through a `SKILL.md` source. Below is the list of skills that can be used. Each entry includes a name, description, and source locator. `file` locators are on the host filesystem, `environment resource` locators are owned by an execution environment, `orchestrator resource` locators are opaque non-filesystem resources, and `custom resource` locators use their provider's access mechanism. ### Available skills - imagegen: Generate or edit raster images when the task benefits from AI-created bitmap visuals such as photos, illustrations, textures, sprites, mockups, or transparent-background cutouts. Use when Codex should create a brand-new image, transform an existing image, or derive visual variants from references, and the output should be a bitmap asset rather than repo-native code or vector. Do not use when the task is better handled by editing existing SVG/vector/code-native assets, extending an established icon or logo system, or building the visual directly in HTML/CSS/canvas. (file: /tmp/codex-home/skills/.system/imagegen/SKILL.md) - openai-docs: Use when the user asks how to build with OpenAI products or APIs, asks about Codex itself or choosing Codex surfaces, needs up-to-date official documentation with citations, help choosing the latest model for a use case, or model upgrade and prompt-upgrade guidance; use OpenAI docs MCP tools for non-Codex docs questions, use the Codex manual helper first for broad Codex self-knowledge, and restrict fallback browsing to official OpenAI domains. (file: /tmp/codex-home/skills/.system/openai-docs/SKILL.md) - plugin-creator: Create and scaffold plugin directories for Codex with a required `.codex-plugin/plugin.json`, optional plugin folders/files, valid manifest defaults, and personal-marketplace entries by default. Use when Codex needs to create a new personal plugin, add optional plugin structure, generate or update marketplace entries for plugin ordering and availability metadata, or update an existing local plugin during development with the CLI-driven cachebuster and reinstall flow. (file: /tmp/codex-home/skills/.system/plugin-creator/SKILL.md) - skill-creator: Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Codex's capabilities with specialized knowledge, workflows, or tool integrations. (file: /tmp/codex-home/skills/.system/skill-creator/SKILL.md) - skill-installer: Install Codex skills into $CODEX_HOME/skills from a curated list or a [code-host] repo path. Use when a user asks to list installable skills, install a curated skill, or install a skill from another repo (including private repos). (file: /tmp/codex-home/skills/.system/skill-installer/SKILL.md) ### How to use skills - Discovery: The list above is the skills available in this session (name + description + source locator). `file` entries live on the host filesystem, `environment resource` entries are owned by their execution environment, `orchestrator resource` entries must be accessed through `skills.list` and `skills.read`, and `custom resource` entries use their provider's access mechanism. - Trigger rules: If the user names a skill (with `$SkillName` or plain text) OR the task clearly matches a skill's description shown above, you must use that skill for that turn. Multiple mentions mean use them all. Do not carry skills across turns unless re-mentioned. - Missing/blocked: If a named skill isn't in the list or its source can't be read, say so briefly and continue with the best fallback. - How to use a skill (progressive disclosure): 1) After deciding to use a skill, the main agent must read its `SKILL.md` completely before taking task actions. For a `file` entry, open the listed path. For an `environment resource`, use the filesystem of the owning environment. For an `orchestrator resource`, call `skills.list` with `{"authority":{"kind":"orchestrator"}}`, select the matching package, and pass its `main_resource` to `skills.read`. If a read is truncated or paginated, continue until EOF. 2) When `SKILL.md` references another resource, use the same access mechanism. Resolve relative paths against a filesystem-backed skill directory. For orchestrator skills, pass the exact referenced resource identifier with the same authority and package to `skills.read`; do not treat `skill://` identifiers as filesystem paths. 3) If `SKILL.md` points to extra folders such as `references/`, use its routing instructions to identify the resources required for the task. The main agent must read each required instruction or reference file itself before acting on it. Do not delegate reading, summarizing, or interpreting skill instructions to a subagent. Subagents may still perform task work when the selected skill allows it. 4) For filesystem-backed skills, prefer running or patching provided scripts instead of retyping large code blocks. For orchestrator skills, use `skills.read` and the available tools; do not invent a local path. 5) Reuse provided assets or templates through the same source access mechanism instead of recreating them. - Coordination and sequencing: - If multiple skills apply, choose the minimal set that covers the request and state the order you'll use them. - Announce which skill(s) you're using and why (one short line). If you skip an obvious skill, say why. - Context hygiene: - Progressive disclosure applies to selecting relevant files, not partially reading a selected instruction file. Do not load unrelated references, scripts, or assets. - Avoid deep reference-chasing: prefer opening only files directly linked from `SKILL.md` unless you're blocked. - When variants exist (frameworks, providers, domains), pick only the relevant reference file(s) and note that choice. - Safety and fallback: If a skill can't be applied cleanly (missing files, unclear instructions), state the issue, pick the next-best approach, and continue. </skills_instructions>
<environment_context> <cwd>/app</cwd> <shell>bash</shell> <current_date>2026-06-21</current_date> <timezone>Etc/UTC</timezone> <filesystem><workspace_roots><root>/app</root></workspace_roots><permission_profile type="disabled"><file_system type="unrestricted" /></permission_profile></filesystem> </environment_context>
The project in /app is a JavaScript bundler written in Go. When it lowers async generator syntax for older targets, the transformed program should preserve native async generator behavior. Calling next, throw, or return on an async generator before earlier iterator method promises have settled must behave like native JavaScript. The first call should start synchronously up to the first await or yield point, later calls must be sequenced correctly, delegated async iteration must not skip values, and a return value supplied to a queued call must be delivered to the right suspended yield expression. Fix the lowering so transformed output matches native Node behavior for concurrent iterator method calls, delegated async generators, for-await loops, return-through-yield flows, and synchronous side-effect ordering. Queued return() calls must still run cleanup code from finally blocks and deliver any value yielded by that cleanup. Queued throw() calls must enter matching catch blocks at the same suspended point as native async generators and preserve the yielded recovery value. The observable contract includes yielded values, done flags, propagated errors, values sent back into suspended yield expressions, and the order of synchronous side effects that occur before and after awaited work. The runtime helpers are in /app/internal/runtime/runtime.go. Coordinate __asyncGenerator with delegated iteration through __yieldStar so queued return, throw, and next calls preserve native finally-yield timing. Keep existing CLI and API behavior unchanged. The fix must handle dozens of concurrent-call patterns, including delegated generators whose inner iterator is waiting on a promise inside try/finally or catch code. A queue that only uses an array plus a running flag is not enough if it lets delegated return() or throw() skip the same promise-completion ordering as native async generators. Preserve the __yieldStar __await handoff protocol: when a delegated iterator result is pending, the outer async generator must resume through the same ordered promise chain instead of resolving the delegated call outside that chain. Use a promise-valued queue rather than a detached array of pending calls when sequencing iterator methods. Each next, throw, and return call should chain its resume work from the previous call's promise so native microtask order is preserved. When no earlier iterator method is still pending, the first resume callback must start immediately and run synchronously until the generator reaches its next await or yield point. Do not add a microtask hop before that first resume; doing so changes side effects that occur before the first await. The scheduling is intentionally asymmetric. A queued next or throw operation that can resume the generator must not be delayed behind an extra Promise.resolve().then hop just because the implementation uses a promise-valued queue. A queued return operation, however, must still wait for the pending yield or delegated-yield handoff to settle before running return cleanup, so the first next result is observed before finally-side effects and cleanup yields from the queued return. A useful minimal check is an outer async generator that yield* delegates to an inner async generator whose try block yields an awaited value and whose finally block records a side effect before yielding a cleanup value. If a caller issues next() and then return("done") before awaiting either promise, the finally side effect is not visible when the first next() promise resolves; the cleanup yield belongs to the queued return() continuation. Seeing the side effect before the first result is observed means delegated cleanup is running too early. The same ordering must hold when more than one resume is queued before a return. For example, if a caller starts two next() calls, then a return("done") call, and then another next("after") call before awaiting any of those promises, the second next() result must settle before return cleanup runs. Cleanup side effects and cleanup yields belong to the queued return() continuation, and the later next("after") observes the generator state that native JavaScript would leave after that return path. Acceptance criteria: - `go build ./cmd/...` succeeds. - Bundled output for es2017 and es6 uses the async generator runtime helpers instead of native async generator or for-await syntax. - Lowered output produces the same JSON trace as native Node.js for concurrent next, throw, and return calls, including delegated generators with awaited yields, try/finally cleanup yields, try/catch recovery yields, and values sent back into suspended yield expressions. - The compatibility table must continue to require async-generator lowering for es2017 and es6 targets. Do not make compatibility-table changes that avoid lowering instead of fixing the runtime helper. Preserve the existing runtime helper exports, including __forAwait, so lowered for-await loops continue to link and execute through the runtime helpers.
I’ll inspect the runtime helpers and existing async generator tests first, then patch the helper behavior and add focused coverage around the queued-call cases you described.
shell
rg -n "asyncGenerator|yieldStar|forAwait|async generator|AsyncGenerator|compatibility" internal cmd scripts tests
output
Chunk ID: 2c0229
Wall time: 0.0000 seconds
Process exited with code 2
Original token count: 3570
Output:
rg: scripts: No such file or directory (os error 2)
rg: tests: No such file or directory (os error 2)
internal/sourcemap/sourcemap.go:500:	// those too for compatibility.
internal/bundler_tests/bundler_lower_test.go:2998:func TestLowerAsyncGenerator(t *testing.T) {
internal/bundler_tests/bundler_lower_test.go:3053:			UnsupportedJSFeatures: compat.AsyncGenerator,
internal/bundler_tests/bundler_lower_test.go:3058:func TestLowerAsyncGeneratorNoAwait(t *testing.T) {
internal/bundler_tests/bundler_lower_test.go:3113:			UnsupportedJSFeatures: compat.AsyncGenerator | compat.AsyncAwait,
internal/bundler_tests/snapshots/snapshots_lower.txt:24:    for (var iter = __forAwait(b), more, temp, error; more = !(temp = await iter.next()).done; more = !1) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1177:TestLowerAsyncGenerator
internal/bundler_tests/snapshots/snapshots_lower.txt:1180:  return __asyncGenerator(this, null, function* () {
internal/bundler_tests/snapshots/snapshots_lower.txt:1185:      yield* __yieldStar(x);
internal/bundler_tests/snapshots/snapshots_lower.txt:1188:        for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1202:        for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1233:  return __asyncGenerator(this, null, function* () {
internal/bundler_tests/snapshots/snapshots_lower.txt:1238:      yield* __yieldStar(x);
internal/bundler_tests/snapshots/snapshots_lower.txt:1241:        for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1255:        for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1286:  return __asyncGenerator(this, null, function* () {
internal/bundler_tests/snapshots/snapshots_lower.txt:1291:      yield* __yieldStar(x);
internal/bundler_tests/snapshots/snapshots_lower.txt:1294:        for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1308:        for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1340:    return __asyncGenerator(this, null, function* () {
internal/bundler_tests/snapshots/snapshots_lower.txt:1345:        yield* __yieldStar(x);
internal/bundler_tests/snapshots/snapshots_lower.txt:1348:          for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1362:          for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1395:    return __asyncGenerator(this, null, function* () {
internal/bundler_tests/snapshots/snapshots_lower.txt:1400:        yield* __yieldStar(x);
internal/bundler_tests/snapshots/snapshots_lower.txt:1403:          for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1417:          for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1457:TestLowerAsyncGeneratorNoAwait
internal/bundler_tests/snapshots/snapshots_lower.txt:1460:  return __asyncGenerator(this, null, function* () {
internal/bundler_tests/snapshots/snapshots_lower.txt:1465:      yield* __yieldStar(x);
internal/bundler_tests/snapshots/snapshots_lower.txt:1468:        for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1482:        for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1513:  return __asyncGenerator(this, null, function* () {
internal/bundler_tests/snapshots/snapshots_lower.txt:1518:      yield* __yieldStar(x);
internal/bundler_tests/snapshots/snapshots_lower.txt:1521:        for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1535:        for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1566:  return __asyncGenerator(this, null, function* () {
internal/bundler_tests/snapshots/snapshots_lower.txt:1571:      yield* __yieldStar(x);
internal/bundler_tests/snapshots/snapshots_lower.txt:1574:        for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1588:        for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1620:    return __asyncGenerator(this, null, function* () {
internal/bundler_tests/snapshots/snapshots_lower.txt:1625:        yield* __yieldStar(x);
internal/bundler_tests/snapshots/snapshots_lower.txt:1628:          for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1642:          for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1675:    return __asyncGenerator(this, null, function* () {
internal/bundler_tests/snapshots/snapshots_lower.txt:1680:        yield* __yieldStar(x);
internal/bundler_tests/snapshots/snapshots_lower.txt:1683:          for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:1697:          for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:2077:      for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:2094:      for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:2111:      for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:2128:      for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:2145:      label: for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:2162:      label: for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:2185:      for (var iter = __forAwait(y), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:2202:      for (var iter = __forAwait(y), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:2219:      for (var iter = __forAwait(y), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:2236:      for (var iter = __forAwait(y), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:2253:      label: for (var iter = __forAwait(y), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
internal/bundler_tests/snapshots/snapshots_lower.txt:2270:      label: for (var iter = __forAwait(y), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
internal/bundler_tests/bundler_importstar_test.go:1730:			// This is for compatibility with node. So this test intentionally behaves
internal/bundler_tests/bundler_importstar_test.go:1779:			// This is for compatibility with node. So this test intentionally behaves
internal/linker/linker.go:1403:					// causing errors. This is for compatibility with older CommonJS-
internal/resolver/package_json.go:207:			// replicate this bug for compatibility. However, Browserify only allows
internal/resolver/resolver.go:37:	// This is unfortunately necessary for compatibility. Some packages
internal/compat/js_table.go:67:	AsyncGenerator
internal/compat/js_table.go:131:	"async-generator":                   AsyncGenerator,
internal/compat/js_table.go:249:	AsyncGenerator: {
internal/compat/js_table.go:250:		// Note: The latest version of "Hermes" failed this test: Asynchronous Iterators: async generators
internal/compat/js_table.go:251:		// Note: The latest version of "IE" failed this test: Asynchronous Iterators: async generators
internal/compat/js_table.go:252:		// Note: The latest version of "Rhino" failed this test: Asynchronous Iterators: async generators
internal/bundler/bundler.go:1892:				// However, requiring a leading "./" also breaks backward compatibility
internal/bundler/bundler.go:2965:	fixInvalidUnsupportedJSFeatureOverrides(options, compat.AsyncAwait, compat.AsyncGenerator|compat.ForAwait|compat.TopLevelAwait)
internal/bundler/bundler.go:2966:	fixInvalidUnsupportedJSFeatureOverrides(options, compat.Generator, compat.AsyncGenerator)
internal/runtime/runtime.go:38:	//   __asyncGenerator
internal/runtime/runtime.go:234:				// If the importer is in node compatibility mode or this is not an ESM
internal/runtime/runtime.go:237:				// "default" to the CommonJS "module.exports" for node compatibility.
internal/runtime/runtime.go:412:		// These help for lowering async generator functions
internal/runtime/runtime.go:417:		export var __asyncGenerator = (__this, __arguments, generator) => {
internal/runtime/runtime.go:437:		export var __yieldStar = value => {
internal/runtime/runtime.go:469:		export var __forAwait = (obj, it, method) =>
internal/js_parser/js_parser.go:8953:			// or async functions, since this is a backwards-compatibility hack from
internal/js_parser/js_parser.go:10832:			// Returning undefined is implicit except when inside an async generator
internal/js_parser/js_parser.go:11062:					(p.options.unsupportedJSFeatures.Has(compat.AsyncGenerator) && p.fnOrArrowDataVisit.isGenerator) {
internal/js_parser/js_parser.go:11072:		// Lower "for await" if it's unsupported if it's in a lowered async generator
internal/js_parser/js_parser.go:11074:			(p.options.unsupportedJSFeatures.Has(compat.AsyncGenerator) && p.fnOrArrowDataVisit.isGenerator)) {
internal/js_parser/js_parser.go:12956:			// Rewrite "module.require()" to "require()" for Webpack compatibility.
internal/js_parser/js_parser.go:14765:		// "yield* x" turns into "yield* __yieldStar(x)" when lowering async generator functions
internal/js_parser/js_parser.go:14766:		if e.IsStar && p.options.unsupportedJSFeatures.Has(compat.AsyncGenerator) && p.fnOrArrowDataVisit.isGenerator {
internal/js_parser/js_parser.go:14767:			e.ValueOrNil = p.callRuntime(expr.Loc, "__yieldStar", []js_ast.Expr{e.ValueOrNil})
internal/js_parser/js_parser.go:17898:					// is only for backward-compatibility.
internal/js_parser/js_parser_lower.go:72:	case compat.AsyncGenerator:
internal/js_parser/js_parser_lower.go:73:		name = "async generator functions"
internal/js_parser/js_parser_lower.go:249:		feature = compat.AsyncGenerator
internal/js_parser/js_parser_lower.go:343:	// Lower async functions and async generator functions
internal/js_parser/js_parser_lower.go:344:	if *isAsync && (p.options.unsupportedJSFeatures.Has(compat.AsyncAwait) || (isGenerator != nil && *isGenerator && p.options.unsupportedJSFeatures.Has(compat.AsyncGenerator))) {
internal/js_parser/js_parser_lower.go:478:			// "async function* foo(a, b) { stmts }" => "function foo(a, b) { return __asyncGenerator(this, null, function* () { stmts }) }"
internal/js_parser/js_parser_lower.go:479:			name = "__asyncGenerator"
internal/js_parser/js_parser_lower.go:1050:	// "await x" turns into "yield __await(x)" when lowering async generator functions
internal/js_parser/js_parser_lower.go:1051:	if p.fnOrArrowDataVisit.isGenerator && (p.options.unsupportedJSFeatures.Has(compat.AsyncAwait) || p.options.unsupportedJSFeatures.Has(compat.AsyncGenerator)) {
internal/js_parser/js_parser_lower.go:1078:	//     for (var iter = __forAwait(y), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
internal/js_parser/js_parser_lower.go:1166:						ValueOrNil: p.callRuntime(loc, "__forAwait", []js_ast.Expr{loop.Value})},
internal/js_parser/js_parser_lower.go:1892:					(p.options.unsupportedJSFeatures.Has(compat.AsyncGenerator) && p.fnOrArrowDataVisit.isGenerator)))) {
internal/js_parser/js_parser_lower_test.go:785:func TestAsyncGeneratorFns(t *testing.T) {
internal/js_parser/js_parser_lower_test.go:802:	expectParseErrorWithUnsupportedFeatures(t, compat.AsyncGenerator, "async function* gen() {}", err)
internal/js_parser/js_parser_lower_test.go:803:	expectParseErrorWithUnsupportedFeatures(t, compat.AsyncGenerator, "(async function* () {});", err)
internal/js_parser/js_parser_lower_test.go:804:	expectParseErrorWithUnsupportedFeatures(t, compat.AsyncGenerator, "({ async *foo() {} });", err)
shell
sed -n '1,260p' internal/runtime/runtime.go
output
Chunk ID: ef7d3a
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 2542
Output:
package runtime

// This is esbuild's runtime code. It contains helper functions that are
// automatically injected into output files to implement certain features. For
// example, the "**" operator is replaced with a call to "__pow" when targeting
// ES2015. Tree shaking automatically removes unused code from the runtime.

import (
	"[code-host]/evanw/esbuild/internal/compat"
	"[code-host]/evanw/esbuild/internal/logger"
)

// The runtime source is always at a special index. The index is always zero
// but this constant is always used instead to improve readability and ensure
// all code that references this index can be discovered easily.
const SourceIndex = uint32(0)

func Source(unsupportedJSFeatures compat.JSFeature) logger.Source {
	// Note: These helper functions used to be named similar things to the helper
	// functions from the TypeScript compiler. However, people sometimes use these
	// two projects in combination and TypeScript's implementation of these helpers
	// causes name collisions. Some examples:
	//
	// * The "tslib" library will overwrite esbuild's helper functions if the bundled
	//   code is run in the global scope: https://[code-host]/evanw/esbuild/issues/1102
	//
	// * Running the TypeScript compiler on esbuild's output to convert ES6 to ES5
	//   will also overwrite esbuild's helper functions because TypeScript doesn't
	//   change the names of its helper functions to avoid name collisions:
	//   https://[code-host]/microsoft/TypeScript/issues/43296
	//
	// These can both be considered bugs in TypeScript. However, they are unlikely
	// to be fixed and it's simplest to just avoid using the same names to avoid
	// these bugs. Forbidden names (from "tslib"):
	//
	//   __assign
	//   __asyncDelegator
	//   __asyncGenerator
	//   __asyncValues
	//   __await
	//   __awaiter
	//   __classPrivateFieldGet
	//   __classPrivateFieldSet
	//   __createBinding
	//   __decorate
	//   __exportStar
	//   __extends
	//   __generator
	//   __importDefault
	//   __importStar
	//   __makeTemplateObject
	//   __metadata
	//   __param
	//   __read
	//   __rest
	//   __spread
	//   __spreadArray
	//   __spreadArrays
	//   __values
	//
	// Note: The "__objRest" function has a for-of loop which requires ES6, but
	// transforming destructuring to ES5 isn't even supported so it's ok.
	text := `
		var __create = Object.create
		var __freeze = Object.freeze
		var __defProp = Object.defineProperty
		var __defProps = Object.defineProperties
		var __getOwnPropDesc = Object.getOwnPropertyDescriptor // Note: can return "undefined" due to a Safari bug
		var __getOwnPropDescs = Object.getOwnPropertyDescriptors
		var __getOwnPropNames = Object.getOwnPropertyNames
		var __getOwnPropSymbols = Object.getOwnPropertySymbols
		var __getProtoOf = Object.getPrototypeOf
		var __hasOwnProp = Object.prototype.hasOwnProperty
		var __propIsEnum = Object.prototype.propertyIsEnumerable
		var __reflectGet = Reflect.get
		var __reflectSet = Reflect.set

		var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for('Symbol.' + name)
		var __typeError = msg => { throw TypeError(msg) }

		export var __pow = Math.pow

		var __defNormalProp = (obj, key, value) => key in obj
			? __defProp(obj, key, {enumerable: true, configurable: true, writable: true, value})
			: obj[key] = value

		export var __spreadValues = (a, b) => {
			for (var prop in b ||= {})
				if (__hasOwnProp.call(b, prop))
					__defNormalProp(a, prop, b[prop])
			if (__getOwnPropSymbols)
		`

	// Avoid "of" when not using ES6
	if !unsupportedJSFeatures.Has(compat.ForOf) {
		text += `
				for (var prop of __getOwnPropSymbols(b)) {
		`
	} else {
		text += `
				for (var props = __getOwnPropSymbols(b), i = 0, n = props.length, prop; i < n; i++) {
					prop = props[i]
		`
	}

	text += `
					if (__propIsEnum.call(b, prop))
						__defNormalProp(a, prop, b[prop])
				}
			return a
		}
		export var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b))

		// Update the "name" property on the function or class for "--keep-names"
		export var __name = (target, value) => __defProp(target, 'name', { value, configurable: true })

		// This fallback "require" function exists so that "typeof require" can
		// naturally be "function" even in non-CommonJS environments since esbuild
		// emulates a CommonJS environment (issue #1202). However, people want this
		// shim to fall back to "globalThis.require" even if it's defined later
		// (including property accesses such as "require.resolve") so we need to
		// use a proxy (issue #1614).
		export var __require =
			/* @__PURE__ */ (x =>
				typeof require !== 'undefined' ? require :
				typeof Proxy !== 'undefined' ? new Proxy(x, {
					get: (a, b) => (typeof require !== 'undefined' ? require : a)[b]
				}) : x
			)(function(x) {
				if (typeof require !== 'undefined') return require.apply(this, arguments)
				throw Error('Dynamic require of "' + x + '" is not supported')
			})

		// This is used for glob imports
		export var __glob = map => path => {
			var fn = map[path]
			if (fn) return fn()
			throw new Error('Module not found in bundle: ' + path)
		}

		// For object rest patterns
		export var __restKey = key => typeof key === 'symbol' ? key : key + ''
		export var __objRest = (source, exclude) => {
			var target = {}
			for (var prop in source)
				if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
					target[prop] = source[prop]
			if (source != null && __getOwnPropSymbols)
	`

	// Avoid "of" when not using ES6
	if !unsupportedJSFeatures.Has(compat.ForOf) {
		text += `
				for (var prop of __getOwnPropSymbols(source)) {
		`
	} else {
		text += `
				for (var props = __getOwnPropSymbols(source), i = 0, n = props.length, prop; i < n; i++) {
					prop = props[i]
		`
	}

	text += `
					if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
						target[prop] = source[prop]
				}
			return target
		}

		// This is for lazily-initialized ESM code. This has two implementations, a
		// compact one for minified code and a verbose one that generates friendly
		// names in V8's profiler and in stack traces.
		export var __esm = (fn, res) => function __init() {
			return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res
		}
		export var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res)

		// Wraps a CommonJS closure and returns a require() function. This has two
		// implementations, a compact one for minified code and a verbose one that
		// generates friendly names in V8's profiler and in stack traces.
		export var __commonJS = (cb, mod) => function __require() {
			return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = {exports: {}}).exports, mod), mod.exports
		}
		export var __commonJSMin = (cb, mod) => () => (mod || cb((mod = {exports: {}}).exports, mod), mod.exports)

		// Used to implement ESM exports both for "require()" and "import * as"
		export var __export = (target, all) => {
			for (var name in all)
				__defProp(target, name, { get: all[name], enumerable: true })
		}

		var __copyProps = (to, from, except, desc) => {
			if (from && typeof from === 'object' || typeof from === 'function')
	`

	// Avoid "let" when not using ES6
	if !unsupportedJSFeatures.Has(compat.ForOf) && !unsupportedJSFeatures.Has(compat.ConstAndLet) {
		text += `
				for (let key of __getOwnPropNames(from))
					if (!__hasOwnProp.call(to, key) && key !== except)
						__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable })
		`
	} else {
		text += `
				for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
					key = keys[i]
					if (!__hasOwnProp.call(to, key) && key !== except)
						__defProp(to, key, { get: (k => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable })
				}
		`
	}

	text += `
			return to
		}

		// This is used to implement "export * from" statements. It copies properties
		// from the imported module to the current module's ESM export object. If the
		// current module is an entry point and the target format is CommonJS, we
		// also copy the properties to "module.exports" in addition to our module's
		// internal ESM export object.
		export var __reExport = (target, mod, secondTarget) => (
			__copyProps(target, mod, 'default'),
			secondTarget && __copyProps(secondTarget, mod, 'default')
		)

		// Converts the module from CommonJS to ESM. When in node mode (i.e. in an
		// ".mjs" file, package.json has "type: module", or the "__esModule" export
		// in the CommonJS file is falsy or missing), the "default" property is
		// overridden to point to the original CommonJS exports object instead.
		export var __toESM = (mod, isNodeMode, target) => (
			target = mod != null ? __create(__getProtoOf(mod)) : {},
			__copyProps(
				// If the importer is in node compatibility mode or this is not an ESM
				// file that has been converted to a CommonJS file using a Babel-
				// compatible transform (i.e. "__esModule" has not been set), then set
				// "default" to the CommonJS "module.exports" for node compatibility.
				isNodeMode || !mod || !mod.__esModule
					? __defProp(target, 'default', { value: mod, enumerable: true })
					: target,
				mod)
		)

		// Converts the module from ESM to CommonJS. This clones the input module
		// object with the addition of a non-enumerable "__esModule" property set
		// to "true", which overwrites any existing export named "__esModule".
		export var __toCommonJS = mod => __copyProps(__defProp({}, '__esModule', { value: true }), mod)

		// For TypeScript experimental decorators
		// - kind === undefined: class
		// - kind === 1: method, parameter
		// - kind === 2: field
		export var __decorateClass = (decorators, target, key, kind) => {
			var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target
			for (var i = decorators.length - 1, decorator; i >= 0; i--)
				if (decorator = decorators[i])
					result = (kind ? decorator(target, key, result) : decorator(result)) || result
			if (kind && result) __defProp(target, key, result)
			return result
		}
shell
rg --files | rg '(_test\.go|runtime|compat|js_parser|bundler)'
output
Chunk ID: 60f6c7
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 621
Output:
pkg/api/api_impl_test.go
pkg/api/api_test.go
internal/bundler_tests/bundler_dce_test.go
internal/bundler_tests/bundler_glob_test.go
internal/bundler_tests/bundler_lower_test.go
internal/bundler_tests/bundler_importphase_test.go
internal/bundler_tests/snapshots/snapshots_dce.txt
internal/bundler_tests/snapshots/snapshots_splitting.txt
internal/bundler_tests/snapshots/snapshots_lower.txt
internal/bundler_tests/snapshots/snapshots_yarnpnp.txt
internal/bundler_tests/snapshots/snapshots_css.txt
internal/bundler_tests/snapshots/snapshots_packagejson.txt
internal/bundler_tests/snapshots/snapshots_importphase.txt
internal/bundler_tests/snapshots/snapshots_ts.txt
internal/bundler_tests/snapshots/snapshots_default.txt
internal/bundler_tests/snapshots/snapshots_tsconfig.txt
internal/bundler_tests/snapshots/snapshots_glob.txt
internal/bundler_tests/snapshots/snapshots_importstar.txt
internal/bundler_tests/snapshots/snapshots_loader.txt
internal/bundler_tests/snapshots/snapshots_importstar_ts.txt
internal/bundler_tests/bundler_importstar_ts_test.go
internal/bundler_tests/bundler_splitting_test.go
internal/bundler_tests/bundler_test.go
internal/bundler_tests/bundler_ts_test.go
internal/bundler_tests/bundler_loader_test.go
internal/bundler_tests/bundler_css_test.go
internal/bundler_tests/bundler_yarnpnp_test.go
internal/bundler_tests/bundler_packagejson_test.go
internal/bundler_tests/bundler_tsconfig_test.go
internal/bundler_tests/bundler_importstar_test.go
internal/bundler_tests/bundler_default_test.go
internal/resolver/yarnpnp_test.go
internal/js_lexer/js_lexer_test.go
internal/css_lexer/css_lexer_test.go
internal/js_parser/sourcemap_parser.go
internal/js_parser/ts_parser_test.go
internal/js_parser/ts_parser.go
internal/js_parser/js_parser_lower_class.go
internal/js_parser/js_parser.go
internal/js_parser/js_parser_lower.go
internal/js_parser/global_name_parser.go
internal/js_parser/json_parser.go
internal/js_parser/js_parser_test.go
internal/js_parser/js_parser_lower_test.go
internal/js_parser/json_parser_test.go
internal/helpers/dataurl_test.go
internal/compat/compat.go
internal/compat/css_table.go
internal/compat/js_table.go
internal/compat/compat_test.go
internal/css_parser/css_parser_test.go
internal/css_printer/css_printer_test.go
internal/bundler/bundler.go
internal/js_ast/js_ast_test.go
internal/fs/fs_mock_test.go
internal/runtime/runtime.go
internal/runtime/runtime_test.go
internal/logger/logger_test.go
internal/js_printer/js_printer_test.go
shell
git status --short
output
Chunk ID: 1f0a37
Wall time: 0.0000 seconds
Process exited with code 128
Original token count: 18
Output:
fatal: not a git repository (or any of the parent directories): .git
The repo isn’t a git checkout, so I’ll avoid relying on git state. I found the lowering snapshots and the async generator helpers in `internal/runtime/runtime.go`; next I’m narrowing the runtime semantics and test harness shape.
shell
sed -n '390,490p' internal/runtime/runtime.go
output
Chunk ID: 9a2e05
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 821
Output:
		// This helps for lowering async functions
		export var __async = (__this, __arguments, generator) => {
			return new Promise((resolve, reject) => {
				var fulfilled = value => {
					try {
						step(generator.next(value))
					} catch (e) {
						reject(e)
					}
				}
				var rejected = value => {
					try {
						step(generator.throw(value))
					} catch (e) {
						reject(e)
					}
				}
				var step = x => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected)
				step((generator = generator.apply(__this, __arguments)).next())
			})
		}

		// These help for lowering async generator functions
		export var __await = function (promise, isYieldStar) {
			this[0] = promise
			this[1] = isYieldStar
		}
		export var __asyncGenerator = (__this, __arguments, generator) => {
			var resume = (k, v, yes, no) => {
				try {
					var x = generator[k](v), isAwait = (v = x.value) instanceof __await, done = x.done
					Promise.resolve(isAwait ? v[0] : v)
						.then(y => isAwait
							? resume(k === 'return' ? k : 'next', v[1] ? { done: y.done, value: y.value } : y, yes, no)
							: yes({ value: y, done }))
						.catch(e => resume('throw', e, yes, no))
				} catch (e) {
					no(e)
				}
			}, method = k => it[k] = x => new Promise((yes, no) => resume(k, x, yes, no)), it = {}
			return generator = generator.apply(__this, __arguments),
				it[__knownSymbol('asyncIterator')] = () => it,
				method('next'),
				method('throw'),
				method('return'),
				it
		}
		export var __yieldStar = value => {
			var obj = value[__knownSymbol('asyncIterator')], isAwait = false, method, it = {}
			if (obj == null) {
				obj = value[__knownSymbol('iterator')]()
				method = k => it[k] = x => obj[k](x)
			} else {
				obj = obj.call(value)
				method = k => it[k] = v => {
					if (isAwait) {
						isAwait = false
						if (k === 'throw') throw v
						return v
					}
					isAwait = true
					return {
						done: false,
						value: new __await(new Promise(resolve => {
							var x = obj[k](v)
							if (!(x instanceof Object)) __typeError('Object expected')
							resolve(x)
						}), 1),
					}
				}
			}
			return it[__knownSymbol('iterator')] = () => it,
				method('next'),
				'throw' in obj ? method('throw') : it.throw = x => { throw x },
				'return' in obj && method('return'),
				it
		}

		// This helps for lowering for-await loops
		export var __forAwait = (obj, it, method) =>
			(it = obj[__knownSymbol('asyncIterator')])
				? it.call(obj)
				: (obj = obj[__knownSymbol('iterator')](),
					it = {},
					method = (key, fn) =>
						(fn = obj[key]) && (it[key] = arg =>
							new Promise((yes, no, done) => (
								arg = fn.call(obj, arg),
								done = arg.done,
								Promise.resolve(arg.value)
									.then(value => yes({ value, done }), no)
							))),
					method('next'),
					method('return'),
					it)

		// This is for the "binary" loader (custom code is ~2x faster than "atob")
		export var __toBinaryNode = Uint8Array.fromBase64 || (base64 => new Uint8Array(Buffer.from(base64, 'base64')))
		export var __toBinary = Uint8Array.fromBase64 || /* @__PURE__ */ (() => {
			var table = new Uint8Array(128)
			for (var i = 0; i < 64; i++) table[i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i * 4 - 205] = i
shell
sed -n '2970,3130p' internal/bundler_tests/bundler_lower_test.go
output
Chunk ID: 6ff844
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1013
Output:
		options: config.Options{
			Mode:                  config.ModePassThrough,
			AbsOutputDir:          "/out",
			UnsupportedJSFeatures: compat.Using,
		},
	})
}

func TestLowerUsingInsideTSNamespace(t *testing.T) {
	lower_suite.expectBundled(t, bundled{
		files: map[string]string{
			"/entry.ts": `
				namespace ns {
					export let a = b
					using c = d
					export let e = f
				}
			`,
		},
		entryPaths: []string{"/entry.ts"},
		options: config.Options{
			Mode:                  config.ModePassThrough,
			AbsOutputDir:          "/out",
			UnsupportedJSFeatures: compat.Using,
		},
	})
}

func TestLowerAsyncGenerator(t *testing.T) {
	lower_suite.expectBundled(t, bundled{
		files: map[string]string{
			"/entry.ts": `
				async function* foo() {
					yield
					yield x
					yield *x
					await using x = await y
					for await (let x of y) {}
					for await (await using x of y) {}
				}
				foo = async function* () {
					yield
					yield x
					yield *x
					await using x = await y
					for await (let x of y) {}
					for await (await using x of y) {}
				}
				foo = { async *bar () {
					yield
					yield x
					yield *x
					await using x = await y
					for await (let x of y) {}
					for await (await using x of y) {}
				} }
				class Foo { async *bar () {
					yield
					yield x
					yield *x
					await using x = await y
					for await (let x of y) {}
					for await (await using x of y) {}
				} }
				Foo = class { async *bar () {
					yield
					yield x
					yield *x
					await using x = await y
					for await (let x of y) {}
					for await (await using x of y) {}
				} }
				async function bar() {
					await using x = await y
					for await (let x of y) {}
					for await (await using x of y) {}
				}
			`,
		},
		entryPaths: []string{"/entry.ts"},
		options: config.Options{
			Mode:                  config.ModePassThrough,
			AbsOutputDir:          "/out",
			UnsupportedJSFeatures: compat.AsyncGenerator,
		},
	})
}

func TestLowerAsyncGeneratorNoAwait(t *testing.T) {
	lower_suite.expectBundled(t, bundled{
		files: map[string]string{
			"/entry.ts": `
				async function* foo() {
					yield
					yield x
					yield *x
					await using x = await y
					for await (let x of y) {}
					for await (await using x of y) {}
				}
				foo = async function* () {
					yield
					yield x
					yield *x
					await using x = await y
					for await (let x of y) {}
					for await (await using x of y) {}
				}
				foo = { async *bar () {
					yield
					yield x
					yield *x
					await using x = await y
					for await (let x of y) {}
					for await (await using x of y) {}
				} }
				class Foo { async *bar () {
					yield
					yield x
					yield *x
					await using x = await y
					for await (let x of y) {}
					for await (await using x of y) {}
				} }
				Foo = class { async *bar () {
					yield
					yield x
					yield *x
					await using x = await y
					for await (let x of y) {}
					for await (await using x of y) {}
				} }
				async function bar() {
					await using x = await y
					for await (let x of y) {}
					for await (await using x of y) {}
				}
			`,
		},
		entryPaths: []string{"/entry.ts"},
		options: config.Options{
			Mode:                  config.ModePassThrough,
			AbsOutputDir:          "/out",
			UnsupportedJSFeatures: compat.AsyncGenerator | compat.AsyncAwait,
		},
	})
}

// https://[code-host]/evanw/esbuild/issues/3768
func TestJavaScriptDecoratorsBundleIssue3768(t *testing.T) {
	lower_suite.expectBundled(t, bundled{
		files: map[string]string{
			"/base-instance-method.js":   `class Foo { @dec foo() { return Foo } }`,
			"/base-instance-field.js":    `class Foo { @dec foo = Foo }`,
			"/base-instance-accessor.js": `class Foo { @dec accessor foo = Foo }`,

			"/base-static-method.js":   `class Foo { @dec static foo() { return Foo } }`,
			"/base-static-field.js":    `class Foo { @dec static foo = Foo }`,
			"/base-static-accessor.js": `class Foo { @dec static accessor foo = Foo }`,

			"/derived-instance-method.js":   `class Foo extends Bar { @dec foo() { return Foo } }`,
shell
sed -n '1,220p' internal/runtime/runtime_test.go
output
Chunk ID: 31e1b1
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 228
Output:
package runtime_test

import (
	"testing"

	"[code-host]/evanw/esbuild/internal/compat"
	"[code-host]/evanw/esbuild/internal/config"
	"[code-host]/evanw/esbuild/internal/js_parser"
	"[code-host]/evanw/esbuild/internal/logger"
	"[code-host]/evanw/esbuild/internal/runtime"
)

func TestUnsupportedFeatures(t *testing.T) {
	for key, feature := range compat.StringToJSFeature {
		t.Run(key, func(t *testing.T) {
			source := runtime.Source(feature)
			log := logger.NewDeferLog(logger.DeferLogAll, nil)

			js_parser.Parse(log, source, js_parser.OptionsFromConfig(&config.Options{
				UnsupportedJSFeatures: feature,
				TreeShaking:           true,
			}))

			if log.HasErrors() {
				msgs := "Internal error: failed to parse runtime:\n"
				for _, msg := range log.Done() {
					msgs += msg.String(logger.OutputOptions{IncludeSource: true}, logger.TerminalInfo{})
				}
				t.Fatal(msgs[:len(msgs)-1])
			}
		})
	}
}
shell
rg -n "Run|node|exec|snapshots|Expect" internal/bundler_tests internal/runtime pkg/api | head -200
output
Chunk ID: aa1d91
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 5505
Output:
internal/bundler_tests/bundler_dce_test.go:22:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:26:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:47:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:51:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:72:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:76:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:97:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:101:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:122:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:126:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:147:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:151:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:173:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:177:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:188:		expectedScanLog: `Users/user/project/src/entry.js: WARNING: Ignoring this import because "Users/user/project/node_modules/demo-pkg/index.js" was marked as having no side effects
internal/bundler_tests/bundler_dce_test.go:189:Users/user/project/node_modules/demo-pkg/package.json: NOTE: "sideEffects" is false in the enclosing "package.json" file:
internal/bundler_tests/bundler_dce_test.go:202:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:206:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:217:		expectedScanLog: `Users/user/project/src/entry.js: WARNING: Ignoring this import because "Users/user/project/node_modules/demo-pkg/index.js" was marked as having no side effects
internal/bundler_tests/bundler_dce_test.go:218:Users/user/project/node_modules/demo-pkg/package.json: NOTE: "sideEffects" is false in the enclosing "package.json" file:
internal/bundler_tests/bundler_dce_test.go:230:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:234:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:245:		expectedScanLog: `Users/user/project/src/entry.js: WARNING: Ignoring this import because "Users/user/project/node_modules/demo-pkg/index.js" was marked as having no side effects
internal/bundler_tests/bundler_dce_test.go:246:Users/user/project/node_modules/demo-pkg/package.json: NOTE: "sideEffects" is false in the enclosing "package.json" file:
internal/bundler_tests/bundler_dce_test.go:258:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:262:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:273:		expectedScanLog: `Users/user/project/src/entry.js: WARNING: Ignoring this import because "Users/user/project/node_modules/demo-pkg/index.js" was marked as having no side effects
internal/bundler_tests/bundler_dce_test.go:274:Users/user/project/node_modules/demo-pkg/package.json: NOTE: "sideEffects" is false in the enclosing "package.json" file:
internal/bundler_tests/bundler_dce_test.go:286:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:290:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:311:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:315:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:336:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:340:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:361:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:365:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:386:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:390:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:411:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:415:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:436:			"~/project/node_modules/demo-pkg/index-main.js": `
internal/bundler_tests/bundler_dce_test.go:440:			"~/project/node_modules/demo-pkg/index-module.js": `
internal/bundler_tests/bundler_dce_test.go:444:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:468:			"~/project/node_modules/demo-pkg/index-main.js": `
internal/bundler_tests/bundler_dce_test.go:472:			"~/project/node_modules/demo-pkg/index-module.js": `
internal/bundler_tests/bundler_dce_test.go:476:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:500:			"~/project/node_modules/demo-pkg/index-main.js": `
internal/bundler_tests/bundler_dce_test.go:504:			"~/project/node_modules/demo-pkg/index-module.js": `
internal/bundler_tests/bundler_dce_test.go:508:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:536:			"~/project/node_modules/demo-pkg/index-main.js": `
internal/bundler_tests/bundler_dce_test.go:540:			"~/project/node_modules/demo-pkg/index-module.js": `
internal/bundler_tests/bundler_dce_test.go:544:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:567:			"~/project/node_modules/demo-pkg/index-main.js": `
internal/bundler_tests/bundler_dce_test.go:571:			"~/project/node_modules/demo-pkg/index-module.js": `
internal/bundler_tests/bundler_dce_test.go:575:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:599:			"~/project/node_modules/demo-pkg/index-main.js": `
internal/bundler_tests/bundler_dce_test.go:603:			"~/project/node_modules/demo-pkg/index-module.js": `
internal/bundler_tests/bundler_dce_test.go:607:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:631:			"~/project/node_modules/demo-pkg/index-main.js": `
internal/bundler_tests/bundler_dce_test.go:635:			"~/project/node_modules/demo-pkg/index-module.js": `
internal/bundler_tests/bundler_dce_test.go:639:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:667:			"~/project/node_modules/demo-pkg/index-main.js": `
internal/bundler_tests/bundler_dce_test.go:671:			"~/project/node_modules/demo-pkg/index-module.js": `
internal/bundler_tests/bundler_dce_test.go:675:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:698:			"~/project/node_modules/demo-pkg/keep/this/file.js": `
internal/bundler_tests/bundler_dce_test.go:701:			"~/project/node_modules/demo-pkg/remove/this/file.js": `
internal/bundler_tests/bundler_dce_test.go:704:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:719:		expectedScanLog: `Users/user/project/src/entry.js: WARNING: Ignoring this import because "Users/user/project/node_modules/demo-pkg/remove/this/file.js" was marked as having no side effects
internal/bundler_tests/bundler_dce_test.go:720:Users/user/project/node_modules/demo-pkg/package.json: NOTE: It was excluded from the "sideEffects" array in the enclosing "package.json" file:
internal/bundler_tests/bundler_dce_test.go:732:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:737:			"~/project/node_modules/demo-pkg/a/b/c/index.js": `
internal/bundler_tests/bundler_dce_test.go:757:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:760:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:781:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:785:			"~/project/node_modules/demo-pkg2/index.js": `
internal/bundler_tests/bundler_dce_test.go:789:			"~/project/node_modules/demo-pkg2/package.json": `
internal/bundler_tests/bundler_dce_test.go:809:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:813:			"~/project/node_modules/demo-pkg/foo.js": `
internal/bundler_tests/bundler_dce_test.go:816:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:835:			"~/project/node_modules/demo-pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:839:			"~/project/node_modules/demo-pkg/foo.js": `
internal/bundler_tests/bundler_dce_test.go:842:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:861:			"~/project/node_modules/a/index.js": `
internal/bundler_tests/bundler_dce_test.go:864:			"~/project/node_modules/a/package.json": `
internal/bundler_tests/bundler_dce_test.go:867:			"~/project/node_modules/b/index.js": `
internal/bundler_tests/bundler_dce_test.go:871:			"~/project/node_modules/b/package.json": `
internal/bundler_tests/bundler_dce_test.go:874:			"~/project/node_modules/c/index.js": `
internal/bundler_tests/bundler_dce_test.go:877:			"~/project/node_modules/c/package.json": `
internal/bundler_tests/bundler_dce_test.go:880:			"~/project/node_modules/d/index.js": `
internal/bundler_tests/bundler_dce_test.go:883:			"~/project/node_modules/d/package.json": `
internal/bundler_tests/bundler_dce_test.go:902:			"~/project/node_modules/a/index.js": `
internal/bundler_tests/bundler_dce_test.go:905:			"~/project/node_modules/b/index.js": `
internal/bundler_tests/bundler_dce_test.go:909:			"~/project/node_modules/b/package.json": `
internal/bundler_tests/bundler_dce_test.go:912:			"~/project/node_modules/c/index.js": `
internal/bundler_tests/bundler_dce_test.go:915:			"~/project/node_modules/d/index.js": `
internal/bundler_tests/bundler_dce_test.go:934:			"~/project/node_modules/a/index.js": `
internal/bundler_tests/bundler_dce_test.go:938:			"~/project/node_modules/b1/index.js": `
internal/bundler_tests/bundler_dce_test.go:942:			"~/project/node_modules/b1/package.json": `
internal/bundler_tests/bundler_dce_test.go:945:			"~/project/node_modules/b2/index.js": `
internal/bundler_tests/bundler_dce_test.go:949:			"~/project/node_modules/b2/package.json": `
internal/bundler_tests/bundler_dce_test.go:952:			"~/project/node_modules/c/index.js": `
internal/bundler_tests/bundler_dce_test.go:955:			"~/project/node_modules/d/index.js": `
internal/bundler_tests/bundler_dce_test.go:973:			"~/project/node_modules/a/index.js": `
internal/bundler_tests/bundler_dce_test.go:976:			"~/project/node_modules/b/index.js": `
internal/bundler_tests/bundler_dce_test.go:980:			"~/project/node_modules/b/package.json": `
internal/bundler_tests/bundler_dce_test.go:983:			"~/project/node_modules/c/index.js": `
internal/bundler_tests/bundler_dce_test.go:987:			"~/project/node_modules/d/index.js": `
internal/bundler_tests/bundler_dce_test.go:1005:			"~/project/node_modules/a/index.js": `
internal/bundler_tests/bundler_dce_test.go:1008:			"~/project/node_modules/b/index.js": `
internal/bundler_tests/bundler_dce_test.go:1012:			"~/project/node_modules/b/package.json": `
internal/bundler_tests/bundler_dce_test.go:1015:			"~/project/node_modules/c/index.js": `
internal/bundler_tests/bundler_dce_test.go:1019:			"~/project/node_modules/c/package.json": `
internal/bundler_tests/bundler_dce_test.go:1022:			"~/project/node_modules/d/index.js": `
internal/bundler_tests/bundler_dce_test.go:1025:			"~/project/node_modules/d/package.json": `
internal/bundler_tests/bundler_dce_test.go:1571:			"~/project/node_modules/pkg/index.js": `
internal/bundler_tests/bundler_dce_test.go:1575:			"~/project/node_modules/pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:1578:			"~/project/node_modules/pkg/foo.js": `
internal/bundler_tests/bundler_dce_test.go:1581:			"~/project/node_modules/pkg/bar.js": `
internal/bundler_tests/bundler_dce_test.go:3780:			"~/project/node_modules/demo-pkg/foo.js": `
internal/bundler_tests/bundler_dce_test.go:3783:			"~/project/node_modules/demo-pkg/bar/index.js": `
internal/bundler_tests/bundler_dce_test.go:3786:			"~/project/node_modules/demo-pkg/package.json": `
internal/bundler_tests/bundler_dce_test.go:3811:			"/project/node_modules/pkg/button.js": `
internal/bundler_tests/bundler_dce_test.go:3815:			"/project/node_modules/pkg/button.css": `
internal/bundler_tests/bundler_dce_test.go:3818:			"/project/node_modules/pkg/menu.js": `
internal/bundler_tests/bundler_dce_test.go:3822:			"/project/node_modules/pkg/menu.css": `
internal/bundler_tests/bundler_dce_test.go:3841:			"/project/node_modules/pkg/entry.js": `
internal/bundler_tests/bundler_dce_test.go:3844:			"/project/node_modules/pkg/package.json": `{
internal/bundler_tests/bundler_dce_test.go:3848:			"/project/node_modules/pkg/components.jsx": `
internal/bundler_tests/bundler_dce_test.go:3852:			"/project/node_modules/pkg/button.css": `
internal/bundler_tests/bundler_dce_test.go:3871:			"/project/node_modules/pkg/entry.js": `
internal/bundler_tests/bundler_dce_test.go:3874:			"/project/node_modules/pkg/package.json": `{
internal/bundler_tests/bundler_dce_test.go:3878:			"/project/node_modules/pkg/components.jsx": `
internal/bundler_tests/bundler_dce_test.go:3882:			"/project/node_modules/pkg/button.css": `
internal/bundler_tests/bundler_dce_test.go:3901:			"/project/node_modules/pkg/entry.js": `
internal/bundler_tests/bundler_dce_test.go:3904:			"/project/node_modules/pkg/package.json": `{
internal/bundler_tests/bundler_dce_test.go:3908:			"/project/node_modules/pkg/components.jsx": `
internal/bundler_tests/bundler_dce_test.go:3912:			"/project/node_modules/pkg/button.css": `
internal/bundler_tests/bundler_dce_test.go:3931:			"/project/node_modules/pkg/entry.js": `
internal/bundler_tests/bundler_dce_test.go:3934:			"/project/node_modules/pkg/package.json": `{
internal/bundler_tests/bundler_dce_test.go:3938:			"/project/node_modules/pkg/components.jsx": `
internal/bundler_tests/bundler_dce_test.go:3942:			"/project/node_modules/pkg/button.css": `
internal/bundler_tests/bundler_dce_test.go:3961:			"/project/node_modules/pkg/package.json": `{
internal/bundler_tests/bundler_dce_test.go:3964:			"/project/node_modules/pkg/button.jsx": `
internal/bundler_tests/bundler_dce_test.go:3968:			"/project/node_modules/pkg/styles.js": `
internal/bundler_tests/bundler_dce_test.go:3972:			"/project/node_modules/pkg/styles.css": `
internal/bundler_tests/bundler_dce_test.go:3991:			"/project/node_modules/pkg/package.json": `{
internal/bundler_tests/bundler_dce_test.go:3994:			"/project/node_modules/pkg/button.jsx": `
internal/bundler_tests/bundler_dce_test.go:3998:			"/project/node_modules/pkg/styles.js": `
internal/bundler_tests/bundler_dce_test.go:4002:			"/project/node_modules/pkg/styles.css": `
internal/bundler_tests/snapshots/snapshots_dce.txt:1174:// Users/user/project/node_modules/pkg/foo.js
internal/bundler_tests/snapshots/snapshots_dce.txt:1176:  "Users/user/project/node_modules/pkg/foo.js"(exports, module) {
internal/bundler_tests/snapshots/snapshots_dce.txt:1181:// Users/user/project/node_modules/pkg/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2228:// Users/user/project/node_modules/demo-pkg/keep/this/file.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2234:// Users/user/project/node_modules/demo-pkg/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2243:// Users/user/project/node_modules/demo-pkg/index-main.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2250:  "Users/user/project/node_modules/demo-pkg/index-main.js"() {
internal/bundler_tests/snapshots/snapshots_dce.txt:2274:// Users/user/project/node_modules/demo-pkg/index-main.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2289:// Users/user/project/node_modules/demo-pkg/index-main.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2296:  "Users/user/project/node_modules/demo-pkg/index-main.js"() {
internal/bundler_tests/snapshots/snapshots_dce.txt:2311:// Users/user/project/node_modules/demo-pkg/index-module.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2326:// Users/user/project/node_modules/demo-pkg/index-module.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2341:// Users/user/project/node_modules/c/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2344:  "Users/user/project/node_modules/c/index.js"() {
internal/bundler_tests/snapshots/snapshots_dce.txt:2349:// Users/user/project/node_modules/b/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2351:  "Users/user/project/node_modules/b/index.js"() {
internal/bundler_tests/snapshots/snapshots_dce.txt:2356:// Users/user/project/node_modules/a/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2362:  "Users/user/project/node_modules/a/index.js"() {
internal/bundler_tests/snapshots/snapshots_dce.txt:2373:// Users/user/project/node_modules/demo-pkg/foo.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2376:// Users/user/project/node_modules/demo-pkg/bar/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2382:// Users/user/project/node_modules/d/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2385:// Users/user/project/node_modules/b/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2394:// Users/user/project/node_modules/d/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2397:// Users/user/project/node_modules/b/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2406:// Users/user/project/node_modules/d/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2409:// Users/user/project/node_modules/b1/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2412:// Users/user/project/node_modules/b2/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2425:// Users/user/project/node_modules/demo-pkg/foo.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2428:// Users/user/project/node_modules/demo-pkg/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2437:// Users/user/project/node_modules/demo-pkg/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2439:  "Users/user/project/node_modules/demo-pkg/index.js"(exports) {
internal/bundler_tests/snapshots/snapshots_dce.txt:2452:// Users/user/project/node_modules/demo-pkg/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2459:  "Users/user/project/node_modules/demo-pkg/index.js"() {
internal/bundler_tests/snapshots/snapshots_dce.txt:2472:// Users/user/project/node_modules/demo-pkg/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2474:  "Users/user/project/node_modules/demo-pkg/index.js"(exports) {
internal/bundler_tests/snapshots/snapshots_dce.txt:2487:// Users/user/project/node_modules/demo-pkg/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2497:// Users/user/project/node_modules/demo-pkg/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2499:  "Users/user/project/node_modules/demo-pkg/index.js"(exports) {
internal/bundler_tests/snapshots/snapshots_dce.txt:2512:// Users/user/project/node_modules/demo-pkg/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2526:// Users/user/project/node_modules/demo-pkg/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2535:// Users/user/project/node_modules/c/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2538:  "Users/user/project/node_modules/c/index.js"() {
internal/bundler_tests/snapshots/snapshots_dce.txt:2543:// Users/user/project/node_modules/d/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2545:  "Users/user/project/node_modules/d/index.js"() {
internal/bundler_tests/snapshots/snapshots_dce.txt:2549:// Users/user/project/node_modules/b/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2551:  "Users/user/project/node_modules/b/index.js"() {
internal/bundler_tests/snapshots/snapshots_dce.txt:2557:// Users/user/project/node_modules/a/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2563:  "Users/user/project/node_modules/a/index.js"() {
internal/bundler_tests/snapshots/snapshots_dce.txt:2610:// Users/user/project/node_modules/demo-pkg/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2625:// Users/user/project/node_modules/demo-pkg/index.js
internal/bundler_tests/snapshots/snapshots_dce.txt:2627:  "Users/user/project/node_modules/demo-pkg/index.js"(exports) {
shell
node --version
output
Chunk ID: 14e59f
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 3
Output:
v22.23.0
shell
rg -n "__await|__yieldStar|__asyncGenerator" internal/bundler_tests/snapshots/snapshots_lower.txt | head -40
output
Chunk ID: c8f40a
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 804
Output:
1180:  return __asyncGenerator(this, null, function* () {
1185:      yield* __yieldStar(x);
1186:      const x = __using(_stack2, yield new __await(y), true);
1188:        for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
1195:          more && (temp = iter.return) && (yield new __await(temp.call(iter)));
1202:        for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
1211:            _promise && (yield new __await(_promise));
1218:          more2 && (temp2 = iter2.return) && (yield new __await(temp2.call(iter2)));
1228:      _promise2 && (yield new __await(_promise2));
1233:  return __asyncGenerator(this, null, function* () {
1238:      yield* __yieldStar(x);
1239:      const x = __using(_stack2, yield new __await(y), true);
1241:        for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
1248:          more && (temp = iter.return) && (yield new __await(temp.call(iter)));
1255:        for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
1264:            _promise && (yield new __await(_promise));
1271:          more2 && (temp2 = iter2.return) && (yield new __await(temp2.call(iter2)));
1281:      _promise2 && (yield new __await(_promise2));
1286:  return __asyncGenerator(this, null, function* () {
1291:      yield* __yieldStar(x);
1292:      const x = __using(_stack2, yield new __await(y), true);
1294:        for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
1301:          more && (temp = iter.return) && (yield new __await(temp.call(iter)));
1308:        for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
1317:            _promise && (yield new __await(_promise));
1324:          more2 && (temp2 = iter2.return) && (yield new __await(temp2.call(iter2)));
1334:      _promise2 && (yield new __await(_promise2));
1340:    return __asyncGenerator(this, null, function* () {
1345:        yield* __yieldStar(x);
1346:        const x = __using(_stack2, yield new __await(y), true);
1348:          for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
1355:            more && (temp = iter.return) && (yield new __await(temp.call(iter)));
1362:          for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
1371:              _promise && (yield new __await(_promise));
1378:            more2 && (temp2 = iter2.return) && (yield new __await(temp2.call(iter2)));
1388:        _promise2 && (yield new __await(_promise2));
1395:    return __asyncGenerator(this, null, function* () {
1400:        yield* __yieldStar(x);
1401:        const x = __using(_stack2, yield new __await(y), true);
1403:          for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
shell
sed -n '1170,1215p' internal/bundler_tests/snapshots/snapshots_lower.txt
output
Chunk ID: 1b2dfa
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 363
Output:
  foo1_default as foo1,
  foo2_default as foo2,
  foo3_default as foo3,
  foo4_default as foo4
};

================================================================================
TestLowerAsyncGenerator
---------- /out/entry.js ----------
function foo() {
  return __asyncGenerator(this, null, function* () {
    var _stack2 = [];
    try {
      yield;
      yield x;
      yield* __yieldStar(x);
      const x = __using(_stack2, yield new __await(y), true);
      try {
        for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
          let x2 = temp.value;
        }
      } catch (temp) {
        error = [temp];
      } finally {
        try {
          more && (temp = iter.return) && (yield new __await(temp.call(iter)));
        } finally {
          if (error)
            throw error[0];
        }
      }
      try {
        for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
          var _x = temp2.value;
          var _stack = [];
          try {
            const x2 = __using(_stack, _x, true);
          } catch (_) {
            var _error = _, _hasError = true;
          } finally {
            var _promise = __callDispose(_stack, _error, _hasError);
            _promise && (yield new __await(_promise));
          }
        }
      } catch (temp2) {
        error2 = [temp2];
shell
node - <<'JS'
let log=[];
async function* g(){ log.push('body'); await 0; log.push('after await'); yield 'x'; }
let it=g(); let p=it.next(); log.push('after next call'); p.then(x=>log.push('p '+JSON.stringify(x))); Promise.resolve().then(()=>log.push('micro')); setTimeout(()=>console.log(log),0);
JS
output
Chunk ID: 9aab76
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 24
Output:
[
  'body',
  'after next call',
  'after await',
  'micro',
  'p {"value":"x","done":false}'
]
A key edge is whether the internal queue advances before or after user-visible resolution handlers for the prior iterator promise. I’m checking native Node’s ordering now because that determines how the promise chain should be wired.
shell
node - <<'JS'
let log=[];
async function* inner(){try{log.push('inner start'); yield await Promise.resolve('v1'); log.push('inner after yield')}finally{log.push('finally before yield'); yield 'cleanup'; log.push('finally after yield')}}
async function* outer(){yield* inner()}
let it=outer();
let p1=it.next();
let p2=it.return('done');
p1.then(x=>{log.push('p1 then '+JSON.stringify(x)+' log='+JSON.stringify(log))});
p2.then(x=>{log.push('p2 then '+JSON.stringify(x))});
setTimeout(()=>console.log(log),0);
JS
output
Chunk ID: 92e2cd
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 39
Output:
[
  'inner start',
  'p1 then {"value":"v1","done":false} log=["inner start"]',
  'finally before yield',
  'p2 then {"value":"cleanup","done":false}'
]
shell
node - <<'JS'
let log=[];
async function* g(){let x; log.push('start'); x=yield await Promise.resolve('v1'); log.push('after yield '+x); yield 'v2'}
let it=g(); let p1=it.next(); let p2=it.next('sent');
p1.then(x=>{log.push('p1 then '+JSON.stringify(x)+' log='+JSON.stringify(log))});
p2.then(x=>{log.push('p2 then '+JSON.stringify(x)+' log='+JSON.stringify(log))});
setTimeout(()=>console.log(log),0);
JS
output
Chunk ID: bc7a22
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 69
Output:
[
  'start',
  'after yield sent',
  'p1 then {"value":"v1","done":false} log=["start","after yield sent"]',
  'p2 then {"value":"v2","done":false} log=["start","after yield sent","p1 then {\\"value\\":\\"v1\\",\\"done\\":false} log=[\\"start\\",\\"after yield sent\\"]"]'
]
shell
node - <<'JS'
let log=[];
async function* g(){try{log.push('start'); yield await Promise.resolve('v1')}catch(e){log.push('catch '+e); yield 'rec'}}
let it=g(); let p1=it.next(); let p2=it.throw('err');
p1.then(x=>{log.push('p1 then '+JSON.stringify(x)+' log='+JSON.stringify(log))});
p2.then(x=>{log.push('p2 then '+JSON.stringify(x)+' log='+JSON.stringify(log))});
setTimeout(()=>console.log(log),0);
JS
output
Chunk ID: f8b6e4
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 62
Output:
[
  'start',
  'catch err',
  'p1 then {"value":"v1","done":false} log=["start","catch err"]',
  'p2 then {"value":"rec","done":false} log=["start","catch err","p1 then {\\"value\\":\\"v1\\",\\"done\\":false} log=[\\"start\\",\\"catch err\\"]"]'
]
shell
node - <<'JS'
async function* inner(){try{yield 'v1'}finally{let x=yield 'cleanup'; console.log('inner got',x);}}
async function* outer(){let y=yield* inner(); console.log('outer y', y); return 'outer'}
(async()=>{let it=outer(); let p1=it.next(); let p2=it.return('done'); let p3=it.next('after'); console.log(await p1); console.log(await p2); console.log(await p3); console.log(await it.next());})()
JS
output
Chunk ID: cd6267
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 39
Output:
{ value: 'v1', done: false }
inner got after
{ value: 'cleanup', done: false }
outer y done
{ value: 'outer', done: true }
{ value: undefined, done: true }
shell
node - <<'JS'
let log=[]; async function* g(){try{log.push('start'); yield 1}finally{log.push('finally')}}
let it=g(); let p=it.return('x'); log.push('after'); p.then(v=>log.push(JSON.stringify(v))); setTimeout(()=>console.log(log),0)
JS
output
Chunk ID: 3bdff8
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 11
Output:
[ 'after', '{"value":"x","done":true}' ]
shell
node - <<'JS'
let log=[]; async function* g(){try{log.push('start'); yield 1}catch(e){log.push('catch')}}
let it=g(); let p=it.throw('x'); log.push('after'); p.then(v=>log.push('ok '+JSON.stringify(v)),e=>log.push('err '+e)); setTimeout(()=>console.log(log),0)
JS
output
Chunk ID: 225e94
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 6
Output:
[ 'after', 'err x' ]
shell
node - <<'JS'
let log=[]; async function* g(){yield 1; log.push('after second call'); yield 2}
let it=g(); let p=it.next(); p.then(async r=>{log.push('p then before'); let q=it.next(); log.push('p then after'); q.then(x=>log.push('q then '+JSON.stringify(x)));}); setTimeout(()=>console.log(log),0)
JS
output
Chunk ID: b9a451
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 25
Output:
[
  'p then before',
  'after second call',
  'p then after',
  'q then {"value":2,"done":false}'
]
shell
node - <<'JS'
let log=[]; async function* g(){yield 1; log.push('after yield1'); yield 2; log.push('after yield2'); yield 3}
let it=g(); let p1=it.next(); let p2=it.next('a');
p1.then(r=>{log.push('p1 before'); let p3=it.next('b'); log.push('p1 after'); p3.then(x=>log.push('p3 '+JSON.stringify(x)))});
p2.then(r=>log.push('p2 '+JSON.stringify(r)));
setTimeout(()=>console.log(log),0)
JS
output
Chunk ID: a22290
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 34
Output:
[
  'after yield1',
  'p1 before',
  'p1 after',
  'after yield2',
  'p2 {"value":2,"done":false}',
  'p3 {"value":3,"done":false}'
]
shell
node - <<'JS'
let log=[]; async function* g(){yield 1}
let p=g().next(); p.then(()=>log.push('p')); Promise.resolve().then(()=>log.push('micro1')).then(()=>log.push('micro2')); setTimeout(()=>console.log(log),0)
JS
output
Chunk ID: d3ef1f
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 7
Output:
[ 'micro1', 'p', 'micro2' ]
shell
node - <<'JS'
let log=[];
async function* inner(){try{yield await Promise.resolve('v1'); log.push('after v1'); yield await Promise.resolve('v2')}finally{log.push('finally'); yield 'cleanup'}}
async function* outer(){yield* inner()}
let it=outer(); let p1=it.next(); let p2=it.next('s1'); let p3=it.return('done'); let p4=it.next('after');
p1.then(x=>log.push('p1 '+JSON.stringify(x)+' log='+JSON.stringify(log)));
p2.then(x=>log.push('p2 '+JSON.stringify(x)+' log='+JSON.stringify(log)));
p3.then(x=>log.push('p3 '+JSON.stringify(x)+' log='+JSON.stringify(log)));
p4.then(x=>log.push('p4 '+JSON.stringify(x)+' log='+JSON.stringify(log)));
setTimeout(()=>console.log(log),0)
JS
output
Chunk ID: 1cec10
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 313
Output:
[
  'after v1',
  'p1 {"value":"v1","done":false} log=["after v1"]',
  'p2 {"value":"v2","done":false} log=["after v1","p1 {\\"value\\":\\"v1\\",\\"done\\":false} log=[\\"after v1\\"]"]',
  'finally',
  'p3 {"value":"cleanup","done":false} log=["after v1","p1 {\\"value\\":\\"v1\\",\\"done\\":false} log=[\\"after v1\\"]","p2 {\\"value\\":\\"v2\\",\\"done\\":false} log=[\\"after v1\\",\\"p1 {\\\\\\"value\\\\\\":\\\\\\"v1\\\\\\",\\\\\\"done\\\\\\":false} log=[\\\\\\"after v1\\\\\\"]\\"]","finally"]',
  'p4 {"done":true} log=["after v1","p1 {\\"value\\":\\"v1\\",\\"done\\":false} log=[\\"after v1\\"]","p2 {\\"value\\":\\"v2\\",\\"done\\":false} log=[\\"after v1\\",\\"p1 {\\\\\\"value\\\\\\":\\\\\\"v1\\\\\\",\\\\\\"done\\\\\\":false} log=[\\\\\\"after v1\\\\\\"]\\"]","finally","p3 {\\"value\\":\\"cleanup\\",\\"done\\":false} log=[\\"after v1\\",\\"p1 {\\\\\\"value\\\\\\":\\\\\\"v1\\\\\\",\\\\\\"done\\\\\\":false} log=[\\\\\\"after v1\\\\\\"]\\",\\"p2 {\\\\\\"value\\\\\\":\\\\\\"v2\\\\\\",\\\\\\"done\\\\\\":false} log=[\\\\\\"after v1\\\\\\",\\\\\\"p1 {\\\\\\\\\\\\\\"value\\\\\\\\\\\\\\":\\\\\\\\\\\\\\"v1\\\\\\\\\\\\\\",\\\\\\\\\\\\\\"done\\\\\\\\\\\\\\":false} log=[\\\\\\\\\\\\\\"after v1\\\\\\\\\\\\\\"]\\\\\\"]\\",\\"finally\\"]"]'
]
shell
node - <<'JS'
let log=[];
async function* inner(){try{yield 'v1'}finally{let x=yield 'cleanup'; log.push('after cleanup '+x)}}
async function* outer(){let y=yield* inner(); log.push('outer '+y); return 'outer'}
let it=outer(); let p1=it.next(); let p2=it.return('done'); let p3=it.next('after');
p1.then(x=>log.push('p1 '+JSON.stringify(x)+' log='+JSON.stringify(log)));
p2.then(x=>log.push('p2 '+JSON.stringify(x)+' log='+JSON.stringify(log)));
p3.then(x=>log.push('p3 '+JSON.stringify(x)+' log='+JSON.stringify(log)));
setTimeout(()=>console.log(log),0)
JS
output
Chunk ID: a7a630
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 126
Output:
[
  'p1 {"value":"v1","done":false} log=[]',
  'after cleanup after',
  'p2 {"value":"cleanup","done":false} log=["p1 {\\"value\\":\\"v1\\",\\"done\\":false} log=[]","after cleanup after"]',
  'outer done',
  'p3 {"value":"outer","done":true} log=["p1 {\\"value\\":\\"v1\\",\\"done\\":false} log=[]","after cleanup after","p2 {\\"value\\":\\"cleanup\\",\\"done\\":false} log=[\\"p1 {\\\\\\"value\\\\\\":\\\\\\"v1\\\\\\",\\\\\\"done\\\\\\":false} log=[]\\",\\"after cleanup after\\"]","outer done"]'
]
I’m going to patch only `__asyncGenerator`. The change will make each iterator call create an internal promise gate; queued `next`/`throw` resume from that gate, while queued `return` waits one microtask after the same gate so prior results are observable before return cleanup.
apply_patch
*** Begin Patch
*** Update File: /app/internal/runtime/runtime.go
@@
 		export var __asyncGenerator = (__this, __arguments, generator) => {
 			var resume = (k, v, yes, no) => {
 				try {
 					var x = generator[k](v), isAwait = (v = x.value) instanceof __await, done = x.done
 					Promise.resolve(isAwait ? v[0] : v)
 						.then(y => isAwait
 							? resume(k === 'return' ? k : 'next', v[1] ? { done: y.done, value: y.value } : y, yes, no)
 							: yes({ value: y, done }))
 						.catch(e => resume('throw', e, yes, no))
 				} catch (e) {
 					no(e)
 				}
-			}, method = k => it[k] = x => new Promise((yes, no) => resume(k, x, yes, no)), it = {}
+			}, tail, method = k => it[k] = x => {
+				var request = {}, promise = new Promise((yes, no) => {
+					request.resolve = yes
+					request.reject = no
+				}), prev = tail, run = () => resume(k, x, value => {
+					request.resolveGate()
+					request.resolve(value)
+				}, error => {
+					request.resolveGate()
+					request.reject(error)
+				})
+				request.gate = new Promise(resolve => request.resolveGate = resolve)
+				tail = request
+				request.gate.then(() => tail === request && (tail = null))
+				prev ? prev.gate.then(k === 'return' ? () => Promise.resolve().then(run) : run) : run()
+				return promise
+			}, it = {}
 			return generator = generator.apply(__this, __arguments),
 				it[__knownSymbol('asyncIterator')] = () => it,
 				method('next'),
*** End Patch


Exit code: 0
Wall time: 0 seconds
Output:
Success. Updated the following files:
M /app/internal/runtime/runtime.go
shell
go test ./internal/runtime
output
Chunk ID: 6db48e
Wall time: 4.9173 seconds
Process exited with code 0
Original token count: 14
Output:
ok  	[code-host]/evanw/esbuild/internal/runtime	0.090s
shell
go build ./cmd/...
output
Chunk ID: 069174
Wall time: 4.6507 seconds
Process exited with code 0
Original token count: 0
Output:
shell
go test ./internal/bundler_tests -run TestLowerAsyncGenerator -count=1
output
Chunk ID: bd1fc8
Wall time: 5.4822 seconds
Process exited with code 1
Original token count: 1339
Output:
PASS
snapshots/snapshots_lower.txt
    No test found for snapshot TestLowerPrivateClassStaticFieldOrder
    No test found for snapshot TestTSLowerClassFieldStrictTsconfigJson2020
    No test found for snapshot TestJavaScriptAutoAccessorES2022
    No test found for snapshot TestLowerForAwait2015
    No test found for snapshot TestLowerPrivateSuperStaticBundleIssue2158
    No test found for snapshot TestLowerStaticSuperES2016NoBundle
    No test found for snapshot TestLowerUsingInsideTSNamespace
    No test found for snapshot TestStaticClassBlockESNext
    No test found for snapshot TestTSLowerObjectRest2018NoBundle
    No test found for snapshot TestForAwaitWithOptionalCatchIssue4378
    No test found for snapshot TestLowerAsyncArrowSuperES2016
    No test found for snapshot TestLowerPrivateClassMethodOrder
    No test found for snapshot TestLowerStaticAsyncSuperES2016NoBundle
    No test found for snapshot TestLowerPrivateClassFieldOrder
    No test found for snapshot TestLowerPrivateFieldAssignments2015NoBundle
    No test found for snapshot TestStaticClassBlockES2021
    No test found for snapshot TestTSLowerPrivateFieldOptionalChain2015NoBundle
    No test found for snapshot TestLowerPrivateFieldAssignments2020NoBundle
    No test found for snapshot TestTSLowerPrivateFieldAndMethodAvoidNameCollision2015
    No test found for snapshot TestLowerPrivateGetterSetter2015
    No test found for snapshot TestLowerPrivateMethodNext
    No test found for snapshot TestLowerObjectSpreadNoBundle
    No test found for snapshot TestJavaScriptDecoratorsESNext
    No test found for snapshot TestLowerNullishCoalescingAssignmentIssue1493
    No test found for snapshot TestLowerPrivateClassStaticAccessorOrder
    No test found for snapshot TestLowerPrivateGetterSetterNext
    No test found for snapshot TestLowerPrivateMethod2019
    No test found for snapshot TestLowerStaticAsyncArrowSuperSetterES2016
    No test found for snapshot TestLowerPrivateFieldOptionalChain2020NoBundle
    No test found for snapshot TestLowerPrivateFieldOptionalChainNextNoBundle
    No test found for snapshot TestLowerPrivateMethod2020
    No test found for snapshot TestLowerAsyncThis2016ES6
    No test found for snapshot TestLowerPrivateFieldAssignmentsNextNoBundle
    No test found for snapshot TestLowerPrivateFieldOptionalChain2019NoBundle
    No test found for snapshot TestLowerStaticAsyncArrowSuperES2016
    No test found for snapshot TestLowerPrivateSuperES2021
    No test found for snapshot TestJavaScriptAutoAccessorES2021
    No test found for snapshot TestJavaScriptDecoratorsBundleIssue3768
    No test found for snapshot TestLowerAsyncThis2016CommonJS
    No test found for snapshot TestLowerClassFieldStrictTsconfigJson2020
    No test found for snapshot TestLowerForAwait2017
    No test found for snapshot TestLowerPrivateClassAccessorOrder
    No test found for snapshot TestLowerTemplateObject
    No test found for snapshot TestLowerAsyncArrowSuperSetterES2016
    No test found for snapshot TestLowerExportStarAsNameCollisionNoBundle
    No test found for snapshot TestLowerNestedFunctionDirectEval
    No test found for snapshot TestLowerPrivateFieldAssignments2019NoBundle
    No test found for snapshot TestLowerPrivateGetterSetter2020
    No test found for snapshot TestLowerStaticAsyncSuperES2021NoBundle
    No test found for snapshot TestLowerStaticSuperES2021NoBundle
    No test found for snapshot TestLowerUsingUnsupportedAsync
    No test found for snapshot TestLowerExportStarAsNameCollision
    No test found for snapshot TestLowerPrivateClassBrandCheckUnsupported
    No test found for snapshot TestLowerPrivateClassExpr2020NoBundle
    No test found for snapshot TestTSLowerClassField2020NoBundle
    No test found for snapshot TestTSLowerClassPrivateFieldNextNoBundle
    No test found for snapshot TestTSLowerObjectRest2017NoBundle
    No test found for snapshot TestJavaScriptAutoAccessorESNext
    No test found for snapshot TestLowerPrivateClassBrandCheckSupported
    No test found for snapshot TestLowerPrivateClassStaticMethodOrder
    No test found for snapshot TestLowerStrictModeSyntax
    No test found for snapshot TestLowerUsing
    No test found for snapshot TestLowerUsingUnsupportedUsingAndAsync
    No test found for snapshot TestLowerAsyncSuperES2016NoBundle
    No test found for snapshot TestLowerOptionalCatchNameCollisionNoBundle
    No test found for snapshot TestLowerUsingHoisting
    No test found for snapshot TestLowerClassFieldNextNoBundle
    No test found for snapshot TestLowerExponentiationOperatorNoBundle
    No test found for snapshot TestLowerPrivateGetterSetter2019
    No test found for snapshot TestTSLowerPrivateStaticMembers2015NoBundle
    No test found for snapshot TestLowerPrivateMethodWithModifiers2020
    No test found for snapshot TestLowerPrivateSuperES2022
    No test found for snapshot TestClassSuperThisIssue242NoBundle
    No test found for snapshot TestLowerAsync2016NoBundle
    No test found for snapshot TestLowerClassField2020NoBundle
    No test found for snapshot TestLowerRegExpNameCollision
    No test found for snapshot TestLowerAsync2017NoBundle
    No test found for snapshot TestLowerAsyncSuperES2017NoBundle
    No test found for snapshot TestLowerPrivateClassFieldStaticIssue1424
FAIL	[code-host]/evanw/esbuild/internal/bundler_tests	0.006s
FAIL
The helper parses and the CLI builds. I’m now running behavioral traces through Node in native form and through the bundled ES2017/ES6 output to catch ordering differences, especially around `yield*` cleanup and queued `throw`.
shell
tmpdir=$(mktemp -d)
cat > "$tmpdir/input.js" <<'JS'
const trace = [];
const snap = () => trace.map(x => typeof x === 'string' ? x : x[0] + ':' + JSON.stringify(x[2]));
const record = (label, promise) => promise.then(
  value => trace.push([label, 'fulfill', value, snap()]),
  error => trace.push([label, 'reject', String(error), snap()]),
);

async function scenarioSyncStart() {
  trace.push('sync:before');
  async function* g() {
    trace.push('sync:start');
    await Promise.resolve();
    trace.push('sync:after-await');
    yield 'sync:value';
  }
  const it = g();
  const p1 = it.next();
  trace.push('sync:after-next');
  await record('sync:p1', p1);
}

async function scenarioDelegateReturn() {
  async function* inner() {
    try {
      trace.push('delegate:start');
      yield await Promise.resolve('delegate:v1');
      trace.push('delegate:after-v1');
    } finally {
      trace.push('delegate:finally-before-yield');
      const sent = yield 'delegate:cleanup';
      trace.push('delegate:finally-after-yield:' + sent);
    }
  }
  async function* outer() {
    const value = yield* inner();
    trace.push('delegate:outer-value:' + value);
    return 'delegate:outer-return';
  }
  const it = outer();
  const p1 = it.next();
  const p2 = it.return('delegate:return');
  const p3 = it.next('delegate:after');
  await Promise.all([record('delegate:p1', p1), record('delegate:p2', p2), record('delegate:p3', p3)]);
}

async function scenarioDelegateTwoNextsReturn() {
  async function* inner() {
    try {
      yield await Promise.resolve('two:v1');
      trace.push('two:after-v1');
      yield await Promise.resolve('two:v2');
      trace.push('two:after-v2');
    } finally {
      trace.push('two:finally-before-yield');
      const sent = yield 'two:cleanup';
      trace.push('two:finally-after-yield:' + sent);
    }
  }
  async function* outer() {
    const value = yield* inner();
    trace.push('two:outer-value:' + value);
    return 'two:outer-return';
  }
  const it = outer();
  const p1 = it.next();
  const p2 = it.next('two:sent1');
  const p3 = it.return('two:return');
  const p4 = it.next('two:after');
  await Promise.all([record('two:p1', p1), record('two:p2', p2), record('two:p3', p3), record('two:p4', p4)]);
}

async function scenarioThrowCatchRecovery() {
  async function* g() {
    try {
      trace.push('throw:start');
      const sent = yield await Promise.resolve('throw:first');
      trace.push('throw:after-yield:' + sent);
    } catch (e) {
      trace.push('throw:catch:' + e);
      const recovered = yield 'throw:recovery';
      trace.push('throw:after-recovery:' + recovered);
    }
    return 'throw:done';
  }
  const it = g();
  const p1 = it.next();
  const p2 = it.throw('throw:boom');
  const p3 = it.next('throw:sent');
  await Promise.all([record('throw:p1', p1), record('throw:p2', p2), record('throw:p3', p3)]);
}

async function scenarioForAwait() {
  async function* inner() {
    try {
      yield await Promise.resolve('for:v1');
      yield await Promise.resolve('for:v2');
    } finally {
      trace.push('for:inner-finally');
    }
  }
  async function* outer() {
    try {
      for await (const value of inner()) {
        trace.push('for:loop:' + value);
        const sent = yield value;
        trace.push('for:sent:' + sent);
      }
    } finally {
      trace.push('for:outer-finally');
      yield 'for:cleanup';
    }
  }
  const it = outer();
  const p1 = it.next();
  const p2 = it.next('for:sent1');
  const p3 = it.return('for:return');
  const p4 = it.next('for:after');
  await Promise.all([record('for:p1', p1), record('for:p2', p2), record('for:p3', p3), record('for:p4', p4)]);
}

(async () => {
  await scenarioSyncStart();
  await scenarioDelegateReturn();
  await scenarioDelegateTwoNextsReturn();
  await scenarioThrowCatchRecovery();
  await scenarioForAwait();
  console.log(JSON.stringify(trace));
})().catch(e => { console.error(e && e.stack || e); process.exit(1); });
JS
node "$tmpdir/input.js" > "$tmpdir/native.json"
go run ./cmd/esbuild "$tmpdir/input.js" --bundle --target=es2017 --format=cjs --outfile="$tmpdir/es2017.js" >/dev/null
node "$tmpdir/es2017.js" > "$tmpdir/es2017.json"
go run ./cmd/esbuild "$tmpdir/input.js" --bundle --target=es6 --format=cjs --outfile="$tmpdir/es6.js" >/dev/null
node "$tmpdir/es6.js" > "$tmpdir/es6.json"
printf 'native vs es2017: '; cmp -s "$tmpdir/native.json" "$tmpdir/es2017.json" && echo ok || { echo differ; diff -u "$tmpdir/native.json" "$tmpdir/es2017.json" | head -200; }
printf 'native vs es6: '; cmp -s "$tmpdir/native.json" "$tmpdir/es6.json" && echo ok || { echo differ; diff -u "$tmpdir/native.json" "$tmpdir/es6.json" | head -200; }
printf 'es2017 native syntax check: '; if rg -q "async function\*|for await" "$tmpdir/es2017.js"; then echo found; rg -n "async function\*|for await|__asyncGenerator|__yieldStar|__forAwait" "$tmpdir/es2017.js"; else echo lowered; rg -n "__asyncGenerator|__yieldStar|__forAwait" "$tmpdir/es2017.js" | head; fi
printf 'es6 native syntax check: '; if rg -q "async function\*|for await" "$tmpdir/es6.js"; then echo found; rg -n "async function\*|for await|__asyncGenerator|__yieldStar|__forAwait" "$tmpdir/es6.js"; else echo lowered; rg -n "__asyncGenerator|__yieldStar|__forAwait" "$tmpdir/es6.js" | head; fi
output
Chunk ID: 3e5da8
Wall time: 0.1572 seconds
Process exited with code 0
Original token count: 12138
Output:
Total output lines: 42


  ../tmp/tmp.aODcJ6DwTY/es2017.js  7.7kb

⚡ Done in 1ms

  ../tmp/tmp.aODcJ6DwTY/es6.js  8.7kb

⚡ Done in 1ms
native vs es2017: differ
--- /tmp/tmp.aODcJ6DwTY/native.json	2026-06-21 17:38:47.864090013 +0000
+++ /tmp/tmp.aODcJ6DwTY/es2017.json	2026-06-21 17:38:48.082090013 +0000
@@ -1 +1 @@
-["sync:before","sync:start","sync:after-next","sync:after-await",["sync:p1","fulfill",{"value":"sync:value","done":false},["sync:before","sync:start","sync:after-next","sync:after-await"]],"delegate:start",["delegate:p1","fulfill",{"value":"delegate:v1","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start"]],"delegate:finally-before-yield","delegate:finally-after-yield:delegate:after",["delegate:p2","fulfill",{"value":"delegate:cleanup","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after"]],"delegate:outer-value:delegate:return",["delegate:p3","fulfill",{"value":"delegate:outer-return","done":true},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return"]],"two:after-v1",["two:p1","fulfill",{"value":"two:v1","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1"]],["two:p2","fulfill",{"value":"two:v2","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}"]],"two:finally-before-yield","two:finally-after-yield:two:after",["two:p3","fulfill",{"value":"two:cleanup","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after"]],"two:outer-value:two:return",["two:p4","fulfill",{"value":"two:outer-return","done":true},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return"]],"throw:start","throw:catch:throw:boom",["throw:p1","fulfill",{"value":"throw:first","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom"]],"throw:after-recovery:throw:sent",["throw:p2","fulfill",{"value":"throw:recovery","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent"]],["throw:p3","fulfill",{"value":"throw:done","done":true},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}"]],"for:loop:for:v1","for:sent:for:sent1",["for:p1","fulfill",{"value":"for:v1","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}","throw:p3:{\"value\":\"throw:done\",\"done\":true}","for:loop:for:v1","for:sent:for:sent1"]],"for:loop:for:v2",["for:p2","fulfill",{"value":"for:v2","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}","throw:p3:{\"value\":\"throw:done\",\"done\":true}","for:loop:for:v1","for:sent:for:sent1","for:p1:{\"value\":\"for:v1\",\"done\":false}","for:loop:for:v2"]],"for:inner-finally","for:outer-finally",["for:p3","fulfill",{"value":"for:cleanup","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}","throw:p3:{\"value\":\"throw:done\",\"done\":true}","for:loop:for:v1","for:sent:for:sent1","for:p1:{\"value\":\"for:v1\",\"done\":false}","for:loop:for:v2","for:p2:{\"value\":\"for:v2\",\"done\":false}","for:inner-finally","for:outer-finally"]],["for:p4","fulfill",{"value":"for:return","done":true},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}","throw:p3:{\"value\":\"throw:done\",\"done\":true}","for:loop:for:v1","for:sent:for:sent1","for:p1:{\"value\":\"for:v1\",\"done\":false}","for:loop:for:v2","for:p2:{\"value\":\"for:v2\",\"done\":false}","for:inner-finally","for:outer-finally","for:p3:{\"value\":\"for:cleanup\",\"done\":false}"]]]
+["sync:before","sync:start","sync:after-next","sync:after-await",["sync:p1","fulfill",{"value":"sync:value","done":false},["sync:before","sync:start","sync:after-next","sync:after-await"]],"delegate:start",["delegate:p1","fulfill",{"value":"delegate:v1","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start"]],"delegate:finally-before-yield","delegate:finally-after-yield:delegate:after",["delegate:p2","fulfill",{"value":"delegate:cleanup","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after"]],"delegate:outer-value:delegate:return",["delegate:p3","fulfill",{"value":"delegate:outer-return","done":true},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return"]],"two:after-v1",["two:p1","fulfill",{"value":"two:v1","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1"]],["two:p2","fulfill",{"value":"two:v2","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}"]],"two:finally-before-yield","two:finally-after-yield:two:after",["two:p3","fulfill",{"value":"two:cleanup","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after"]],"two:outer-value:two:return",["two:p4","fulfill",{"value":"two:outer-return","done":true},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return"]],"throw:start","throw:catch:throw:boom",["throw:p1","fulfill",{"value":"throw:first","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom"]],"throw:after-recovery:throw:sent",["throw:p2","fulfill",{"value":"throw:recovery","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent"]],["throw:p3","fulfill",{"value":"throw:done","done":true},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}"]],"for:loop:for:v1","for:sent:for:sent1",["for:p1","fulfill",{"value":"for:v1","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}","throw:p3:{\"value\":\"throw:done\",\"done\":true}","for:loop:for:v1","for:sent:for:sent1"]],"for:loop:for:v2",["for:p2","fulfill",{"value":"for:v2","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-a…2138 tokens truncated…alse}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent"]],["throw:p3","fulfill",{"value":"throw:done","done":true},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}"]],"for:loop:for:v1","for:sent:for:sent1",["for:p1","fulfill",{"value":"for:v1","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}","throw:p3:{\"value\":\"throw:done\",\"done\":true}","for:loop:for:v1","for:sent:for:sent1"]],"for:loop:for:v2",["for:p2","fulfill",{"value":"for:v2","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}","throw:p3:{\"value\":\"throw:done\",\"done\":true}","for:loop:for:v1","for:sent:for:sent1","for:p1:{\"value\":\"for:v1\",\"done\":false}","for:loop:for:v2"]],"for:inner-finally","for:outer-finally",["for:p3","fulfill",{"value":"for:cleanup","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}","throw:p3:{\"value\":\"throw:done\",\"done\":true}","for:loop:for:v1","for:sent:for:sent1","for:p1:{\"value\":\"for:v1\",\"done\":false}","for:loop:for:v2","for:p2:{\"value\":\"for:v2\",\"done\":false}","for:inner-finally","for:outer-finally"]],["for:p4","fulfill",{"value":"for:return","done":true},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}","throw:p3:{\"value\":\"throw:done\",\"done\":true}","for:loop:for:v1","for:sent:for:sent1","for:p1:{\"value\":\"for:v1\",\"done\":false}","for:loop:for:v2","for:p2:{\"value\":\"for:v2\",\"done\":false}","for:inner-finally","for:outer-finally","for:p3:{\"value\":\"for:cleanup\",\"done\":false}"]]]
+["sync:before","sync:start","sync:after-next","sync:after-await",["sync:p1","fulfill",{"value":"sync:value","done":false},["sync:before","sync:start","sync:after-next","sync:after-await"]],"delegate:start",["delegate:p1","fulfill",{"value":"delegate:v1","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start"]],"delegate:finally-before-yield","delegate:finally-after-yield:delegate:after",["delegate:p2","fulfill",{"value":"delegate:cleanup","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after"]],"delegate:outer-value:delegate:return",["delegate:p3","fulfill",{"value":"delegate:outer-return","done":true},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return"]],"two:after-v1",["two:p1","fulfill",{"value":"two:v1","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1"]],["two:p2","fulfill",{"value":"two:v2","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}"]],"two:finally-before-yield","two:finally-after-yield:two:after",["two:p3","fulfill",{"value":"two:cleanup","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after"]],"two:outer-value:two:return",["two:p4","fulfill",{"value":"two:outer-return","done":true},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return"]],"throw:start","throw:catch:throw:boom",["throw:p1","fulfill",{"value":"throw:first","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom"]],"throw:after-recovery:throw:sent",["throw:p2","fulfill",{"value":"throw:recovery","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent"]],["throw:p3","fulfill",{"value":"throw:done","done":true},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}"]],"for:loop:for:v1","for:sent:for:sent1",["for:p1","fulfill",{"value":"for:v1","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}","throw:p3:{\"value\":\"throw:done\",\"done\":true}","for:loop:for:v1","for:sent:for:sent1"]],"for:loop:for:v2",["for:p2","fulfill",{"value":"for:v2","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}","throw:p3:{\"value\":\"throw:done\",\"done\":true}","for:loop:for:v1","for:sent:for:sent1","for:p1:{\"value\":\"for:v1\",\"done\":false}","for:loop:for:v2"]],"for:inner-finally","for:outer-finally",["for:p3","fulfill",{"value":"for:cleanup","done":false},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}","throw:p3:{\"value\":\"throw:done\",\"done\":true}","for:loop:for:v1","for:sent:for:sent1","for:p1:{\"value\":\"for:v1\",\"done\":false}","for:loop:for:v2","for:p2:{\"value\":\"for:v2\",\"done\":false}","for:inner-finally","for:outer-finally"]],["for:p4","fulfill",{"value":{"done":true},"done":true},["sync:before","sync:start","sync:after-next","sync:after-await","sync:p1:{\"value\":\"sync:value\",\"done\":false}","delegate:start","delegate:p1:{\"value\":\"delegate:v1\",\"done\":false}","delegate:finally-before-yield","delegate:finally-after-yield:delegate:after","delegate:p2:{\"value\":\"delegate:cleanup\",\"done\":false}","delegate:outer-value:delegate:return","delegate:p3:{\"value\":\"delegate:outer-return\",\"done\":true}","two:after-v1","two:p1:{\"value\":\"two:v1\",\"done\":false}","two:p2:{\"value\":\"two:v2\",\"done\":false}","two:finally-before-yield","two:finally-after-yield:two:after","two:p3:{\"value\":\"two:cleanup\",\"done\":false}","two:outer-value:two:return","two:p4:{\"value\":\"two:outer-return\",\"done\":true}","throw:start","throw:catch:throw:boom","throw:p1:{\"value\":\"throw:first\",\"done\":false}","throw:after-recovery:throw:sent","throw:p2:{\"value\":\"throw:recovery\",\"done\":false}","throw:p3:{\"value\":\"throw:done\",\"done\":true}","for:loop:for:v1","for:sent:for:sent1","for:p1:{\"value\":\"for:v1\",\"done\":false}","for:loop:for:v2","for:p2:{\"value\":\"for:v2\",\"done\":false}","for:inner-finally","for:outer-finally","for:p3:{\"value\":\"for:cleanup\",\"done\":false}"]]]
es2017 native syntax check: lowered
9:var __asyncGenerator = (__this, __arguments, generator) => {
36:var __yieldStar = (value) => {
64:var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it);
76:    return __asyncGenerator(this, null, function* () {
90:    return __asyncGenerator(this, null, function* () {
103:    return __asyncGenerator(this, null, function* () {
104:      const value = yield* __yieldStar(inner());
117:    return __asyncGenerator(this, null, function* () {
131:    return __asyncGenerator(this, null, function* () {
132:      const value = yield* __yieldStar(inner());
es6 native syntax check: lowered
29:var __asyncGenerator = (__this, __arguments, generator) => {
56:var __yieldStar = (value) => {
84:var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it);
97:      return __asyncGenerator(this, null, function* () {
113:      return __asyncGenerator(this, null, function* () {
126:      return __asyncGenerator(this, null, function* () {
127:        const value = yield* __yieldStar(inner());
142:      return __asyncGenerator(this, null, function* () {
156:      return __asyncGenerator(this, null, function* () {
157:        const value = yield* __yieldStar(inner());
shell
tmpdir=$(ls -td /tmp/tmp.* | head -1); sed -n '160,220p' "$tmpdir/es2017.js"
output
Chunk ID: b9f618
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 469
Output:
  const p1 = it.next();
  const p2 = it.throw("throw:boom");
  const p3 = it.next("throw:sent");
  await Promise.all([record("throw:p1", p1), record("throw:p2", p2), record("throw:p3", p3)]);
}
async function scenarioForAwait() {
  function inner() {
    return __asyncGenerator(this, null, function* () {
      try {
        yield yield new __await(Promise.resolve("for:v1"));
        yield yield new __await(Promise.resolve("for:v2"));
      } finally {
        trace.push("for:inner-finally");
      }
    });
  }
  function outer() {
    return __asyncGenerator(this, null, function* () {
      try {
        try {
          for (var iter = __forAwait(inner()), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
            const value = temp.value;
            trace.push("for:loop:" + value);
            const sent = yield value;
            trace.push("for:sent:" + sent);
          }
        } catch (temp) {
          error = [temp];
        } finally {
          try {
            more && (temp = iter.return) && (yield new __await(temp.call(iter)));
          } finally {
            if (error)
              throw error[0];
          }
        }
      } finally {
        trace.push("for:outer-finally");
        yield "for:cleanup";
      }
    });
  }
  const it = outer();
  const p1 = it.next();
  const p2 = it.next("for:sent1");
  const p3 = it.return("for:return");
  const p4 = it.next("for:after");
  await Promise.all([record("for:p1", p1), record("for:p2", p2), record("for:p3", p3), record("for:p4", p4)]);
}
(async () => {
  await scenarioSyncStart();
  await scenarioDelegateReturn();
  await scenarioDelegateTwoNextsReturn();
  await scenarioThrowCatchRecovery();
  await scenarioForAwait();
  console.log(JSON.stringify(trace));
})().catch((e) => {
  console.error(e && e.stack || e);
  process.exit(1);
});
The queued-call ordering now matches through `yield*` and catch recovery, but the broader trace exposed an existing return-path issue for lowered `for await`: an ordinary lowered `await` inside return cleanup was being resumed with `return` instead of `next`. I’m tightening that without changing the `__yieldStar` handoff case, where `return` must be preserved.
apply_patch
*** Begin Patch
*** Update File: /app/internal/runtime/runtime.go
@@
 					Promise.resolve(isAwait ? v[0] : v)
 						.then(y => isAwait
-							? resume(k === 'return' ? k : 'next', v[1] ? { done: y.done, value: y.value } : y, yes, no)
+							? resume(k === 'return' && v[1] ? k : 'next', v[1] ? { done: y.done, value: y.value } : y, yes, no)
 							: yes({ value: y, done }))
*** End Patch


Exit code: 0
Wall time: 0 seconds
Output:
Success. Updated the following files:
M /app/internal/runtime/runtime.go
shell
go test ./internal/runtime
output
Chunk ID: 7c0e3e
Wall time: 1.1863 seconds
Process exited with code 0
Original token count: 14
Output:
ok  	[code-host]/evanw/esbuild/internal/runtime	0.041s
shell
go build ./cmd/...
output
Chunk ID: 6f5e00
Wall time: 1.4984 seconds
Process exited with code 0
Original token count: 0
Output:
The runtime still parses and `go build ./cmd/...` succeeds after the await-resume adjustment. I’m rerunning the native-vs-lowered trace now to confirm ES2017 and ES6 are both aligned.
shell
tmpdir=$(mktemp -d)
cat > "$tmpdir/input.js" <<'JS'
const trace = [];
const snap = () => trace.map(x => typeof x === 'string' ? x : x[0] + ':' + JSON.stringify(x[2]));
const record = (label, promise) => promise.then(
  value => trace.push([label, 'fulfill', value, snap()]),
  error => trace.push([label, 'reject', String(error), snap()]),
);

async function scenarioSyncStart() {
  trace.push('sync:before');
  async function* g() {
    trace.push('sync:start');
    await Promise.resolve();
    trace.push('sync:after-await');
    yield 'sync:value';
  }
  const it = g();
  const p1 = it.next();
  trace.push('sync:after-next');
  await record('sync:p1', p1);
}

async function scenarioDelegateReturn() {
  async function* inner() {
    try {
      trace.push('delegate:start');
      yield await Promise.resolve('delegate:v1');
      trace.push('delegate:after-v1');
    } finally {
      trace.push('delegate:finally-before-yield');
      const sent = yield 'delegate:cleanup';
      trace.push('delegate:finally-after-yield:' + sent);
    }
  }
  async function* outer() {
    const value = yield* inner();
    trace.push('delegate:outer-value:' + value);
    return 'delegate:outer-return';
  }
  const it = outer();
  const p1 = it.next();
  const p2 = it.return('delegate:return');
  const p3 = it.next('delegate:after');
  await Promise.all([record('delegate:p1', p1), record('delegate:p2', p2), record('delegate:p3', p3)]);
}

async function scenarioDelegateTwoNextsReturn() {
  async function* inner() {
    try {
      yield await Promise.resolve('two:v1');
      trace.push('two:after-v1');
      yield await Promise.resolve('two:v2');
      trace.push('two:after-v2');
    } finally {
      trace.push('two:finally-before-yield');
      const sent = yield 'two:cleanup';
      trace.push('two:finally-after-yield:' + sent);
    }
  }
  async function* outer() {
    const value = yield* inner();
    trace.push('two:outer-value:' + value);
    return 'two:outer-return';
  }
  const it = outer();
  const p1 = it.next();
  const p2 = it.next('two:sent1');
  const p3 = it.return('two:return');
  const p4 = it.next('two:after');
  await Promise.all([record('two:p1', p1), record('two:p2', p2), record('two:p3', p3), record('two:p4', p4)]);
}

async function scenarioThrowCatchRecovery() {
  async function* g() {
    try {
      trace.push('throw:start');
      const sent = yield await Promise.resolve('throw:first');
      trace.push('throw:after-yield:' + sent);
    } catch (e) {
      trace.push('throw:catch:' + e);
      const recovered = yield 'throw:recovery';
      trace.push('throw:after-recovery:' + recovered);
    }
    return 'throw:done';
  }
  const it = g();
  const p1 = it.next();
  const p2 = it.throw('throw:boom');
  const p3 = it.next('throw:sent');
  await Promise.all([record('throw:p1', p1), record('throw:p2', p2), record('throw:p3', p3)]);
}

async function scenarioForAwait() {
  async function* inner() {
    try {
      yield await Promise.resolve('for:v1');
      yield await Promise.resolve('for:v2');
    } finally {
      trace.push('for:inner-finally');
    }
  }
  async function* outer() {
    try {
      for await (const value of inner()) {
        trace.push('for:loop:' + value);
        const sent = yield value;
        trace.push('for:sent:' + sent);
      }
    } finally {
      trace.push('for:outer-finally');
      yield 'for:cleanup';
    }
  }
  const it = outer();
  const p1 = it.next();
  const p2 = it.next('for:sent1');
  const p3 = it.return('for:return');
  const p4 = it.next('for:after');
  await Promise.all([record('for:p1', p1), record('for:p2', p2), record('for:p3', p3), record('for:p4', p4)]);
}

(async () => {
  await scenarioSyncStart();
  await scenarioDelegateReturn();
  await scenarioDelegateTwoNextsReturn();
  await scenarioThrowCatchRecovery();
  await scenarioForAwait();
  console.log(JSON.stringify(trace));
})().catch(e => { console.error(e && e.stack || e); process.exit(1); });
JS
node "$tmpdir/input.js" > "$tmpdir/native.json"
go run ./cmd/esbuild "$tmpdir/input.js" --bundle --target=es2017 --format=cjs --outfile="$tmpdir/es2017.js" >/dev/null
node "$tmpdir/es2017.js" > "$tmpdir/es2017.json"
go run ./cmd/esbuild "$tmpdir/input.js" --bundle --target=es6 --format=cjs --outfile="$tmpdir/es6.js" >/dev/null
node "$tmpdir/es6.js" > "$tmpdir/es6.json"
printf 'native vs es2017: '; cmp -s "$tmpdir/native.json" "$tmpdir/es2017.json" && echo ok || { echo differ; diff -u "$tmpdir/native.json" "$tmpdir/es2017.json" | head -120; }
printf 'native vs es6: '; cmp -s "$tmpdir/native.json" "$tmpdir/es6.json" && echo ok || { echo differ; diff -u "$tmpdir/native.json" "$tmpdir/es6.json" | head -120; }
printf 'es2017 syntax/runtime: '; if rg -q "async function\*|for await" "$tmpdir/es2017.js"; then echo 'native syntax found'; else printf 'lowered, '; rg -q "__asyncGenerator" "$tmpdir/es2017.js" && rg -q "__yieldStar" "$tmpdir/es2017.js" && rg -q "__forAwait" "$tmpdir/es2017.js" && echo 'helpers present'; fi
printf 'es6 syntax/runtime: '; if rg -q "async function\*|for await" "$tmpdir/es6.js"; then echo 'native syntax found'; else printf 'lowered, '; rg -q "__asyncGenerator" "$tmpdir/es6.js" && rg -q "__yieldStar" "$tmpdir/es6.js" && rg -q "__forAwait" "$tmpdir/es6.js" && echo 'helpers present'; fi
output
Chunk ID: 19a433
Wall time: 0.1029 seconds
Process exited with code 0
Original token count: 62
Output:

  ../tmp/tmp.k1JhmlKEVi/es2017.js  7.7kb

⚡ Done in 1ms

  ../tmp/tmp.k1JhmlKEVi/es6.js  8.7kb

⚡ Done in 1ms
native vs es2017: ok
native vs es6: ok
es2017 syntax/runtime: lowered, helpers present
es6 syntax/runtime: lowered, helpers present
The manual trace now matches native Node for ES2017 and ES6, and both outputs are lowered through `__asyncGenerator`, `__yieldStar`, and `__forAwait`. I’m adding a skipped-if-Node-is-missing regression test so this behavior is covered without making Go-only environments fail.
shell
rg -n "type Target|ES2015|ES6|ES2017" pkg/api/api.go
output
Chunk ID: 559ecf
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 12
Output:
121:type Target uint8
127:	ES2015
129:	ES2017
shell
sed -n '121,136p' pkg/api/api.go
output
Chunk ID: e04dbc
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 38
Output:
type Target uint8

const (
	DefaultTarget Target = iota
	ESNext
	ES5
	ES2015
	ES2016
	ES2017
	ES2018
	ES2019
	ES2020
	ES2021
	ES2022
	ES2023
	ES2024
apply_patch
*** Begin Patch
*** Update File: /app/internal/runtime/runtime_test.go
@@
 import (
+	"context"
+	"os/exec"
+	"strings"
 	"testing"
+	"time"
 
 	"[code-host]/evanw/esbuild/internal/compat"
 	"[code-host]/evanw/esbuild/internal/config"
 	"[code-host]/evanw/esbuild/internal/js_parser"
 	"[code-host]/evanw/esbuild/internal/logger"
 	"[code-host]/evanw/esbuild/internal/runtime"
+	"[code-host]/evanw/esbuild/pkg/api"
 )
@@
 func TestUnsupportedFeatures(t *testing.T) {
 	for key, feature := range compat.StringToJSFeature {
 		t.Run(key, func(t *testing.T) {
 			source := runtime.Source(feature)
@@
 		})
 	}
 }
+
+func TestAsyncGeneratorLoweringConcurrentCalls(t *testing.T) {
+	if _, err := exec.LookPath("node"); err != nil {
+		t.Skip("node not found")
+	}
+
+	source := `
+		const trace = []
+		const record = (label, promise) => promise.then(
+			value => trace.push(label + ':ok:' + JSON.stringify(value) + ':' + trace.join('|')),
+			error => trace.push(label + ':err:' + String(error) + ':' + trace.join('|')),
+		)
+
+		async function syncStart() {
+			trace.push('sync:before')
+			async function* g() {
+				trace.push('sync:start')
+				await Promise.resolve()
+				trace.push('sync:after-await')
+				yield 'sync:value'
+			}
+			const it = g()
+			const p1 = it.next()
+			trace.push('sync:after-next')
+			await record('sync:p1', p1)
+		}
+
+		async function delegateReturn() {
+			async function* inner() {
+				try {
+					trace.push('delegate:start')
+					yield await Promise.resolve('delegate:value')
+				} finally {
+					trace.push('delegate:finally')
+					const sent = yield 'delegate:cleanup'
+					trace.push('delegate:after-cleanup:' + sent)
+				}
+			}
+			async function* outer() {
+				const value = yield* inner()
+				trace.push('delegate:outer:' + value)
+				return 'delegate:done'
+			}
+			const it = outer()
+			const p1 = it.next()
+			const p2 = it.return('delegate:return')
+			const p3 = it.next('delegate:sent')
+			await Promise.all([record('delegate:p1', p1), record('delegate:p2', p2), record('delegate:p3', p3)])
+		}
+
+		async function twoNextsThenReturn() {
+			async function* inner() {
+				try {
+					yield await Promise.resolve('two:one')
+					trace.push('two:after-one')
+					yield await Promise.resolve('two:two')
+				} finally {
+					trace.push('two:finally')
+					const sent = yield 'two:cleanup'
+					trace.push('two:after-cleanup:' + sent)
+				}
+			}
+			async function* outer() {
+				const value = yield* inner()
+				trace.push('two:outer:' + value)
+				return 'two:done'
+			}
+			const it = outer()
+			const p1 = it.next()
+			const p2 = it.next('two:sent-one')
+			const p3 = it.return('two:return')
+			const p4 = it.next('two:sent-cleanup')
+			await Promise.all([record('two:p1', p1), record('two:p2', p2), record('two:p3', p3), record('two:p4', p4)])
+		}
+
+		async function throwCatchRecovery() {
+			async function* g() {
+				try {
+					trace.push('throw:start')
+					yield await Promise.resolve('throw:first')
+				} catch (e) {
+					trace.push('throw:catch:' + e)
+					const sent = yield 'throw:recovery'
+					trace.push('throw:after-recovery:' + sent)
+				}
+				return 'throw:done'
+			}
+			const it = g()
+			const p1 = it.next()
+			const p2 = it.throw('throw:boom')
+			const p3 = it.next('throw:sent')
+			await Promise.all([record('throw:p1', p1), record('throw:p2', p2), record('throw:p3', p3)])
+		}
+
+		async function forAwaitReturn() {
+			async function* inner() {
+				try {
+					yield await Promise.resolve('for:one')
+					yield await Promise.resolve('for:two')
+				} finally {
+					trace.push('for:inner-finally')
+				}
+			}
+			async function* outer() {
+				try {
+					for await (const value of inner()) {
+						trace.push('for:loop:' + value)
+						const sent = yield value
+						trace.push('for:sent:' + sent)
+					}
+				} finally {
+					trace.push('for:outer-finally')
+					yield 'for:cleanup'
+				}
+			}
+			const it = outer()
+			const p1 = it.next()
+			const p2 = it.next('for:sent-one')
+			const p3 = it.return('for:return')
+			const p4 = it.next('for:sent-cleanup')
+			await Promise.all([record('for:p1', p1), record('for:p2', p2), record('for:p3', p3), record('for:p4', p4)])
+		}
+
+		(async () => {
+			await syncStart()
+			await delegateReturn()
+			await twoNextsThenReturn()
+			await throwCatchRecovery()
+			await forAwaitReturn()
+			console.log(JSON.stringify(trace))
+		})().catch(e => {
+			console.error(e && e.stack || e)
+			process.exit(1)
+		})
+	`
+
+	native := runNodeForRuntimeTest(t, source)
+	for _, target := range []api.Target{api.ES2017, api.ES2015} {
+		result := api.Transform(source, api.TransformOptions{
+			Target: target,
+			Format: api.FormatCommonJS,
+		})
+		if len(result.Errors) > 0 {
+			t.Fatalf("Transform failed: %v", result.Errors)
+		}
+
+		lowered := string(result.Code)
+		if strings.Contains(lowered, "async function*") || strings.Contains(lowered, "for await") {
+			t.Fatalf("Target %v was not lowered:\n%s", target, lowered)
+		}
+		for _, helper := range []string{"__asyncGenerator", "__yieldStar", "__forAwait"} {
+			if !strings.Contains(lowered, helper) {
+				t.Fatalf("Target %v did not use %s:\n%s", target, helper, lowered)
+			}
+		}
+
+		if js := runNodeForRuntimeTest(t, lowered); js != native {
+			t.Fatalf("Target %v did not match native node behavior\nNative:\n%s\nLowered:\n%s", target, native, js)
+		}
+	}
+}
+
+func runNodeForRuntimeTest(t *testing.T, js string) string {
+	t.Helper()
+
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+
+	cmd := exec.CommandContext(ctx, "node")
+	cmd.Stdin = strings.NewReader(js)
+	out, err := cmd.CombinedOutput()
+	if ctx.Err() != nil {
+		t.Fatal(ctx.Err())
+	}
+	if err != nil {
+		t.Fatalf("node failed: %v\n%s", err, out)
+	}
+	return string(out)
+}
*** End Patch


Exit code: 0
Wall time: 0 seconds
Output:
Success. Updated the following files:
M /app/internal/runtime/runtime_test.go
shell
gofmt -w internal/runtime/runtime_test.go
output
Chunk ID: 19ee5b
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:
shell
sed -n '1,260p' internal/runtime/runtime_test.go
output
Chunk ID: 4874ed
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1511
Output:
package runtime_test

import (
	"context"
	"os/exec"
	"strings"
	"testing"
	"time"

	"[code-host]/evanw/esbuild/internal/compat"
	"[code-host]/evanw/esbuild/internal/config"
	"[code-host]/evanw/esbuild/internal/js_parser"
	"[code-host]/evanw/esbuild/internal/logger"
	"[code-host]/evanw/esbuild/internal/runtime"
	"[code-host]/evanw/esbuild/pkg/api"
)

func TestUnsupportedFeatures(t *testing.T) {
	for key, feature := range compat.StringToJSFeature {
		t.Run(key, func(t *testing.T) {
			source := runtime.Source(feature)
			log := logger.NewDeferLog(logger.DeferLogAll, nil)

			js_parser.Parse(log, source, js_parser.OptionsFromConfig(&config.Options{
				UnsupportedJSFeatures: feature,
				TreeShaking:           true,
			}))

			if log.HasErrors() {
				msgs := "Internal error: failed to parse runtime:\n"
				for _, msg := range log.Done() {
					msgs += msg.String(logger.OutputOptions{IncludeSource: true}, logger.TerminalInfo{})
				}
				t.Fatal(msgs[:len(msgs)-1])
			}
		})
	}
}

func TestAsyncGeneratorLoweringConcurrentCalls(t *testing.T) {
	if _, err := exec.LookPath("node"); err != nil {
		t.Skip("node not found")
	}

	source := `
		const trace = []
		const record = (label, promise) => promise.then(
			value => trace.push(label + ':ok:' + JSON.stringify(value) + ':' + trace.join('|')),
			error => trace.push(label + ':err:' + String(error) + ':' + trace.join('|')),
		)

		async function syncStart() {
			trace.push('sync:before')
			async function* g() {
				trace.push('sync:start')
				await Promise.resolve()
				trace.push('sync:after-await')
				yield 'sync:value'
			}
			const it = g()
			const p1 = it.next()
			trace.push('sync:after-next')
			await record('sync:p1', p1)
		}

		async function delegateReturn() {
			async function* inner() {
				try {
					trace.push('delegate:start')
					yield await Promise.resolve('delegate:value')
				} finally {
					trace.push('delegate:finally')
					const sent = yield 'delegate:cleanup'
					trace.push('delegate:after-cleanup:' + sent)
				}
			}
			async function* outer() {
				const value = yield* inner()
				trace.push('delegate:outer:' + value)
				return 'delegate:done'
			}
			const it = outer()
			const p1 = it.next()
			const p2 = it.return('delegate:return')
			const p3 = it.next('delegate:sent')
			await Promise.all([record('delegate:p1', p1), record('delegate:p2', p2), record('delegate:p3', p3)])
		}

		async function twoNextsThenReturn() {
			async function* inner() {
				try {
					yield await Promise.resolve('two:one')
					trace.push('two:after-one')
					yield await Promise.resolve('two:two')
				} finally {
					trace.push('two:finally')
					const sent = yield 'two:cleanup'
					trace.push('two:after-cleanup:' + sent)
				}
			}
			async function* outer() {
				const value = yield* inner()
				trace.push('two:outer:' + value)
				return 'two:done'
			}
			const it = outer()
			const p1 = it.next()
			const p2 = it.next('two:sent-one')
			const p3 = it.return('two:return')
			const p4 = it.next('two:sent-cleanup')
			await Promise.all([record('two:p1', p1), record('two:p2', p2), record('two:p3', p3), record('two:p4', p4)])
		}

		async function throwCatchRecovery() {
			async function* g() {
				try {
					trace.push('throw:start')
					yield await Promise.resolve('throw:first')
				} catch (e) {
					trace.push('throw:catch:' + e)
					const sent = yield 'throw:recovery'
					trace.push('throw:after-recovery:' + sent)
				}
				return 'throw:done'
			}
			const it = g()
			const p1 = it.next()
			const p2 = it.throw('throw:boom')
			const p3 = it.next('throw:sent')
			await Promise.all([record('throw:p1', p1), record('throw:p2', p2), record('throw:p3', p3)])
		}

		async function forAwaitReturn() {
			async function* inner() {
				try {
					yield await Promise.resolve('for:one')
					yield await Promise.resolve('for:two')
				} finally {
					trace.push('for:inner-finally')
				}
			}
			async function* outer() {
				try {
					for await (const value of inner()) {
						trace.push('for:loop:' + value)
						const sent = yield value
						trace.push('for:sent:' + sent)
					}
				} finally {
					trace.push('for:outer-finally')
					yield 'for:cleanup'
				}
			}
			const it = outer()
			const p1 = it.next()
			const p2 = it.next('for:sent-one')
			const p3 = it.return('for:return')
			const p4 = it.next('for:sent-cleanup')
			await Promise.all([record('for:p1', p1), record('for:p2', p2), record('for:p3', p3), record('for:p4', p4)])
		}

		(async () => {
			await syncStart()
			await delegateReturn()
			await twoNextsThenReturn()
			await throwCatchRecovery()
			await forAwaitReturn()
			console.log(JSON.stringify(trace))
		})().catch(e => {
			console.error(e && e.stack || e)
			process.exit(1)
		})
	`

	native := runNodeForRuntimeTest(t, source)
	for _, target := range []api.Target{api.ES2017, api.ES2015} {
		result := api.Transform(source, api.TransformOptions{
			Target: target,
			Format: api.FormatCommonJS,
		})
		if len(result.Errors) > 0 {
			t.Fatalf("Transform failed: %v", result.Errors)
		}

		lowered := string(result.Code)
		if strings.Contains(lowered, "async function*") || strings.Contains(lowered, "for await") {
			t.Fatalf("Target %v was not lowered:\n%s", target, lowered)
		}
		for _, helper := range []string{"__asyncGenerator", "__yieldStar", "__forAwait"} {
			if !strings.Contains(lowered, helper) {
				t.Fatalf("Target %v did not use %s:\n%s", target, helper, lowered)
			}
		}

		if js := runNodeForRuntimeTest(t, lowered); js != native {
			t.Fatalf("Target %v did not match native node behavior\nNative:\n%s\nLowered:\n%s", target, native, js)
		}
	}
}

func runNodeForRuntimeTest(t *testing.T, js string) string {
	t.Helper()

	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	cmd := exec.CommandContext(ctx, "node")
	cmd.Stdin = strings.NewReader(js)
	out, err := cmd.CombinedOutput()
	if ctx.Err() != nil {
		t.Fatal(ctx.Err())
	}
	if err != nil {
		t.Fatalf("node failed: %v\n%s", err, out)
	}
	return string(out)
}
shell
sed -n '412,456p' internal/runtime/runtime.go
output
Chunk ID: 2b45aa
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 414
Output:
		// These help for lowering async generator functions
		export var __await = function (promise, isYieldStar) {
			this[0] = promise
			this[1] = isYieldStar
		}
		export var __asyncGenerator = (__this, __arguments, generator) => {
			var resume = (k, v, yes, no) => {
				try {
					var x = generator[k](v), isAwait = (v = x.value) instanceof __await, done = x.done
					Promise.resolve(isAwait ? v[0] : v)
						.then(y => isAwait
							? resume(k === 'return' && v[1] ? k : 'next', v[1] ? { done: y.done, value: y.value } : y, yes, no)
							: yes({ value: y, done }))
						.catch(e => resume('throw', e, yes, no))
				} catch (e) {
					no(e)
				}
			}, tail, method = k => it[k] = x => {
				var request = {}, promise = new Promise((yes, no) => {
					request.resolve = yes
					request.reject = no
				}), prev = tail, run = () => resume(k, x, value => {
					request.resolveGate()
					request.resolve(value)
				}, error => {
					request.resolveGate()
					request.reject(error)
				})
				request.gate = new Promise(resolve => request.resolveGate = resolve)
				tail = request
				request.gate.then(() => tail === request && (tail = null))
				prev ? prev.gate.then(k === 'return' ? () => Promise.resolve().then(run) : run) : run()
				return promise
			}, it = {}
			return generator = generator.apply(__this, __arguments),
				it[__knownSymbol('asyncIterator')] = () => it,
				method('next'),
				method('throw'),
				method('return'),
				it
		}
		export var __yieldStar = value => {
			var obj = value[__knownSymbol('asyncIterator')], isAwait = false, method, it = {}
			if (obj == null) {
				obj = value[__knownSymbol('iterator')]()
shell
go test ./internal/runtime -count=1
output
Chunk ID: 6ab9bc
Wall time: 0.2045 seconds
Process exited with code 0
Original token count: 14
Output:
ok  	[code-host]/evanw/esbuild/internal/runtime	0.123s
shell
go build ./cmd/...
output
Chunk ID: 89b89f
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:
The regression test passes locally and covers native-vs-lowered traces for ES2017 and ES2015. I’m running the broader relevant Go tests now, including compatibility coverage.
shell
go test ./internal/compat ./internal/js_parser ./internal/runtime -count=1
output
Chunk ID: a2442b
Wall time: 1.6916 seconds
Process exited with code 0
Original token count: 41
Output:
ok  	[code-host]/evanw/esbuild/internal/compat	0.001s
ok  	[code-host]/evanw/esbuild/internal/js_parser	0.164s
ok  	[code-host]/evanw/esbuild/internal/runtime	0.147s
shell
go test ./internal/bundler_tests -count=1
output
Chunk ID: f500f0
Wall time: 1.5479 seconds
Process exited with code 0
Original token count: 15
Output:
ok  	[code-host]/evanw/esbuild/internal/bundler_tests	1.404s
shell
go test ./pkg/api -count=1
output
Chunk ID: 5845a8
Wall time: 0.6517 seconds
Process exited with code 0
Original token count: 12
Output:
ok  	[code-host]/evanw/esbuild/pkg/api	0.002s
The focused parser/runtime/bundler/API tests are green. I’m doing one full `go test ./...` pass to catch package-level fallout before wrapping up.
shell
go test ./...
output
Chunk ID: 74a832
Wall time: 1.9212 seconds
Process exited with code 0
Original token count: 436
Output:
?   	[code-host]/evanw/esbuild/cmd/esbuild	[no test files]
?   	[code-host]/evanw/esbuild/internal/api_helpers	[no test files]
?   	[code-host]/evanw/esbuild/internal/ast	[no test files]
?   	[code-host]/evanw/esbuild/internal/bundler	[no test files]
ok  	[code-host]/evanw/esbuild/internal/bundler_tests	0.884s
?   	[code-host]/evanw/esbuild/internal/cache	[no test files]
?   	[code-host]/evanw/esbuild/internal/cli_helpers	[no test files]
ok  	[code-host]/evanw/esbuild/internal/compat	0.001s
?   	[code-host]/evanw/esbuild/internal/config	[no test files]
?   	[code-host]/evanw/esbuild/internal/css_ast	[no test files]
ok  	[code-host]/evanw/esbuild/internal/css_lexer	0.001s
ok  	[code-host]/evanw/esbuild/internal/css_parser	0.040s
ok  	[code-host]/evanw/esbuild/internal/css_printer	0.003s
ok  	[code-host]/evanw/esbuild/internal/fs	0.020s
?   	[code-host]/evanw/esbuild/internal/graph	[no test files]
ok  	[code-host]/evanw/esbuild/internal/helpers	0.001s
ok  	[code-host]/evanw/esbuild/internal/js_ast	0.001s
ok  	[code-host]/evanw/esbuild/internal/js_lexer	0.003s
ok  	[code-host]/evanw/esbuild/internal/js_parser	0.240s
ok  	[code-host]/evanw/esbuild/internal/js_printer	0.023s
?   	[code-host]/evanw/esbuild/internal/linker	[no test files]
ok  	[code-host]/evanw/esbuild/internal/logger	0.001s
?   	[code-host]/evanw/esbuild/internal/renamer	[no test files]
ok  	[code-host]/evanw/esbuild/internal/resolver	0.008s
ok  	[code-host]/evanw/esbuild/internal/runtime	0.124s
?   	[code-host]/evanw/esbuild/internal/sourcemap	[no test files]
?   	[code-host]/evanw/esbuild/internal/test	[no test files]
?   	[code-host]/evanw/esbuild/internal/xxhash	[no test files]
ok  	[code-host]/evanw/esbuild/pkg/api	0.001s
?   	[code-host]/evanw/esbuild/pkg/cli	[no test files]
Implemented the async generator lowering fix in [runtime.go](/app/internal/runtime/runtime.go:417). What changed: - `__asyncGenerator` now sequences `next`/`throw`/`return` through promise-valued internal gates instead of resuming every call immediately. - Queued `next`/`throw` resume from the previous operation’s gate without an extra hop. - Queued `return` waits one microtask after the previous gate so prior iterator results are observable before `finally` cleanup runs. - Ordinary lowered `await` during a `return` path now resumes with `next`; the special `__yieldStar` return handoff still resumes with `return`. Added regression coverage in [runtime_test.go](/app/internal/runtime/runtime_test.go:37) comparing native Node behavior against lowered ES2017 and ES2015 output for concurrent calls, delegated generators, cleanup yields, catch recovery, `for await`, and sync start ordering. Verification: - `go build ./cmd/...` - `go test ./...` - Manual native-vs-lowered Node trace for ES2017 and ES6 matched, with helpers present and no native `async function*` / `for await` syntax in output. No compatibility-table changes were made.
Final diff , what the agent changed

No file changes, the agent left the workspace untouched.

Verifier output , the proof behind the reward
tests/test.sh
============================= test session starts ==============================
platform linux -- Python 3.11.2, pytest-8.3.3, pluggy-1.6.0 -- /opt/test-venv/bin/python3
cachedir: .pytest_cache
rootdir: /tests
collecting ... collected 6 items

../tests/test_outputs.py::test_async_generator_lowering_matches_native PASSED [ 16%]
../tests/test_outputs.py::test_bundled_output_uses_lowered_async_generator_helpers PASSED [ 33%]
../tests/test_outputs.py::test_case_roster_actually_ran PASSED           [ 50%]
../tests/test_outputs.py::test_output_is_json_trace PASSED               [ 66%]
../tests/test_outputs.py::test_async_generator_compatibility_targets_still_require_lowering PASSED [ 83%]
../tests/test_outputs.py::test_no_hardcoded_hidden_literals PASSED       [100%]

==================================== PASSES ====================================
=========================== short test summary info ============================
PASSED ../tests/test_outputs.py::test_async_generator_lowering_matches_native
PASSED ../tests/test_outputs.py::test_bundled_output_uses_lowered_async_generator_helpers
PASSED ../tests/test_outputs.py::test_case_roster_actually_ran
PASSED ../tests/test_outputs.py::test_output_is_json_trace
PASSED ../tests/test_outputs.py::test_async_generator_compatibility_targets_still_require_lowering
PASSED ../tests/test_outputs.py::test_no_hardcoded_hidden_literals
============================== 6 passed in 3.24s ===============================

Reproduce this trial: git checkout 2f94510 && PYTHONPATH=src python3 scripts/build_site.py , then open trial/trial_eadd5466083b44cb. Re-running the agent live requires EVAL_PLATFORM_ENABLE_OAUTH_SMOKE=1 and is non-deterministic.

Trial trial_eadd5466083b44cb · verifier authoritative; classifier explanatory.