How This Example Works
Compilers frequently transform closures by packing captured outer variables (endpointName, maxBurst, windowSeconds, usedTokens) into a flat heap array _c = ["/api/v2/inference", 50, 60, 12], and wrap calls in internal runtime trampolines like __withCompilerTrampoline(cb).
This example demonstrates two key features of the Scopes proposal:
1) Marking __withCompilerTrampoline's range with isHidden: true (and retaining the definition scope pointer on wrappers that contain authored code) so Chrome DevTools automatically strips internal compiler frames from the Call Stack.
2) Reconstructing the outer createEndpointHandler closure scope from _c[0..3] alongside the inner handleRequest function scope and if (allowed) block scope.
What to Try & Verify in DevTools
Try:Click "Run & Pause in Debugger" to pause inside handleRequest in closures-hidden.ts and inspect the Call Stack pane.
- Clean Call Stack:
handleRequestappears called directly byexecuteRateLimitCheck(line 45). - Hidden Runtime Wrappers: Both
__withCompilerTrampolineand its anonymous callback (isHidden: true) are automatically omitted from the stack trace.
Try:While paused at debugger; on line 19 of closures-hidden.ts, expand each section in the Scope sidebar.
- Block Scope (
if (allowed)): ShowsburstUtilization: 40. - Local Scope (
handleRequest): ShowsclientIp: "192.0.2.44",requestWeight: 8,remainingTokens: 30, and synthesizedallowed: true. - Closure Scope (
createEndpointHandler): Unpacks tuple_c[0..3]intoendpointName: "/api/v2/inference",maxBurst: 50,windowSeconds: 60, andusedTokens: 20.executeRateLimitCheck's variables (limiter,handler) must not show up: it is not a lexical parent ofhandleRequest. - Module Scope: Shows
DEFAULT_REGION: "us-central1"(andRateLimiteras<unavailable>).
Try:Open the Console (Esc) while paused and type prefixes from different scope levels: burst, rem, endp, usedT, and DEFAULT_.
- Full Lexical Chain Aggregation: Autocomplete merges variables from the
Block,Function, outerClosure, andModulescopes.
Try:Right-click line 20 (return { region: DEFAULT_REGION, ... }), add a conditional breakpoint burstUtilization >= 40 && usedTokens === 20, resume (F8), and re-run.
- Cross-Scope Condition Rewriting: DevTools rewrites
burstUtilizationtoutilandusedTokensto_c[3], pausing cleanly at thereturnstatement.
Try:Run the expressions below in the Console while paused at debugger;.
- Multi-Scope Substitution: A single expression can seamlessly combine
DEFAULT_REGION(Module),endpointName/usedTokens/maxBurst(Closure),remainingTokens/allowed(Function), andburstUtilization(Block).
Other things to try
- Step Out (
Shift+F11) ofhandleRequest: you should never land in__withCompilerTrampoline. - Add Watch expressions using closure variables (
usedTokens,maxBurst), then select another frame. - Hover
DEFAULT_REGION,endpointNameandusedTokensin the editor with different frames selected.
Not sure if it's a DevTools bug? Tab 4. Decoded Scopes shows what the source map actually encodes.
Try in the Console While Paused
While paused, select a frame and evaluate these in the Console (Esc opens the drawer) using the authored names:
`${DEFAULT_REGION}:${endpointName} -> ${usedTokens}/${maxBurst} tokens (${burstUtilization}%)`
usedTokens + remainingTokens === maxBurst
allowed && windowSeconds === 60