Skip to content

enhance: ImmutableJS always denormalizes to normal JS #3421

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/brave-bats-itch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@data-client/normalizr': minor
---

BREAKING CHANGE: Denormalize always transforms immutablejs entities into the class

Previously using ImmutableJS structures when calling denormalize() would maintain
nested schemas as immutablejs structures still. Now everything is converted to normal JS.
This is how the types have always been specified.
4 changes: 2 additions & 2 deletions docs/core/concepts/normalization.md
Original file line number Diff line number Diff line change
Expand Up @@ -392,15 +392,15 @@ xychart-beta
title "Denormalize Single Entity"
x-axis [normalizr, "Data Client", "Data Client (cached)"]
y-axis "Operations per second" 0 --> 5618500
bar [212500, 1288500, 5618500]
bar [212500, 1341000, 5618500]
```

```mermaid
xychart-beta
title "Denormalize Large List"
x-axis [normalizr, "Data Client", "Data Client (cached)"]
y-axis "Operations per second" 0 --> 12962
bar [1151, 1807, 13182]
bar [1151, 1986, 13182]
```

</Grid>
Expand Down
4 changes: 1 addition & 3 deletions examples/benchmark/old-normalizr/normalizr.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ function mergeWithStore({ entities, result }, storeState) {

let curState = state;
export default function addNormlizrSuite(suite) {
%OptimizeFunctionOnNextCall(normalize);
%OptimizeFunctionOnNextCall(denormalize);
return suite
.add('normalizeLong', () => {
return mergeWithStore(normalize(data, ProjectSchema), state);
Expand All @@ -63,7 +61,7 @@ export default function addNormlizrSuite(suite) {
})
.add('denormalizeShort donotcache 500x', () => {
for (let i = 0; i < 500; ++i) {
const user = denormalize('gnoff', User, githubState.entities);
var user = denormalize('gnoff', User, githubState.entities);
// legacy normalizr doesn't convert this for us, so we must do manually afterward.
user.createdAt = new Date(user.createdAt);
user.updatedAt = new Date(user.updatedAt);
Expand Down
2 changes: 0 additions & 2 deletions packages/endpoint/src/schemas/__tests__/Entity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -812,10 +812,8 @@ describe(`${Entity.name} denormalization`, () => {
},
};

expect(denormalize(Menu, '1', entities)).toMatchSnapshot();
expect(denormalize(Menu, '1', fromJS(entities))).toMatchSnapshot();

expect(denormalize(Menu, '2', entities)).toMatchSnapshot();
expect(denormalize(Menu, '2', fromJS(entities))).toMatchSnapshot();
});

Expand Down
2 changes: 0 additions & 2 deletions packages/endpoint/src/schemas/__tests__/EntityMixin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -948,10 +948,8 @@ describe(`${schema.Entity.name} denormalization`, () => {
},
};

expect(denormalize(Menu, '1', entities)).toMatchSnapshot();
expect(denormalize(Menu, '1', fromJS(entities))).toMatchSnapshot();

expect(denormalize(Menu, '2', entities)).toMatchSnapshot();
expect(denormalize(Menu, '2', fromJS(entities))).toMatchSnapshot();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,6 @@ Menu {
`;

exports[`Entity denormalization denormalizes deep entities with records 2`] = `
Menu {
"food": Food {
"id": "1",
},
"id": "1",
}
`;

exports[`Entity denormalization denormalizes deep entities with records 3`] = `
Menu {
"food": null,
"id": "2",
}
`;

exports[`Entity denormalization denormalizes deep entities with records 4`] = `
Menu {
"food": null,
"id": "2",
Expand Down Expand Up @@ -107,15 +91,15 @@ exports[`Entity denormalization denormalizes recursive dependencies 2`] = `
Report {
"draftedBy": User {
"id": "456",
"reports": Immutable.List [
"reports": [
[Circular],
],
"role": "manager",
},
"id": "123",
"publishedBy": User {
"id": "456",
"reports": Immutable.List [
"reports": [
[Circular],
],
"role": "manager",
Expand All @@ -142,7 +126,7 @@ User {
exports[`Entity denormalization denormalizes recursive dependencies 4`] = `
User {
"id": "456",
"reports": Immutable.List [
"reports": [
Report {
"draftedBy": [Circular],
"id": "123",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,22 +75,6 @@ Menu {
`;

exports[`EntityMixin denormalization denormalizes deep entities with records 2`] = `
Menu {
"food": Food {
"id": "1",
},
"id": "1",
}
`;

exports[`EntityMixin denormalization denormalizes deep entities with records 3`] = `
Menu {
"food": null,
"id": "2",
}
`;

exports[`EntityMixin denormalization denormalizes deep entities with records 4`] = `
Menu {
"food": null,
"id": "2",
Expand Down Expand Up @@ -148,15 +132,15 @@ exports[`EntityMixin denormalization nesting denormalizes recursive dependencies
Report {
"draftedBy": User {
"id": "456",
"reports": Immutable.List [
"reports": [
[Circular],
],
"role": "manager",
},
"id": "123",
"publishedBy": User {
"id": "456",
"reports": Immutable.List [
"reports": [
[Circular],
],
"role": "manager",
Expand All @@ -183,7 +167,7 @@ User {
exports[`EntityMixin denormalization nesting denormalizes recursive dependencies 4`] = `
User {
"id": "456",
"reports": Immutable.List [
"reports": [
Report {
"draftedBy": [Circular],
"id": "123",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -461,69 +461,69 @@ exports[`input (immutable) ValuesSchema denormalization (current) works on compl
"data": {
"estimates": {
"BTC": Estimate {
"coinbase_fees": Immutable.Map {
"coinbase_fees": {
"amount": "0.00002270",
"currency": "BTC",
},
"confirmation_duration": 900,
"exchange": Immutable.Map {
"rate": "6820.07",
"local": "USD",
"exchange": {
"crypto": "BTC",
},
"exchange_to_proceeds": Immutable.Map {
"local": "USD",
"rate": "6820.07",
"local": "EUR",
},
"exchange_to_proceeds": {
"crypto": "BTC",
"local": "EUR",
"rate": "6820.07",
},
"fee": Immutable.Map {
"fee": {
"amount": "0.00002270",
"currency": "BTC",
},
"fee_per_kb": Immutable.Map {
"fee_per_kb": {
"amount": "0.00016566",
"currency": "BTC",
},
"min_order_size": Immutable.Map {
"min_order_size": {
"amount": "0.001",
"currency": "BTC",
},
"priority": "fast",
"recipient_value": Immutable.Map {
"recipient_value": {
"amount": "0.00054147",
"currency": "BTC",
},
},
"ETH": Estimate {
"coinbase_fees": Immutable.Map {
"coinbase_fees": {
"amount": "0.00002270",
"currency": "BTC",
},
"confirmation_duration": 900,
"exchange": Immutable.Map {
"rate": "197.07",
"local": "USD",
"exchange": {
"crypto": "ETH",
"local": "USD",
"rate": "197.07",
},
"exchange_to_proceeds": Immutable.Map {
"rate": "6820.07",
"local": "EUR",
"exchange_to_proceeds": {
"crypto": "BTC",
"local": "EUR",
"rate": "6820.07",
},
"fee": Immutable.Map {
"fee": {
"amount": "0.03795",
"currency": "ETH",
},
"fee_per_kb": Immutable.Map {
"fee_per_kb": {
"amount": "0.00086",
"currency": "ETH",
},
"min_order_size": Immutable.Map {
"min_order_size": {
"amount": "0.001",
"currency": "BTC",
},
"priority": "fast",
"recipient_value": Immutable.Map {
"recipient_value": {
"amount": "2.53",
"currency": "ETH",
},
Expand Down
2 changes: 2 additions & 0 deletions packages/normalizr/src/denormalize/denormalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { getEntities } from './getEntities.js';
import LocalCache from './localCache.js';
import getUnvisit from './unvisit.js';
import type { Schema } from '../interface.js';
import { isImmutable } from '../schemas/ImmutableUtils.js';
import type { DenormalizeNullable } from '../types.js';

export function denormalize<S extends Schema>(
Expand All @@ -19,5 +20,6 @@ export function denormalize<S extends Schema>(
getEntities(entities),
new LocalCache(),
args,
isImmutable(entities),
)(schema, input).data;
}
Loading