Skip to content

feat(browser-next): add immediate capture delivery - #4676

Draft
dustinbyrne wants to merge 1 commit into
fix/browser-next-sync-capturefrom
feat/browser-next-capture-immediate
Draft

feat(browser-next): add immediate capture delivery#4676
dustinbyrne wants to merge 1 commit into
fix/browser-next-sync-capturefrom
feat/browser-next-capture-immediate

Conversation

@dustinbyrne

Copy link
Copy Markdown
Contributor

Problem

Some callers need confirmation that Capture Analytics V1 reached a terminal persistence outcome before advancing their own work. Ordinary browser capture intentionally provides synchronous bounded queue admission, while flush() is a lane snapshot barrier and does not report the fate of a specific event.

This is a stacked follow-up to #4675 and should be reviewed against fix/browser-next-sync-capture.

Changes

  • Add PostHog.captureImmediate(...) => Promise<CaptureSummary> to the private experimental browser client.
  • Finalize immediate events through the ordinary consent, identity, session, protected-property, size, and rate-limit boundaries, then bypass the lane and deliver inline.
  • Extend the private analytics capability with a batch-oriented immediate method while sharing the existing Capture V1 transformation, partitioning, compression, retry, and response-classification code.
  • Resolve summaries for valid 2xx responses: ok and warning count as persisted; drop, final retry, and missing outcomes do not.
  • Reject terminal HTTP, exhausted transport, malformed-response, cancellation, and unavailable-delivery failures. Rejections after partial delivery carry the partial summary.
  • Keep denial authoritative across opt-out/opt-in so an admitted immediate retry cannot be revived.
  • Preserve queued delivery with older analytics capabilities; immediate delivery rejects as unavailable when the installed capability predates the method.
  • Add real-cloud playground support and browser coverage.

Immediate delivery deliberately bypasses lane ordering, can overtake buffered work, and is never retained for a later flush. The root lazily loads analytics for an admitted immediate call. The core entrypoint still contains no delivery import and requires explicitly installed analytics.

Bundle impact

Compared with #4675:

  • Core: 41,366 B minified / 11,972 B gzip / 10,801 B Brotli (+786 / +223 / +173 B)
  • Eager analytics: 55,628 / 17,092 / 15,355 B (+2,481 / +764 / +666 B)
  • Lazy initial: 41,845 / 12,298 / 11,088 B (+786 / +230 / +201 B)
  • Lazy total: 55,239 / 17,751 / 16,001 B (+2,467 / +833 / +737 B)

Capture V1 delivery remains outside the core graph.

Validation

  • Browser-next lint and TypeScript checks
  • Browser-next unit suite: 14 suites / 360 tests
  • Browser-next build, declarations, and mixed CommonJS/ESM delivery check
  • Playwright: 21 tests across Chromium, Firefox, and WebKit
  • Browser-v1 differential suite: 14 scenarios
  • Playground formatting and lint
  • Bundle graph and size measurement
  • Replay incident-risk matcher: no matched incident patterns
  • Fresh-context review found two material issues around deny/regrant retry authority and inherited result lookup; both were fixed and the focused re-review confirmed resolution

Release info Sub-libraries affected

Libraries affected

  • All of them
  • posthog-js (web)
  • posthog-js-lite (web lite)
  • posthog-node
  • posthog-react-native
  • @posthog/react-native-plugin
  • @posthog/react
  • @posthog/ai
  • @posthog/convex
  • @posthog/next
  • @posthog/nextjs-config
  • @posthog/nuxt
  • @posthog/openfeature-node-provider
  • @posthog/openfeature-web-provider
  • @posthog/rollup-plugin
  • @posthog/webpack-plugin
  • @posthog/types
  • @posthog/browser-common

@posthog/browser remains private and unpublished, so this stacked PR has no release changeset.

Checklist

  • Tests for new code
  • Accounted for the impact of any changes across different platforms
  • Accounted for backwards compatibility of any changes (no breaking changes!)
  • Took care not to unnecessarily increase the bundle size

If releasing new changes

  • Ran pnpm changeset to generate a changeset file

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

The human selected a Rust-inspired immediate-delivery contract: bypass buffered delivery, share Capture V1 machinery, return a persistence summary for valid responses, and reject request-level failures. Pi's coding agent implemented and validated the change in a local session without a public transcript link. A fresh-context built-in reviewer identified consent-revival and prototype-lookup issues; both were fixed and confirmed in focused re-review.

@dustinbyrne dustinbyrne self-assigned this Aug 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📝 No Changeset Found

This PR doesn't include a changeset. A changeset is required to release a new version.

How to add a changeset

Run this command and follow the prompts:

pnpm changeset

Remember: Never use major version bumps for posthog-js as it's autoloaded by clients.

@github-actions

Copy link
Copy Markdown
Contributor
⚠️ `@posthog/browser` is modified but this PR has no changeset

This is informational — the PR is not blocked. Click the triangle above to collapse, or push a fix and this comment will auto-delete.

Modified in this PR but no changeset added:

  • @posthog/browser

If this change should ship, run pnpm changeset and select a bump level.
If it isn't user-facing (refactor with no behavior change, internal tooling, generated files), no action needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant