feat(appkit-ui): share in-flight useAnalyticsQuery requests - #524
Open
MarioCadenas wants to merge 3 commits into
Open
feat(appkit-ui): share in-flight useAnalyticsQuery requests#524MarioCadenas wants to merge 3 commits into
MarioCadenas wants to merge 3 commits into
Conversation
Contributor
📦 Bundle size reportCompared against
|
| dist | raw | gzip |
|---|---|---|
| JS (runtime) | 869 KB | 303 KB |
| Type declarations | 314 KB | 109 KB |
| Source maps | 1.7 MB | 566 KB |
| Other | 11 KB | 3.7 KB |
| Total | 2.9 MB | 981 KB |
Per-entry composition (own code — deps external (as shipped))
| Entry | Initial (gz) | Lazy (gz) | Total (gz) | node_modules (min) | Own code (min) |
|---|---|---|---|---|---|
. |
88 KB | 2.5 KB | 91 KB | external | 288 KB |
./beta |
49 KB | 458 B | 49 KB | external | 143 KB |
./type-generator |
21 KB | 0 B | 21 KB | external | 60 KB |
Chunks:
| Entry | Chunk | Load | Size (gz) |
|---|---|---|---|
. |
index.js |
initial | 84 KB |
. |
utils.js |
initial | 4.0 KB |
. |
remote-tunnel-manager.js |
lazy | 2.5 KB |
./beta |
beta.js |
initial | 33 KB |
./beta |
stream-manager.js |
initial | 5.8 KB |
./beta |
wide-event-emitter.js |
initial | 3.2 KB |
./beta |
databricks.js |
initial | 3.0 KB |
./beta |
configuration.js |
initial | 2.1 KB |
./beta |
service-context.js |
initial | 1.3 KB |
./beta |
client.js |
initial | 431 B |
./beta |
client-options.js |
initial | 219 B |
./beta |
supervisor-api.js |
lazy | 194 B |
./beta |
databricks.js |
lazy | 142 B |
./beta |
index.js |
lazy | 122 B |
./type-generator |
index.js |
initial | 21 KB |
@databricks/appkit-ui
npm tarball (packed): 346 KB (+4.5 KB) — gzipped download (dist + bin; excludes release-only docs/NOTICE).
| dist | raw | gzip |
|---|---|---|
| JS (runtime) | 393 KB (+3.3 KB) | 132 KB (+1.4 KB) |
| Type declarations | 228 KB (+341 B) | 83 KB (+152 B) |
| Source maps | 761 KB (+8.4 KB) | 251 KB (+3.4 KB) |
| CSS | 16 KB | 3.3 KB |
| Total | 1.4 MB (+12 KB) | 469 KB (+4.9 KB) |
Per-entry composition (consumer bundle — deps bundled, peerDeps external)
| Entry | Initial (gz) | Lazy (gz) | Total (gz) | node_modules (min) | Own code (min) |
|---|---|---|---|---|---|
./js |
5.3 KB | 49 KB | 55 KB | 208 KB | 14 KB |
./js/beta |
20 B | 0 B | 20 B | 0 B | 0 B |
./react |
432 KB (+413 B) | 49 KB | 481 KB (+413 B) | 1.3 MB (+27 B) | 176 KB (+1002 B) |
./react/beta |
1.0 KB | 0 B | 1.0 KB | 0 B | 1.9 KB |
Chunks:
| Entry | Chunk | Load | Size (gz) |
|---|---|---|---|
./js |
index.js |
initial | 5.2 KB |
./js |
chunk |
initial | 120 B |
./js |
apache-arrow |
lazy | 49 KB |
./js/beta |
beta.js |
initial | 20 B |
./react |
index.js |
initial | 430 KB |
./react |
tslib |
initial | 2.1 KB |
./react |
apache-arrow |
lazy | 49 KB |
./react/beta |
beta.js |
initial | 1.0 KB |
Contributor
🤖 AppKit PR bot🔬 Run evalsStart an eval for this PR from the evals-monitor app: Go to Evals Monitor → 📦 Try this PR's app templateScaffolds a new app from this PR's SDK build. Run it in any folder (requires the GitHub CLI — gh run download 31693281308 -R databricks/appkit -n appkit-template-0.60.0-pr.2fb3ce8-in-flight-requests-524 -D appkit-pr-524 \
&& unzip -o "appkit-pr-524/appkit-template-0.60.0-pr.2fb3ce8-in-flight-requests-524.zip" -d "appkit-pr-524" \
&& databricks apps init --template "appkit-pr-524"The template pins |
MarioCadenas
force-pushed
the
in-flight-requests
branch
from
August 13, 2026 09:44
9568e60 to
f5e5958
Compare
Identical analytics requests (same query key, parameters, format, and dev mode) now share a single in-flight network request instead of one per hook instance. A module-singleton request store (mirroring the ResourceStatusStore idiom) owns the transport; useAnalyticsQuery becomes a useSyncExternalStore subscriber. Late subscribers read the current snapshot; the request is torn down a tick after the last subscriber unmounts, so a StrictMode unmount->remount reuses it rather than aborting. useChartData and all charts inherit the dedup for free. Dedup-only, no result cache. UseAnalyticsQueryResult is unchanged (non-breaking). Adds a /query-dedup playground route that counts analytics fetches in-page to make the behavior observable. Closes #496 Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
…ery dedup The arrow-analytics and data-visualization integration specs asserted one network request per chart instance (times a StrictMode x2 multiplier). With shared in-flight requests, components resolving to the same (queryKey, parameters, format) signature now share one request, and deferred teardown means StrictMode remounts reuse it rather than refiring — so the multiplier no longer applies to request counts. Update expectations to the deduplicated counts (each key collapses to one request per distinct resolved format) and drop the now-unused STRICT_MODE_MULTIPLIER. Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
Quality-only cleanup of the shared-request code, behavior unchanged: - use-analytics-query: drop the redundant `cacheKey === null` guards and the NOOP_SUBSCRIBE constant (a verbatim copy of the one in use-resource-status). The store already returns the stable idle snapshot for unused keys, so the cache key is computed unconditionally; only the `retain` and error-field guards on `payload === null` remain. Un-export EMPTY_SNAPSHOT from the store. - query-dedup demo route: replace the hand-rolled useSyncExternalStore counter with a plain useState (single consumer). - Trim verbose/duplicated comments across the store, hook, and integration specs to their load-bearing facts. Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
MarioCadenas
force-pushed
the
in-flight-requests
branch
from
August 13, 2026 10:55
d2c6b27 to
70f200e
Compare
MarioCadenas
marked this pull request as ready for review
August 13, 2026 10:57
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
useAnalyticsQuerydeduplicates identical in-flight requests. When multiple components call the hook with the same query key, parameters, format, and dev mode, they now share a single network request instead of each firing its own.Closes #496.
How
analytics-request-store.ts— a module-singleton request store mirroring the existingResourceStatusStoreidiom (keyedMap+ subscribe/notify + immutable snapshot viauseSyncExternalStore). It owns the transport lifecycle (SSE forJSON_ARRAY, direct Arrow fetch forARROW_STREAM) and fans both the final result and mid-flightwarehouse_statusupdates out to every subscriber.use-analytics-query.tsbecomes a thinuseSyncExternalStoresubscriber. Cache key =urlSuffix + serialized({parameters, format}). Warehouse-status mirroring intoResourceStatusProvidermoved from the transport into a hook effect.useChartDataand all charts route throughuseAnalyticsQuery, so they inherit dedup for free.UseAnalyticsQueryResultis unchanged — non-breaking.Showcase
New
/query-dedupplayground route (Data → "Query Dedup"). It wrapswindow.fetchwhile mounted to count analytics POSTs in-page, so you can watch "N components mounted → 1 network request fired" without the DevTools Network tab. Buttons mount more panels (count stays 1) and give the last panel a different key (count ticks to 2, proving distinct keys still fan out).Testing
appkit-uisuite: 371 passed / 18 files, including new dedup + store-lifecycle tests and the warehouse-status integration tests (both test files reset the singleton store between cases).appkit-uitypecheck: clean. dev-playground clienttsc --noEmit: clean.biome checkandknip: clean.Not yet run end-to-end against a live warehouse (no creds in this environment); the dedup counter is exercised by the request-store tests regardless of query success.