Commit Graph

2 Commits

Author SHA1 Message Date
agent_coder 51ded06fde fix(#342 review round-2 F5-F6): drop the posthog re-render remount + test chunk detector
- F5 [stability/regression]: the round-1 F2 fix re-rendered the root with
  <PostHogProvider><App/></PostHogProvider> after the analytics chunk loaded. In
  the ChunkLoadErrorBoundary child slot the element TYPE changes App ->
  PostHogProvider, so React does NOT reconcile in place — it REMOUNTS the whole
  App: every mount effect runs twice (websocket connect/disconnect, origin
  tracking, subscriptions) and local state / focus / scroll / in-progress input is
  lost on cloud cold-load (e.g. typing in /login before analytics loads). And it
  was USELESS: the app has ZERO consumers of the PostHog React context (no
  usePostHog / useFeatureFlag* / PostHogFeature), and PostHogProvider given an
  initialized client is a no-op — all capture goes through the posthog singleton.
  Fix: initAnalytics now inits the posthog SINGLETON only (no posthog-js/react
  import, no second render); renderApp() renders <App/> once. First paint stays
  instant, cloud analytics behavior unchanged, no remount.
- F6 [test]: exported isChunkLoadError + chunk-load-error-boundary.test.ts —
  pins the detector (ChunkLoadError name + the 3 dynamic-import failure messages,
  case-insensitive → true; null/undefined/ordinary errors → false) so a
  false-negative that re-blanks the app on a real chunk-404 is caught.

Gate: client tsc 0, chunk-load + sanitize tests 14 passed. Entry chunk unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 04:18:29 +03:00
agent_coder 456a91d289 fix(#342 review F1-F4): chunk-load error boundary + non-blocking posthog + tests
- F1 [HIGH]: added a root ChunkLoadErrorBoundary (react-error-boundary) wrapping
  the routed app in main.tsx, ABOVE all the route-level/Aside/AiChatWindow
  Suspense boundaries. A stale-deploy chunk 404 (React.lazy reject) is caught and
  auto-reloads once (sessionStorage-guarded against a reload loop), else shows a
  manual "new version available" reload UI — instead of unmounting the whole tree
  to a white screen. Existing per-feature ErrorBoundaries untouched.
- F2 [MED-HIGH]: posthog no longer blocks/blanks the cloud first paint. main.tsx
  now renders <App/> immediately for everyone, then `void initAnalytics()` — which
  keeps the exact cloud gate, dynamically imports posthog, and RE-RENDERS the same
  React root wrapped in PostHogProvider (React reconciles onto the painted DOM, so
  cloud ends up wrapped exactly as before). The import+init is try/catch'd: a
  failed analytics chunk (network / stale-404 / ad-blocker on a "posthog" chunk)
  degrades to no-analytics instead of a permanently blank page.
- F3: sanitize-url.test.ts mirroring editor-ext's security contract (javascript:/
  data:/vbscript:/obfuscated → ""; https/relative/mailto preserved).
- F4: the idle-warm `void import(...)` prefetch in layout.tsx gets `.catch(()=>{})`
  so a failed best-effort prefetch can't surface as an unhandledrejection.

No new deps (lockfile unchanged). Gate: client tsc 0, sanitize test 3/3, client
build succeeds (entry chunk still 556K, posthog in separate dynamic chunks).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 04:18:29 +03:00