Repository navigation
fix(endpoint): Make Entity classes assignable to EntityInterface - #4149
Conversation
🦋 Changeset detectedLatest commit: 2da5e5c The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
ntucker
left a comment
There was a problem hiding this comment.
CHANGE_THIS_PR: finish the readonly fix in the TS 4.0 type overlays.
lib / modern path looks right: Entity.pk, IEntityClass.pk, and endpoint EntityInterface.pk all take readonly any[], so Entity classes assign under strictFunctionTypes, and dropping EntityLike is the right cleanup after #4130.
packages/endpoint/src-4.0-types/schemas/Entity.d.ts and EntityTypes.d.ts still declare class/static pk with mutable args?: any[]. scripts/build-legacy-types.sh applies those overlays after downlevel-dts from lib, and typesVersions still sends TS 4.0–4.1 to ts4.0/. There is no interface.d.ts overlay, and normalizr’s EntityInterface.pk is already readonly any[], so that path keeps the same assignability hole this PR closes for everyone else. Instance pk in those same overlays already uses readonly any[]; the overlay’s reason is only removing abstract new.
Please change those two args to readonly any[] (same one-line edits as the source). That completes the fix without a redesign.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #4149 +/- ##
=======================================
Coverage 98.01% 98.01%
=======================================
Files 160 160
Lines 3127 3127
Branches 622 622
=======================================
Hits 3065 3065
Misses 18 18
Partials 44 44 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Confirmed: Generated by Claude Code |
|
Lead Engineer: The TypeScript 4.0 overlay is already readonly on the current tip. No new commit. #4149 (review) was against Motivation: |
Entity classes now satisfy normalizr's EntityInterface, so Controller drops its private EntityLike workaround. Endpoint's own EntityInterface also takes readonly args, so both contracts match. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F92DVcdVpL6sVLSA69App5
64a0af7 to
b50f6c5
Compare
|
Size Change: 0 B Total Size: 103 kB ℹ️ View Unchanged
|
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F92DVcdVpL6sVLSA69App5
There was a problem hiding this comment.
Benchmark React
Details
| Benchmark suite | Current: 2da5e5c | Previous: b4b502d | Ratio |
|---|---|---|---|
data-client: getlist-100 |
131.58 ops/s (± 4.6%) |
212.77 ops/s (± 5.7%) |
1.62 |
data-client: getlist-500 |
41.5 ops/s (± 5.2%) |
63.7 ops/s (± 5.7%) |
1.53 |
data-client: update-entity |
327.96 ops/s (± 8.5%) |
465.37 ops/s (± 8.5%) |
1.42 |
data-client: update-user |
322.58 ops/s (± 8.2%) |
454.55 ops/s (± 6.8%) |
1.41 |
data-client: getlist-500-sorted |
42.31 ops/s (± 10.1%) |
63.9 ops/s (± 7.9%) |
1.51 |
data-client: update-entity-sorted |
277.78 ops/s (± 6.5%) |
408.33 ops/s (± 6.2%) |
1.47 |
data-client: update-entity-multi-view |
303.03 ops/s (± 7.6%) |
444.66 ops/s (± 7.2%) |
1.47 |
data-client: list-detail-switch-10 |
7.69 ops/s (± 7.6%) |
20.2 ops/s (± 10.0%) |
2.63 |
data-client: update-user-10000 |
72.46 ops/s (± 12.4%) |
114.29 ops/s (± 13.5%) |
1.58 |
data-client: invalidate-and-resolve |
36.56 ops/s (± 6.0%) |
58.49 ops/s (± 5.5%) |
1.60 |
data-client: unshift-item |
144.93 ops/s (± 12.5%) |
294.12 ops/s (± 5.1%) |
2.03 |
data-client: delete-item |
270.27 ops/s (± 2.4%) |
416.67 ops/s (± 4.3%) |
1.54 |
data-client: move-item |
170.95 ops/s (± 7.7%) |
243.9 ops/s (± 8.8%) |
1.43 |
This comment was automatically generated by workflow using github-action-benchmark.
There was a problem hiding this comment.
Benchmark
Details
| Benchmark suite | Current: 2da5e5c | Previous: b4b502d | Ratio |
|---|---|---|---|
normalizeLong |
432 ops/sec (±3.12%) |
435 ops/sec (±4.05%) |
1.01 |
normalizeLong Values |
394 ops/sec (±0.41%) |
396 ops/sec (±1.28%) |
1.01 |
normalizeLong Scalar |
363 ops/sec (±3.16%) |
371 ops/sec (±3.34%) |
1.02 |
normalizeLong Scalar update |
893 ops/sec (±0.55%) |
901 ops/sec (±0.24%) |
1.01 |
denormalizeLong |
223 ops/sec (±6.06%) |
227 ops/sec (±6.64%) |
1.02 |
denormalizeLong Values |
211 ops/sec (±4.77%) |
219 ops/sec (±4.15%) |
1.04 |
denormalizeLong donotcache |
991 ops/sec (±0.52%) |
1004 ops/sec (±0.68%) |
1.01 |
denormalizeLong Values donotcache |
731 ops/sec (±0.56%) |
741 ops/sec (±0.15%) |
1.01 |
denormalizeLong Scalar donotcache |
1040 ops/sec (±0.47%) |
1034 ops/sec (±0.57%) |
0.99 |
denormalizeShort donotcache 500x |
1267 ops/sec (±1.11%) |
1383 ops/sec (±0.14%) |
1.09 |
denormalizeShort 500x |
585 ops/sec (±6.47%) |
628 ops/sec (±7.30%) |
1.07 |
denormalizeShort 500x withCache |
5920 ops/sec (±0.37%) |
6544 ops/sec (±0.57%) |
1.11 |
queryShort 500x withCache |
3126 ops/sec (±0.73%) |
3096 ops/sec (±2.95%) |
0.99 |
buildQueryKey All |
57986 ops/sec (±0.94%) |
59202 ops/sec (±1.22%) |
1.02 |
query All withCache |
5648 ops/sec (±2.63%) |
6282 ops/sec (±2.76%) |
1.11 |
denormalizeLong with mixin Entity |
206 ops/sec (±5.57%) |
213 ops/sec (±8.11%) |
1.03 |
denormalizeLong withCache |
5746 ops/sec (±3.90%) |
6436 ops/sec (±0.36%) |
1.12 |
denormalizeLong withCache (Scalar churn) |
7063 ops/sec (±0.46%) |
6429 ops/sec (±0.70%) |
0.91 |
denormalizeLong Values withCache |
5158 ops/sec (±1.67%) |
5157 ops/sec (±1.10%) |
1.00 |
denormalizeLong Scalar withCache |
7485 ops/sec (±1.13%) |
7840 ops/sec (±0.38%) |
1.05 |
denormalizeLong Scalar update withCache |
4047 ops/sec (±0.73%) |
4086 ops/sec (±0.46%) |
1.01 |
denormalizeLong All withCache |
6330 ops/sec (±0.30%) |
6426 ops/sec (±0.24%) |
1.02 |
denormalizeLong Query-sorted withCache |
6144 ops/sec (±1.24%) |
6538 ops/sec (±1.91%) |
1.06 |
denormalizeLongAndShort withEntityCacheOnly |
1441 ops/sec (±0.47%) |
1769 ops/sec (±0.30%) |
1.23 |
denormalize bidirectional 50 |
4391 ops/sec (±10.60%) |
4565 ops/sec (±7.95%) |
1.04 |
denormalize bidirectional 50 donotcache |
41969 ops/sec (±0.35%) |
41869 ops/sec (±0.22%) |
1.00 |
getResponse |
4260 ops/sec (±2.55%) |
4469 ops/sec (±3.49%) |
1.05 |
getResponse (null) |
7294192 ops/sec (±0.82%) |
10408471 ops/sec (±0.70%) |
1.43 |
getResponse (clear cache) |
192 ops/sec (±8.26%) |
210 ops/sec (±7.15%) |
1.09 |
getSmallResponse |
3329 ops/sec (±1.51%) |
3553 ops/sec (±1.61%) |
1.07 |
getSmallInferredResponse |
2689 ops/sec (±0.20%) |
2886 ops/sec (±0.13%) |
1.07 |
getResponse Collection |
4328 ops/sec (±3.84%) |
4488 ops/sec (±3.44%) |
1.04 |
get Collection |
2718 ops/sec (±0.72%) |
3804 ops/sec (±0.22%) |
1.40 |
get Query-sorted |
5024 ops/sec (±1.93%) |
4955 ops/sec (±1.97%) |
0.99 |
setLong |
434 ops/sec (±0.87%) |
434 ops/sec (±0.27%) |
1 |
setLongWithMerge |
249 ops/sec (±0.43%) |
252 ops/sec (±0.95%) |
1.01 |
setLongWithSimpleMerge |
266 ops/sec (±0.31%) |
268 ops/sec (±0.51%) |
1.01 |
setSmallResponse 500x |
849 ops/sec (±1.51%) |
909 ops/sec (±1.44%) |
1.07 |
setMany 50x one-per-row |
142 ops/sec (±0.54%) |
156 ops/sec (±0.22%) |
1.10 |
setMany 50 batch |
3417 ops/sec (±0.80%) |
3655 ops/sec (±0.58%) |
1.07 |
setMany 500x one-per-row |
14.36 ops/sec (±0.76%) |
15.95 ops/sec (±0.39%) |
1.11 |
setMany 500 batch |
1366 ops/sec (±3.22%) |
1422 ops/sec (±0.16%) |
1.04 |
This comment was automatically generated by workflow using github-action-benchmark.
Declare static pk() with method syntax so subclass overrides that type args as a mutable array still compile. Revert endpoint EntityInterface and keep core's loose EntityLike so mixed package versions keep working. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F92DVcdVpL6sVLSA69App5
Entity now satisfies EntityInterface, so the private EntityLike type is no longer needed. Batch set() is unreleased, so this only requires matching endpoint versions for a new feature. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F92DVcdVpL6sVLSA69App5
Add plans/next-breaking-release.md for the compatibility shims, and note in the v0.19 blog and changeset that static pk() overrides should type args as readonly ahead of that release. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F92DVcdVpL6sVLSA69App5
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F92DVcdVpL6sVLSA69App5
Requested by Nathaniel · project thread
Follow-up to #4130.
Motivation
Entity's static
pk()declaredargs?: any[], butEntityInterface.pktakesreadonly any[], so understrictFunctionTypesan Entity class wasn't assignable toEntityInterface.Solution
Entity.pkandIEntityClass.pk(EntityMixin) takeargs?: readonly any[].Entity.pkis declared with method syntax, so existing subclass overrides that annotateargs?: any[]keep compiling.controller.set()types useEntityInterfaceinstead of the privateEntityLike. Batchset()is unreleased (v0.19), so the only effect is that it needs@data-client/rest/endpoint/graphqlfrom the same release; noted in its changeset.EntityInterfacekeeps mutableargs, so classes implementing it are unaffected.Nothing already released breaks. Verified with
yarn build:types(incl. legacy ts* outputs) andtsc -p tsconfig.test.json;Entity.test.tscovers assignability and a mutable-argsoverride.🤖 Generated with Claude Code
https://claude.ai/code/session_01F92DVcdVpL6sVLSA69App5
Note
Low Risk
Type-only compatibility shims with no runtime behavior change; main follow-up is aligning package versions for batch
set()typings and eventual removal ofpk()shims.Overview
Aligns Entity static
pk()withEntityInterfaceby typing theargsparameter asreadonly any[], so assignments likeconst schema: EntityInterface = Usertypecheck understrictFunctionTypes.A method-syntax declaration on
Entity.pkkeeps existingstatic pk()overrides that still annotateargsas a mutable array compiling for now; docs and changesets steer users towardreadonly any[]before a future cleanup tracked inplans/next-breaking-release.md. Maintainer guidance for shipping non-breaking type fixes is added in.cursor/rules/breaking-changes.mdc.Batch
controller.set([Entity], rows)typings in core now useEntityInterfaceinstead of a localEntityLikehelper, so batchset()expects matching@data-client/endpoint/rest/graphqlfrom the same release. Release notes, changesets, and the v0.19 blog cover the assignability fix andpk()migration tip; tests coverEntityInterfaceassignability and mutable-argsoverrides.Reviewed by Cursor Bugbot for commit 2da5e5c. Bugbot is set up for automated code reviews on this repo. Configure here.