Skip to content

[refactor] Extract usePaginatedQuery for the Credits usage table - #15602

Open
claude[bot] wants to merge 3 commits into
mainfrom
refactor/usage-table-paginated-query
Open

[refactor] Extract usePaginatedQuery for the Credits usage table#15602
claude[bot] wants to merge 3 commits into
mainfrom
refactor/usage-table-paginated-query

Conversation

@claude

@claude claude Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Requested by Christian Byrne · Slack thread

Summary

Illustrative refactor for an architecture discussion in Slack, demonstrating an alternative pattern for UsageLogsTable's pagination/refresh state per docs/guidance/state-and-effects.md (raised as a side discussion on #15151, which already carries its own approval — this is a separate, standalone PR and does not touch that one).

Revised after review pushback (Christian): the first version of this PR also replaced UsageLogsTable's defineExpose({ refresh }) with a refetchKey prop threaded down from each parent. That was wrong — refresh() is a stateless imperative command with no state to desync, exactly the case this repo's own convention says defineExpose is for (docs/guidance/vue-components.md:21, src/components/AGENTS.md:6, .agents/checks/vue-patterns.md:17). docs/guidance/state-and-effects.md never mentions defineExpose/imperative commands/child refs at all, so nothing there justified the change. Reverted that part; see "What changed since the last push" below for what's kept instead.

Before / After, in plain language

Before

  • UsageLogsTable.vue kept pagination in one mutable ref, { page, limit, total, totalPages }, and wrote page from three different places: a page-click handler, refresh() resetting it to 1, and the server response echoing it back. Nothing made those three writers agree with each other by construction — they just had to be kept in sync by hand.
  • A hand-rolled latestLoadToken counter guarded against a billing-rail flip superseding an in-flight fetch. That guard is generic pagination-fetch plumbing, but it lived inline in this one component.
  • Two different parents each drove a reload by reaching into UsageLogsTable via a template ref and calling its exposed refresh() method: CreditsPanel.vue (watching balance locally) and PlanCreditsPanelContent.vue (not watching balance at all — a top-up while on its Activity tab never refreshed that table).

After

  • A new composable, usePaginatedQuery (src/composables/usePaginatedQuery.ts), owns the query: page, limit, total, and first are all computed from the last server response — one source of truth, not several fields a caller has to remember to keep in sync ("derive everything derivable"). The request-token race guard is baked into the composable once, instead of duplicated per call site.
  • UsageLogsTable still exposes refresh() via defineExpose — unchanged from main, per review feedback.
  • The "should credits UI refresh" decision is centralized in useBillingContext (the shared composable that already owns balance) as a new usageLogsRefreshSignal, instead of each panel re-deriving the same skip-first-hydration balance-watch. CreditsPanel and PlanCreditsPanelContent each just watch(usageLogsRefreshSignal, ...) and call their own table ref's refresh() — the "when" lives once in the data layer; the "how" stays an imperative command on the child, where it belongs. This also fixes the PlanCreditsPanelContent gap above: it now reacts to balance changes too.

Why

Per docs/guidance/state-and-effects.md:

  • "Do not store ... a second copy of data that already exists. If a computed can name it, do not put it in a ref and keep it in sync by hand — the sync is where the bugs live." (§4) — page/limit/total are computed from the response instead of three independently-writable fields.
  • The doc has nothing to say about defineExpose/parent-child method calls — that convention comes from docs/guidance/vue-components.md and .agents/checks/vue-patterns.md instead, and both call this exact pattern (a stateless command like refresh()) correct usage.

Changes

  • What: Added src/composables/usePaginatedQuery.ts + test. Refactored UsageLogsTable.vue to use it instead of a hand-rolled pagination ref and loadToken guard (still exposes refresh()). Added usageLogsRefreshSignal to useBillingContext/BillingContext (src/composables/billing/types.ts, useBillingContext.ts), owning the balance-change-detection watch once. CreditsPanel.vue and PlanCreditsPanelContent.vue watch that signal and call their own table ref's refresh().
  • Behavior: Same error messages and race-guard semantics for a superseded fetch. One behavior change: PlanCreditsPanelContent's Activity tab now refreshes on a genuine balance change, which it never did before (previously only CreditsPanel watched balance at all).
  • Breaking: None.

Review Focus

  • This is a demonstration/example PR for an architecture discussion, not a bug fix.
  • Whether usageLogsRefreshSignal (a plain incrementing counter) is the right shape for this signal, versus e.g. a callback-registration/event-bus approach — went with the simpler reactive-counter since it needs no subscribe/unsubscribe lifecycle management.

Testing

  • pnpm test:unit — full suite passes (1201 test files, 16499 tests, 7 expected fail, 13 skipped).
  • pnpm typecheck — clean.
  • pnpm lint — clean (0 errors; pre-existing warnings elsewhere untouched by this PR).

Illustrative refactor for an architecture discussion, per
docs/guidance/state-and-effects.md. Rebased onto main now that #15151
has merged (as 7494f71) and FE-1609 (#15239) added an `embedded` prop
to CreditsPanel in the meantime.

- UsageLogsTable owned pagination as a mutable {page, limit, total,
  totalPages} ref written from three places (a click handler, refresh(),
  and the server response echo), plus a hand-rolled loadToken race guard
  duplicated per-component.
- CreditsPanel, and separately PlanCreditsPanelContent, each drove a
  reload by reaching into UsageLogsTable via a template ref and calling
  an exposed refresh() method.

usePaginatedQuery now owns page/limit/total/first as computed values
derived from the last response (one source of truth, not several fields
kept in sync by hand), bakes the request-token guard in once, and
resets/refetches through a single reactive `key`. UsageLogsTable loads
itself on mount (no external refresh() needed); CreditsPanel passes a
plain `refetchKey` prop instead of imperatively calling into the child,
and PlanCreditsPanelContent's now-redundant refresh-on-mount is removed.

Behavior is unchanged: same initial load, same refresh triggers, same
error messages.
@claude
claude Bot force-pushed the refactor/usage-table-paginated-query branch from e04f809 to 85ded15 Compare August 22, 2026 03:14
@github-actions

github-actions Bot commented Aug 22, 2026

Copy link
Copy Markdown

🎭 Playwright: ✅ 1979 passed, 0 failed · 2 flaky

📊 Browser Reports
  • chromium: View Report (✅ 1958 / ❌ 0 / ⚠️ 2 / ⏭️ 5)
  • chromium-2x: View Report (✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • chromium-0.5x: View Report (✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • mobile-chrome: View Report (✅ 18 / ❌ 0 / ⚠️ 0 / ⏭️ 0)

🎨 Storybook: ✅ Built — View Storybook

Details

⏰ Completed at: 08/22/2026, 04:10:29 AM UTC

Links

📦 Bundle: 9.11 MB gzip 🔴 +504 B

Details

Summary

  • Raw size: 38.6 MB baseline 38.6 MB — 🔴 +1.12 kB
  • Gzip: 9.11 MB baseline 9.11 MB — 🔴 +504 B
  • Brotli: 6.37 MB baseline 6.37 MB — 🔴 +539 B
  • Bundles: 438 current • 438 baseline • 144 added / 144 removed

Category Glance
Panels & Settings 🔴 +937 B (592 kB) · Data & Services 🔴 +177 B (3.53 MB) · Other 🔴 +6 B (14.1 MB) · Vendor & Third-Party ⚪ 0 B (18.1 MB) · Graph Workspace ⚪ 0 B (1.37 MB) · Utilities & Hooks ⚪ 0 B (549 kB) · + 5 more

App Entry Points — 3.71 kB (baseline 3.71 kB) • ⚪ 0 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-Cq_qPUne.js (new) 3.71 kB 🔴 +3.71 kB 🔴 +1.86 kB 🔴 +1.61 kB
assets/index-Drb4FD7k.js (removed) 3.71 kB 🟢 -3.71 kB 🟢 -1.86 kB 🟢 -1.62 kB

Status: 1 added / 1 removed

Graph Workspace — 1.37 MB (baseline 1.37 MB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-ByjbvPKu.js (removed) 1.37 MB 🟢 -1.37 MB 🟢 -298 kB 🟢 -224 kB
assets/GraphView-DNwOXm3b.js (new) 1.37 MB 🔴 +1.37 MB 🔴 +298 kB 🔴 +224 kB
assets/WidgetCompositor-BM-cgJsC.js (new) 8.17 kB 🔴 +8.17 kB 🔴 +2.76 kB 🔴 +2.46 kB
assets/WidgetCompositor-nMIhEDQG.js (removed) 8.17 kB 🟢 -8.17 kB 🟢 -2.76 kB 🟢 -2.46 kB

Status: 2 added / 2 removed / 1 unchanged

Views & Navigation — 124 kB (baseline 124 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CloudSurveyView-CcoRO1AZ.js (new) 25 kB 🔴 +25 kB 🔴 +6.25 kB 🔴 +5.53 kB
assets/CloudSurveyView-DlIszcuL.js (removed) 25 kB 🟢 -25 kB 🟢 -6.25 kB 🟢 -5.53 kB
assets/CloudLayoutView-BQWJMaVW.js (new) 21.8 kB 🔴 +21.8 kB 🔴 +6.56 kB 🔴 +5.74 kB
assets/CloudLayoutView-DIrCUBCc.js (removed) 21.8 kB 🟢 -21.8 kB 🟢 -6.56 kB 🟢 -5.74 kB
assets/UserCheckView-BhG_Iayo.js (new) 8.75 kB 🔴 +8.75 kB 🔴 +2.19 kB 🔴 +1.9 kB
assets/UserCheckView-DDq5qOEi.js (removed) 8.75 kB 🟢 -8.75 kB 🟢 -2.19 kB 🟢 -1.9 kB
assets/CloudLoginView-BziUx7r1.js (new) 8.74 kB 🔴 +8.74 kB 🔴 +2.55 kB 🔴 +2.26 kB
assets/CloudLoginView-CH_YabHW.js (removed) 8.74 kB 🟢 -8.74 kB 🟢 -2.55 kB 🟢 -2.26 kB
assets/useCloudAuthPage-Bhc5Vnok.js (removed) 7.08 kB 🟢 -7.08 kB 🟢 -2.51 kB 🟢 -2.19 kB
assets/useCloudAuthPage-DCVwgmXJ.js (new) 7.08 kB 🔴 +7.08 kB 🔴 +2.51 kB 🔴 +2.2 kB
assets/CloudSignupView-BAlvVqsf.js (removed) 6.96 kB 🟢 -6.96 kB 🟢 -2.28 kB 🟢 -2 kB
assets/CloudSignupView-Dtxso5C_.js (new) 6.96 kB 🔴 +6.96 kB 🔴 +2.28 kB 🔴 +2 kB
assets/WidgetTextPreview-CwPpIpib.js (new) 6.07 kB 🔴 +6.07 kB 🔴 +2.13 kB 🔴 +1.9 kB
assets/WidgetTextPreview-DVRe3i7k.js (removed) 6.07 kB 🟢 -6.07 kB 🟢 -2.13 kB 🟢 -1.9 kB
assets/CloudSubscriptionRedirectView-CVTEBz-h.js (new) 6.05 kB 🔴 +6.05 kB 🔴 +2.25 kB 🔴 +1.96 kB
assets/CloudSubscriptionRedirectView-CwjqCArg.js (removed) 6.05 kB 🟢 -6.05 kB 🟢 -2.25 kB 🟢 -1.96 kB
assets/UserSelectView-DG2dW4bz.js (new) 5.49 kB 🔴 +5.49 kB 🔴 +1.96 kB 🔴 +1.71 kB
assets/UserSelectView-KZJpH7rI.js (removed) 5.49 kB 🟢 -5.49 kB 🟢 -1.96 kB 🟢 -1.71 kB
assets/CloudForgotPasswordView-CAA2Diwe.js (new) 4.97 kB 🔴 +4.97 kB 🔴 +1.72 kB 🔴 +1.49 kB
assets/CloudForgotPasswordView-dd7ov6Ca.js (removed) 4.97 kB 🟢 -4.97 kB 🟢 -1.72 kB 🟢 -1.49 kB
assets/CloudAuthTimeoutView-C0cSPe8T.js (new) 4.43 kB 🔴 +4.43 kB 🔴 +1.54 kB 🔴 +1.34 kB
assets/CloudAuthTimeoutView-DgIOmbBm.js (removed) 4.43 kB 🟢 -4.43 kB 🟢 -1.54 kB 🟢 -1.34 kB
assets/OAuthLayoutView-C5RySSRs.js (new) 1.31 kB 🔴 +1.31 kB 🔴 +700 B 🔴 +586 B
assets/OAuthLayoutView-DDosDj2s.js (removed) 1.31 kB 🟢 -1.31 kB 🟢 -699 B 🟢 -586 B
assets/WidgetTextPreview-BClyrABg.js (removed) 131 B 🟢 -131 B 🟢 -100 B 🟢 -84 B
assets/WidgetTextPreview-fVsjzq4t.js (new) 131 B 🔴 +131 B 🔴 +100 B 🔴 +94 B

Status: 13 added / 13 removed / 4 unchanged

Panels & Settings — 592 kB (baseline 591 kB) • 🔴 +937 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/KeybindingPanel-DIA1Y2ZK.js (removed) 49.4 kB 🟢 -49.4 kB 🟢 -9.94 kB 🟢 -8.79 kB
assets/KeybindingPanel-Ytus1Rxn.js (new) 49.4 kB 🔴 +49.4 kB 🔴 +9.94 kB 🔴 +8.8 kB
assets/CreditsPanel-CEDdRI5L.js (new) 37.6 kB 🔴 +37.6 kB 🔴 +9.35 kB 🔴 +8.18 kB
assets/CreditsPanel-CF9Sb0H3.js (removed) 36.6 kB 🟢 -36.6 kB 🟢 -8.9 kB 🟢 -7.79 kB
assets/SecretsPanel-BzicXPui.js (removed) 33.7 kB 🟢 -33.7 kB 🟢 -7.88 kB 🟢 -6.9 kB
assets/SecretsPanel-qudHU7Hi.js (new) 33.7 kB 🔴 +33.7 kB 🔴 +7.88 kB 🔴 +6.9 kB
assets/AboutPanel-CQoefPNd.js (new) 11.2 kB 🔴 +11.2 kB 🔴 +3.12 kB 🔴 +2.82 kB
assets/AboutPanel-lC2OEVIq.js (removed) 11.2 kB 🟢 -11.2 kB 🟢 -3.12 kB 🟢 -2.81 kB
assets/ExtensionPanel-BQzugpW4.js (new) 9.19 kB 🔴 +9.19 kB 🔴 +2.51 kB 🔴 +2.23 kB
assets/ExtensionPanel-CzZGprTO.js (removed) 9.19 kB 🟢 -9.19 kB 🟢 -2.51 kB 🟢 -2.23 kB
assets/ServerConfigPanel-CJTVQeja.js (new) 6.09 kB 🔴 +6.09 kB 🔴 +1.94 kB 🔴 +1.72 kB
assets/ServerConfigPanel-CWjzUy2L.js (removed) 6.09 kB 🟢 -6.09 kB 🟢 -1.94 kB 🟢 -1.72 kB
assets/UserPanel-BfZkZPSn.js (new) 5.73 kB 🔴 +5.73 kB 🔴 +1.78 kB 🔴 +1.54 kB
assets/UserPanel-D9RsiwYd.js (removed) 5.73 kB 🟢 -5.73 kB 🟢 -1.78 kB 🟢 -1.54 kB
assets/refreshRemoteConfig-LdeQG0UQ.js (new) 4.24 kB 🔴 +4.24 kB 🔴 +1.51 kB 🔴 +1.34 kB
assets/refreshRemoteConfig-xzOvvM7x.js (removed) 4.24 kB 🟢 -4.24 kB 🟢 -1.51 kB 🟢 -1.33 kB
assets/cloudRemoteConfig-CbpNKs4Q.js (new) 951 B 🔴 +951 B 🔴 +515 B 🔴 +423 B
assets/cloudRemoteConfig-DiIABjOd.js (removed) 951 B 🟢 -951 B 🟢 -516 B 🟢 -417 B
assets/CreditsPanel-1sQgJcxl.js (new) 116 B 🔴 +116 B 🔴 +95 B 🔴 +93 B
assets/CreditsPanel-Cw1xka0m.js (removed) 116 B 🟢 -116 B 🟢 -95 B 🟢 -91 B
assets/refreshRemoteConfig-BsX6FjgU.js (new) 110 B 🔴 +110 B 🔴 +89 B 🔴 +92 B
assets/refreshRemoteConfig-D1yuS4wl.js (removed) 110 B 🟢 -110 B 🟢 -89 B 🟢 -84 B

Status: 11 added / 11 removed / 16 unchanged

User & Accounts — 27.5 kB (baseline 27.5 kB) • ⚪ 0 B

Authentication, profile, and account management bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/SignUpForm-024_plVt.js (new) 13.3 kB 🔴 +13.3 kB 🔴 +4.52 kB 🔴 +3.93 kB
assets/SignUpForm-LqMIqENM.js (removed) 13.3 kB 🟢 -13.3 kB 🟢 -4.52 kB 🟢 -3.93 kB
assets/auth-CDTU71WH.js (removed) 3.48 kB 🟢 -3.48 kB 🟢 -1.21 kB 🟢 -1.01 kB
assets/auth-DqH52mOa.js (new) 3.48 kB 🔴 +3.48 kB 🔴 +1.2 kB 🔴 +1.01 kB
assets/UpdatePasswordContent-BBvg5uet.js (removed) 1.85 kB 🟢 -1.85 kB 🟢 -843 B 🟢 -735 B
assets/UpdatePasswordContent-DthrGXB4.js (new) 1.85 kB 🔴 +1.85 kB 🔴 +842 B 🔴 +736 B
assets/authStore-Bn1mysAA.js (removed) 128 B 🟢 -128 B 🟢 -104 B 🟢 -105 B
assets/authStore-Dmpmj1Ug.js (new) 128 B 🔴 +128 B 🔴 +104 B 🔴 +105 B
assets/workspaceAuthStore-BrUhbmI9.js (removed) 108 B 🟢 -108 B 🟢 -99 B 🟢 -104 B
assets/workspaceAuthStore-nUG8-dsX.js (new) 108 B 🔴 +108 B 🔴 +99 B 🔴 +102 B
assets/auth-CXdTHyMR.js (removed) 105 B 🟢 -105 B 🟢 -96 B 🟢 -80 B
assets/auth-DYuQK2d8.js (new) 105 B 🔴 +105 B 🔴 +96 B 🔴 +82 B

Status: 6 added / 6 removed / 5 unchanged

Editors & Dialogs — 125 kB (baseline 125 kB) • ⚪ 0 B

Modals, dialogs, drawers, and in-app editors

File Before After Δ Raw Δ Gzip Δ Brotli
assets/ComfyHubPublishDialog-Bzp1zGHW.js (new) 90.1 kB 🔴 +90.1 kB 🔴 +19.3 kB 🔴 +16.5 kB
assets/ComfyHubPublishDialog-D3jzfrqp.js (removed) 90.1 kB 🟢 -90.1 kB 🟢 -19.3 kB 🟢 -16.5 kB
assets/useShareDialog-Dn2k9-xU.js (new) 23.9 kB 🔴 +23.9 kB 🔴 +5.7 kB 🔴 +5.03 kB
assets/useShareDialog-zGrCJQeU.js (removed) 23.9 kB 🟢 -23.9 kB 🟢 -5.69 kB 🟢 -5.03 kB
assets/feedbackDialog-CsKho1do.js (removed) 4.45 kB 🟢 -4.45 kB 🟢 -1.86 kB 🟢 -1.59 kB
assets/feedbackDialog-DhQyZauv.js (new) 4.45 kB 🔴 +4.45 kB 🔴 +1.87 kB 🔴 +1.6 kB
assets/useRangeEditor-D3-cP1OM.js (removed) 3.29 kB 🟢 -3.29 kB 🟢 -1.14 kB 🟢 -1.03 kB
assets/useRangeEditor-Dht739Ec.js (new) 3.29 kB 🔴 +3.29 kB 🔴 +1.14 kB 🔴 +1.05 kB
assets/useLayerEditor-C8sTW3Zw.js (removed) 1.01 kB 🟢 -1.01 kB 🟢 -490 B 🟢 -405 B
assets/useLayerEditor-RcnwHszC.js (new) 1.01 kB 🔴 +1.01 kB 🔴 +489 B 🔴 +400 B
assets/ComfyHubPublishDialog-CzVVma1g.js (removed) 143 B 🟢 -143 B 🟢 -105 B 🟢 -91 B
assets/ComfyHubPublishDialog-D25uJJyi.js (new) 143 B 🔴 +143 B 🔴 +105 B 🔴 +87 B
assets/useSubscriptionDialog-CA9esJ1d.js (new) 108 B 🔴 +108 B 🔴 +102 B 🔴 +93 B
assets/useSubscriptionDialog-DOF3Cq2I.js (removed) 108 B 🟢 -108 B 🟢 -102 B 🟢 -96 B

Status: 7 added / 7 removed / 1 unchanged

UI Components — 67.1 kB (baseline 67.1 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/ComfyQueueButton-Czuif1yk.js (removed) 14.6 kB 🟢 -14.6 kB 🟢 -3.97 kB 🟢 -3.52 kB
assets/ComfyQueueButton-DqbqBlJn.js (new) 14.6 kB 🔴 +14.6 kB 🔴 +3.97 kB 🔴 +3.52 kB
assets/useTerminalTabs-D_ZiHh6A.js (removed) 11.8 kB 🟢 -11.8 kB 🟢 -3.69 kB 🟢 -3.28 kB
assets/useTerminalTabs-DxvcUpON.js (new) 11.8 kB 🔴 +11.8 kB 🔴 +3.69 kB 🔴 +3.28 kB
assets/InviteMembersForm-BOBpvUCR.js (new) 8.23 kB 🔴 +8.23 kB 🔴 +2.74 kB 🔴 +2.43 kB
assets/InviteMembersForm-kVBstXAp.js (removed) 8.23 kB 🟢 -8.23 kB 🟢 -2.74 kB 🟢 -2.44 kB
assets/SubscribeButton--IGeqYod.js (removed) 2.15 kB 🟢 -2.15 kB 🟢 -968 B 🟢 -848 B
assets/SubscribeButton-C8n6i191.js (new) 2.15 kB 🔴 +2.15 kB 🔴 +967 B 🔴 +849 B
assets/cloudFeedbackTopbarButton-Ba_JE6_F.js (new) 705 B 🔴 +705 B 🔴 +421 B 🔴 +360 B
assets/cloudFeedbackTopbarButton-BFAhN2oN.js (removed) 705 B 🟢 -705 B 🟢 -419 B 🟢 -357 B
assets/ComfyQueueButton-CwSSwv3d.js (new) 128 B 🔴 +128 B 🔴 +99 B 🔴 +91 B
assets/ComfyQueueButton-DIXOStuS.js (removed) 128 B 🟢 -128 B 🟢 -99 B 🟢 -89 B

Status: 6 added / 6 removed / 8 unchanged

Data & Services — 3.53 MB (baseline 3.53 MB) • 🔴 +177 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/settingStore-hBGrMluA.js (new) 3.16 MB 🔴 +3.16 MB 🔴 +742 kB 🔴 +558 kB
assets/settingStore-BNubhuF3.js (removed) 3.16 MB 🟢 -3.16 MB 🟢 -742 kB 🟢 -558 kB
assets/api-Baz2mBiH.js (new) 186 kB 🔴 +186 kB 🔴 +39.8 kB 🔴 +33.3 kB
assets/api-VWXg-0V-.js (removed) 186 kB 🟢 -186 kB 🟢 -39.8 kB 🟢 -33.4 kB
assets/load3dService-B4W_EaPk.js (new) 131 kB 🔴 +131 kB 🔴 +29.2 kB 🔴 +24.6 kB
assets/load3dService-kM4BxrOn.js (removed) 131 kB 🟢 -131 kB 🟢 -29.2 kB 🟢 -24.6 kB
assets/workflowShareService-_X87DDpe.js (new) 16.5 kB 🔴 +16.5 kB 🔴 +4.91 kB 🔴 +4.35 kB
assets/workflowShareService-CPkalyTd.js (removed) 16.5 kB 🟢 -16.5 kB 🟢 -4.91 kB 🟢 -4.35 kB
assets/keybindingService-DaBm6qy-.js (new) 6.95 kB 🔴 +6.95 kB 🔴 +1.74 kB 🔴 +1.51 kB
assets/keybindingService-l-ypHXD1.js (removed) 6.95 kB 🟢 -6.95 kB 🟢 -1.74 kB 🟢 -1.5 kB
assets/releaseStore-BgKm8NV8.js (removed) 6.72 kB 🟢 -6.72 kB 🟢 -2.03 kB 🟢 -1.77 kB
assets/releaseStore-CkiHuKRz.js (new) 6.72 kB 🔴 +6.72 kB 🔴 +2.03 kB 🔴 +1.77 kB
assets/systemStatsStore-CDxXlAbY.js (new) 4.93 kB 🔴 +4.93 kB 🔴 +1.74 kB 🔴 +1.47 kB
assets/systemStatsStore-p5-T3Rxs.js (removed) 4.93 kB 🟢 -4.93 kB 🟢 -1.74 kB 🟢 -1.47 kB
assets/userStore-B5-kgCGd.js (removed) 2.38 kB 🟢 -2.38 kB 🟢 -898 B 🟢 -795 B
assets/userStore-bJiTqvXL.js (new) 2.38 kB 🔴 +2.38 kB 🔴 +897 B 🔴 +796 B
assets/audioService-Bphu8V3_.js (removed) 1.71 kB 🟢 -1.71 kB 🟢 -828 B 🟢 -731 B
assets/audioService-dVkVKong.js (new) 1.71 kB 🔴 +1.71 kB 🔴 +828 B 🔴 +723 B
assets/dialogService-Cs3Y-NyX.js (new) 98 B 🔴 +98 B 🔴 +97 B 🔴 +84 B
assets/dialogService-DPGs2z6H.js (removed) 98 B 🟢 -98 B 🟢 -97 B 🟢 -93 B
assets/releaseStore-BHt4UuBN.js (removed) 95 B 🟢 -95 B 🟢 -86 B 🟢 -88 B
assets/releaseStore-Cpbk5RzB.js (new) 95 B 🔴 +95 B 🔴 +86 B 🔴 +85 B
assets/settingStore-BkujLwrx.js (new) 95 B 🔴 +95 B 🔴 +86 B 🔴 +88 B
assets/settingStore-mmCz62vi.js (removed) 95 B 🟢 -95 B 🟢 -86 B 🟢 -86 B
assets/assetsStore-EHC6CCzv.js (removed) 94 B 🟢 -94 B 🟢 -92 B 🟢 -84 B
assets/assetsStore-sfH1Js-G.js (new) 94 B 🔴 +94 B 🔴 +92 B 🔴 +84 B
assets/api-DaTGmc01.js (new) 62 B 🔴 +62 B 🔴 +74 B 🔴 +66 B
assets/api-RdbSaa9E.js (removed) 62 B 🟢 -62 B 🟢 -74 B 🟢 -66 B

Status: 14 added / 14 removed / 3 unchanged

Utilities & Hooks — 549 kB (baseline 549 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useConflictDetection-CgINeQ5d.js (removed) 236 kB 🟢 -236 kB 🟢 -53.1 kB 🟢 -43.2 kB
assets/useConflictDetection-CROAWNUW.js (new) 236 kB 🔴 +236 kB 🔴 +53.1 kB 🔴 +43.2 kB
assets/useLayerEditorSession-C4_3VVcY.js (removed) 158 kB 🟢 -158 kB 🟢 -40.8 kB 🟢 -34.3 kB
assets/useLayerEditorSession-CJT5LJFX.js (new) 158 kB 🔴 +158 kB 🔴 +40.8 kB 🔴 +34.3 kB
assets/useLoad3d-CoxiJSQ-.js (new) 25.8 kB 🔴 +25.8 kB 🔴 +5.8 kB 🔴 +5.14 kB
assets/useLoad3d-DOV1dohR.js (removed) 25.8 kB 🟢 -25.8 kB 🟢 -5.8 kB 🟢 -5.14 kB
assets/useLoad3dViewer-3FkSrvqN.js (new) 21.2 kB 🔴 +21.2 kB 🔴 +4.98 kB 🔴 +4.38 kB
assets/useLoad3dViewer-oWAtuhY_.js (removed) 21.2 kB 🟢 -21.2 kB 🟢 -4.98 kB 🟢 -4.35 kB
assets/useImageCrop-BwTkYjGC.js (new) 14.9 kB 🔴 +14.9 kB 🔴 +3.42 kB 🔴 +2.98 kB
assets/useImageCrop-Cq1bwapK.js (removed) 14.9 kB 🟢 -14.9 kB 🟢 -3.42 kB 🟢 -2.98 kB
assets/useDowngradeToPersonal-BPWDrtKm.js (removed) 10.9 kB 🟢 -10.9 kB 🟢 -2.74 kB 🟢 -2.35 kB
assets/useDowngradeToPersonal-Dom-nayX.js (new) 10.9 kB 🔴 +10.9 kB 🔴 +2.74 kB 🔴 +2.35 kB
assets/useFeatureFlags-D1jdlIV2.js (new) 7.25 kB 🔴 +7.25 kB 🔴 +2.05 kB 🔴 +1.73 kB
assets/useFeatureFlags-JnSQlaw8.js (removed) 7.25 kB 🟢 -7.25 kB 🟢 -2.05 kB 🟢 -1.74 kB
assets/useCompositorLayers-B25OMHfh.js (removed) 2.94 kB 🟢 -2.94 kB 🟢 -897 B 🟢 -803 B
assets/useCompositorLayers-Dmm6udoU.js (new) 2.94 kB 🔴 +2.94 kB 🔴 +897 B 🔴 +805 B
assets/assetPreviewUtil-B5FZUmKy.js (new) 2.35 kB 🔴 +2.35 kB 🔴 +967 B 🔴 +846 B
assets/assetPreviewUtil-CmT5aayQ.js (removed) 2.35 kB 🟢 -2.35 kB 🟢 -970 B 🟢 -845 B
assets/useUpstreamValue-CCY3euMK.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -757 B 🟢 -684 B
assets/useUpstreamValue-DH2ZmOB9.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +758 B 🔴 +684 B
assets/useWorkspaceTierLabel-C3U5F3w-.js (removed) 1.93 kB 🟢 -1.93 kB 🟢 -814 B 🟢 -696 B
assets/useWorkspaceTierLabel-nGim8BEU.js (new) 1.93 kB 🔴 +1.93 kB 🔴 +813 B 🔴 +697 B
assets/subscriptionCheckoutUtil--LNFc0vT.js (new) 877 B 🔴 +877 B 🔴 +524 B 🔴 +436 B
assets/subscriptionCheckoutUtil-BktJhycq.js (removed) 877 B 🟢 -877 B 🟢 -524 B 🟢 -436 B
assets/useSessionCookie-IeR4yjes.js (new) 652 B 🔴 +652 B 🔴 +336 B 🔴 +291 B
assets/useSessionCookie-Q8vp5_-K.js (removed) 652 B 🟢 -652 B 🟢 -337 B 🟢 -291 B
assets/useLoad3d-BR2wyi6Z.js (removed) 311 B 🟢 -311 B 🟢 -162 B 🟢 -146 B
assets/useLoad3d-jw4Nfda0.js (new) 311 B 🔴 +311 B 🔴 +163 B 🔴 +147 B
assets/useSessionCookie-J7tf36fn.js (new) 101 B 🔴 +101 B 🔴 +86 B 🔴 +81 B
assets/useSessionCookie-TURPT31U.js (removed) 101 B 🟢 -101 B 🟢 -86 B 🟢 -84 B
assets/useFeatureFlags-CF7BcBvR.js (new) 98 B 🔴 +98 B 🔴 +85 B 🔴 +82 B
assets/useFeatureFlags-CkLBje4R.js (removed) 98 B 🟢 -98 B 🟢 -85 B 🟢 -90 B
assets/useLoad3dViewer-Bp1l-Asr.js (new) 98 B 🔴 +98 B 🔴 +85 B 🔴 +85 B
assets/useLoad3dViewer-BTufcB5v.js (removed) 98 B 🟢 -98 B 🟢 -85 B 🟢 -89 B
assets/useCurrentUser-CakWb1-o.js (removed) 94 B 🟢 -94 B 🟢 -95 B 🟢 -93 B
assets/useCurrentUser-HhrENts3.js (new) 94 B 🔴 +94 B 🔴 +95 B 🔴 +93 B

Status: 18 added / 18 removed / 19 unchanged

Vendor & Third-Party — 18.1 MB (baseline 18.1 MB) • ⚪ 0 B

External libraries and shared vendor chunks

Status: 18 unchanged

Other — 14.1 MB (baseline 14.1 MB) • 🔴 +6 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/core-BsQt6N1w.js (new) 115 kB 🔴 +115 kB 🔴 +30 kB 🔴 +25.4 kB
assets/core-DVuvQFyB.js (removed) 115 kB 🟢 -115 kB 🟢 -30 kB 🟢 -25.4 kB
assets/WorkspaceSettingsPanelContent-BNelupfq.js (new) 109 kB 🔴 +109 kB 🔴 +21.4 kB 🔴 +18.1 kB
assets/WorkspaceSettingsPanelContent-B-w_-1jN.js (removed) 109 kB 🟢 -109 kB 🟢 -21.4 kB 🟢 -18 kB
assets/WidgetSelect-C7lDydYi.js (new) 88.8 kB 🔴 +88.8 kB 🔴 +20.1 kB 🔴 +17.3 kB
assets/WidgetSelect-Db8GRYX3.js (removed) 88.8 kB 🟢 -88.8 kB 🟢 -20.1 kB 🟢 -17.3 kB
assets/Load3D-CyfSs09N.js (new) 73.3 kB 🔴 +73.3 kB 🔴 +12.1 kB 🔴 +10.3 kB
assets/Load3D-DsHcwe1u.js (removed) 73.3 kB 🟢 -73.3 kB 🟢 -12.1 kB 🟢 -10.3 kB
assets/WidgetVideoEdit-BNLeaAAI.js (new) 71.2 kB 🔴 +71.2 kB 🔴 +16.9 kB 🔴 +14.9 kB
assets/WidgetVideoEdit-CLmFvV29.js (removed) 71.2 kB 🟢 -71.2 kB 🟢 -16.9 kB 🟢 -14.9 kB
assets/SubscriptionTransitionPreviewWorkspace-BFxf9It3.js (new) 66.4 kB 🔴 +66.4 kB 🔴 +13.4 kB 🔴 +11.7 kB
assets/SubscriptionTransitionPreviewWorkspace-CbQamyX7.js (removed) 66.4 kB 🟢 -66.4 kB 🟢 -13.4 kB 🟢 -11.7 kB
assets/Preview3d-B-EQOrEV.js (removed) 50.9 kB 🟢 -50.9 kB 🟢 -8.32 kB 🟢 -7.25 kB
assets/Preview3d-iDq9puG2.js (new) 50.9 kB 🔴 +50.9 kB 🔴 +8.32 kB 🔴 +7.25 kB
assets/main-Dd3xylqH.js (new) 47.4 kB 🔴 +47.4 kB 🔴 +13.7 kB 🔴 +11.9 kB
assets/main-DH-9KxPh.js (removed) 47.4 kB 🟢 -47.4 kB 🟢 -13.7 kB 🟢 -11.9 kB
assets/SubscriptionRequiredDialogContentUnified-Be-MPqXJ.js (removed) 42.7 kB 🟢 -42.7 kB 🟢 -9.38 kB 🟢 -8.18 kB
assets/SubscriptionRequiredDialogContentUnified-Dy4Avyfe.js (new) 42.7 kB 🔴 +42.7 kB 🔴 +9.39 kB 🔴 +8.19 kB
assets/LayerEditorContent-D8qZJ5A8.js (new) 42.5 kB 🔴 +42.5 kB 🔴 +9.62 kB 🔴 +8.41 kB
assets/LayerEditorContent-DrzYYt5-.js (removed) 42.5 kB 🟢 -42.5 kB 🟢 -9.62 kB 🟢 -8.41 kB
assets/WidgetBoundingBoxes-CXhTLc7x.js (new) 33.7 kB 🔴 +33.7 kB 🔴 +9.16 kB 🔴 +8.12 kB
assets/WidgetBoundingBoxes-pmFs-G0T.js (removed) 33.7 kB 🟢 -33.7 kB 🟢 -9.16 kB 🟢 -8.12 kB
assets/WidgetPainter-D8uN7vd4.js (removed) 32.6 kB 🟢 -32.6 kB 🟢 -7.88 kB 🟢 -6.97 kB
assets/WidgetPainter-DuCllCTr.js (new) 32.6 kB 🔴 +32.6 kB 🔴 +7.88 kB 🔴 +6.97 kB
assets/Load3dViewerContent-D8lCgSL2.js (removed) 30.8 kB 🟢 -30.8 kB 🟢 -6.28 kB 🟢 -5.45 kB
assets/Load3dViewerContent-Dlbc7rec.js (new) 30.8 kB 🔴 +30.8 kB 🔴 +6.28 kB 🔴 +5.44 kB
assets/SubscriptionRequiredDialogContent-C1TCDlxa.js (removed) 26.9 kB 🟢 -26.9 kB 🟢 -6.36 kB 🟢 -5.6 kB
assets/SubscriptionRequiredDialogContent-D2zeVpGO.js (new) 26.9 kB 🔴 +26.9 kB 🔴 +6.36 kB 🔴 +5.61 kB
assets/SubscriptionRequiredDialogContentWorkspace-BS9XgfOY.js (new) 25.1 kB 🔴 +25.1 kB 🔴 +5.81 kB 🔴 +5.11 kB
assets/SubscriptionRequiredDialogContentWorkspace-C1R8PyNO.js (removed) 25.1 kB 🟢 -25.1 kB 🟢 -5.81 kB 🟢 -5.11 kB
assets/load3d-Ci3a0c2v.js (removed) 22.2 kB 🟢 -22.2 kB 🟢 -5.4 kB 🟢 -4.67 kB
assets/load3d-Cpc5WS6J.js (new) 22.2 kB 🔴 +22.2 kB 🔴 +5.4 kB 🔴 +4.68 kB
assets/SignInContent-BZOmg8QW.js (removed) 20.6 kB 🟢 -20.6 kB 🟢 -5.18 kB 🟢 -4.53 kB
assets/SignInContent-C79W-Ki6.js (new) 20.6 kB 🔴 +20.6 kB 🔴 +5.18 kB 🔴 +4.53 kB
assets/WidgetRecordAudio-CC9m0yqu.js (new) 16.6 kB 🔴 +16.6 kB 🔴 +4.6 kB 🔴 +4.1 kB
assets/WidgetRecordAudio-Ds8LTv93.js (removed) 16.6 kB 🟢 -16.6 kB 🟢 -4.6 kB 🟢 -4.11 kB
assets/CurrentUserPopoverWorkspace-CPW0Q_kW.js (removed) 15.9 kB 🟢 -15.9 kB 🟢 -3.86 kB 🟢 -3.4 kB
assets/CurrentUserPopoverWorkspace-CxU73vp-.js (new) 15.9 kB 🔴 +15.9 kB 🔴 +3.86 kB 🔴 +3.41 kB
assets/WidgetInputNumber-BweFxNhu.js (new) 13.9 kB 🔴 +13.9 kB 🔴 +3.63 kB 🔴 +3.22 kB
assets/WidgetInputNumber-CfSWBDyc.js (removed) 13.9 kB 🟢 -13.9 kB 🟢 -3.63 kB 🟢 -3.22 kB
assets/WidgetRange-D-4nrvoh.js (new) 13.7 kB 🔴 +13.7 kB 🔴 +3.55 kB 🔴 +3.13 kB
assets/WidgetRange-D74c42mW.js (removed) 13.7 kB 🟢 -13.7 kB 🟢 -3.55 kB 🟢 -3.12 kB
assets/WaveAudioPlayer-B1nxxSD0.js (new) 12.8 kB 🔴 +12.8 kB 🔴 +3.46 kB 🔴 +3.04 kB
assets/WaveAudioPlayer-Cl5q9-Rs.js (removed) 12.8 kB 🟢 -12.8 kB 🟢 -3.46 kB 🟢 -3.05 kB
assets/WidgetCurve-B91Z7VfC.js (removed) 11.2 kB 🟢 -11.2 kB 🟢 -3.47 kB 🟢 -3.14 kB
assets/WidgetCurve-DvQ6kMWJ.js (new) 11.2 kB 🔴 +11.2 kB 🔴 +3.48 kB 🔴 +3.14 kB
assets/TeamWorkspacesDialogContent-BzKxT_kF.js (new) 10.3 kB 🔴 +10.3 kB 🔴 +2.97 kB 🔴 +2.63 kB
assets/TeamWorkspacesDialogContent-D-DhdXfY.js (removed) 10.3 kB 🟢 -10.3 kB 🟢 -2.97 kB 🟢 -2.62 kB
assets/onboardingCloudRoutes-0V1AJKId.js (new) 9.49 kB 🔴 +9.49 kB 🔴 +2.86 kB 🔴 +2.45 kB
assets/onboardingCloudRoutes-DWhcqySt.js (removed) 9.49 kB 🟢 -9.49 kB 🟢 -2.85 kB 🟢 -2.44 kB
assets/Load3DConfiguration-CdipRi4W.js (removed) 8.91 kB 🟢 -8.91 kB 🟢 -2.61 kB 🟢 -2.3 kB
assets/Load3DConfiguration-CVckrN_W.js (new) 8.91 kB 🔴 +8.91 kB 🔴 +2.61 kB 🔴 +2.3 kB
assets/WidgetImageCrop-Bm3ZpdLy.js (removed) 8.49 kB 🟢 -8.49 kB 🟢 -2.65 kB 🟢 -2.34 kB
assets/WidgetImageCrop-D89bd265.js (new) 8.49 kB 🔴 +8.49 kB 🔴 +2.66 kB 🔴 +2.34 kB
assets/SetMemberCreditLimitDialogContent-BufcLyI_.js (new) 8.47 kB 🔴 +8.47 kB 🔴 +2.34 kB 🔴 +2.06 kB
assets/SetMemberCreditLimitDialogContent-DYLN47KF.js (removed) 8.47 kB 🟢 -8.47 kB 🟢 -2.34 kB 🟢 -2.05 kB
assets/nodeTemplates-P1lI8yxY.js (removed) 8.32 kB 🟢 -8.32 kB 🟢 -2.85 kB 🟢 -2.5 kB
assets/nodeTemplates-VoEacwP3.js (new) 8.32 kB 🔴 +8.32 kB 🔴 +2.85 kB 🔴 +2.51 kB
assets/WorkspaceSwitcherPopover-B-pbY35s.js (removed) 8.01 kB 🟢 -8.01 kB 🟢 -2.38 kB 🟢 -2.12 kB
assets/WorkspaceSwitcherPopover-UURuWl2T.js (new) 8.01 kB 🔴 +8.01 kB 🔴 +2.38 kB 🔴 +2.12 kB
assets/NightlySurveyController-BHkz3leu.js (new) 7.5 kB 🔴 +7.5 kB 🔴 +2.55 kB 🔴 +2.24 kB
assets/NightlySurveyController-ClAkM9GJ.js (removed) 7.5 kB 🟢 -7.5 kB 🟢 -2.55 kB 🟢 -2.24 kB
assets/CloudRunButtonWrapper-Cs3KGUGm.js (removed) 7.29 kB 🟢 -7.29 kB 🟢 -2.29 kB 🟢 -2.01 kB
assets/CloudRunButtonWrapper-fXFihBNG.js (new) 7.29 kB 🔴 +7.29 kB 🔴 +2.29 kB 🔴 +2.01 kB
assets/WidgetWithControl-BDtFM6IC.js (removed) 6.51 kB 🟢 -6.51 kB 🟢 -2.66 kB 🟢 -2.33 kB
assets/WidgetWithControl-DESmcSFG.js (new) 6.51 kB 🔴 +6.51 kB 🔴 +2.67 kB 🔴 +2.33 kB
assets/missingModelMetadata-BdEn50RX.js (removed) 6.45 kB 🟢 -6.45 kB 🟢 -2.2 kB 🟢 -1.93 kB
assets/missingModelMetadata-TB_hOOC7.js (new) 6.45 kB 🔴 +6.45 kB 🔴 +2.21 kB 🔴 +1.93 kB
assets/CancelSubscriptionDialogContent-DwCmnKXT.js (removed) 5.97 kB 🟢 -5.97 kB 🟢 -1.98 kB 🟢 -1.75 kB
assets/CancelSubscriptionDialogContent-vjv1jvMJ.js (new) 5.97 kB 🔴 +5.97 kB 🔴 +1.98 kB 🔴 +1.75 kB
assets/load3dPreviewExtensions-BOMcJp-G.js (new) 5.88 kB 🔴 +5.88 kB 🔴 +1.81 kB 🔴 +1.6 kB
assets/load3dPreviewExtensions-DSzcKbeE.js (removed) 5.88 kB 🟢 -5.88 kB 🟢 -1.81 kB 🟢 -1.6 kB
assets/launchCancellationFlow-Ce1X9lFr.js (removed) 5.18 kB 🟢 -5.18 kB 🟢 -1.78 kB 🟢 -1.56 kB
assets/launchCancellationFlow-O6CO9D4K.js (new) 5.18 kB 🔴 +5.18 kB 🔴 +1.78 kB 🔴 +1.56 kB
assets/CreateWorkspaceDialogContent-_3Z79X1H.js (new) 5.12 kB 🔴 +5.12 kB 🔴 +1.79 kB 🔴 +1.55 kB
assets/CreateWorkspaceDialogContent-xajE30_E.js (removed) 5.12 kB 🟢 -5.12 kB 🟢 -1.79 kB 🟢 -1.55 kB
assets/ChangeMemberRoleDialogContent-Cln5HFGP.js (new) 4.97 kB 🔴 +4.97 kB 🔴 +1.64 kB 🔴 +1.43 kB
assets/ChangeMemberRoleDialogContent-J5x7C_0L.js (removed) 4.97 kB 🟢 -4.97 kB 🟢 -1.64 kB 🟢 -1.43 kB
assets/InviteMemberDialogContent-CTfSoRtF.js (new) 4.96 kB 🔴 +4.96 kB 🔴 +1.64 kB 🔴 +1.44 kB
assets/InviteMemberDialogContent-DtsTFXhA.js (removed) 4.96 kB 🟢 -4.96 kB 🟢 -1.64 kB 🟢 -1.44 kB
assets/EditWorkspaceDialogContent-B28qzV2P.js (removed) 4.93 kB 🟢 -4.93 kB 🟢 -1.76 kB 🟢 -1.52 kB
assets/EditWorkspaceDialogContent-BlA7GQf_.js (new) 4.93 kB 🔴 +4.93 kB 🔴 +1.76 kB 🔴 +1.53 kB
assets/WidgetTextarea-CNhA-DMQ.js (removed) 4.83 kB 🟢 -4.83 kB 🟢 -1.88 kB 🟢 -1.64 kB
assets/WidgetTextarea-DGR8jXXs.js (new) 4.83 kB 🔴 +4.83 kB 🔴 +1.88 kB 🔴 +1.65 kB
assets/saveMesh-CO1kWmop.js (new) 4.76 kB 🔴 +4.76 kB 🔴 +1.52 kB 🔴 +1.34 kB
assets/saveMesh-DcskMVjl.js (removed) 4.76 kB 🟢 -4.76 kB 🟢 -1.51 kB 🟢 -1.34 kB
assets/ValueControlPopover-Bj2y2p3p.js (removed) 4.49 kB 🟢 -4.49 kB 🟢 -1.55 kB 🟢 -1.38 kB
assets/ValueControlPopover-DVAspDqg.js (new) 4.49 kB 🔴 +4.49 kB 🔴 +1.55 kB 🔴 +1.38 kB
assets/DeleteWorkspaceDialogContent-BsWpWohn.js (new) 3.84 kB 🔴 +3.84 kB 🔴 +1.44 kB 🔴 +1.24 kB
assets/DeleteWorkspaceDialogContent-wgBe6KGl.js (removed) 3.84 kB 🟢 -3.84 kB 🟢 -1.44 kB 🟢 -1.24 kB
assets/RemoveMemberDialogContent-CmWlOtuh.js (removed) 3.76 kB 🟢 -3.76 kB 🟢 -1.38 kB 🟢 -1.23 kB
assets/RemoveMemberDialogContent-DIldiRf5.js (new) 3.76 kB 🔴 +3.76 kB 🔴 +1.38 kB 🔴 +1.22 kB
assets/RevokeInviteDialogContent-5kr5332a.js (new) 3.67 kB 🔴 +3.67 kB 🔴 +1.39 kB 🔴 +1.21 kB
assets/RevokeInviteDialogContent-Czd7MLxb.js (removed) 3.67 kB 🟢 -3.67 kB 🟢 -1.39 kB 🟢 -1.21 kB
assets/LeaveWorkspaceDialogContent-CerOYOa5.js (removed) 3.67 kB 🟢 -3.67 kB 🟢 -1.39 kB 🟢 -1.19 kB
assets/LeaveWorkspaceDialogContent-oGXznflI.js (new) 3.67 kB 🔴 +3.67 kB 🔴 +1.38 kB 🔴 +1.21 kB
assets/InviteMemberUpsellDialogContent-CnXP7b8G.js (removed) 3.47 kB 🟢 -3.47 kB 🟢 -1.24 kB 🟢 -1.09 kB
assets/InviteMemberUpsellDialogContent-DzBro9W-.js (new) 3.47 kB 🔴 +3.47 kB 🔴 +1.24 kB 🔴 +1.08 kB
assets/workspaceCheckoutTelemetry-Dh-whnxd.js (removed) 3.4 kB 🟢 -3.4 kB 🟢 -1.52 kB 🟢 -1.32 kB
assets/workspaceCheckoutTelemetry-HOJaJmQk.js (new) 3.4 kB 🔴 +3.4 kB 🔴 +1.52 kB 🔴 +1.32 kB
assets/GlobalToast-BybNsPpa.js (removed) 3.25 kB 🟢 -3.25 kB 🟢 -1.3 kB 🟢 -1.11 kB
assets/GlobalToast-UptjJPRc.js (new) 3.25 kB 🔴 +3.25 kB 🔴 +1.3 kB 🔴 +1.11 kB
assets/Media3DTop-BML03bTN.js (removed) 3.21 kB 🟢 -3.21 kB 🟢 -1.26 kB 🟢 -1.1 kB
assets/Media3DTop-PnMxCNJw.js (new) 3.21 kB 🔴 +3.21 kB 🔴 +1.27 kB 🔴 +1.11 kB
assets/load3dAdvanced-CGomYPG6.js (removed) 2.82 kB 🟢 -2.82 kB 🟢 -1.09 kB 🟢 -954 B
assets/load3dAdvanced-mZu70W4E.js (new) 2.82 kB 🔴 +2.82 kB 🔴 +1.09 kB 🔴 +954 B
assets/SubscribeToRun-HJkqSQGD.js (new) 2.39 kB 🔴 +2.39 kB 🔴 +1.03 kB 🔴 +907 B
assets/SubscribeToRun-sqYunfc9.js (removed) 2.39 kB 🟢 -2.39 kB 🟢 -1.03 kB 🟢 -907 B
assets/MediaAudioTop-7sm2P6SH.js (removed) 1.62 kB 🟢 -1.62 kB 🟢 -808 B 🟢 -668 B
assets/MediaAudioTop-Drl832Yv.js (new) 1.62 kB 🔴 +1.62 kB 🔴 +806 B 🔴 +668 B
assets/cloudSessionCookie-0JWBjjbH.js (new) 933 B 🔴 +933 B 🔴 +429 B 🔴 +376 B
assets/cloudSessionCookie-B2lPbofa.js (removed) 933 B 🟢 -933 B 🟢 -434 B 🟢 -378 B
assets/cloudBadges-BMPSByup.js (removed) 922 B 🟢 -922 B 🟢 -512 B 🟢 -441 B
assets/cloudBadges-dX3v8yoo.js (new) 922 B 🔴 +922 B 🔴 +512 B 🔴 +437 B
assets/Load3DAdvanced-CVQhOTch.js (removed) 761 B 🟢 -761 B 🟢 -422 B 🟢 -358 B
assets/Load3DAdvanced-NSG81Zdo.js (new) 761 B 🔴 +761 B 🔴 +422 B 🔴 +359 B
assets/nightlyBadges-Bjd-Tw42.js (removed) 411 B 🟢 -411 B 🟢 -271 B 🟢 -231 B
assets/nightlyBadges-D1bgDIU8.js (new) 411 B 🔴 +411 B 🔴 +272 B 🔴 +231 B
assets/Load3dViewerContent-C7p3nCyQ.js (removed) 137 B 🟢 -137 B 🟢 -103 B 🟢 -92 B
assets/Load3dViewerContent-CH8oqq7J.js (new) 137 B 🔴 +137 B 🔴 +103 B 🔴 +91 B
assets/missingModelMetadata-Bj3Mo5qk.js (removed) 125 B 🟢 -125 B 🟢 -103 B 🟢 -106 B
assets/missingModelMetadata-Xt9TpjC-.js (new) 125 B 🔴 +125 B 🔴 +103 B 🔴 +104 B
assets/Load3DAdvanced-D-WscEKJ.js (removed) 122 B 🟢 -122 B 🟢 -97 B 🟢 -88 B
assets/Load3DAdvanced-D8HtOOcr.js (new) 122 B 🔴 +122 B 🔴 +97 B 🔴 +89 B
assets/WidgetLegacy-CCd3Exsr.js (removed) 117 B 🟢 -117 B 🟢 -106 B 🟢 -101 B
assets/WidgetLegacy-DRZ-80C5.js (new) 117 B 🔴 +117 B 🔴 +106 B 🔴 +104 B
assets/workflowDraftStoreV2-CaaEbBdI.js (removed) 112 B 🟢 -112 B 🟢 -101 B 🟢 -107 B
assets/workflowDraftStoreV2-rtlRMEY9.js (new) 112 B 🔴 +112 B 🔴 +101 B 🔴 +111 B
assets/Load3D-C0Hy4DTb.js (new) 98 B 🔴 +98 B 🔴 +89 B 🔴 +84 B
assets/Load3D-CZBIO0fX.js (removed) 98 B 🟢 -98 B 🟢 -89 B 🟢 -78 B
assets/changeTracker-DszLwRyi.js (removed) 91 B 🟢 -91 B 🟢 -93 B 🟢 -85 B
assets/changeTracker-zeoQLH8y.js (new) 91 B 🔴 +91 B 🔴 +93 B 🔴 +88 B

Status: 66 added / 66 removed / 219 unchanged

⚡ Performance Report

canvas-idle: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 75.0 MB heap
canvas-mouse-sweep: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 54.9 MB heap
canvas-zoom-sweep: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 61.7 MB heap
dom-widget-clipping: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 69.5 MB heap
large-graph-idle: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 71.1 MB heap
large-graph-pan: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 69.1 MB heap
large-graph-zoom: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 67.9 MB heap
legacy-node-drag: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 67.0 MB heap
minimap-idle: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 63.7 MB heap
subgraph-dom-widget-clipping: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 70.4 MB heap
subgraph-idle: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 71.7 MB heap
subgraph-mouse-sweep: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 58.3 MB heap
subgraph-transition-enter: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 141ms TBT · 82.5 MB heap
viewport-pan-sweep: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 77.0 MB heap
vue-large-graph-idle: · 55.4 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 172.6 MB heap
vue-large-graph-pan: · 56.2 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 36ms TBT · 183.7 MB heap
workflow-execution: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 62.9 MB heap

⚠️ 4 regressions detected

Show regressions
Metric Baseline PR (median) Δ Sig
canvas-idle: task duration 510ms 548ms +8% ⚠️ z=4.9
large-graph-pan: task duration 1204ms 1202ms -0% ⚠️ z=2.8
subgraph-idle: task duration 476ms 476ms -0% ⚠️ z=3.4
workflow-execution: event listeners 49 63 +29% ⚠️ z=2.6
All metrics
Metric Baseline PR (median) Δ Sig
canvas-idle: avg frame time 17ms 17ms -0% z=-0.5
canvas-idle: p95 frame time 17ms 17ms +0%
canvas-idle: layout duration 0ms 0ms +0%
canvas-idle: style recalc duration 8ms 7ms -5% z=-4.0
canvas-idle: layout count 0 0 +0%
canvas-idle: style recalc count 7 9 +21% z=-4.7
canvas-idle: task duration 510ms 548ms +8% ⚠️ z=4.9
canvas-idle: script duration 9ms 9ms +1% z=-7.4
canvas-idle: TBT 0ms 0ms +0%
canvas-idle: heap used 76.0 MB 75.0 MB -1%
canvas-idle: DOM nodes -285 -280 -2% z=-237.3
canvas-idle: event listeners -151 -152 +1% z=-34.6
canvas-mouse-sweep: avg frame time 17ms 17ms +0% z=0.2
canvas-mouse-sweep: p95 frame time 17ms 17ms -0%
canvas-mouse-sweep: layout duration 3ms 3ms +0% z=-1.4
canvas-mouse-sweep: style recalc duration 34ms 37ms +7% z=-1.9
canvas-mouse-sweep: layout count 12 12 +0%
canvas-mouse-sweep: style recalc count 72 74 +3% z=-2.0
canvas-mouse-sweep: task duration 849ms 851ms +0% z=-0.2
canvas-mouse-sweep: script duration 109ms 110ms +1% z=-4.0
canvas-mouse-sweep: TBT 0ms 0ms +0%
canvas-mouse-sweep: heap used 68.0 MB 54.9 MB -19%
canvas-mouse-sweep: DOM nodes -281 -281 -0% z=-132.5
canvas-mouse-sweep: event listeners -183 -152 -17% z=-38.5
canvas-zoom-sweep: avg frame time 17ms 17ms +0% z=0.5
canvas-zoom-sweep: p95 frame time 17ms 17ms +0%
canvas-zoom-sweep: layout duration 1ms 1ms +18% z=1.1
canvas-zoom-sweep: style recalc duration 16ms 18ms +14% z=-0.8
canvas-zoom-sweep: layout count 6 6 +0%
canvas-zoom-sweep: style recalc count 30 30 +0% z=-2.8
canvas-zoom-sweep: task duration 347ms 350ms +1% z=1.0
canvas-zoom-sweep: script duration 9ms 9ms +2% z=-5.9
canvas-zoom-sweep: TBT 0ms 0ms +0%
canvas-zoom-sweep: heap used 62.4 MB 61.7 MB -1%
canvas-zoom-sweep: DOM nodes 77 76 -1% z=-4.1
canvas-zoom-sweep: event listeners 19 19 +0% z=-0.9
dom-widget-clipping: avg frame time 17ms 17ms +0% z=0.1
dom-widget-clipping: p95 frame time 17ms 17ms +0%
dom-widget-clipping: layout duration 0ms 0ms +0%
dom-widget-clipping: style recalc duration 7ms 7ms -7% z=-4.0
dom-widget-clipping: layout count 0 0 +0%
dom-widget-clipping: style recalc count 11 10 -9% z=-6.2
dom-widget-clipping: task duration 359ms 352ms -2% z=-0.8
dom-widget-clipping: script duration 55ms 55ms -1% z=-4.0
dom-widget-clipping: TBT 0ms 0ms +0%
dom-widget-clipping: heap used 68.6 MB 69.5 MB +1%
dom-widget-clipping: DOM nodes 18 16 -11% z=-4.3
dom-widget-clipping: event listeners 2 1 -50% variance too high
large-graph-idle: avg frame time 17ms 17ms +0% z=-0.2
large-graph-idle: p95 frame time 17ms 17ms -0%
large-graph-idle: layout duration 0ms 0ms +0%
large-graph-idle: style recalc duration 10ms 9ms -0% z=-2.6
large-graph-idle: layout count 0 0 +0%
large-graph-idle: style recalc count 10 9 -10% z=-8.3
large-graph-idle: task duration 608ms 605ms -0% z=1.2
large-graph-idle: script duration 15ms 15ms +0% z=-8.3
large-graph-idle: TBT 0ms 0ms +0%
large-graph-idle: heap used 68.3 MB 71.1 MB +4%
large-graph-idle: DOM nodes -279 -271 -3% z=-327.1
large-graph-idle: event listeners -151 -150 -1% z=-28.9
large-graph-pan: avg frame time 17ms 17ms +0% z=0.3
large-graph-pan: p95 frame time 17ms 17ms +0%
large-graph-pan: layout duration 0ms 0ms +0%
large-graph-pan: style recalc duration 14ms 17ms +23% z=0.1
large-graph-pan: layout count 0 0 +0%
large-graph-pan: style recalc count 69 70 +1% z=-0.1
large-graph-pan: task duration 1204ms 1202ms -0% ⚠️ z=2.8
large-graph-pan: script duration 348ms 344ms -1% z=-3.2
large-graph-pan: TBT 0ms 0ms +0%
large-graph-pan: heap used 66.4 MB 69.1 MB +4%
large-graph-pan: DOM nodes -279 -258 -8% z=-167.6
large-graph-pan: event listeners -149 -147 -1% z=-183.5
large-graph-zoom: avg frame time 17ms 17ms -0%
large-graph-zoom: p95 frame time 17ms 17ms +0%
large-graph-zoom: layout duration 7ms 7ms +1%
large-graph-zoom: style recalc duration 14ms 13ms -5%
large-graph-zoom: layout count 60 60 +0%
large-graph-zoom: style recalc count 65 64 -2%
large-graph-zoom: task duration 1386ms 1371ms -1%
large-graph-zoom: script duration 386ms 391ms +1%
large-graph-zoom: TBT 0ms 0ms +0%
large-graph-zoom: heap used 64.1 MB 67.9 MB +6%
large-graph-zoom: DOM nodes -287 -285 -1%
large-graph-zoom: event listeners -153 -150 -2%
legacy-node-drag: avg frame time 17ms 17ms +0%
legacy-node-drag: p95 frame time 17ms 17ms +0%
legacy-node-drag: layout duration 0ms 0ms +0%
legacy-node-drag: style recalc duration 10ms 11ms +10%
legacy-node-drag: layout count 0 0 +0%
legacy-node-drag: style recalc count 45 47 +4%
legacy-node-drag: task duration 1444ms 1434ms -1%
legacy-node-drag: script duration 472ms 475ms +1%
legacy-node-drag: TBT 0ms 0ms +0%
legacy-node-drag: heap used 66.6 MB 67.0 MB +0%
legacy-node-drag: DOM nodes 10 14 +40%
legacy-node-drag: event listeners 184 186 +1%
minimap-idle: avg frame time 17ms 17ms +0% z=0.1
minimap-idle: p95 frame time 17ms 17ms -1%
minimap-idle: layout duration 0ms 0ms +0%
minimap-idle: style recalc duration 9ms 8ms -11% z=-1.4
minimap-idle: layout count 0 0 +0%
minimap-idle: style recalc count 8 10 +19% z=-0.1
minimap-idle: task duration 603ms 598ms -1% z=1.5
minimap-idle: script duration 14ms 13ms -4% z=-8.6
minimap-idle: TBT 0ms 0ms +0%
minimap-idle: heap used 68.8 MB 63.7 MB -7%
minimap-idle: DOM nodes -279 -280 +0% z=-218.7
minimap-idle: event listeners -149 -164 +10% z=-255.3
subgraph-dom-widget-clipping: avg frame time 17ms 17ms +0% z=0.7
subgraph-dom-widget-clipping: p95 frame time 17ms 17ms +0%
subgraph-dom-widget-clipping: layout duration 0ms 0ms +0%
subgraph-dom-widget-clipping: style recalc duration 10ms 9ms -4% z=-3.8
subgraph-dom-widget-clipping: layout count 0 0 +0%
subgraph-dom-widget-clipping: style recalc count 45 45 +0% z=-5.0
subgraph-dom-widget-clipping: task duration 393ms 384ms -2% z=0.3
subgraph-dom-widget-clipping: script duration 119ms 117ms -2% z=-1.8
subgraph-dom-widget-clipping: TBT 0ms 0ms +0%
subgraph-dom-widget-clipping: heap used 70.6 MB 70.4 MB -0%
subgraph-dom-widget-clipping: DOM nodes 16 16 +0% z=-5.5
subgraph-dom-widget-clipping: event listeners 8 8 +0% z=-1.4
subgraph-idle: avg frame time 17ms 17ms +0% z=0.4
subgraph-idle: p95 frame time 17ms 17ms -1%
subgraph-idle: layout duration 0ms 0ms +0%
subgraph-idle: style recalc duration 7ms 8ms +16% z=-3.0
subgraph-idle: layout count 0 0 +0%
subgraph-idle: style recalc count 8 9 +13% z=-2.9
subgraph-idle: task duration 476ms 476ms -0% ⚠️ z=3.4
subgraph-idle: script duration 6ms 6ms -1% z=-5.3
subgraph-idle: TBT 0ms 0ms +0%
subgraph-idle: heap used 62.8 MB 71.7 MB +14%
subgraph-idle: DOM nodes -283 -281 -1% z=-202.5
subgraph-idle: event listeners -151 -166 +10% variance too high
subgraph-mouse-sweep: avg frame time 17ms 17ms -0% z=-0.1
subgraph-mouse-sweep: p95 frame time 17ms 17ms +0%
subgraph-mouse-sweep: layout duration 4ms 4ms +5% z=-0.7
subgraph-mouse-sweep: style recalc duration 35ms 36ms +3% z=-1.9
subgraph-mouse-sweep: layout count 16 16 +0%
subgraph-mouse-sweep: style recalc count 75 76 +1% z=-2.4
subgraph-mouse-sweep: task duration 791ms 799ms +1% z=0.5
subgraph-mouse-sweep: script duration 85ms 84ms -2% z=-2.6
subgraph-mouse-sweep: TBT 0ms 0ms +0%
subgraph-mouse-sweep: heap used 62.4 MB 58.3 MB -7%
subgraph-mouse-sweep: DOM nodes -280 -283 +1% z=-156.4
subgraph-mouse-sweep: event listeners -151 -167 +11% variance too high
subgraph-transition-enter: avg frame time 17ms 17ms +0%
subgraph-transition-enter: p95 frame time 17ms 17ms +0%
subgraph-transition-enter: layout duration 15ms 15ms -1%
subgraph-transition-enter: style recalc duration 32ms 32ms -1%
subgraph-transition-enter: layout count 14 13 -7%
subgraph-transition-enter: style recalc count 19 18 -5%
subgraph-transition-enter: task duration 910ms 897ms -1%
subgraph-transition-enter: script duration 16ms 16ms +0%
subgraph-transition-enter: TBT 138ms 141ms +2%
subgraph-transition-enter: heap used 82.7 MB 82.5 MB -0%
subgraph-transition-enter: DOM nodes 13673 13673 +0%
subgraph-transition-enter: event listeners 2373 2373 +0%
viewport-pan-sweep: avg frame time 17ms 17ms +0%
viewport-pan-sweep: p95 frame time 17ms 17ms +0%
viewport-pan-sweep: layout duration 0ms 0ms +0%
viewport-pan-sweep: style recalc duration 37ms 36ms -4%
viewport-pan-sweep: layout count 0 0 +0%
viewport-pan-sweep: style recalc count 250 249 -0%
viewport-pan-sweep: task duration 4175ms 4204ms +1%
viewport-pan-sweep: script duration 1057ms 1114ms +5%
viewport-pan-sweep: TBT 0ms 0ms +0%
viewport-pan-sweep: heap used 66.7 MB 77.0 MB +15%
viewport-pan-sweep: DOM nodes -281 -260 -8%
viewport-pan-sweep: event listeners -135 -132 -2%
vue-large-graph-idle: avg frame time 18ms 18ms +2%
vue-large-graph-idle: p95 frame time 17ms 17ms +0%
vue-large-graph-idle: layout duration 0ms 0ms +0%
vue-large-graph-idle: style recalc duration 0ms 0ms +0%
vue-large-graph-idle: layout count 0 0 +0%
vue-large-graph-idle: style recalc count 0 0 +0%
vue-large-graph-idle: task duration 16419ms 16396ms -0%
vue-large-graph-idle: script duration 105ms 109ms +4%
vue-large-graph-idle: TBT 0ms 0ms +0%
vue-large-graph-idle: heap used 172.4 MB 172.6 MB +0%
vue-large-graph-idle: DOM nodes -8312 -8312 +0%
vue-large-graph-idle: event listeners -16391 -16391 +0%
vue-large-graph-pan: avg frame time 18ms 18ms +0%
vue-large-graph-pan: p95 frame time 17ms 17ms +0%
vue-large-graph-pan: layout duration 0ms 0ms +0%
vue-large-graph-pan: style recalc duration 17ms 19ms +7%
vue-large-graph-pan: layout count 0 0 +0%
vue-large-graph-pan: style recalc count 175 178 +2%
vue-large-graph-pan: task duration 20310ms 20328ms +0%
vue-large-graph-pan: script duration 396ms 416ms +5%
vue-large-graph-pan: TBT 50ms 36ms -29%
vue-large-graph-pan: heap used 183.5 MB 183.7 MB +0%
vue-large-graph-pan: DOM nodes -8312 -8312 +0%
vue-large-graph-pan: event listeners -16387 -16386 -0%
workflow-execution: avg frame time 17ms 17ms -0% z=0.1
workflow-execution: p95 frame time 17ms 17ms -0%
workflow-execution: layout duration 1ms 1ms +89% z=-1.5
workflow-execution: style recalc duration 14ms 18ms +27% z=-2.8
workflow-execution: layout count 3 3 -17% z=-4.5
workflow-execution: style recalc count 9 12 +33% z=-2.8
workflow-execution: task duration 85ms 93ms +10% z=-2.8
workflow-execution: script duration 6ms 6ms +6% z=-7.7
workflow-execution: TBT 0ms 0ms +0%
workflow-execution: heap used 62.3 MB 62.9 MB +1%
workflow-execution: DOM nodes 119 137 +15% z=-3.4
workflow-execution: event listeners 49 63 +29% ⚠️ z=2.6
Historical variance (last 15 runs)
Metric μ σ CV
canvas-idle: avg frame time 17ms 0ms 0.0%
canvas-idle: layout duration 0ms 0ms 0.0%
canvas-idle: style recalc duration 11ms 1ms 8.2%
canvas-idle: layout count 0 0 0.0%
canvas-idle: style recalc count 11 1 5.0%
canvas-idle: task duration 395ms 31ms 7.9%
canvas-idle: script duration 25ms 2ms 8.8%
canvas-idle: TBT 0ms 0ms 0.0%
canvas-idle: DOM nodes 23 1 5.6%
canvas-idle: event listeners 12 5 40.9%
canvas-mouse-sweep: avg frame time 17ms 0ms 0.0%
canvas-mouse-sweep: layout duration 4ms 0ms 5.4%
canvas-mouse-sweep: style recalc duration 43ms 3ms 7.4%
canvas-mouse-sweep: layout count 12 0 0.0%
canvas-mouse-sweep: style recalc count 79 2 3.0%
canvas-mouse-sweep: task duration 865ms 58ms 6.7%
canvas-mouse-sweep: script duration 136ms 6ms 4.8%
canvas-mouse-sweep: TBT 0ms 0ms 0.0%
canvas-mouse-sweep: DOM nodes 62 3 4.2%
canvas-mouse-sweep: event listeners 8 4 49.4%
canvas-zoom-sweep: avg frame time 17ms 0ms 0.0%
canvas-zoom-sweep: layout duration 1ms 0ms 7.0%
canvas-zoom-sweep: style recalc duration 19ms 2ms 8.0%
canvas-zoom-sweep: layout count 6 0 0.0%
canvas-zoom-sweep: style recalc count 31 0 1.5%
canvas-zoom-sweep: task duration 327ms 23ms 7.1%
canvas-zoom-sweep: script duration 27ms 3ms 11.1%
canvas-zoom-sweep: TBT 0ms 0ms 0.0%
canvas-zoom-sweep: DOM nodes 79 1 1.0%
canvas-zoom-sweep: event listeners 24 5 21.8%
dom-widget-clipping: avg frame time 17ms 0ms 0.0%
dom-widget-clipping: layout duration 0ms 0ms 0.0%
dom-widget-clipping: style recalc duration 10ms 1ms 8.0%
dom-widget-clipping: layout count 0 0 0.0%
dom-widget-clipping: style recalc count 13 0 3.8%
dom-widget-clipping: task duration 365ms 16ms 4.5%
dom-widget-clipping: script duration 68ms 3ms 4.8%
dom-widget-clipping: TBT 0ms 0ms 0.0%
dom-widget-clipping: DOM nodes 22 1 6.4%
dom-widget-clipping: event listeners 8 6 81.2%
large-graph-idle: avg frame time 17ms 0ms 0.0%
large-graph-idle: layout duration 0ms 0ms 0.0%
large-graph-idle: style recalc duration 12ms 1ms 8.6%
large-graph-idle: layout count 0 0 0.0%
large-graph-idle: style recalc count 12 0 2.7%
large-graph-idle: task duration 542ms 54ms 10.0%
large-graph-idle: script duration 102ms 11ms 10.3%
large-graph-idle: TBT 0ms 0ms 0.0%
large-graph-idle: DOM nodes 25 1 3.7%
large-graph-idle: event listeners 26 6 23.2%
large-graph-pan: avg frame time 17ms 0ms 0.0%
large-graph-pan: layout duration 0ms 0ms 0.0%
large-graph-pan: style recalc duration 17ms 1ms 4.6%
large-graph-pan: layout count 0 0 0.0%
large-graph-pan: style recalc count 70 1 0.9%
large-graph-pan: task duration 1082ms 43ms 4.0%
large-graph-pan: script duration 408ms 20ms 4.8%
large-graph-pan: TBT 0ms 0ms 0.0%
large-graph-pan: DOM nodes 19 2 8.7%
large-graph-pan: event listeners 5 1 16.8%
minimap-idle: avg frame time 17ms 0ms 0.0%
minimap-idle: layout duration 0ms 0ms 0.0%
minimap-idle: style recalc duration 10ms 1ms 8.6%
minimap-idle: layout count 0 0 0.0%
minimap-idle: style recalc count 10 1 7.1%
minimap-idle: task duration 527ms 47ms 9.0%
minimap-idle: script duration 98ms 10ms 10.1%
minimap-idle: TBT 0ms 0ms 0.0%
minimap-idle: DOM nodes 19 1 7.1%
minimap-idle: event listeners 5 1 14.4%
subgraph-dom-widget-clipping: avg frame time 17ms 0ms 0.0%
subgraph-dom-widget-clipping: layout duration 0ms 0ms 0.0%
subgraph-dom-widget-clipping: style recalc duration 13ms 1ms 7.4%
subgraph-dom-widget-clipping: layout count 0 0 0.0%
subgraph-dom-widget-clipping: style recalc count 48 1 1.2%
subgraph-dom-widget-clipping: task duration 378ms 18ms 4.9%
subgraph-dom-widget-clipping: script duration 128ms 6ms 4.9%
subgraph-dom-widget-clipping: TBT 0ms 0ms 0.0%
subgraph-dom-widget-clipping: DOM nodes 22 1 5.0%
subgraph-dom-widget-clipping: event listeners 16 6 36.0%
subgraph-idle: avg frame time 17ms 0ms 0.0%
subgraph-idle: layout duration 0ms 0ms 0.0%
subgraph-idle: style recalc duration 10ms 1ms 7.5%
subgraph-idle: layout count 0 0 0.0%
subgraph-idle: style recalc count 11 1 6.0%
subgraph-idle: task duration 370ms 31ms 8.5%
subgraph-idle: script duration 20ms 3ms 13.2%
subgraph-idle: TBT 0ms 0ms 0.0%
subgraph-idle: DOM nodes 22 1 6.9%
subgraph-idle: event listeners 10 7 64.5%
subgraph-mouse-sweep: avg frame time 17ms 0ms 0.0%
subgraph-mouse-sweep: layout duration 5ms 0ms 6.8%
subgraph-mouse-sweep: style recalc duration 42ms 3ms 7.8%
subgraph-mouse-sweep: layout count 16 0 0.0%
subgraph-mouse-sweep: style recalc count 80 2 2.4%
subgraph-mouse-sweep: task duration 766ms 69ms 9.0%
subgraph-mouse-sweep: script duration 101ms 7ms 6.5%
subgraph-mouse-sweep: TBT 0ms 0ms 0.0%
subgraph-mouse-sweep: DOM nodes 67 2 3.3%
subgraph-mouse-sweep: event listeners 8 4 52.6%
workflow-execution: avg frame time 17ms 0ms 0.0%
workflow-execution: layout duration 2ms 0ms 9.4%
workflow-execution: style recalc duration 24ms 2ms 9.1%
workflow-execution: layout count 5 1 11.0%
workflow-execution: style recalc count 18 2 11.5%
workflow-execution: task duration 123ms 11ms 8.8%
workflow-execution: script duration 29ms 3ms 10.2%
workflow-execution: TBT 0ms 0ms 0.0%
workflow-execution: DOM nodes 161 7 4.4%
workflow-execution: event listeners 52 4 8.4%
Trend (last 15 commits on main)
Metric Trend Dir Latest
canvas-idle: avg frame time ▆▃▆▁▆▃▆█▆▆▄▃▃▄▃ ➡️ 17ms
canvas-idle: p95 frame time ➡️ NaNms
canvas-idle: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
canvas-idle: style recalc duration ▇▇▆▆▃█▄▃▄▃▇▄▁▆▇ ➡️ 11ms
canvas-idle: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
canvas-idle: style recalc count █▃▅▂▅▆▃▁▂▁▂▅▆▅▆ ➡️ 12
canvas-idle: task duration ▃▃▃▆▂▃▃▅▆▂█▃▁▃▃ ➡️ 391ms
canvas-idle: script duration ▄▃▅▇▂▅▃▆▇▅█▄▁▅▆ ➡️ 27ms
canvas-idle: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
canvas-idle: heap used ➡️ NaN MB
canvas-idle: DOM nodes █▇▆▅▃▇▃▁▂▂▅▆▆▆▇ ➡️ 24
canvas-idle: event listeners ▅█▅▄▁▅▁▁▁▄▅▅▁▅▄ 📉 11
canvas-mouse-sweep: avg frame time ▆█▆▃▁▃▁▆▆▁▃▆▆▃▃ ➡️ 17ms
canvas-mouse-sweep: p95 frame time ➡️ NaNms
canvas-mouse-sweep: layout duration ▁▃▂▄▁▂▁▃▆▂█▇▆▄▃ ➡️ 4ms
canvas-mouse-sweep: style recalc duration ▄▄▂▄▁▂▃▃▅▄█▆▂▄▄ ➡️ 43ms
canvas-mouse-sweep: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 12
canvas-mouse-sweep: style recalc count █▅▄▃▂▂▁▄▄▅▆▅▂▇▄ ➡️ 79
canvas-mouse-sweep: task duration █▆▄▂▂▃▂▄▄▅█▆▁▆▄ ➡️ 868ms
canvas-mouse-sweep: script duration ▄▅▄▆▄▆▆▆▅▅█▆▁▅▆ ➡️ 139ms
canvas-mouse-sweep: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
canvas-mouse-sweep: heap used ➡️ NaN MB
canvas-mouse-sweep: DOM nodes █▅▃▃▁▂▂▃▂▄▆▅▃▅▅ ➡️ 64
canvas-mouse-sweep: event listeners █▁▁▁▁▁▇▁▁▁██▇▁█ 📈 13
canvas-zoom-sweep: avg frame time ▅▅█▄▅▁▁▁▅▁▁▅▄▅▁ ➡️ 17ms
canvas-zoom-sweep: p95 frame time ➡️ NaNms
canvas-zoom-sweep: layout duration ▆▅▅▄▁▁█▅▃▅▇▆▁▂▆ ➡️ 1ms
canvas-zoom-sweep: style recalc duration ▆▅▄▆▅▃█▆▇▅▇▄▁▃▅ ➡️ 20ms
canvas-zoom-sweep: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 6
canvas-zoom-sweep: style recalc count ▁▁▃▄▆▃▆█▄▄▆▁▆▁▆ ➡️ 32
canvas-zoom-sweep: task duration ▄▂▁▇▂▂▄▅▆▃█▄▁▁▅ ➡️ 338ms
canvas-zoom-sweep: script duration ▃▃▂▇▂▂▅▇▆▅█▄▁▂▆ ➡️ 30ms
canvas-zoom-sweep: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
canvas-zoom-sweep: heap used ➡️ NaN MB
canvas-zoom-sweep: DOM nodes ▄▃▁▅█▁▃▆▄▅▅▃▃▄▃ ➡️ 79
canvas-zoom-sweep: event listeners ▁▁▂▅█▂▁▅▁▅▅▄▁▅▁ ➡️ 19
dom-widget-clipping: avg frame time ▂▄▅▅▂▄█▇▅▇▇▅▅▁▇ ➡️ 17ms
dom-widget-clipping: p95 frame time ➡️ NaNms
dom-widget-clipping: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
dom-widget-clipping: style recalc duration ▆▆▂▆▄▃██▄▁▆▇▆▃▅ ➡️ 10ms
dom-widget-clipping: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
dom-widget-clipping: style recalc count ▇█▅█▅▄█▇▇▁▇▄▇▂▅ ➡️ 13
dom-widget-clipping: task duration ▃▃▁▅▄▃▅▆▅▂▇█▁▅▅ ➡️ 371ms
dom-widget-clipping: script duration ▅▄▄▆▆▅▇▇▆▃█▇▁▇▇ ➡️ 71ms
dom-widget-clipping: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
dom-widget-clipping: heap used ➡️ NaN MB
dom-widget-clipping: DOM nodes ▇▇▄▇▅▄█▇▅▁▅▄▇▃▄ ➡️ 21
dom-widget-clipping: event listeners ▅▅▅▅▁▅██▁▁▁▁█▁▁ 📉 2
large-graph-idle: avg frame time ▅▅▅▅▅▂▁▂▄▅▄▂▂▅█ ➡️ 17ms
large-graph-idle: p95 frame time ➡️ NaNms
large-graph-idle: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
large-graph-idle: style recalc duration ▅▅▅▆▄▅▃▄▅▅▆█▁▄▆ ➡️ 13ms
large-graph-idle: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
large-graph-idle: style recalc count █▆█▃▃▁▃▆▃▆▆▃▆██ ➡️ 12
large-graph-idle: task duration ▂▃▂▆▂▃▃▇▅▃██▁▂▅ ➡️ 569ms
large-graph-idle: script duration ▄▅▄▆▄▅▅▇▆▅█▆▁▃▆ ➡️ 110ms
large-graph-idle: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
large-graph-idle: heap used ➡️ NaN MB
large-graph-idle: DOM nodes ▆█▅▂▅▃▁▂▃▅▅▆▂▆▅ ➡️ 25
large-graph-idle: event listeners ███▇██▄▁▄▇▇█▂█▇ ➡️ 29
large-graph-pan: avg frame time ▆▃▃▆█▃▁█▆▆▆▆█▁▆ ➡️ 17ms
large-graph-pan: p95 frame time ➡️ NaNms
large-graph-pan: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
large-graph-pan: style recalc duration ▃▂▄▄▁▅▂▂▁▄▄█▃▁▂ ➡️ 17ms
large-graph-pan: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
large-graph-pan: style recalc count ▆▃█▂▃▂▂▂▁▇▅▃█▆▃ ➡️ 69
large-graph-pan: task duration ▄▃▄▆▄▄▄▆▄▄█▆▁▂▅ ➡️ 1100ms
large-graph-pan: script duration ▅▄▅▆▆▅▄▆▄▅█▄▁▄▅ ➡️ 413ms
large-graph-pan: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
large-graph-pan: heap used ➡️ NaN MB
large-graph-pan: DOM nodes ▅▃▆▂▄▁▃▁▁▅▁▂█▅▂ ➡️ 18
large-graph-pan: event listeners █▆█▁▁▆▁▁▃▆▁▃██▃ ➡️ 5
minimap-idle: avg frame time ▃▆▆▃█▁█▆▆▃▃▆█▆█ ➡️ 17ms
minimap-idle: p95 frame time ➡️ NaNms
minimap-idle: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
minimap-idle: style recalc duration ▄█▁█▅▅█▅▅▃▅▁▁▄▆ ➡️ 10ms
minimap-idle: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
minimap-idle: style recalc count ▃▅▂▄█▃▆▁▂▅▂▁▅▆▃ ➡️ 9
minimap-idle: task duration ▃▄▁▅▁▃▄▅▇▃█▅▁▁▅ ➡️ 547ms
minimap-idle: script duration ▄▆▃▇▃▅▆▆▇▅█▅▁▃▆ ➡️ 106ms
minimap-idle: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
minimap-idle: heap used ➡️ NaN MB
minimap-idle: DOM nodes ▃▅▂▄█▃▆▁▂▅▂▁▅▆▃ ➡️ 19
minimap-idle: event listeners ▃▃▆▁▁▁▃▁▁▆▁▃█▆▁ ➡️ 4
subgraph-dom-widget-clipping: avg frame time ▅▄▄▄▄▄█▄▄▄▃▁▆▃▃ ➡️ 17ms
subgraph-dom-widget-clipping: p95 frame time ➡️ NaNms
subgraph-dom-widget-clipping: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-dom-widget-clipping: style recalc duration ▂▄▃▅▅▃▂▅▇▃▄█▁▄▆ ➡️ 14ms
subgraph-dom-widget-clipping: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
subgraph-dom-widget-clipping: style recalc count ▇█▆▃▆▃▁▆█▇▃▆▇█▅ ➡️ 48
subgraph-dom-widget-clipping: task duration ▂▃▃▆▅▅▂▅█▂▆█▁▂▇ ➡️ 398ms
subgraph-dom-widget-clipping: script duration ▃▃▃▄▅▅▂▄█▂▅▇▁▂▅ ➡️ 131ms
subgraph-dom-widget-clipping: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-dom-widget-clipping: heap used ➡️ NaN MB
subgraph-dom-widget-clipping: DOM nodes ▅▇▅▂▅▂▁▅▅▅▁▇▅█▄ ➡️ 22
subgraph-dom-widget-clipping: event listeners ▅▅▅▂▅▁▅██▁▁█▅█▅ 📈 16
subgraph-idle: avg frame time ▆▆█▁▆▃▆▆▆▃▆▁▃▆█ ➡️ 17ms
subgraph-idle: p95 frame time ➡️ NaNms
subgraph-idle: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-idle: style recalc duration ▁▇▃▆▂▄▂▃▃▆▆▄▃▇█ ➡️ 12ms
subgraph-idle: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
subgraph-idle: style recalc count ▃▆▃▃▂▅▁▂▁▆▃▃██▇ ➡️ 12
subgraph-idle: task duration ▁▃▁▇▁▁▃▆▅▂█▅▁▁▄ ➡️ 378ms
subgraph-idle: script duration ▁▃▂▇▁▂▃▇▆▂█▅▂▁▅ ➡️ 22ms
subgraph-idle: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-idle: heap used ➡️ NaN MB
subgraph-idle: DOM nodes ▃▅▃▂▁▄▁▂▁▅▃▂▇█▇ ➡️ 24
subgraph-idle: event listeners ▁▅▁▁▁▁▁▁▁▅▄▁███ 📈 21
subgraph-mouse-sweep: avg frame time ▅▄▁▃▃▄▆▄▆▃▃█▁▃▃ ➡️ 17ms
subgraph-mouse-sweep: p95 frame time ➡️ NaNms
subgraph-mouse-sweep: layout duration ▁▄▄▄▃▃▅▅▅▂█▇▂▃▆ ➡️ 5ms
subgraph-mouse-sweep: style recalc duration ▃▂▄▅▂▃▄▅█▃█▆▁▂▅ ➡️ 43ms
subgraph-mouse-sweep: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 16
subgraph-mouse-sweep: style recalc count ▅▂▅▅▁▄▃▅█▅▆▄▂▄▅ ➡️ 81
subgraph-mouse-sweep: task duration ▃▂▄▅▂▄▄▅▇▄█▆▁▃▅ ➡️ 785ms
subgraph-mouse-sweep: script duration ▄▅▄▇▅▅▆▇▆▅██▁▄▆ ➡️ 105ms
subgraph-mouse-sweep: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-mouse-sweep: heap used ➡️ NaN MB
subgraph-mouse-sweep: DOM nodes ▅▁▄▅▁▄▃▃█▅▅▄▂▅▃ ➡️ 66
subgraph-mouse-sweep: event listeners ▇▁▂▇▁▂▂▂█▇▂▂▇▇▂ 📈 5
workflow-execution: avg frame time ▆▆▆▄▆▆▃▄▁▄█▆▅▄▆ ➡️ 17ms
workflow-execution: p95 frame time ➡️ NaNms
workflow-execution: layout duration ▁▆▁▃▂▄▃▂▃▃▅█▄▂▅ ➡️ 2ms
workflow-execution: style recalc duration ▃▇▅▇▁▅▆▇█▁██▂▄▆ ➡️ 25ms
workflow-execution: layout count ▁█▂▃▂▃▃▁▃▃▄▃▂▃▂ ➡️ 5
workflow-execution: style recalc count ▃█▅▇▁▄▅▆▅▅▅▅▄▄▂ ➡️ 15
workflow-execution: task duration ▂▅▄▅▁▄▆▆▆▁▇█▁▃▃ ➡️ 120ms
workflow-execution: script duration ▄▃▄▄▃▅▄▅▆▂▇█▁▃▄ ➡️ 29ms
workflow-execution: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
workflow-execution: heap used ➡️ NaN MB
workflow-execution: DOM nodes ▂█▃▆▁▄▃▅▃█▃▃▄▃▁ ➡️ 152
workflow-execution: event listeners ▅███▁▅███▁██▅█▅ ➡️ 49
Raw data
{
  "timestamp": "2026-08-22T04:21:47.732Z",
  "gitSha": "09ad9b78566772036a6ddfed8b187b5b54e69ef1",
  "branch": "refactor/usage-table-paginated-query",
  "measurements": [
    {
      "name": "canvas-idle",
      "durationMs": 2087.2759999999744,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 7.526000000000002,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 588.061,
      "heapDeltaBytes": 16898936,
      "heapUsedBytes": 78958460,
      "domNodes": -278,
      "jsHeapTotalBytes": 4710400,
      "scriptDurationMs": 6.5230000000000015,
      "eventListeners": -153,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-idle",
      "durationMs": 2057.7560000000403,
      "styleRecalcs": 8,
      "styleRecalcDurationMs": 6.970000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 508.90600000000006,
      "heapDeltaBytes": 17053436,
      "heapUsedBytes": 78419172,
      "domNodes": -282,
      "jsHeapTotalBytes": 3923968,
      "scriptDurationMs": 11.225999999999999,
      "eventListeners": -151,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "canvas-mouse-sweep",
      "durationMs": 1840.174999999988,
      "styleRecalcs": 71,
      "styleRecalcDurationMs": 32.900000000000006,
      "layouts": 12,
      "layoutDurationMs": 3.3280000000000003,
      "taskDurationMs": 838.1429999999999,
      "heapDeltaBytes": -5382776,
      "heapUsedBytes": 56714116,
      "domNodes": -283,
      "jsHeapTotalBytes": 4972544,
      "scriptDurationMs": 110.751,
      "eventListeners": -153,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-mouse-sweep",
      "durationMs": 1872.1550000000207,
      "styleRecalcs": 77,
      "styleRecalcDurationMs": 40.195,
      "layouts": 12,
      "layoutDurationMs": 3.3600000000000003,
      "taskDurationMs": 864.425,
      "heapDeltaBytes": -3588780,
      "heapUsedBytes": 58477212,
      "domNodes": -278,
      "jsHeapTotalBytes": 4448256,
      "scriptDurationMs": 109.185,
      "eventListeners": -151,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.670000000000012,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "canvas-zoom-sweep",
      "durationMs": 1717.5770000000057,
      "styleRecalcs": 30,
      "styleRecalcDurationMs": 16.742,
      "layouts": 6,
      "layoutDurationMs": 0.7130000000000001,
      "taskDurationMs": 349.74799999999993,
      "heapDeltaBytes": 3113968,
      "heapUsedBytes": 64692924,
      "domNodes": 75,
      "jsHeapTotalBytes": 4456448,
      "scriptDurationMs": 8.939000000000002,
      "eventListeners": 19,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "canvas-zoom-sweep",
      "durationMs": 1686.249000000089,
      "styleRecalcs": 30,
      "styleRecalcDurationMs": 18.996,
      "layouts": 6,
      "layoutDurationMs": 0.67,
      "taskDurationMs": 350.60999999999996,
      "heapDeltaBytes": 3034100,
      "heapUsedBytes": 64744572,
      "domNodes": 77,
      "jsHeapTotalBytes": 5242880,
      "scriptDurationMs": 9.747,
      "eventListeners": 19,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "dom-widget-clipping",
      "durationMs": 561.725000000024,
      "styleRecalcs": 11,
      "styleRecalcDurationMs": 7.483000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 350.383,
      "heapDeltaBytes": 10804456,
      "heapUsedBytes": 73601460,
      "domNodes": 18,
      "jsHeapTotalBytes": 5242880,
      "scriptDurationMs": 54.092,
      "eventListeners": 0,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "dom-widget-clipping",
      "durationMs": 553.4260000000586,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 6.002000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 354.015,
      "heapDeltaBytes": 10681220,
      "heapUsedBytes": 72088356,
      "domNodes": 14,
      "jsHeapTotalBytes": 4980736,
      "scriptDurationMs": 55.641000000000005,
      "eventListeners": 2,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "large-graph-idle",
      "durationMs": 2056.2679999999887,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 8.408000000000003,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 615.0649999999999,
      "heapDeltaBytes": -3922520,
      "heapUsedBytes": 72908784,
      "domNodes": -275,
      "jsHeapTotalBytes": -1839104,
      "scriptDurationMs": 14.130999999999998,
      "eventListeners": -149,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "large-graph-idle",
      "durationMs": 2072.7470000000494,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 10.561999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 595.4760000000001,
      "heapDeltaBytes": -356748,
      "heapUsedBytes": 76197508,
      "domNodes": -267,
      "jsHeapTotalBytes": -1314816,
      "scriptDurationMs": 16.433,
      "eventListeners": -151,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "large-graph-pan",
      "durationMs": 2149.5350000000144,
      "styleRecalcs": 70,
      "styleRecalcDurationMs": 18.043999999999997,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 1207.8950000000002,
      "heapDeltaBytes": -5772400,
      "heapUsedBytes": 71875392,
      "domNodes": -275,
      "jsHeapTotalBytes": -40960,
      "scriptDurationMs": 343.13000000000005,
      "eventListeners": -147,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "large-graph-pan",
      "durationMs": 2198.7830000000486,
      "styleRecalcs": 69,
      "styleRecalcDurationMs": 16.773999999999997,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 1196.596,
      "heapDeltaBytes": -4347960,
      "heapUsedBytes": 73080548,
      "domNodes": -240,
      "jsHeapTotalBytes": 221184,
      "scriptDurationMs": 345.683,
      "eventListeners": -147,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "large-graph-zoom",
      "durationMs": 3183.4570000000326,
      "styleRecalcs": 62,
      "styleRecalcDurationMs": 12.248000000000001,
      "layouts": 60,
      "layoutDurationMs": 6.973999999999999,
      "taskDurationMs": 1379.131,
      "heapDeltaBytes": -1594812,
      "heapUsedBytes": 77290060,
      "domNodes": -280,
      "jsHeapTotalBytes": -1576960,
      "scriptDurationMs": 397.27000000000004,
      "eventListeners": -147,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "large-graph-zoom",
      "durationMs": 3166.7340000000195,
      "styleRecalcs": 65,
      "styleRecalcDurationMs": 14.329000000000004,
      "layouts": 60,
      "layoutDurationMs": 7.357000000000001,
      "taskDurationMs": 1363.62,
      "heapDeltaBytes": -13756628,
      "heapUsedBytes": 65076400,
      "domNodes": -289,
      "jsHeapTotalBytes": 5500928,
      "scriptDurationMs": 385.58699999999993,
      "eventListeners": -153,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333335,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "legacy-node-drag",
      "durationMs": 2343.570999999997,
      "styleRecalcs": 47,
      "styleRecalcDurationMs": 10.527000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 1460.571,
      "heapDeltaBytes": -14355300,
      "heapUsedBytes": 70708500,
      "domNodes": 14,
      "jsHeapTotalBytes": 9211904,
      "scriptDurationMs": 494.8429999999999,
      "eventListeners": 186,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "legacy-node-drag",
      "durationMs": 2206.5810000000283,
      "styleRecalcs": 47,
      "styleRecalcDurationMs": 11.097999999999997,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 1407.126,
      "heapDeltaBytes": -15703732,
      "heapUsedBytes": 69712776,
      "domNodes": 14,
      "jsHeapTotalBytes": 8163328,
      "scriptDurationMs": 455.845,
      "eventListeners": 186,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "minimap-idle",
      "durationMs": 2052.769000000012,
      "styleRecalcs": 10,
      "styleRecalcDurationMs": 9.28,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 606.119,
      "heapDeltaBytes": -12766512,
      "heapUsedBytes": 70200192,
      "domNodes": -277,
      "jsHeapTotalBytes": 4714496,
      "scriptDurationMs": 13.134,
      "eventListeners": -149,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "minimap-idle",
      "durationMs": 2008.1370000000334,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 7.537999999999999,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 589.052,
      "heapDeltaBytes": -14205900,
      "heapUsedBytes": 63452244,
      "domNodes": -283,
      "jsHeapTotalBytes": 3403776,
      "scriptDurationMs": 13.586000000000004,
      "eventListeners": -179,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "subgraph-dom-widget-clipping",
      "durationMs": 589.5449999999869,
      "styleRecalcs": 45,
      "styleRecalcDurationMs": 9.697000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 391.6069999999999,
      "heapDeltaBytes": 11719204,
      "heapUsedBytes": 74012924,
      "domNodes": 16,
      "jsHeapTotalBytes": 5767168,
      "scriptDurationMs": 116.81800000000001,
      "eventListeners": 8,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-dom-widget-clipping",
      "durationMs": 580.693999999994,
      "styleRecalcs": 45,
      "styleRecalcDurationMs": 8.645,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 376.705,
      "heapDeltaBytes": 11698412,
      "heapUsedBytes": 73618924,
      "domNodes": 16,
      "jsHeapTotalBytes": 5242880,
      "scriptDurationMs": 117.06,
      "eventListeners": 8,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.670000000000012,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-idle",
      "durationMs": 2039.5829999999933,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 7.994999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 480.005,
      "heapDeltaBytes": 6015420,
      "heapUsedBytes": 68742128,
      "domNodes": -281,
      "jsHeapTotalBytes": 4448256,
      "scriptDurationMs": 6.295999999999999,
      "eventListeners": -181,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "subgraph-idle",
      "durationMs": 2007.0259999999962,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 8.120000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 471.687,
      "heapDeltaBytes": 18920644,
      "heapUsedBytes": 81564880,
      "domNodes": -281,
      "jsHeapTotalBytes": 4448256,
      "scriptDurationMs": 5.918000000000001,
      "eventListeners": -151,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-mouse-sweep",
      "durationMs": 1757.520999999997,
      "styleRecalcs": 77,
      "styleRecalcDurationMs": 37.483000000000004,
      "layouts": 16,
      "layoutDurationMs": 4.598,
      "taskDurationMs": 816.5720000000001,
      "heapDeltaBytes": -6441840,
      "heapUsedBytes": 55879220,
      "domNodes": -282,
      "jsHeapTotalBytes": 5758976,
      "scriptDurationMs": 84.09400000000001,
      "eventListeners": -151,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "subgraph-mouse-sweep",
      "durationMs": 1706.963000000087,
      "styleRecalcs": 74,
      "styleRecalcDurationMs": 34.728,
      "layouts": 16,
      "layoutDurationMs": 4.351,
      "taskDurationMs": 782.177,
      "heapDeltaBytes": 3710720,
      "heapUsedBytes": 66400188,
      "domNodes": -283,
      "jsHeapTotalBytes": 4972544,
      "scriptDurationMs": 82.979,
      "eventListeners": -183,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-transition-enter",
      "durationMs": 1399.314000000004,
      "styleRecalcs": 18,
      "styleRecalcDurationMs": 31.626999999999995,
      "layouts": 13,
      "layoutDurationMs": 14.547,
      "taskDurationMs": 896.99,
      "heapDeltaBytes": -7799396,
      "heapUsedBytes": 86508076,
      "domNodes": 13673,
      "jsHeapTotalBytes": 11534336,
      "scriptDurationMs": 16.401000000000007,
      "eventListeners": 2373,
      "totalBlockingTimeMs": 141,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "viewport-pan-sweep",
      "durationMs": 8332.878999999992,
      "styleRecalcs": 250,
      "styleRecalcDurationMs": 36.543000000000006,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 4330.206,
      "heapDeltaBytes": 2699204,
      "heapUsedBytes": 79484820,
      "domNodes": -275,
      "jsHeapTotalBytes": 745472,
      "scriptDurationMs": 1177.6480000000001,
      "eventListeners": -133,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "viewport-pan-sweep",
      "durationMs": 8207.458999999972,
      "styleRecalcs": 248,
      "styleRecalcDurationMs": 35.314,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 4077.9519999999998,
      "heapDeltaBytes": 5440372,
      "heapUsedBytes": 82054432,
      "domNodes": -244,
      "jsHeapTotalBytes": 221184,
      "scriptDurationMs": 1049.3560000000002,
      "eventListeners": -131,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.670000000000012,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "vue-large-graph-idle",
      "durationMs": 16805.196999999964,
      "styleRecalcs": 0,
      "styleRecalcDurationMs": 0,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 16265.434,
      "heapDeltaBytes": -34068104,
      "heapUsedBytes": 180647856,
      "domNodes": -8312,
      "jsHeapTotalBytes": -12238848,
      "scriptDurationMs": 113.23000000000002,
      "eventListeners": -16389,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 17.776666666666642,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "vue-large-graph-idle",
      "durationMs": 17212.301000000025,
      "styleRecalcs": 0,
      "styleRecalcDurationMs": 0,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 16525.824,
      "heapDeltaBytes": -30592112,
      "heapUsedBytes": 181338520,
      "domNodes": -8312,
      "jsHeapTotalBytes": -10047488,
      "scriptDurationMs": 105.386,
      "eventListeners": -16393,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 18.333333333333332,
      "p95FrameDurationMs": 16.80000000000291
    },
    {
      "name": "vue-large-graph-pan",
      "durationMs": 21054.520999999964,
      "styleRecalcs": 177,
      "styleRecalcDurationMs": 17.08399999999999,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 20395.249999999996,
      "heapDeltaBytes": -19100204,
      "heapUsedBytes": 193116660,
      "domNodes": -8312,
      "jsHeapTotalBytes": -18460672,
      "scriptDurationMs": 403.24600000000004,
      "eventListeners": -16385,
      "totalBlockingTimeMs": 23,
      "frameDurationMs": 17.780000000000047,
      "p95FrameDurationMs": 16.80000000000291
    },
    {
      "name": "vue-large-graph-pan",
      "durationMs": 20962.850000000002,
      "styleRecalcs": 179,
      "styleRecalcDurationMs": 20.060999999999996,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 20261.231000000003,
      "heapDeltaBytes": -22358312,
      "heapUsedBytes": 192226272,
      "domNodes": -8312,
      "jsHeapTotalBytes": -19648512,
      "scriptDurationMs": 429.604,
      "eventListeners": -16387,
      "totalBlockingTimeMs": 48,
      "frameDurationMs": 17.776666666666763,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "workflow-execution",
      "durationMs": 464.40499999994245,
      "styleRecalcs": 17,
      "styleRecalcDurationMs": 21.612000000000002,
      "layouts": 3,
      "layoutDurationMs": 1.383,
      "taskDurationMs": 107.64,
      "heapDeltaBytes": 5075540,
      "heapUsedBytes": 66569020,
      "domNodes": 148,
      "jsHeapTotalBytes": 262144,
      "scriptDurationMs": 7.120000000000001,
      "eventListeners": 99,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "workflow-execution",
      "durationMs": 114.15099999999256,
      "styleRecalcs": 7,
      "styleRecalcDurationMs": 14.586,
      "layouts": 2,
      "layoutDurationMs": 1.281,
      "taskDurationMs": 78.318,
      "heapDeltaBytes": 3001952,
      "heapUsedBytes": 65253748,
      "domNodes": 125,
      "jsHeapTotalBytes": 0,
      "scriptDurationMs": 5.402,
      "eventListeners": 27,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    }
  ]
}

@github-actions github-actions Bot added the risk:R3 PR risk grade (advisory shadow check; grader-owned) label Aug 22, 2026
@codecov

codecov Bot commented Aug 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.36066% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...mponents/dialog/content/setting/UsageLogsTable.vue 95.83% 1 Missing ⚠️
@@            Coverage Diff             @@
##             main   #15602      +/-   ##
==========================================
+ Coverage   79.39%   81.86%   +2.46%     
==========================================
  Files        2217     1888     -329     
  Lines      112188   107186    -5002     
  Branches    35091    34371     -720     
==========================================
- Hits        89069    87745    -1324     
+ Misses      22640    19102    -3538     
+ Partials      479      339     -140     
Flag Coverage Δ
e2e 67.43% <75.00%> (-0.06%) ⬇️
unit 73.43% <98.36%> (+<0.01%) ⬆️
website-unit ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...components/dialog/content/setting/CreditsPanel.vue 79.41% <100.00%> (-0.59%) ⬇️
src/composables/billing/useBillingContext.ts 88.66% <100.00%> (+0.31%) ⬆️
src/composables/usePaginatedQuery.ts 100.00% <100.00%> (ø)
...nents/dialogs/settings/PlanCreditsPanelContent.vue 100.00% <100.00%> (ø)
src/storybook/mocks/useBillingContext.ts 0.00% <ø> (ø)
...mponents/dialog/content/setting/UsageLogsTable.vue 96.49% <95.83%> (+2.51%) ⬆️

... and 339 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@dante01yoon dante01yoon left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One blocking contract/complexity issue: the new generic composable recreates backend-owned pagination state that its only caller does not use. Please remove that derived surface or source it from the API contract.

Comment thread src/composables/usePaginatedQuery.ts Outdated
const page = computed(() => lastResponse.value?.page ?? 1)
const limit = computed(() => lastResponse.value?.limit ?? initialLimit)
const total = computed(() => lastResponse.value?.total ?? 0)
const totalPages = computed(() =>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: totalPages is already returned deterministically by both billing APIs, but this generic layer drops that field and recomputes it from total / limit. That creates a second frontend definition of backend pagination semantics, and the only caller does not consume totalPages at all. Could we remove totalPages from this composable’s public return instead of introducing unused, potentially drifting state?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in c42f753. Removed totalPages from the composable's public return (and the now-invalid test assertion); the only caller never consumed it, and this avoids re-deriving a value the billing APIs already return deterministically.


Generated by Claude Code

totalPages was recomputed from total/limit, duplicating a value both
billing APIs already return deterministically, and the only caller
(UsageLogsTable) never consumed it. Removed it from the composable's
public return instead of keeping unused, potentially drifting state.
@claude
claude Bot requested a review from dante01yoon August 22, 2026 03:47
dante01yoon
dante01yoon previously approved these changes Aug 22, 2026

@dante01yoon dante01yoon left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified the follow-up: totalPages and its test assertion were removed, so the composable no longer recreates that unused backend-owned pagination state. No further findings.

@dante01yoon dante01yoon added needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch core/1.51 Backport PRs for core 1.51 cloud/1.51 Backport PRs for cloud 1.51 labels Aug 22, 2026
@dante01yoon
dante01yoon marked this pull request as ready for review August 22, 2026 03:55
@dante01yoon
dante01yoon requested a review from a team August 22, 2026 03:55
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Aug 22, 2026
…eBillingContext

Per review feedback: defineExpose('refresh') on UsageLogsTable was a
legitimate stateless imperative command (no state to desync), so the
refetchKey-prop replacement was the wrong fix for the wrong problem.
Reverted UsageLogsTable to expose refresh() again via a template ref,
matching this repo's own defineExpose convention
(docs/guidance/vue-components.md, src/components/AGENTS.md,
.agents/checks/vue-patterns.md).

What still needed fixing was where the "should credits UI refresh"
decision lived: CreditsPanel had its own local watch(balance) +
revision counter, and PlanCreditsPanelContent had none at all (so a
top-up while on its Activity tab never refreshed that table). Moved
the skip-first-hydration balance-watch into useBillingContext as a new
exposed `usageLogsRefreshSignal`, the shared composable that already
owns `balance`. Both CreditsPanel and PlanCreditsPanelContent now just
watch that one signal and call their own table ref's refresh() -
the "when" lives once in the data layer; the "how" (an imperative
command) stays where Vue's defineExpose convention says it belongs.

usePaginatedQuery's page/limit/total derivation is unchanged - that
part was never in dispute.
@claude

claude Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor Author

Updated per feedback (Christian): reverted UsageLogsTable back to defineExpose({ refresh }) — that was a legitimate stateless imperative command, not state to synchronize, so replacing it with a refetchKey prop was solving a problem that didn't exist. Kept usePaginatedQuery's page/limit/total derivation (never disputed).

What actually needed fixing was where the "should credits UI refresh" decision lived — it was duplicated (and in PlanCreditsPanelContent's case, missing entirely) per component. Moved it into useBillingContext as a new usageLogsRefreshSignal, next to the balance it's derived from. CreditsPanel and PlanCreditsPanelContent now just watch that one shared signal and call their own table ref's refresh().

Pushed as 998a7e6. Tests/typecheck/lint all clean.


Generated by Claude Code

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

Labels

cloud/1.51 Backport PRs for cloud 1.51 core/1.51 Backport PRs for core 1.51 needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch risk:R3 PR risk grade (advisory shadow check; grader-owned) size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants