Browse Source

bug-fix

imwald
Silberengel 1 month ago
parent
commit
5b6e5db306
  1. 4
      package-lock.json
  2. 2
      package.json
  3. 8
      src/components/ErrorBoundary.tsx
  4. 50
      src/lib/stale-chunk-recovery.ts
  5. 31
      src/main.tsx

4
package-lock.json generated

@ -1,12 +1,12 @@ @@ -1,12 +1,12 @@
{
"name": "jumble-imwald",
"version": "21.2.0",
"version": "21.2.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "jumble-imwald",
"version": "21.2.0",
"version": "21.2.1",
"license": "MIT",
"dependencies": {
"@asciidoctor/core": "^3.0.4",

2
package.json

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
{
"name": "jumble-imwald",
"version": "21.2.0",
"version": "21.2.1",
"description": "A user-friendly Nostr client focused on relay feed browsing and relay discovery, forked from Jumble",
"private": true,
"type": "module",

8
src/components/ErrorBoundary.tsx

@ -3,6 +3,7 @@ import { MessageCircle, RotateCw } from 'lucide-react' @@ -3,6 +3,7 @@ import { MessageCircle, RotateCw } from 'lucide-react'
import React, { Component, ReactNode } from 'react'
import { toast } from 'sonner'
import logger from '@/lib/logger'
import { isChunkLoadFailureMessage, tryStaleChunkReloadOnce } from '@/lib/stale-chunk-recovery'
const ISSUES_URL =
'https://gitrepublic.imwald.eu/repos/npub1l5sga6xg72phsz5422ykujprejwud075ggrr3z2hwyrfgr7eylqstegx9z/jumble-imwald-edition?tab=issues'
@ -66,6 +67,13 @@ export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundarySt @@ -66,6 +67,13 @@ export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundarySt
render() {
if (this.state.hasError) {
const msg = this.state.error?.message ?? ''
if (isChunkLoadFailureMessage(msg) && tryStaleChunkReloadOnce()) {
return (
<div className="flex h-screen w-screen items-center justify-center p-4 text-muted-foreground">
Reloading to pick up the latest app version
</div>
)
}
if (isLikelyBrokenReactContextFromHmr(msg) && tryContextRecoveryReload()) {
return (
<div className="flex h-screen w-screen items-center justify-center p-4 text-muted-foreground">

50
src/lib/stale-chunk-recovery.ts

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
/**
* After a deploy, hashed chunks from the previous build are removed. A tab that still runs old JS
* (HTTP cache, or a service worker precache race) can 404 on `import()`. One reload usually picks
* up fresh `index.html` and the new asset graph.
*/
const SESSION_KEY = 'jumble:stale-chunk-reload'
export function isChunkLoadFailureMessage(message: string): boolean {
const m = message.toLowerCase()
return (
m.includes('failed to fetch dynamically imported module') ||
m.includes('error loading dynamically imported module') ||
m.includes('importing a module script failed') ||
// Safari / some WebKit builds
(m.includes('dynamically imported module') && (m.includes('failed') || m.includes('error')))
)
}
/** Returns true if a reload was scheduled (at most once per session). */
export function tryStaleChunkReloadOnce(): boolean {
if (typeof window === 'undefined') return false
try {
if (sessionStorage.getItem(SESSION_KEY)) return false
sessionStorage.setItem(SESSION_KEY, '1')
} catch {
return false
}
window.location.reload()
return true
}
export function installStaleBuildChunkRecovery(): void {
if (typeof window === 'undefined') return
window.addEventListener('unhandledrejection', (event) => {
const r = event.reason
const msg =
typeof r === 'string' ? r : r instanceof Error ? r.message : String(r ?? '')
if (!isChunkLoadFailureMessage(msg)) return
event.preventDefault()
tryStaleChunkReloadOnce()
})
window.addEventListener('error', (event) => {
const msg = event.message ?? ''
if (!isChunkLoadFailureMessage(msg)) return
event.preventDefault()
tryStaleChunkReloadOnce()
})
}

31
src/main.tsx

@ -12,36 +12,7 @@ import { ErrorBoundary } from './components/ErrorBoundary.tsx' @@ -12,36 +12,7 @@ import { ErrorBoundary } from './components/ErrorBoundary.tsx'
import { initI18n } from './i18n'
import storage from './services/local-storage.service'
import { restoreSessionFeedSnapshotsAfterHardRefresh } from './services/session-feed-snapshot.service'
/**
* After a deploy, hashed chunks from the previous build are removed. A tab that still runs old JS
* (HTTP cache, or a service worker that just dropped the old precache) can hit 404 on import().
* One reload usually picks up the new index.html and asset graph.
*/
function installStaleBuildChunkRecovery() {
if (typeof window === 'undefined') return
const isChunkLoadFailure = (msg: string) =>
msg.includes('Failed to fetch dynamically imported module') ||
msg.includes('error loading dynamically imported module') ||
msg.includes('Importing a module script failed')
window.addEventListener('unhandledrejection', (event) => {
const r = event.reason
const msg =
typeof r === 'string' ? r : r instanceof Error ? r.message : String(r ?? '')
if (!isChunkLoadFailure(msg)) return
event.preventDefault()
try {
const key = 'jumble:stale-chunk-reload'
if (sessionStorage.getItem(key)) return
sessionStorage.setItem(key, '1')
} catch {
return
}
window.location.reload()
})
}
import { installStaleBuildChunkRecovery } from './lib/stale-chunk-recovery'
installStaleBuildChunkRecovery()

Loading…
Cancel
Save