Skip to content

fix(plugin-map,plugin-calendar,plugin-gantt): re-key fetch effects onto dataConfig primitives - #6698

Merged
os-sales merged 4 commits into
mainfrom
claude/issue-6592-rekey-fetch-effects-on-primitives
Aug 28, 2026
Merged

fix(plugin-map,plugin-calendar,plugin-gantt): re-key fetch effects onto dataConfig primitives#6698
os-sales merged 4 commits into
mainfrom
claude/issue-6592-rekey-fetch-effects-on-primitives

Conversation

@os-sales

@os-salesos-sales commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Fixes#6592

Re-keys the load-bearing fetch effects onto the primitives they actually
read off dataConfig (provider / object / items), so useMemo goes
back to being a pure optimisation instead of a correctness dependency
(the sturdier half triage adopted from #6270, deferred out of PR #6591's
dispatch order).

The premise this PR is NOT resting on

PR #6591 made the schema identity stable. It did not make it
guaranteed. useMemo carries no semantic guarantee — React is
permitted to discard a memo cache and recompute even when the dependency
array compares equal to the previous render. getDataConfig(schema)
builds a fresh { provider, object } / { provider, items } wrapper
object on every call, so a discard alone — no author or caller action —
was enough to give the fetch effects below a new dataConfig identity and
re-run them. This PR removes that dependence; it does not (and does not
need to) touch anything about schema's own stability.

Census — method and per-renderer result

Method. A systematic sweep (script, not grep-by-eye) over every
packages/**/*.{ts,tsx} file (excluding tests): collect every
const x = useMemo(...) binding per file, then every useEffect whose
dependency array names one of those bindings as a bare identifier
(dataConfig, not dataConfig.foo — the first pass conflated the two and
produced false positives, caught and fixed before trusting any result),
classified as a fetch effect when its body contains an await, .then(,
a dataSource.*( call, or fetch(.

Positive control.packages/plugin-map (the known member) was
required to come back from the same query that reports every other
package. It did — confirmed both effects in ObjectMap.tsx — before any
"absent" result elsewhere was trusted. git ls-tree -r HEAD -- packages/plugin-map
was also checked non-empty before running anything, per the dispatch's
"don't believe a zero from a path nobody proved exists" instruction.

Per-renderer result (the dataConfig-style family the sweep actually
targets — every renderer with a local getDataConfig(schema) helper fed
into a useMemo):

renderermember?fetch effects keyed on dataConfigthis PR
packages/plugin-map/ObjectMap.tsxyes (known)both (dataConfig memoised on [schema])fixed
packages/plugin-calendar/ObjectCalendar.tsxyesthe record-fetch effect (its own dataConfig memo was already primitive-keyed by #6018, but the effect's deps still named the container)fixed
packages/plugin-gantt/ObjectGantt.tsxyesreload()'s deps (direct); the "fetch object schema" effect's dataConfig dep was dead code (unused in its body)fixed
packages/plugin-tree/ObjectTree.tsxyesbothdeferred — see below, not in this diff
packages/plugin-grid/ObjectGrid.tsxyesthe record-fetch effectfenced by #6597 (plugin-grid/plugin-dashboard/types) — not touched, reported only
packages/react/**n/afenced in full by PR #6690 (awaiting merge) — not reached

Three more renderer effects outside this dataConfig family carry the
same structural hazard (a memoised object read by identity in a fetch/
count-probe effect) — filed separately as #6697 rather than folded into
this diff, to keep this PR scoped to the family the card names:
plugin-detail/RelatedList.tsx (defaultSortSpec/listFilterNode),
components/renderers/layout/containers.tsx (probeTargets, a Map),
and plugin-list/ListView.tsx (expandFields, untriaged).

ObjectTree — found, then dropped from this diff mid-flight

My own census independently confirmed ObjectTree.tsx as a member (both
effects). While implementing it, the PM coordinator relayed that PR #6696
(objectui#6481, open, ready, not yet merged) rewrites the SAME file: it
replaces ObjectTree's objectSchema/schemaSettled state pair with the
shared useSettledSchema hook and, as an incidental improvement, re-keys
the schema-resolution effect onto a derived schemaKey primitive — already
satisfying this card's acceptance direction for that one effect. The
record-fetch effect (ObjectTree.tsx:468 on current main) still closes
over bare dataConfig and is untouched by #6696 — a real, confirmed
remaining member — but editing the file now would be editing around a
shape that is about to change out from under it. ObjectTree.tsx and its
would-be ObjectTree.discardedConfigMemo.test.tsx pin were reverted out of
this branch; the changeset no longer names @object-ui/plugin-tree. This
is a needs_decision-shaped follow-up for the PM: re-dispatch the
record-fetch effect once #6696 lands (small, single-effect fix, same shape
as the three in this PR).

What each fixed effect was keyed on, before → after

ObjectMap.tsx — two effects, deps [dataProp, dataConfig, dataSource, hasInlineData, schema.filter, schema.sort, objectSchema] and [schema.objectName, dataSource, hasInlineData, dataConfig] → both now list dataProvider / dataObjectName / dataItems (the three primitive fields either effect reads) in place of dataConfig.

ObjectCalendar.tsx — the record-fetch effect's deps [hasExternalData, dataConfig, dataSource, hasInlineData, schema.filter, schema.sort, refreshKey, objectSchemaReady, objectSchema]dataConfig replaced by dataProvider / dataItems, reusing the schemaObjectName primitive the file already computed for its (already-correct) schema-fetch effect.

ObjectGantt.tsxreload()'s deps [effectiveDataSource, resource, hasInlineData, dataConfig, schema.filter, schema.sort, objectSchema]dataConfig replaced by dataProvider / dataItems. The "fetch object schema" effect's deps [resource, effectiveDataSource, hasInlineData, dataConfig]dataConfig dropped entirely (dead: never read in that effect's body).

Known, documented boundary in ObjectGantt.tsx:effectiveDataSource = useMemo(() => resolveDataSource(dataConfig, ...), [dataConfig, dataSource, apiFetch]) deliberately keeps dataConfig (the whole object) as a dependency. resolveDataSource needs the whole provider-shaped value — the api provider reads its read/writeHttpRequest config, which cannot be flattened to a fixed primitive list the way object/value can. For the object/value providers resolveDataSource returns the fallback DataSource / a fresh ValueDataSource without depending on further fields of the input, which is what keeps the discard-immunity demonstration below true for those two providers; api was not similarly decoupled here.

Discarded-memo demonstration (the review question: "the effect no longer reads an object identity")

There is no public API to force React's internal memo-discard path, so
each new *.discardedConfigMemo.test.tsx file drives the same observable
failure a discard produces: a dataConfig recompute that yields a NEW
object reference carrying the SAME primitive fields. getDataConfig(schema)
builds a fresh wrapper on every call, so any recompute — whether triggered
by a discard or, as constructed here, by one of dataConfig's own useMemo
dependencies changing reference without changing value — produces exactly
this "different identity, same content" shape. From the fetch effect's
perspective the two triggers are indistinguishable; what's under test is
whether the effect's OWN dependency array reacts to the identity or only to
the primitives.

The construction differs per file because each dataConfig memo has a
different discard-proxy trigger:

  • ObjectMap / ObjectTree-shape (useMemo(() => getDataConfig(schema), [schema])): two schema object literals, different references, byte-identical content — forces the recompute via the [schema] dep.
  • ObjectCalendar (already primitive-keyed: [schema.data, schema.staticData, schema.objectName]): the schema-reference trick above does NOT recompute it (all three deps compare equal) — so the pin instead varies schema.data itself, one object reference vs. another with identical content, which forces the recompute since that dep is compared by reference.
  • ObjectGantt (useMemo(() => rawDataConfig, [JSON.stringify(rawDataConfig)])): neither trick above recomputes it (JSON-string dep already buys value stability against reference churn) — so the pin adds an inert _probe field to schema.data, read by nothing, whose value differs between renders and so forces JSON.stringify to differ.

Each file's two tests:

  • does not re-firedataConfig recomputes to a new identity, same primitives → dataSource.find / getObjectSchema call counts are unchanged after the rerender.
  • still DOES re-fire (counter-probe) — the recomputed dataConfig carries a genuinely different object → call counts increase, against the new object name. Without this, "immune to identity churn" would be equally satisfiable by an effect that never reacts to anything.

Ablation — prediction stated before it ran, then observed

The important leg is the acceptance direction itself. Predicted: with the
effect re-keyed, the discarded-memo proxy does not re-run the fetch; before
the change, it does.

Mutation leg — commit the fix first, then restore the pre-fix content of ObjectMap.tsx / ObjectTree.tsx / ObjectCalendar.tsx / ObjectGantt.tsx from the branch fork point (BASE=881d5c292) via git checkout pinned to that commit, path-scoped to each file. Ran the four new *.discardedConfigMemo.test.tsx files against the restored pre-fix source:

FAIL packages/plugin-gantt/src/ObjectGantt.discardedConfigMemo.test.tsx
x does not re-fire either fetch when dataConfig recomputes to a new identity with the SAME primitive fields
AssertionError: expected 3 to be 2
FAIL packages/plugin-map/src/ObjectMap.discardedConfigMemo.test.tsx
x does not re-fire either fetch effect when schema gets a new reference with the SAME primitive fields
AssertionError: expected 3 to be 2
FAIL packages/plugin-tree/src/ObjectTree.discardedConfigMemo.test.tsx
x does not re-fire either fetch effect when schema gets a new reference with the SAME primitive fields
AssertionError: expected 2 to be 1
Test Files 3 failed | 1 passed (4)
Tests 3 failed | 5 passed (8)

Prediction miss, reported rather than forced:ObjectCalendar's pin
(with its ORIGINAL schema-reference trigger, which is wrong for that
file's already-primitive-keyed memo) passed even on pre-fix source — a
fact about the trigger's discriminating power, not the effect's
correctness. Rewritten to vary schema.data by reference instead
(documented above); re-run against the same restored pre-fix source:

FAIL packages/plugin-calendar/src/ObjectCalendar.discardedConfigMemo.test.tsx
x does not re-fire the fetch when dataConfig recomputes to a new identity with the SAME primitive fields
AssertionError: expected 2 to be 1

All four now RED before the fix, for the predicted reason.

Restoration leg: restored all four files from HEAD (this branch's fix commit — a path-scoped git checkout pinned to HEAD, never a bare unscoped restore, which would have restored from the polluted index instead). Verified git diff HEAD empty on all four, and a git hash-object of the restored file vs. git rev-parse of the HEAD-committed blob matching on all four (ObjectMap.tsx338e6f78…, ObjectTree.tsxdf4609e3…, ObjectCalendar.tsx5dead55e…, ObjectGantt.tsxb8e552ad… — equal both sides).

GREEN leg: re-ran the (by-then-final) four discard pins against the
restored fixed source: Test Files 4 passed (4) / Tests 8 passed (8).

ObjectTree.tsx was subsequently reverted out of this branch entirely
(see the census section above), so the shipped diff only carries the
map/calendar/gantt legs; the tree leg's RED/GREEN pair above is preserved
here as the record of what was measured before the surface turned out to
be contested.

Gate table

Verdicts quoted from each gate's own printed line; exit captured by
redirect-then-capture, never after a pipe.

gateinvocationverdict
plugin-map typechecktsc --noEmit -p packages/plugin-map/tsconfig.json (after pnpm --filter @object-ui/plugin-map^... build)EXIT=0
plugin-calendar typechecktsc --noEmit -p packages/plugin-calendar/tsconfig.json (after pnpm --filter @object-ui/plugin-calendar^... build, which pulls in @object-ui/plugin-detail)EXIT=0
plugin-gantt typechecktsc --noEmit -p packages/plugin-gantt/tsconfig.jsonEXIT=0
plugin-map vitestpnpm exec vitest run packages/plugin-map/ from repo root (objectui#3378)Test Files 16 passed (16) / Tests 92 passed (92)
plugin-calendar vitestpnpm exec vitest run packages/plugin-calendar/ from repo rootTest Files 15 passed (15) / Tests 104 passed (104)
plugin-gantt vitestpnpm exec vitest run packages/plugin-gantt/ from repo rootTest Files 50 passed (50) / Tests 420 passed (420)
union (all 3, final HEAD 8da309855)pnpm exec vitest run packages/plugin-map/ packages/plugin-calendar/ packages/plugin-gantt/Test Files 84 passed (84) / Tests 622 passed (622)
control bytespnpm run check:control-bytes (new files git add-ed first)check-control-bytes: OK (scanned 5544 tracked text file(s); skipped 85 binary)
changeset presencenode scripts/check-changeset-presence.mjs6 source file(s) of 3 released package(s) changed, and this change declares 1 changeset(s)
changeset no-majornode scripts/check-changeset-no-major.mjsNo changeset declares a major bump.
vi.mock specifiersnode scripts/check-vi-mock-specifiers.mjsOK (3907 tracked source file(s) …)
lint (touched files, narrowed)eslint --format json on the 6 touched .ts(x) files (3 source + 3 new test files)0 errors, 225 warnings — all pre-existing-class @typescript-eslint/no-explicit-any / react-hooks/* (warn severity; lint.yml sets no --max-warnings)
lint narrowing, proveneslint on the 3 shipped SOURCE files at their pre-fix (origin/main) content vs. this branch's content188 warnings both sides, 0 errors both sides — this diff adds zero new lint findings to the touched source; the new warnings visible in the touched-file run above all live in the 3 new test files (standard as any mock casts)

Full pnpm lint / farm-wide check:* is CI's to run; the narrowing above
covers everything this diff touches, and the un-narrowed sibling
comparison proves the narrowing didn't hide anything.

Generated by Claude Code

…h effects onto dataConfig primitives
useMemo carries no semantic guarantee -- React may discard a memo cache and
recompute even when its deps compare equal, and getDataConfig(schema) builds
a fresh {provider, object}/{provider, items} wrapper object on every call.
So a fetch effect keyed on the whole `dataConfig` object was correct only
for as long as that identity happened to survive a discard: a recompute was
enough to re-run the effect and refetch, with schema itself unchanged.
Re-keys the load-bearing fetch effects onto the primitive fields they
actually read off dataConfig (provider / object / items) instead of the
container object, across every renderer the census found using the local
getDataConfig(schema)-into-useMemo pattern:
- plugin-map/ObjectMap.tsx -- both fetch effects (the known member, objectui#6270/#6591's deferred half)
- plugin-tree/ObjectTree.tsx -- both fetch effects
- plugin-calendar/ObjectCalendar.tsx -- the record-fetch effect (reusing the
existing schemaObjectName primitive; the schema-fetch effect was already
primitive-keyed)
- plugin-gantt/ObjectGantt.tsx -- reload()'s deps, and the fetch-object-schema
effect's dead (unused) dataConfig dependency dropped entirely. gantt's
effectiveDataSource memo deliberately keeps dataConfig as a dependency --
resolveDataSource needs the whole provider-shaped value, which cannot be
flattened to a fixed primitive list -- documented in-line as a scoped
exception; see the PR body's "known boundary" note.
packages/plugin-grid/src/ObjectGrid.tsx has the same dataConfig-in-deps
shape but sits inside objectui#6597's fence (plugin-grid/plugin-dashboard/
types) and is left untouched; packages/react is fenced in full (PR #6690).
Each touched renderer gets a new pinned test demonstrating the acceptance
direction: a dataConfig identity change carrying the SAME primitive fields
(the observable a discarded-and-recomputed memo produces) must not add an
extra dataSource.find/getObjectSchema call, alongside a counter-probe that a
genuinely different object name still does refetch.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_8ca04858-ea8e-5b85-9182-de59aa49e00c
ObjectCalendar's own `dataConfig` memo is already primitive-keyed
(objectui#6018), so varying `schema.objectName` between two new schema
references -- the trick that works for plugin-map/plugin-tree's [schema]-keyed
memo -- never even recomputes it here (all three of its own deps compare
equal). Vary `schema.data` (an object, compared by reference) instead, which
does force the recompute while leaving `provider`/`object` unchanged --
confirmed against the pre-fix source in this session's reverse verification
(RED before, GREEN after).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_8ca04858-ea8e-5b85-9182-de59aa49e00c
…#6696
PM coordinator flagged (after this branch was already cut, and after
ObjectTree.tsx had already been edited on this branch) that PR #6696
(objectui#6481, "key ObjectTree's schema-settled gate to the bound object")
is open, ready, and rewrites this exact file: it replaces the
objectSchema/schemaSettled state pair this branch also touched with a
shared `useSettledSchema` hook, re-keyed onto a derived `schemaKey`
primitive as an incidental improvement -- already satisfying this card's
acceptance direction for that one effect. ObjectTree's SECOND effect (the
record fetch, ObjectTree.tsx:468 on current main) still closes over bare
`dataConfig` and is untouched by #6696 -- a real, confirmed remaining
census member -- but #6696 is "ready and heading for the queue" per the
coordinator, so this file is contested until it lands.
Reverts ObjectTree.tsx to its origin/main content (verified byte-identical
to origin/main @ e0d83da, which does not yet contain #6696) and drops
the new ObjectTree.discardedConfigMemo.test.tsx pin along with it, so this
branch edits a file #6696 is mid-flight on nowhere. The changeset drops the
@object-ui/plugin-tree entry to match.
plugin-map / plugin-calendar / plugin-gantt are unaffected and ship as
originally verified.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_8ca04858-ea8e-5b85-9182-de59aa49e00c
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 49 chunks)3231.7 KB3266.6 KB
Main entry chunk (gzip)157.2 KB350 KB
Entry fileindex-DpwXxv4_.js
StatusPASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)11.89KB4.50KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)509.24KB115.61KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)173.10KB47.96KB
fields (index.js)239.05KB60.06KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)9.53KB3.38KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)4.64KB1.50KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)1.93KB0.88KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.89KB12.91KB
plugin-charts (index.js)64.66KB18.32KB
plugin-chatbot (index.js)190.33KB45.10KB
plugin-dashboard (index.js)133.43KB34.48KB
plugin-designer (index.js)212.80KB43.15KB
plugin-detail (index.js)245.29KB62.39KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.01KB32.23KB
plugin-gantt (index.js)165.20KB40.37KB
plugin-grid (index.js)201.51KB54.54KB
plugin-kanban (index.js)53.11KB14.62KB
plugin-list (index.js)113.01KB27.57KB
plugin-map (index.js)20.17KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)26.44KB7.59KB
plugin-tree (index.js)9.26KB3.13KB
plugin-view (index.js)85.87KB21.12KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)65.97KB21.98KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)2.44KB1.21KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Re-key the load-bearing fetch effects onto the primitives they read, so useMemo is an optimisation again and not a correctness dependency

2 participants

@os-sales@claude