Skip to content

experiment(widgets): embeddable same-document Query editor widget#71089

Draft
mariusandra wants to merge 1 commit into
masterfrom
code-widgets-experiment
Draft

experiment(widgets): embeddable same-document Query editor widget#71089
mariusandra wants to merge 1 commit into
masterfrom
code-widgets-experiment

Conversation

@mariusandra

Copy link
Copy Markdown
Collaborator

Experiment: widgets entry — mount the real Query editor in a foreign app

Draft/experiment — not intended to merge as-is. User-approved companion to PostHog/code#3473, which consumes this branch.

Adds a widgets vite entry (toolbar pattern) exposing window.PostHogWidgets.mountQueryEditor(el, { query, onQueryChange, apiHost, getAccessToken, theme, onClose }){ update, unmount }. Internally: shadow root with injected styles, own React 18 + kea copy, FloatingContainerContext pointing popovers/tooltips inside the shadow root, and the full editable Query/InsightViz editor (series, math, TaxonomicFilter, breakdown/filters) emitting plain query JSON to the host.

  • Auth rides the existing standalone OAuth mode in lib/api.ts, plus one new seam: setOAuthSessionOverride(session, refreshFn) — an in-memory session (never persisted in the host origin) whose 401 path calls the host's token refresh.
  • Only userLogic + teamLogic need explicit mounting; the rest self-mounts via kea connect. loadUserSuccess seeds ApiConfig ids in OAuth mode — no POSTHOG_APP_CONTEXT required.
  • Proven inside PostHog Code (React 19): two React copies coexist in one document, onQueryChange round-trips, live theme flip restyles open popovers. See companion PR for details and the harness.

Bundle: widgets.js 2.03 MB (603 KB gz) + CSS 137 KB gz; ~2.7 MB gz eager mount cost; 186 lazy chunks deferred.

If this graduates from experiment, the maintainability contract would be: keep the entry building, keep tokens on :root, :host, keep FloatingContainerContext honored by portaling primitives, promote setOAuthSessionOverride to a first-class embedded-auth API, and add a size budget like check-toolbar-size.

Screenshots

Taxonomic filter in shadow root

Mounted in the Electron app

🤖 Generated with Claude Code

New standalone 'widgets' entry that exposes window.PostHogWidgets.mountQueryEditor:
the real editable Query/InsightViz editor (series, taxonomic pickers, breakdown,
date range, chart type) mounted into a foreign document with its own React 18 +
kea inside a shadow root — the toolbar pattern, but for the insight editor.

- frontend/src/widgets/: mount API, shadow-root component (FloatingContainerContext
  keeps popovers/tooltips/modals inside the shadow root; [theme] attribute drives
  dark mode), tiny instance store for handle.update(), harness page.
- Auth: reuses the standalone OAuth mode in lib/api. setOAuthSessionOverride()
  seeds an IN-MEMORY session (host apiHost + bearer token, host-provided refresh
  callback) instead of localStorage, so host tokens never persist.
- vite.widgets.config.mts builds dist-widgets/widgets.js (ESM + lazy chunks) and
  widgets.css, linked into the shadow root at runtime; bin/serve-widgets.mjs
  serves it with CORS for cross-origin module loading.
- __unsafeMockContext option seeds userLogic/teamLogic for credential-less
  harness testing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Bundle size — 🔺 +149 B (+0.0%)

Uncompressed size of every built .js bundle, compared against the base branch.

Total: 64.80 MiB · 🔺 +149 B (+0.0%)

No file changed by more than 1000 B.

Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report

Eager graph — within budget

How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.

Root Eager (shipped) Δ vs base Budget
entry (logged-out pages, app bootstrap)
src/index.tsx
1.22 MiB · 22 files 🔺 +47 B (+0.0%) ███░░░░░░░ 28.4% of 4.29 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
8.15 MiB · 2,979 files 🔺 +142 B (+0.0%) █████████░ 88.1% of 9.25 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx

Largest files eagerly shipped from src/index.tsx
Size File
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
24.6 KiB ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js
6.3 KiB ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js
4.5 KiB ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js
3.9 KiB ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js
1.4 KiB ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
1.3 KiB src/RootErrorBoundary.tsx
912 B ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js
789 B src/scenes/ChunkLoadErrorBoundary.tsx
762 B src/index.tsx
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
281.1 KiB ../node_modules/.pnpm/posthog-js@1.401.0/node_modules/posthog-js/dist/rrweb.js
267.7 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
235.5 KiB src/taxonomy/core-filter-definitions-by-group.json
222.7 KiB ../node_modules/.pnpm/posthog-js@1.401.0/node_modules/posthog-js/dist/module.js
164.0 KiB src/queries/validators.js
154.3 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
106.1 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
92.7 KiB ../packages/quill/packages/quill/dist/index.js

Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479

Dist folder size — 🔺 +7.5 KiB (+0.0%)

Total size of the built frontend/dist folder (all assets), compared against the base branch.

Total: 1308.72 MiB · 🔺 +7.5 KiB (+0.0%)

@trunk-io

trunk-io Bot commented Jul 15, 2026

Copy link
Copy Markdown

Static BadgeStatic BadgeStatic BadgeStatic Badge

View Full Report ↗︎Docs

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