Skip to content

Commit 59845ba

Browse files
committed
docs: Add 0.10 release post
1 parent a722f1a commit 59845ba

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
---
2+
title: "v0.10: Consistent Null Handling, URL Utilities"
3+
authors: [ntucker]
4+
tags: [releases, rest, endpoint, schema]
5+
description: Data Client 0.10 brings consistent null handling across all schemas, new URL construction utilities for RestEndpoint, and fixes memory leaks in DevTools.
6+
---
7+
8+
import Link from '@docusaurus/Link';
9+
10+
This release focuses on consistency and extensibility. [Null handling](/blog/2024/02/15/v0.10-null-consistency-url-utilities#null-consistency) is now uniform across all schema types,
11+
making data transformations more predictable. New [URL utilities](/blog/2024/02/15/v0.10-null-consistency-url-utilities#url-utilities) enable custom URL construction and search parameter encoding.
12+
13+
```ts
14+
class MyEndpoint<O extends RestGenerics = any> extends RestEndpoint<O> {
15+
searchToString(searchParams) {
16+
// Use qs library for complex nested object encoding
17+
return qs.stringify(searchParams);
18+
}
19+
}
20+
```
21+
22+
<center>
23+
24+
<Link className="button button--secondary" to="/blog/2024/02/15/v0.10-null-consistency-url-utilities#migration-guide">Migration guide</Link>
25+
26+
</center>
27+
28+
**Breaking Changes:**
29+
30+
- [Null values retained in Array/Object schemas](/blog/2024/02/15/v0.10-null-consistency-url-utilities#null-consistency)
31+
32+
**Other Improvements:**
33+
34+
- [RestEndpoint.searchToString()](/blog/2024/02/15/v0.10-null-consistency-url-utilities#searchtostring) for custom search param encoding
35+
- [getUrlBase, getUrlTokens exports](/blog/2024/02/15/v0.10-null-consistency-url-utilities#url-utilities) for custom URL construction
36+
- [DevToolsManager memory leak fix](/blog/2024/02/15/v0.10-null-consistency-url-utilities#devtools-fix)
37+
38+
<!--truncate-->
39+
40+
import DiffEditor from '@site/src/components/DiffEditor';
41+
import PkgTabs from '@site/src/components/PkgTabs';
42+
43+
## Consistent null handling {#null-consistency}
44+
45+
`null` values are now consistently retained across all schema types. Previously, `[]` shorthand and [schema.Array](/rest/api/Array)
46+
behaved differently when encountering `null` values. [#2912](https://github.com/reactive/data-client/pull/2912)
47+
48+
- `[]` and [schema.Array](/rest/api/Array) now behave identically
49+
- `null` values are retained everywhere (they were already retained in [nested Entities](/rest/guides/relational-data#nesting))
50+
- `undefined` values are still filtered out
51+
52+
This change ensures more predictable behavior when working with APIs that explicitly return `null` to indicate
53+
absence of data versus `undefined` for missing fields.
54+
55+
## URL Utilities {#url-utilities}
56+
57+
### RestEndpoint.searchToString() {#searchtostring}
58+
59+
[RestEndpoint.searchToString()](/rest/api/RestEndpoint#searchToString) enables custom encoding of search parameters.
60+
This is particularly useful for APIs that expect complex nested objects in query strings.
61+
[#2919](https://github.com/reactive/data-client/pull/2919)
62+
63+
For example, to encode complex objects using the [qs](https://github.com/ljharb/qs) library:
64+
65+
```typescript
66+
import { RestEndpoint, RestGenerics } from '@data-client/rest';
67+
import qs from 'qs';
68+
69+
class MyEndpoint<O extends RestGenerics = any> extends RestEndpoint<O> {
70+
searchToString(searchParams) {
71+
return qs.stringify(searchParams);
72+
}
73+
}
74+
```
75+
76+
### getUrlBase, getUrlTokens {#geturlbase}
77+
78+
New exports `getUrlBase` and `getUrlTokens` provide the building blocks for custom
79+
[RestEndpoint.url()](/rest/api/RestEndpoint#url) implementations.
80+
[#2919](https://github.com/reactive/data-client/pull/2919)
81+
82+
```ts
83+
import { getUrlBase, getUrlTokens } from '@data-client/rest';
84+
85+
// Parse path tokens for custom URL logic
86+
const tokens = getUrlTokens('/users/:id/posts/:postId');
87+
// => ['id', 'postId']
88+
89+
// Get base URL without path parameters
90+
const base = getUrlBase('/users/:id');
91+
// => '/users/'
92+
```
93+
94+
## DevToolsManager memory fix {#devtools-fix}
95+
96+
The DevToolsManager action buffer is now limited to 100 entries, preventing memory leaks in long-running
97+
applications or those with frequent updates. [`4e6a39e`](https://github.com/reactive/data-client/commit/4e6a39ea2bfdb1390051f12781e899488609e1a8)
98+
99+
## Migration Guide
100+
101+
This upgrade requires updating all package versions simultaneously.
102+
103+
<PkgTabs pkgs="@data-client/react@^0.10.0 @data-client/rest@^0.10.0 @data-client/test@^0.10.0 @data-client/img@^0.10.0" upgrade />
104+
105+
### Null values in arrays {#null-arrays}
106+
107+
If your code relied on `null` values being filtered out of arrays, you'll need to handle this explicitly:
108+
109+
<DiffEditor>
110+
111+
```ts title="Before"
112+
import { Entity, schema, RestEndpoint } from '@data-client/rest';
113+
114+
class User extends Entity {
115+
id = '';
116+
name = '';
117+
pk() { return this.id; }
118+
}
119+
120+
const getUsers = new RestEndpoint({
121+
path: '/users',
122+
schema: new schema.Array(User),
123+
});
124+
125+
// API response: [{ id: '1' }, null, { id: '2' }]
126+
const usersWithoutNull = useSuspense(getUsers);
127+
```
128+
129+
```ts title="After"
130+
import { Entity, schema, RestEndpoint } from '@data-client/rest';
131+
132+
class User extends Entity {
133+
id = '';
134+
name = '';
135+
pk() { return this.id; }
136+
}
137+
138+
const getUsers = new RestEndpoint({
139+
path: '/users',
140+
schema: new schema.Array(User),
141+
});
142+
143+
// API response: [{ id: '1' }, null, { id: '2' }]
144+
const usersWithoutNull = useSuspense(getUsers).filter(Boolean);
145+
```
146+
147+
</DiffEditor>
148+
149+
This change aligns with how [nested Entities](/rest/guides/relational-data#nesting) already handled `null` values,
150+
making the behavior consistent across all schema types.
151+
152+
### Upgrade support
153+
154+
As usual, if you have any troubles or questions, feel free to join our [![Chat](https://img.shields.io/discord/768254430381735967.svg?style=flat-square&colorB=758ED3)](https://discord.gg/wXGV27xm6t) or [file a bug](https://github.com/reactive/data-client/issues/new/choose)
155+

website/raw-plugin.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ module.exports = function (context, options) {
44
// to support running babel transformer we need to polyfill node api 'fs'
55
configureWebpack(config, isServer, utils) {
66
return {
7+
ignoreWarnings: [
8+
// Suppress warning about dynamic import expressions in monaco-init.ts
9+
// This is expected behavior for dynamic TypeScript definition loading
10+
{
11+
module: /monaco-init\.ts/,
12+
message:
13+
/Critical dependency: the request of a dependency is an expression/,
14+
},
15+
],
716
module: {
817
rules: [
918
{

0 commit comments

Comments
 (0)