Last active
March 19, 2026 21:16
-
-
Save genesiscz/ce819fbe87e1b3166b82f56de5886236 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Metro Bundle Line Inspector | |
| # Usage: .\metro-line-inspector.ps1 <line_or_offset> [port] [context] | |
| # Example: .\metro-line-inspector.ps1 2141134 | |
| # Example: .\metro-line-inspector.ps1 2141134 8081 15 | |
| param( | |
| [Parameter(Mandatory=$true, Position=0)] | |
| [int]$Position, | |
| [Parameter(Position=1)] | |
| [int]$Port = 8081, | |
| [Parameter(Position=2)] | |
| [int]$Context = 10 | |
| ) | |
| $bundleFile = "$env:TEMP\metro-bundle-$Port.js" | |
| # Ask user: download fresh or use cached? | |
| if (Test-Path $bundleFile) { | |
| $cachedSize = [math]::Round((Get-Item $bundleFile).Length / 1MB, 1) | |
| $choice = Read-Host "Cached bundle found (${cachedSize}MB). Download fresh or use cached? [D]ownload / [C]ached (default: C)" | |
| if ($choice -match '^[Dd]') { | |
| $download = $true | |
| } else { | |
| $download = $false | |
| Write-Host "Using cached bundle." -ForegroundColor DarkGray | |
| } | |
| } else { | |
| $download = $true | |
| } | |
| if ($download) { | |
| $url = "http://localhost:$Port/col-mobile-expo/index.bundle?platform=android&dev=true&minify=false" | |
| Write-Host "Fetching bundle from $url ..." -ForegroundColor Cyan | |
| Write-Host "(this may take a while for large bundles)" -ForegroundColor DarkGray | |
| Invoke-WebRequest -Uri $url -OutFile $bundleFile -UseBasicParsing | |
| if (-not (Test-Path $bundleFile) -or (Get-Item $bundleFile).Length -lt 1000) { | |
| Write-Host "ERROR: Failed to download bundle. Is Metro running on port $Port?" -ForegroundColor Red | |
| exit 1 | |
| } | |
| $size = [math]::Round((Get-Item $bundleFile).Length / 1MB, 1) | |
| Write-Host "Downloaded: ${size}MB" -ForegroundColor Green | |
| } | |
| # Get bundle stats | |
| $totalLines = (Get-Content $bundleFile | Measure-Object -Line).Lines | |
| $totalChars = (Get-Item $bundleFile).Length | |
| Write-Host "Bundle: $totalLines lines, $totalChars chars ($([math]::Round($totalChars / 1MB, 1))MB)" -ForegroundColor Cyan | |
| Write-Host "" | |
| # === ATTEMPT 1: Try as line number === | |
| $lineWorked = $false | |
| if ($Position -le $totalLines) { | |
| Write-Host "=== LINE MODE (line $Position) ===" -ForegroundColor Yellow | |
| $start = [Math]::Max(1, $Position - $Context) | |
| $count = $Context * 2 + 1 | |
| Get-Content $bundleFile | | |
| Select-Object -Skip ($start - 1) -First $count | | |
| ForEach-Object -Begin { $i = $start } -Process { | |
| $prefix = if ($i -eq $Position) { ">>>" } else { " " } | |
| $color = if ($i -eq $Position) { "Yellow" } else { "Gray" } | |
| Write-Host ("{0} {1,7}: {2}" -f $prefix, $i, ($_.Substring(0, [Math]::Min($_.Length, 200)))) -ForegroundColor $color | |
| if ($_.Length -gt 200) { Write-Host " ... (line truncated, $($_.Length) chars total)" -ForegroundColor DarkGray } | |
| $i++ | |
| } | |
| $lineWorked = $true | |
| Write-Host "" | |
| } else { | |
| Write-Host "Line $Position exceeds bundle ($totalLines lines) - skipping line mode." -ForegroundColor DarkYellow | |
| Write-Host "" | |
| } | |
| # === ATTEMPT 2: Try as character offset === | |
| Write-Host "=== OFFSET MODE (char offset $Position) ===" -ForegroundColor Yellow | |
| $content = [System.IO.File]::ReadAllText($bundleFile) | |
| if ($Position -ge $content.Length) { | |
| Write-Host "Offset $Position also exceeds file length ($($content.Length) chars)." -ForegroundColor Red | |
| Write-Host "" | |
| Write-Host "The Hermes error position doesn't match the downloaded bundle." -ForegroundColor Red | |
| Write-Host "Possible causes:" -ForegroundColor Yellow | |
| Write-Host " - Metro cache is stale (try: yarn expo start --clear)" -ForegroundColor Gray | |
| Write-Host " - Device loaded an old pre-bundled JS from the APK" -ForegroundColor Gray | |
| Write-Host " - Line endings differ (CRLF vs LF)" -ForegroundColor Gray | |
| exit 1 | |
| } | |
| # Specific bytes: +/- 30 chars | |
| $specStart = [Math]::Max(0, $Position - 30) | |
| $specLen = [Math]::Min(61, $content.Length - $specStart) | |
| $specific = $content.Substring($specStart, $specLen) | |
| Write-Host "" | |
| Write-Host "--- Specific bytes (+/- 30 chars around offset $Position) ---" -ForegroundColor Magenta | |
| Write-Host $specific -ForegroundColor White | |
| Write-Host "" | |
| # Wide context: +/- 1000 chars | |
| $wideStart = [Math]::Max(0, $Position - 1000) | |
| $wideLen = [Math]::Min(2001, $content.Length - $wideStart) | |
| $wide = $content.Substring($wideStart, $wideLen) | |
| Write-Host "--- Wide context (+/- 1000 chars around offset $Position) ---" -ForegroundColor Magenta | |
| Write-Host $wide -ForegroundColor Gray | |
| Write-Host "" | |
| # Try to find the module name from __d( wrapper | |
| $searchStart = [Math]::Max(0, $Position - 5000) | |
| $searchLen = [Math]::Min(5000, $Position - $searchStart) | |
| $before = $content.Substring($searchStart, $searchLen) | |
| $moduleMatch = [regex]::Match($before, '__d\(function.*?"([^"]+)"', 'RightToLeft') | |
| if ($moduleMatch.Success) { | |
| Write-Host "Likely module: $($moduleMatch.Groups[1].Value)" -ForegroundColor Green | |
| } | |
| Write-Host "" | |
| Write-Host "Bundle saved at: $bundleFile" -ForegroundColor DarkGray |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment