@emeryld/rrroutes-client 2.2.14 → 2.2.16
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/dist/index.cjs +367 -118
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +371 -121
- package/dist/index.mjs.map +1 -1
- package/dist/routesV3.client.index.d.ts +2 -2
- package/dist/routesV3.client.types.d.ts +85 -42
- package/dist/sockets/socket.client.index.d.ts +2 -2
- package/dist/sockets/socketedRoute/socket.client.helper.d.ts +5 -5
- package/package.json +3 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { AnyLeafLowProfile, HttpMethod, InferBody, InferOutput, InferParams, InferQuery, Prettify } from '@emeryld/rrroutes-contract';
|
|
1
2
|
import type { InfiniteData, QueryClient, QueryKey, UseInfiniteQueryOptions, UseInfiniteQueryResult, UseMutationOptions, UseMutationResult, UseQueryOptions, UseQueryResult } from '@tanstack/react-query';
|
|
2
|
-
import type { AnyLeaf, HttpMethod, InferBody, InferOutput, InferParams, InferQuery, Prettify } from '@emeryld/rrroutes-contract';
|
|
3
3
|
/** Helper type used when setting React Query cache data. */
|
|
4
4
|
export type Updater<T> = T | ((prev: T | undefined) => T | undefined) | undefined;
|
|
5
5
|
/** Cursor string extracted from paginated endpoints. */
|
|
@@ -97,21 +97,20 @@ export type RouteClientOptions<Names extends string = string> = {
|
|
|
97
97
|
*/
|
|
98
98
|
environment?: RouteClientEnvironment;
|
|
99
99
|
};
|
|
100
|
-
type
|
|
101
|
-
type
|
|
102
|
-
type
|
|
103
|
-
type BodyOf<L extends AnyLeaf> = InferBody<L>;
|
|
104
|
-
type OnReceive<L extends AnyLeaf> = (data: OutputOf<L>) => void;
|
|
105
|
-
type OnReceiveRegistrar<L extends AnyLeaf> = (listener: OnReceive<L>) => () => void;
|
|
106
|
-
type UseEndpointResult<L extends AnyLeaf, Result> = Result & {
|
|
100
|
+
type OnReceive<L extends AnyLeafLowProfile> = (data: InferOutput<L>) => void;
|
|
101
|
+
type OnReceiveRegistrar<L extends AnyLeafLowProfile> = (listener: OnReceive<L>) => () => void;
|
|
102
|
+
type UseEndpointResult<L extends AnyLeafLowProfile, Result> = Result & {
|
|
107
103
|
onReceive: OnReceiveRegistrar<L>;
|
|
108
104
|
};
|
|
109
105
|
/** Variadic args consumed by the direct fetch helper: optional args + body. */
|
|
110
|
-
export type MutationFetchArgs<L extends
|
|
106
|
+
export type MutationFetchArgs<L extends AnyLeafLowProfile> = Prettify<[
|
|
107
|
+
...ArgsTuple<L>,
|
|
108
|
+
InferBody<L>
|
|
109
|
+
]>;
|
|
111
110
|
/** Signature for the fetch helper returned by mutation builds. */
|
|
112
|
-
export type MutationFetcher<L extends
|
|
111
|
+
export type MutationFetcher<L extends AnyLeafLowProfile> = (...args: MutationFetchArgs<L>) => Promise<InferOutput<L>>;
|
|
113
112
|
/** Fetch args for GET endpoints (optionally include a body when a schema exists). */
|
|
114
|
-
type QueryFetchArgs<L extends
|
|
113
|
+
type QueryFetchArgs<L extends AnyLeafLowProfile> = InferBody<L> extends never ? ArgsTuple<L> : Prettify<ArgsTuple<L> | [...ArgsTuple<L>, InferBody<L>]>;
|
|
115
114
|
/** Optional metadata provided when building a helper (used for debug filtering). */
|
|
116
115
|
export type BuildMeta<Names extends string = string> = {
|
|
117
116
|
/**
|
|
@@ -121,57 +120,60 @@ export type BuildMeta<Names extends string = string> = {
|
|
|
121
120
|
name?: Names;
|
|
122
121
|
};
|
|
123
122
|
/** Object shape the user passes to hooks and helpers (params/query are optional). */
|
|
124
|
-
export type ArgsFor<L extends
|
|
125
|
-
params:
|
|
126
|
-
}) & (
|
|
127
|
-
query:
|
|
123
|
+
export type ArgsFor<L extends AnyLeafLowProfile> = Prettify<(InferParams<L> extends never ? {} : {
|
|
124
|
+
params: InferParams<L>;
|
|
125
|
+
}) & (InferQuery<L> extends never ? {} : {
|
|
126
|
+
query: InferQuery<L>;
|
|
128
127
|
})>;
|
|
129
128
|
/** Variadic tuple representation that omits the argument entirely when not needed. */
|
|
130
|
-
export type ArgsTuple<L extends
|
|
129
|
+
export type ArgsTuple<L extends AnyLeafLowProfile> = keyof ArgsFor<L> extends never ? [] : [args: ArgsFor<L>];
|
|
131
130
|
/** Cache data shape for setData(...) */
|
|
132
|
-
export type DataShape<L extends
|
|
133
|
-
type ArgsFromTuple<L extends
|
|
134
|
-
type ParamsFromArgs<L extends
|
|
131
|
+
export type DataShape<L extends AnyLeafLowProfile> = L['method'] extends 'get' ? L['cfg']['feed'] extends true ? InfiniteData<InferOutput<L>> : InferOutput<L> : InferOutput<L>;
|
|
132
|
+
type ArgsFromTuple<L extends AnyLeafLowProfile, T extends ArgsTuple<L>> = T extends [infer A] ? A : undefined;
|
|
133
|
+
type ParamsFromArgs<L extends AnyLeafLowProfile, T extends ArgsTuple<L>> = ArgsFromTuple<L, T> extends {
|
|
135
134
|
params: infer P;
|
|
136
135
|
} ? P : undefined;
|
|
137
|
-
type SetDataArgs<L extends
|
|
138
|
-
|
|
136
|
+
type SetDataArgs<L extends AnyLeafLowProfile> = Prettify<[
|
|
137
|
+
updater: Updater<DataShape<L>>,
|
|
138
|
+
...ArgsTuple<L>
|
|
139
|
+
]>;
|
|
140
|
+
type QueryFromArgs<L extends AnyLeafLowProfile, T extends ArgsTuple<L>> = ArgsFromTuple<L, T> extends {
|
|
139
141
|
query: infer Q;
|
|
140
142
|
} ? Q : undefined;
|
|
141
143
|
/** Typed query key array derived from the leaf plus the specific args passed in. */
|
|
142
144
|
type SplitUrl<L extends string> = L extends `/${infer A}` ? SplitUrl<A> : L extends `${infer A}/${infer B}` ? [A, ...SplitUrl<B>] : [L];
|
|
143
|
-
type MapParams<P extends any[], Params> = P extends [infer A, ...infer Rest] ? A extends `:${infer Key}` ? [
|
|
144
|
-
A,
|
|
145
|
+
type MapParams<P extends any[], Params> = P extends [infer A, ...infer Rest] ? A extends `:${infer Key}` ? [
|
|
146
|
+
Params extends Record<Key, infer V> ? (string extends V ? A : V) : A,
|
|
145
147
|
...MapParams<Rest, Params>
|
|
146
|
-
] : [];
|
|
147
|
-
export type QueryKeysFor<L extends
|
|
148
|
+
] : [A, ...MapParams<Rest, Params>] : [];
|
|
149
|
+
export type QueryKeysFor<L extends AnyLeafLowProfile, T extends ArgsTuple<L>> = Prettify<readonly [
|
|
148
150
|
L['method'],
|
|
149
151
|
...MapParams<SplitUrl<L['path']>, ParamsFromArgs<L, T>>,
|
|
150
152
|
QueryFromArgs<L, T> extends undefined ? {} : QueryFromArgs<L, T>
|
|
151
153
|
]>;
|
|
152
154
|
/** React Query build options specialized for a plain GET leaf. */
|
|
153
|
-
export type QueryBuildOptionsFor<L extends
|
|
155
|
+
export type QueryBuildOptionsFor<L extends AnyLeafLowProfile> = Omit<UseQueryOptions<InferOutput<L>, unknown, InferOutput<L>, QueryKey>, 'queryKey' | 'queryFn'> & {
|
|
154
156
|
/** Hook invoked after a successful fetch + validation. */
|
|
155
157
|
onReceive?: OnReceive<L>;
|
|
156
158
|
};
|
|
157
159
|
/** Build options for feed-style GET leaves (`cfg.feed === true`). */
|
|
158
|
-
export type InfiniteBuildOptionsFor<L extends
|
|
160
|
+
export type InfiniteBuildOptionsFor<L extends AnyLeafLowProfile> = Omit<UseInfiniteQueryOptions<InferOutput<L>, unknown, InfiniteData<InferOutput<L>>, QueryKey, Cursor>, 'queryKey' | 'queryFn' | 'initialPageParam' | 'getNextPageParam'> & {
|
|
159
161
|
/** Hook invoked after a successful fetch + validation. */
|
|
160
162
|
onReceive?: OnReceive<L>;
|
|
161
163
|
};
|
|
162
164
|
/** Build options for mutation leaves (non-GET). */
|
|
163
|
-
export type MutationBuildOptionsFor<L extends
|
|
165
|
+
export type MutationBuildOptionsFor<L extends AnyLeafLowProfile> = Omit<UseMutationOptions<InferOutput<L>, unknown, InferBody<L>, unknown>, 'mutationFn' | 'mutationKey'> & {
|
|
164
166
|
/** Hook invoked after a successful fetch + validation. */
|
|
165
167
|
onReceive?: OnReceive<L>;
|
|
166
168
|
};
|
|
167
169
|
/** Build options narrowed to the method/feed shape of the leaf. */
|
|
168
|
-
export type BuildOptionsFor<L extends
|
|
169
|
-
export type UseEndpointArgs<L extends
|
|
170
|
-
export type QueryUseEndpointResultFor<L extends
|
|
171
|
-
export type InfiniteUseEndpointResultFor<L extends
|
|
172
|
-
export type MutationUseEndpointResultFor<L extends
|
|
170
|
+
export type BuildOptionsFor<L extends AnyLeafLowProfile> = L['method'] extends 'get' ? L['cfg']['feed'] extends true ? InfiniteBuildOptionsFor<L> : QueryBuildOptionsFor<L> : MutationBuildOptionsFor<L>;
|
|
171
|
+
export type UseEndpointArgs<L extends AnyLeafLowProfile> = ArgsTuple<L>;
|
|
172
|
+
export type QueryUseEndpointResultFor<L extends AnyLeafLowProfile> = UseEndpointResult<L, UseQueryResult<InferOutput<L>, unknown>>;
|
|
173
|
+
export type InfiniteUseEndpointResultFor<L extends AnyLeafLowProfile> = UseEndpointResult<L, UseInfiniteQueryResult<InfiniteData<InferOutput<L>>, unknown>>;
|
|
174
|
+
export type MutationUseEndpointResultFor<L extends AnyLeafLowProfile> = UseEndpointResult<L, UseMutationResult<InferOutput<L>, unknown, InferBody<L>, unknown>>;
|
|
173
175
|
/** Shared capabilities exposed by every built endpoint helper. */
|
|
174
|
-
export type BuiltCommon<L extends
|
|
176
|
+
export type BuiltCommon<L extends AnyLeafLowProfile> = {
|
|
175
177
|
/**
|
|
176
178
|
* Deterministic key (infinite keys omit the cursor by design).
|
|
177
179
|
* @param args Optional params/query tuple for the leaf.
|
|
@@ -191,7 +193,7 @@ export type BuiltCommon<L extends AnyLeaf> = {
|
|
|
191
193
|
setData: (...args: SetDataArgs<L>) => DataShape<L> | undefined;
|
|
192
194
|
};
|
|
193
195
|
/** Hook+helpers for a standard GET endpoint. */
|
|
194
|
-
export type BuiltQuery<L extends
|
|
196
|
+
export type BuiltQuery<L extends AnyLeafLowProfile> = BuiltCommon<L> & {
|
|
195
197
|
/**
|
|
196
198
|
* React hook bound to the GET leaf.
|
|
197
199
|
* @param args Optional params/query tuple for the leaf.
|
|
@@ -201,10 +203,10 @@ export type BuiltQuery<L extends AnyLeaf> = BuiltCommon<L> & {
|
|
|
201
203
|
* Direct fetch helper mirroring the query hook without touching the cache.
|
|
202
204
|
* @param args Optional params/query tuple for the leaf.
|
|
203
205
|
*/
|
|
204
|
-
fetch: (...args: QueryFetchArgs<L>) => Promise<
|
|
206
|
+
fetch: (...args: QueryFetchArgs<L>) => Promise<InferOutput<L>>;
|
|
205
207
|
};
|
|
206
208
|
/** Hook+helpers for a cursor-paginated GET endpoint. */
|
|
207
|
-
export type BuiltInfinite<L extends
|
|
209
|
+
export type BuiltInfinite<L extends AnyLeafLowProfile> = BuiltCommon<L> & {
|
|
208
210
|
/**
|
|
209
211
|
* React hook bound to an infinite GET leaf.
|
|
210
212
|
* @param args Optional params/query tuple for the leaf.
|
|
@@ -214,10 +216,10 @@ export type BuiltInfinite<L extends AnyLeaf> = BuiltCommon<L> & {
|
|
|
214
216
|
* Direct fetch helper for a single page of the feed (pass cursor in query args).
|
|
215
217
|
* @param args Optional params/query tuple for the leaf.
|
|
216
218
|
*/
|
|
217
|
-
fetch: (...args: QueryFetchArgs<L>) => Promise<
|
|
219
|
+
fetch: (...args: QueryFetchArgs<L>) => Promise<InferOutput<L>>;
|
|
218
220
|
};
|
|
219
221
|
/** Hook+helpers for non-GET endpoints (mutations). */
|
|
220
|
-
export type BuiltMutation<L extends
|
|
222
|
+
export type BuiltMutation<L extends AnyLeafLowProfile> = BuiltCommon<L> & {
|
|
221
223
|
/**
|
|
222
224
|
* React hook bound to a mutation leaf.
|
|
223
225
|
* @param args Optional params/query tuple for the leaf.
|
|
@@ -230,7 +232,7 @@ export type BuiltMutation<L extends AnyLeaf> = BuiltCommon<L> & {
|
|
|
230
232
|
fetch: MutationFetcher<L>;
|
|
231
233
|
};
|
|
232
234
|
/** Type-safe union that resolves to the correct built helper for a leaf. */
|
|
233
|
-
export type BuiltForLeaf<L extends
|
|
235
|
+
export type BuiltForLeaf<L extends AnyLeafLowProfile> = L['method'] extends 'get' ? L['cfg']['feed'] extends true ? BuiltInfinite<L> : BuiltQuery<L> : BuiltMutation<L>;
|
|
234
236
|
/** Public surface returned by `createRouteClient`. */
|
|
235
237
|
export type RouteClient<Names extends string = string> = {
|
|
236
238
|
/**
|
|
@@ -240,15 +242,56 @@ export type RouteClient<Names extends string = string> = {
|
|
|
240
242
|
*/
|
|
241
243
|
invalidate: (prefix: string[], exact?: boolean) => Promise<void>;
|
|
242
244
|
/** Build a typed endpoint from a leaf. */
|
|
243
|
-
build: <L extends
|
|
245
|
+
build: <L extends AnyLeafLowProfile>(leaf: L, opts?: BuildOptionsFor<L>,
|
|
244
246
|
/** Optional metadata (third arg) to assign a debug name for filtering via `debug.only`. */
|
|
245
247
|
meta?: BuildMeta<Names>) => BuiltForLeaf<L>;
|
|
246
248
|
/** Underlying React Query client (exposed for advanced scenarios). */
|
|
247
249
|
queryClient: QueryClient;
|
|
250
|
+
/**
|
|
251
|
+
* Low-level fetch helper that does not depend on a leaf definition.
|
|
252
|
+
* Handles path param interpolation and enforces flat string query objects.
|
|
253
|
+
*/
|
|
254
|
+
fetch: RouteClientFetch;
|
|
248
255
|
};
|
|
249
256
|
/**
|
|
250
257
|
* Helper signature returned by `buildRouter`, enabling lookups by name instead of leaves.
|
|
251
258
|
* Accepts the same build options/meta the underlying client does, narrowed per leaf shape.
|
|
252
259
|
*/
|
|
253
|
-
export type RouterBuilder<Routes extends Record<PropertyKey,
|
|
260
|
+
export type RouterBuilder<Routes extends Record<PropertyKey, AnyLeafLowProfile>, Names extends string = string> = <K extends keyof Routes>(key: K, opts?: BuildOptionsFor<Routes[K]>, meta?: BuildMeta<Names>) => BuiltForLeaf<Routes[K]>;
|
|
261
|
+
/**
|
|
262
|
+
* Arguments for the low-level RouteClient.fetch helper.
|
|
263
|
+
* This is intentionally NOT tied to AnyLeafLowProfile.
|
|
264
|
+
*/
|
|
265
|
+
export type RouteClientFetchArgs = {
|
|
266
|
+
/**
|
|
267
|
+
* Route template or concrete path, e.g. "/api/users/:id".
|
|
268
|
+
* Params from `params` will be interpolated into any `:name` segments.
|
|
269
|
+
*/
|
|
270
|
+
path: string;
|
|
271
|
+
/**
|
|
272
|
+
* HTTP method. Can be provided as lowercase (HttpMethod) or uppercase;
|
|
273
|
+
* the client normalizes it to uppercase internally.
|
|
274
|
+
*/
|
|
275
|
+
method: HttpMethod | Uppercase<HttpMethod>;
|
|
276
|
+
/**
|
|
277
|
+
* Flat query string object. Only string values are allowed.
|
|
278
|
+
* Nested objects/arrays will cause a runtime error in the client.
|
|
279
|
+
*/
|
|
280
|
+
query?: Record<string, string>;
|
|
281
|
+
/**
|
|
282
|
+
* Path parameters used to fill `:name` segments in the `path`.
|
|
283
|
+
* Extra keys that do not match a path segment, or non-primitive values,
|
|
284
|
+
* will cause a runtime error in the client.
|
|
285
|
+
*/
|
|
286
|
+
params?: Record<string, string | number | boolean | null | undefined>;
|
|
287
|
+
/**
|
|
288
|
+
* Optional request body (already normalized by the caller).
|
|
289
|
+
*/
|
|
290
|
+
body?: unknown;
|
|
291
|
+
};
|
|
292
|
+
/**
|
|
293
|
+
* Signature of the low-level RouteClient.fetch helper.
|
|
294
|
+
* Callers may specify a response type parameter if desired.
|
|
295
|
+
*/
|
|
296
|
+
export type RouteClientFetch = (args: RouteClientFetchArgs) => Promise<any>;
|
|
254
297
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { EventMap,
|
|
2
|
-
import type { MaybeSocket, SysEventMap } from './socket.client.sys';
|
|
1
|
+
import type { EventMap, Payload, SocketConnectionConfigOutput, SocketSchemaOutput } from '@emeryld/rrroutes-contract';
|
|
3
2
|
import { SocketClientDebugEvent } from './socket.client.debug';
|
|
3
|
+
import type { MaybeSocket, SysEventMap } from './socket.client.sys';
|
|
4
4
|
export type ServerEnvelope<T extends EventMap, K extends keyof T & string> = {
|
|
5
5
|
eventName: K;
|
|
6
6
|
sentAt: string | Date;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AnyLeafLowProfile, EventMap, InferOutput, Payload, SocketConnectionConfigOutput, SocketSchemaOutput } from '@emeryld/rrroutes-contract';
|
|
2
2
|
import type { BuiltInfinite, BuiltQuery, DataShape, InfiniteUseEndpointResultFor, QueryUseEndpointResultFor, UseEndpointArgs } from '../../routesV3.client.types';
|
|
3
3
|
import type { ClientCtx, ServerEnvelope, SocketClient } from '../socket.client.index';
|
|
4
4
|
type RoomsInput = string | string[] | undefined | null;
|
|
5
|
-
type SocketedBuilt<L extends
|
|
6
|
-
type SocketedRouteResult<L extends
|
|
5
|
+
type SocketedBuilt<L extends AnyLeafLowProfile> = L['cfg']['feed'] extends true ? BuiltInfinite<L> : BuiltQuery<L>;
|
|
6
|
+
type SocketedRouteResult<L extends AnyLeafLowProfile> = (L['cfg']['feed'] extends true ? InfiniteUseEndpointResultFor<L> : QueryUseEndpointResultFor<L>) & {
|
|
7
7
|
rooms: string[];
|
|
8
8
|
};
|
|
9
|
-
export type SocketedRouteOptions<L extends
|
|
9
|
+
export type SocketedRouteOptions<L extends AnyLeafLowProfile, Events extends EventMap, C extends SocketConnectionConfigOutput> = {
|
|
10
10
|
built: SocketedBuilt<L>;
|
|
11
11
|
toRooms: (data: InferOutput<L>) => {
|
|
12
12
|
rooms: RoomsInput;
|
|
@@ -26,5 +26,5 @@ export type SocketedRouteOptions<L extends AnyLeaf, Events extends EventMap, C e
|
|
|
26
26
|
* - joins/leaves rooms derived from the endpoint data
|
|
27
27
|
* - subscribes to a socket event and applies messages to the cache
|
|
28
28
|
*/
|
|
29
|
-
export declare function buildSocketedRoute<L extends
|
|
29
|
+
export declare function buildSocketedRoute<L extends AnyLeafLowProfile, Events extends EventMap, C extends SocketConnectionConfigOutput>(options: SocketedRouteOptions<L, Events, C>): (...useArgs: UseEndpointArgs<L>) => SocketedRouteResult<L>;
|
|
30
30
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@emeryld/rrroutes-client",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.16",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"dist"
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@emeryld/rrroutes-contract": "^2.
|
|
23
|
-
"zod": "^4.1.
|
|
22
|
+
"@emeryld/rrroutes-contract": "^2.3.9",
|
|
23
|
+
"zod": "^4.1.13"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"@tanstack/react-query": "^5.87.4",
|