basalt-ui 1.29.1 → 1.29.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [1.29.2](https://github.com/jkrumm/basalt-ui/compare/v1.29.1...v1.29.2) (2026-09-03)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * distribute unwrap's NonNullable over Eden's union response shape ([d46bc00](https://github.com/jkrumm/basalt-ui/commit/d46bc00ae46fcbe76e0b89516140735b1f3295fb))
7
+
1
8
  ## [1.29.1](https://github.com/jkrumm/basalt-ui/compare/v1.29.0...v1.29.1) (2026-09-03)
2
9
 
3
10
 
package/MIGRATING.md CHANGED
@@ -58,6 +58,13 @@ What is new, one line each — nothing here renames or removes anything:
58
58
  type of the reference rather than applying an overload, and TS cannot propagate generic inference
59
59
  across an overload set the way it can for a single signature. `.then(unwrap)` now infers `TData`
60
60
  again, alongside `unwrap(await p)` and `unwrap(p)` — nothing about the runtime behaviour changed.
61
+ - **`unwrap` strips `null`/`undefined` from a union-typed Eden response again** — the single
62
+ conditional signature above still inferred `TData` off `Envelope<infer TData>`, and an Eden
63
+ Treaty response is a UNION of envelopes (`{ data: T; error: null } | { data: null; error:
64
+ EdenFetchError }`), not one envelope with a nullable `data`; inferring through the wrapper type
65
+ read `T | null` at every Eden call site. `UnwrapResult` now infers the raw `data` field and wraps
66
+ it in `NonNullable`, which distributes over a union `R` — `unwrap(await api.x.get())` resolves to
67
+ `T` again, with no `| null`. Runtime unchanged.
61
68
  - **`scrollParentOf` / `SCROLLPORT_ATTRIBUTE`** (`basalt-ui`) — resolve which box actually scrolls an
62
69
  element (`null` = the document). The seam behind the shell scrollport change below.
63
70
  - **`PageAside`** (`basalt-ui`) — the right-hand aside REGION a route claims, with the panel filter
@@ -42,6 +42,16 @@ export declare function createBasaltQueryClient(config?: QueryClientConfig): Que
42
42
  * `unwrap` reference — so `api.threads.get().then(unwrap)` silently widened. A single generic
43
43
  * signature has exactly one type to read regardless of how the reference is used.
44
44
  *
45
+ * **The conditional infers the raw `data` type and strips `null`/`undefined` from it**, rather
46
+ * than inferring the already-narrowed `Envelope<TData>`'s `TData` directly — Eden Treaty's
47
+ * response type is a UNION of envelope shapes (`{ data: T; error: null } | { data: null; error:
48
+ * EdenFetchError }`), and inferring through `Envelope<infer TData>` reads `TData` off whichever
49
+ * union member the conditional happens to match, landing on `T | null` at every Eden call site. A
50
+ * conditional type distributes over a union input when the checked type is a bare type parameter,
51
+ * so inferring `D` from `{ data: infer D; error: unknown }` and wrapping the result in
52
+ * `NonNullable` runs the check per union member and unions the results back together —
53
+ * `NonNullable<T> | NonNullable<null>` collapses to `T`.
54
+ *
45
55
  * @example
46
56
  * import { unwrap } from 'basalt-ui'
47
57
  *
@@ -61,7 +71,15 @@ type Envelope<TData = unknown> = {
61
71
  error: unknown;
62
72
  };
63
73
  /** `unwrap`'s conditional return: a `Promise<TData>` when `R` is a promised envelope, `TData` when
64
- * it is an already-resolved one — inferred off the SAME `R` the overload used to split on. */
65
- type UnwrapResult<R> = R extends Promise<Envelope<infer TData>> ? Promise<TData> : R extends Envelope<infer TData> ? TData : never;
74
+ * it is an already-resolved one — inferred off the SAME `R` the overload used to split on, and
75
+ * distributing over a union `R` (see the JSDoc above) so an Eden Treaty response's null branch
76
+ * never leaks into the resolved type. */
77
+ type UnwrapResult<R> = R extends Promise<{
78
+ data: infer TData;
79
+ error: unknown;
80
+ }> ? Promise<NonNullable<TData>> : R extends {
81
+ data: infer TData;
82
+ error: unknown;
83
+ } ? NonNullable<TData> : never;
66
84
  export {};
67
85
  //# sourceMappingURL=query-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-client.d.ts","sourceRoot":"","sources":["../src/query-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAW9D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,WAAW,CAQ/E;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAK3F;AAED,iGAAiG;AACjG,KAAK,QAAQ,CAAC,KAAK,GAAG,OAAO,IAAI;IAAE,IAAI,EAAE,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAA;AAEnF;8FAC8F;AAC9F,KAAK,YAAY,CAAC,CAAC,IACjB,CAAC,SAAS,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,GACpC,OAAO,CAAC,KAAK,CAAC,GACd,CAAC,SAAS,QAAQ,CAAC,MAAM,KAAK,CAAC,GAC7B,KAAK,GACL,KAAK,CAAA"}
1
+ {"version":3,"file":"query-client.d.ts","sourceRoot":"","sources":["../src/query-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAW9D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,WAAW,CAQ/E;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAK3F;AAED,iGAAiG;AACjG,KAAK,QAAQ,CAAC,KAAK,GAAG,OAAO,IAAI;IAAE,IAAI,EAAE,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAA;AAEnF;;;yCAGyC;AACzC,KAAK,YAAY,CAAC,CAAC,IACjB,CAAC,SAAS,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,GACpD,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,GAC3B,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC7C,WAAW,CAAC,KAAK,CAAC,GAClB,KAAK,CAAA"}
package/llms.txt CHANGED
@@ -1,4 +1,4 @@
1
- # basalt-ui v1.29.1
1
+ # basalt-ui v1.29.2
2
2
  # Opinionated framework for Mantine-based React apps — theme, app shell, visx charts, toolchain presets
3
3
  #
4
4
  # basalt-ui is an opinionated framework for Mantine-based React apps.
@@ -19,7 +19,7 @@
19
19
  # ./tokens.css subpath. Guide: docs/FRAMEWORK-FREE.md in the repo.
20
20
 
21
21
  Package: basalt-ui
22
- Version: 1.29.1
22
+ Version: 1.29.2
23
23
 
24
24
  ## basalt-ui
25
25
  Import: import { ... } from 'basalt-ui'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "basalt-ui",
3
- "version": "1.29.1",
3
+ "version": "1.29.2",
4
4
  "description": "Opinionated framework for Mantine-based React apps — theme, app shell, visx charts, toolchain presets",
5
5
  "keywords": [
6
6
  "charts",
@@ -63,6 +63,16 @@ export function createBasaltQueryClient(config?: QueryClientConfig): QueryClient
63
63
  * `unwrap` reference — so `api.threads.get().then(unwrap)` silently widened. A single generic
64
64
  * signature has exactly one type to read regardless of how the reference is used.
65
65
  *
66
+ * **The conditional infers the raw `data` type and strips `null`/`undefined` from it**, rather
67
+ * than inferring the already-narrowed `Envelope<TData>`'s `TData` directly — Eden Treaty's
68
+ * response type is a UNION of envelope shapes (`{ data: T; error: null } | { data: null; error:
69
+ * EdenFetchError }`), and inferring through `Envelope<infer TData>` reads `TData` off whichever
70
+ * union member the conditional happens to match, landing on `T | null` at every Eden call site. A
71
+ * conditional type distributes over a union input when the checked type is a bare type parameter,
72
+ * so inferring `D` from `{ data: infer D; error: unknown }` and wrapping the result in
73
+ * `NonNullable` runs the check per union member and unions the results back together —
74
+ * `NonNullable<T> | NonNullable<null>` collapses to `T`.
75
+ *
66
76
  * @example
67
77
  * import { unwrap } from 'basalt-ui'
68
78
  *
@@ -86,12 +96,14 @@ export function unwrap<R extends Envelope | Promise<Envelope>>(response: R): Unw
86
96
  type Envelope<TData = unknown> = { data: TData | null | undefined; error: unknown }
87
97
 
88
98
  /** `unwrap`'s conditional return: a `Promise<TData>` when `R` is a promised envelope, `TData` when
89
- * it is an already-resolved one — inferred off the SAME `R` the overload used to split on. */
99
+ * it is an already-resolved one — inferred off the SAME `R` the overload used to split on, and
100
+ * distributing over a union `R` (see the JSDoc above) so an Eden Treaty response's null branch
101
+ * never leaks into the resolved type. */
90
102
  type UnwrapResult<R> =
91
- R extends Promise<Envelope<infer TData>>
92
- ? Promise<TData>
93
- : R extends Envelope<infer TData>
94
- ? TData
103
+ R extends Promise<{ data: infer TData; error: unknown }>
104
+ ? Promise<NonNullable<TData>>
105
+ : R extends { data: infer TData; error: unknown }
106
+ ? NonNullable<TData>
95
107
  : never
96
108
 
97
109
  function unwrapEnvelope<TData>(envelope: Envelope<TData>): TData {