@sylphx/lens-solid 2.1.1 → 2.1.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/dist/create.d.ts +40 -38
- package/dist/create.d.ts.map +1 -1
- package/dist/index.d.ts +7 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +54 -92
- package/package.json +3 -3
- package/src/create.ts +110 -180
- package/src/index.ts +10 -8
package/dist/create.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @sylphx/lens-solid - Create Client
|
|
3
3
|
*
|
|
4
4
|
* Creates a typed Lens client with SolidJS primitives.
|
|
5
|
-
*
|
|
5
|
+
* Base client methods work in vanilla JS, primitives are extensions.
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
8
8
|
* ```tsx
|
|
@@ -15,18 +15,20 @@
|
|
|
15
15
|
* transport: httpTransport({ url: '/api/lens' }),
|
|
16
16
|
* });
|
|
17
17
|
*
|
|
18
|
-
* //
|
|
19
|
-
* const
|
|
18
|
+
* // Vanilla JS (anywhere - SSR, utilities, event handlers)
|
|
19
|
+
* const user = await client.user.get({ input: { id } });
|
|
20
|
+
* client.user.get({ input: { id } }).subscribe(data => console.log(data));
|
|
20
21
|
*
|
|
21
|
-
* //
|
|
22
|
-
* const
|
|
22
|
+
* // SolidJS primitives (in components)
|
|
23
|
+
* const { data, loading } = client.user.get.createQuery({ input: { id } });
|
|
24
|
+
* const { mutate, loading } = client.user.create.createMutation();
|
|
23
25
|
* ```
|
|
24
26
|
*/
|
|
25
|
-
import { type LensClientConfig, type SelectionObject, type TypedClientConfig } from "@sylphx/lens-client";
|
|
27
|
+
import { type LensClientConfig, type QueryResult, type SelectionObject, type TypedClientConfig } from "@sylphx/lens-client";
|
|
26
28
|
import type { MutationDef, QueryDef, RouterDef, RouterRoutes } from "@sylphx/lens-core";
|
|
27
29
|
import { type Accessor } from "solid-js";
|
|
28
|
-
/** Query
|
|
29
|
-
export interface
|
|
30
|
+
/** Query primitive options */
|
|
31
|
+
export interface QueryPrimitiveOptions<TInput> {
|
|
30
32
|
/** Query input parameters */
|
|
31
33
|
input?: TInput;
|
|
32
34
|
/** Field selection */
|
|
@@ -34,8 +36,8 @@ export interface QueryHookOptions<TInput> {
|
|
|
34
36
|
/** Skip query execution */
|
|
35
37
|
skip?: boolean;
|
|
36
38
|
}
|
|
37
|
-
/** Query
|
|
38
|
-
export interface
|
|
39
|
+
/** Query primitive result */
|
|
40
|
+
export interface QueryPrimitiveResult<T> {
|
|
39
41
|
/** Reactive data accessor */
|
|
40
42
|
data: Accessor<T | null>;
|
|
41
43
|
/** Reactive loading state */
|
|
@@ -45,8 +47,8 @@ export interface QueryHookResult<T> {
|
|
|
45
47
|
/** Refetch the query */
|
|
46
48
|
refetch: () => void;
|
|
47
49
|
}
|
|
48
|
-
/** Mutation
|
|
49
|
-
export interface
|
|
50
|
+
/** Mutation primitive options */
|
|
51
|
+
export interface MutationPrimitiveOptions<TOutput> {
|
|
50
52
|
/** Called on successful mutation */
|
|
51
53
|
onSuccess?: (data: TOutput) => void;
|
|
52
54
|
/** Called on mutation error */
|
|
@@ -54,8 +56,8 @@ export interface MutationHookOptions<TOutput> {
|
|
|
54
56
|
/** Called when mutation settles (success or error) */
|
|
55
57
|
onSettled?: () => void;
|
|
56
58
|
}
|
|
57
|
-
/** Mutation
|
|
58
|
-
export interface
|
|
59
|
+
/** Mutation primitive result */
|
|
60
|
+
export interface MutationPrimitiveResult<TInput, TOutput> {
|
|
59
61
|
/** Execute the mutation */
|
|
60
62
|
mutate: (options: {
|
|
61
63
|
input: TInput;
|
|
@@ -70,28 +72,27 @@ export interface MutationHookResult<TInput, TOutput> {
|
|
|
70
72
|
/** Reset mutation state */
|
|
71
73
|
reset: () => void;
|
|
72
74
|
}
|
|
73
|
-
/** Query endpoint
|
|
75
|
+
/** Query endpoint with SolidJS primitives */
|
|
74
76
|
export interface QueryEndpoint<TInput, TOutput> {
|
|
75
|
-
/**
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
input: TInput;
|
|
83
|
-
select?: TSelect;
|
|
84
|
-
}) => Promise<TOutput>;
|
|
77
|
+
/** Vanilla JS call - returns QueryResult (Promise + Observable) */
|
|
78
|
+
(options?: {
|
|
79
|
+
input?: TInput;
|
|
80
|
+
select?: SelectionObject;
|
|
81
|
+
}): QueryResult<TOutput>;
|
|
82
|
+
/** SolidJS primitive for reactive queries */
|
|
83
|
+
createQuery: (options?: TInput extends void ? QueryPrimitiveOptions<void> | void : QueryPrimitiveOptions<TInput>) => QueryPrimitiveResult<TOutput>;
|
|
85
84
|
}
|
|
86
|
-
/** Mutation endpoint
|
|
85
|
+
/** Mutation endpoint with SolidJS primitives */
|
|
87
86
|
export interface MutationEndpoint<TInput, TOutput> {
|
|
88
|
-
/**
|
|
89
|
-
(options
|
|
90
|
-
/** Promise call (SSR) */
|
|
91
|
-
fetch: <TSelect extends SelectionObject = Record<string, never>>(options: {
|
|
87
|
+
/** Vanilla JS call - returns Promise */
|
|
88
|
+
(options: {
|
|
92
89
|
input: TInput;
|
|
93
|
-
select?:
|
|
94
|
-
})
|
|
90
|
+
select?: SelectionObject;
|
|
91
|
+
}): Promise<{
|
|
92
|
+
data: TOutput;
|
|
93
|
+
}>;
|
|
94
|
+
/** SolidJS primitive for mutations */
|
|
95
|
+
createMutation: (options?: MutationPrimitiveOptions<TOutput>) => MutationPrimitiveResult<TInput, TOutput>;
|
|
95
96
|
}
|
|
96
97
|
/** Infer client type from router routes */
|
|
97
98
|
type InferTypedClient<TRoutes extends RouterRoutes> = {
|
|
@@ -102,9 +103,8 @@ export type TypedClient<TRouter extends RouterDef> = TRouter extends RouterDef<i
|
|
|
102
103
|
/**
|
|
103
104
|
* Create a Lens client with SolidJS primitives.
|
|
104
105
|
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
* - Via .fetch() for promises: `await client.user.get.fetch({ input: { id } })`
|
|
106
|
+
* Base client methods work in vanilla JS (SSR, utilities, event handlers).
|
|
107
|
+
* SolidJS primitives are available as `.createQuery()` and `.createMutation()`.
|
|
108
108
|
*
|
|
109
109
|
* @example
|
|
110
110
|
* ```tsx
|
|
@@ -117,14 +117,16 @@ export type TypedClient<TRouter extends RouterDef> = TRouter extends RouterDef<i
|
|
|
117
117
|
* transport: httpTransport({ url: '/api/lens' }),
|
|
118
118
|
* });
|
|
119
119
|
*
|
|
120
|
+
* // Vanilla JS (anywhere)
|
|
121
|
+
* const user = await client.user.get({ input: { id } });
|
|
122
|
+
*
|
|
120
123
|
* // Component usage
|
|
121
124
|
* function UserProfile(props: { id: string }) {
|
|
122
|
-
* const { data, loading, error } = client.user.get({
|
|
125
|
+
* const { data, loading, error } = client.user.get.createQuery({
|
|
123
126
|
* input: { id: props.id },
|
|
124
|
-
* select: { name: true },
|
|
125
127
|
* });
|
|
126
128
|
*
|
|
127
|
-
* const { mutate, loading: saving } = client.user.update({
|
|
129
|
+
* const { mutate, loading: saving } = client.user.update.createMutation({
|
|
128
130
|
* onSuccess: () => console.log('Updated!'),
|
|
129
131
|
* });
|
|
130
132
|
*
|
package/dist/create.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,14 +15,16 @@
|
|
|
15
15
|
* transport: httpTransport({ url: '/api/lens' }),
|
|
16
16
|
* });
|
|
17
17
|
*
|
|
18
|
-
* //
|
|
19
|
-
* const
|
|
18
|
+
* // Vanilla JS (anywhere - SSR, utilities, event handlers)
|
|
19
|
+
* const user = await client.user.get({ input: { id } });
|
|
20
|
+
* client.user.get({ input: { id } }).subscribe(data => console.log(data));
|
|
20
21
|
*
|
|
21
|
-
* //
|
|
22
|
-
* const
|
|
22
|
+
* // SolidJS primitives (in components)
|
|
23
|
+
* const { data, loading } = client.user.get.createQuery({ input: { id } });
|
|
24
|
+
* const { mutate } = client.user.create.createMutation();
|
|
23
25
|
* ```
|
|
24
26
|
*/
|
|
25
|
-
export { createClient, type MutationEndpoint, type
|
|
27
|
+
export { createClient, type MutationEndpoint, type MutationPrimitiveOptions, type MutationPrimitiveResult, type QueryEndpoint, type QueryPrimitiveOptions, type QueryPrimitiveResult, type TypedClient, } from "./create.js";
|
|
26
28
|
export { LensProvider, type LensProviderProps, useLensClient } from "./context.js";
|
|
27
29
|
export { type CreateLazyQueryResult, type CreateMutationResult, type CreateQueryOptions, type CreateQueryResult, createLazyQuery, createMutation, createQuery, type MutationFn, type QueryInput, } from "./primitives.js";
|
|
28
30
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAMH,OAAO,EACN,YAAY,EACZ,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,WAAW,GAChB,MAAM,aAAa,CAAC;AAMrB,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAMnF,OAAO,EACN,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,eAAe,EAEf,cAAc,EAEd,WAAW,EACX,KAAK,UAAU,EAEf,KAAK,UAAU,GACf,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1051,17 +1051,9 @@ class SubscriptionRegistry {
|
|
|
1051
1051
|
}
|
|
1052
1052
|
|
|
1053
1053
|
// src/create.ts
|
|
1054
|
-
import {
|
|
1055
|
-
function
|
|
1056
|
-
|
|
1057
|
-
const parts = p.split(".");
|
|
1058
|
-
let current = baseClient;
|
|
1059
|
-
for (const part of parts) {
|
|
1060
|
-
current = current[part];
|
|
1061
|
-
}
|
|
1062
|
-
return current;
|
|
1063
|
-
};
|
|
1064
|
-
const useQueryPrimitive = (options) => {
|
|
1054
|
+
import { createSignal, onCleanup } from "solid-js";
|
|
1055
|
+
function createQueryPrimitiveFactory(getEndpoint) {
|
|
1056
|
+
return function createQuery(options) {
|
|
1065
1057
|
const [data, setData] = createSignal(null);
|
|
1066
1058
|
const [loading, setLoading] = createSignal(!options?.skip);
|
|
1067
1059
|
const [error, setError] = createSignal(null);
|
|
@@ -1077,7 +1069,7 @@ function createQueryHook(baseClient, path) {
|
|
|
1077
1069
|
setError(null);
|
|
1078
1070
|
return;
|
|
1079
1071
|
}
|
|
1080
|
-
const endpoint = getEndpoint(
|
|
1072
|
+
const endpoint = getEndpoint();
|
|
1081
1073
|
const query = endpoint({ input: options?.input, select: options?.select });
|
|
1082
1074
|
setLoading(true);
|
|
1083
1075
|
setError(null);
|
|
@@ -1097,10 +1089,6 @@ function createQueryHook(baseClient, path) {
|
|
|
1097
1089
|
});
|
|
1098
1090
|
};
|
|
1099
1091
|
executeQuery();
|
|
1100
|
-
createEffect(() => {
|
|
1101
|
-
const _ = JSON.stringify(options);
|
|
1102
|
-
executeQuery();
|
|
1103
|
-
});
|
|
1104
1092
|
onCleanup(() => {
|
|
1105
1093
|
if (unsubscribe) {
|
|
1106
1094
|
unsubscribe();
|
|
@@ -1114,7 +1102,7 @@ function createQueryHook(baseClient, path) {
|
|
|
1114
1102
|
}
|
|
1115
1103
|
setLoading(true);
|
|
1116
1104
|
setError(null);
|
|
1117
|
-
const endpoint = getEndpoint(
|
|
1105
|
+
const endpoint = getEndpoint();
|
|
1118
1106
|
const query = endpoint({ input: options?.input, select: options?.select });
|
|
1119
1107
|
if (query) {
|
|
1120
1108
|
unsubscribe = query.subscribe((value) => {
|
|
@@ -1134,24 +1122,9 @@ function createQueryHook(baseClient, path) {
|
|
|
1134
1122
|
};
|
|
1135
1123
|
return { data, loading, error, refetch };
|
|
1136
1124
|
};
|
|
1137
|
-
const fetch2 = async (options) => {
|
|
1138
|
-
const endpoint = getEndpoint(path);
|
|
1139
|
-
const queryResult = endpoint({ input: options?.input, select: options?.select });
|
|
1140
|
-
return queryResult.then((data) => data);
|
|
1141
|
-
};
|
|
1142
|
-
useQueryPrimitive.fetch = fetch2;
|
|
1143
|
-
return useQueryPrimitive;
|
|
1144
1125
|
}
|
|
1145
|
-
function
|
|
1146
|
-
|
|
1147
|
-
const parts = p.split(".");
|
|
1148
|
-
let current = baseClient;
|
|
1149
|
-
for (const part of parts) {
|
|
1150
|
-
current = current[part];
|
|
1151
|
-
}
|
|
1152
|
-
return current;
|
|
1153
|
-
};
|
|
1154
|
-
const useMutationPrimitive = (hookOptions) => {
|
|
1126
|
+
function createMutationPrimitiveFactory(getEndpoint) {
|
|
1127
|
+
return function createMutation(primitiveOptions) {
|
|
1155
1128
|
const [data, setData] = createSignal(null);
|
|
1156
1129
|
const [loading, setLoading] = createSignal(false);
|
|
1157
1130
|
const [error, setError] = createSignal(null);
|
|
@@ -1159,20 +1132,19 @@ function createMutationHook(baseClient, path) {
|
|
|
1159
1132
|
setLoading(true);
|
|
1160
1133
|
setError(null);
|
|
1161
1134
|
try {
|
|
1162
|
-
const endpoint = getEndpoint(
|
|
1135
|
+
const endpoint = getEndpoint();
|
|
1163
1136
|
const result = await endpoint({ input: options.input, select: options.select });
|
|
1164
|
-
|
|
1165
|
-
setData(() => mutationResult.data);
|
|
1137
|
+
setData(() => result.data);
|
|
1166
1138
|
setLoading(false);
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
return
|
|
1139
|
+
primitiveOptions?.onSuccess?.(result.data);
|
|
1140
|
+
primitiveOptions?.onSettled?.();
|
|
1141
|
+
return result.data;
|
|
1170
1142
|
} catch (err) {
|
|
1171
1143
|
const mutationError = err instanceof Error ? err : new Error(String(err));
|
|
1172
1144
|
setError(mutationError);
|
|
1173
1145
|
setLoading(false);
|
|
1174
|
-
|
|
1175
|
-
|
|
1146
|
+
primitiveOptions?.onError?.(mutationError);
|
|
1147
|
+
primitiveOptions?.onSettled?.();
|
|
1176
1148
|
throw mutationError;
|
|
1177
1149
|
}
|
|
1178
1150
|
};
|
|
@@ -1183,16 +1155,8 @@ function createMutationHook(baseClient, path) {
|
|
|
1183
1155
|
};
|
|
1184
1156
|
return { mutate, loading, error, data, reset };
|
|
1185
1157
|
};
|
|
1186
|
-
const fetch2 = async (options) => {
|
|
1187
|
-
const endpoint = getEndpoint(path);
|
|
1188
|
-
const result = await endpoint({ input: options.input, select: options.select });
|
|
1189
|
-
const mutationResult = result;
|
|
1190
|
-
return mutationResult.data;
|
|
1191
|
-
};
|
|
1192
|
-
useMutationPrimitive.fetch = fetch2;
|
|
1193
|
-
return useMutationPrimitive;
|
|
1194
1158
|
}
|
|
1195
|
-
var
|
|
1159
|
+
var primitiveCache = new Map;
|
|
1196
1160
|
function createClient2(config) {
|
|
1197
1161
|
const baseClient = createClient(config);
|
|
1198
1162
|
function createProxy(path) {
|
|
@@ -1201,21 +1165,35 @@ function createClient2(config) {
|
|
|
1201
1165
|
if (typeof prop === "symbol")
|
|
1202
1166
|
return;
|
|
1203
1167
|
const key = prop;
|
|
1204
|
-
if (key === "
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
current =
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1168
|
+
if (key === "createQuery") {
|
|
1169
|
+
const cacheKey = `${path}:createQuery`;
|
|
1170
|
+
if (!primitiveCache.has(cacheKey)) {
|
|
1171
|
+
const getEndpoint = () => {
|
|
1172
|
+
const parts = path.split(".");
|
|
1173
|
+
let current = baseClient;
|
|
1174
|
+
for (const part of parts) {
|
|
1175
|
+
current = current[part];
|
|
1176
|
+
}
|
|
1177
|
+
return current;
|
|
1178
|
+
};
|
|
1179
|
+
primitiveCache.set(cacheKey, createQueryPrimitiveFactory(getEndpoint));
|
|
1180
|
+
}
|
|
1181
|
+
return primitiveCache.get(cacheKey);
|
|
1182
|
+
}
|
|
1183
|
+
if (key === "createMutation") {
|
|
1184
|
+
const cacheKey = `${path}:createMutation`;
|
|
1185
|
+
if (!primitiveCache.has(cacheKey)) {
|
|
1186
|
+
const getEndpoint = () => {
|
|
1187
|
+
const parts = path.split(".");
|
|
1188
|
+
let current = baseClient;
|
|
1189
|
+
for (const part of parts) {
|
|
1190
|
+
current = current[part];
|
|
1191
|
+
}
|
|
1192
|
+
return current;
|
|
1193
|
+
};
|
|
1194
|
+
primitiveCache.set(cacheKey, createMutationPrimitiveFactory(getEndpoint));
|
|
1195
|
+
}
|
|
1196
|
+
return primitiveCache.get(cacheKey);
|
|
1219
1197
|
}
|
|
1220
1198
|
if (key === "then")
|
|
1221
1199
|
return;
|
|
@@ -1225,33 +1203,17 @@ function createClient2(config) {
|
|
|
1225
1203
|
return createProxy(newPath);
|
|
1226
1204
|
},
|
|
1227
1205
|
apply(_target, _thisArg, args) {
|
|
1228
|
-
const
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
const cacheKeyMutation = `${path}:mutation`;
|
|
1233
|
-
if (isQueryOptions) {
|
|
1234
|
-
if (!hookCache.has(cacheKeyQuery)) {
|
|
1235
|
-
hookCache.set(cacheKeyQuery, createQueryHook(baseClient, path));
|
|
1236
|
-
}
|
|
1237
|
-
const hook2 = hookCache.get(cacheKeyQuery);
|
|
1238
|
-
return hook2(options);
|
|
1239
|
-
}
|
|
1240
|
-
if (isMutationOptions) {
|
|
1241
|
-
if (!hookCache.has(cacheKeyMutation)) {
|
|
1242
|
-
hookCache.set(cacheKeyMutation, createMutationHook(baseClient, path));
|
|
1243
|
-
}
|
|
1244
|
-
const hook2 = hookCache.get(cacheKeyMutation);
|
|
1245
|
-
return hook2(options);
|
|
1246
|
-
}
|
|
1247
|
-
if (!hookCache.has(cacheKeyQuery)) {
|
|
1248
|
-
hookCache.set(cacheKeyQuery, createQueryHook(baseClient, path));
|
|
1206
|
+
const parts = path.split(".");
|
|
1207
|
+
let current = baseClient;
|
|
1208
|
+
for (const part of parts) {
|
|
1209
|
+
current = current[part];
|
|
1249
1210
|
}
|
|
1250
|
-
const
|
|
1251
|
-
return
|
|
1211
|
+
const endpoint = current;
|
|
1212
|
+
return endpoint(args[0]);
|
|
1252
1213
|
}
|
|
1253
1214
|
};
|
|
1254
|
-
|
|
1215
|
+
const proxy = new Proxy(() => {}, handler);
|
|
1216
|
+
return proxy;
|
|
1255
1217
|
}
|
|
1256
1218
|
return createProxy("");
|
|
1257
1219
|
}
|
|
@@ -1271,7 +1233,7 @@ function useLensClient() {
|
|
|
1271
1233
|
return client;
|
|
1272
1234
|
}
|
|
1273
1235
|
// src/primitives.ts
|
|
1274
|
-
import { createEffect
|
|
1236
|
+
import { createEffect, createSignal as createSignal2, onCleanup as onCleanup2 } from "solid-js";
|
|
1275
1237
|
function resolveQuery(input) {
|
|
1276
1238
|
return typeof input === "function" ? input() : input;
|
|
1277
1239
|
}
|
|
@@ -1310,7 +1272,7 @@ function createQuery(queryInput, options) {
|
|
|
1310
1272
|
};
|
|
1311
1273
|
const initialQuery = resolveQuery(queryInput);
|
|
1312
1274
|
executeQuery(initialQuery);
|
|
1313
|
-
|
|
1275
|
+
createEffect(() => {
|
|
1314
1276
|
const queryResult = resolveQuery(queryInput);
|
|
1315
1277
|
if (queryResult !== initialQuery) {
|
|
1316
1278
|
executeQuery(queryResult);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sylphx/lens-solid",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "SolidJS bindings for Lens API framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"author": "SylphxAI",
|
|
32
32
|
"license": "MIT",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@sylphx/lens-client": "^2.2.
|
|
35
|
-
"@sylphx/lens-core": "^2.
|
|
34
|
+
"@sylphx/lens-client": "^2.2.1",
|
|
35
|
+
"@sylphx/lens-core": "^2.2.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"solid-js": ">=1.8.0"
|
package/src/create.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @sylphx/lens-solid - Create Client
|
|
3
3
|
*
|
|
4
4
|
* Creates a typed Lens client with SolidJS primitives.
|
|
5
|
-
*
|
|
5
|
+
* Base client methods work in vanilla JS, primitives are extensions.
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
8
8
|
* ```tsx
|
|
@@ -15,11 +15,13 @@
|
|
|
15
15
|
* transport: httpTransport({ url: '/api/lens' }),
|
|
16
16
|
* });
|
|
17
17
|
*
|
|
18
|
-
* //
|
|
19
|
-
* const
|
|
18
|
+
* // Vanilla JS (anywhere - SSR, utilities, event handlers)
|
|
19
|
+
* const user = await client.user.get({ input: { id } });
|
|
20
|
+
* client.user.get({ input: { id } }).subscribe(data => console.log(data));
|
|
20
21
|
*
|
|
21
|
-
* //
|
|
22
|
-
* const
|
|
22
|
+
* // SolidJS primitives (in components)
|
|
23
|
+
* const { data, loading } = client.user.get.createQuery({ input: { id } });
|
|
24
|
+
* const { mutate, loading } = client.user.create.createMutation();
|
|
23
25
|
* ```
|
|
24
26
|
*/
|
|
25
27
|
|
|
@@ -31,14 +33,14 @@ import {
|
|
|
31
33
|
type TypedClientConfig,
|
|
32
34
|
} from "@sylphx/lens-client";
|
|
33
35
|
import type { MutationDef, QueryDef, RouterDef, RouterRoutes } from "@sylphx/lens-core";
|
|
34
|
-
import { type Accessor,
|
|
36
|
+
import { type Accessor, createSignal, onCleanup } from "solid-js";
|
|
35
37
|
|
|
36
38
|
// =============================================================================
|
|
37
39
|
// Types
|
|
38
40
|
// =============================================================================
|
|
39
41
|
|
|
40
|
-
/** Query
|
|
41
|
-
export interface
|
|
42
|
+
/** Query primitive options */
|
|
43
|
+
export interface QueryPrimitiveOptions<TInput> {
|
|
42
44
|
/** Query input parameters */
|
|
43
45
|
input?: TInput;
|
|
44
46
|
/** Field selection */
|
|
@@ -47,8 +49,8 @@ export interface QueryHookOptions<TInput> {
|
|
|
47
49
|
skip?: boolean;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
/** Query
|
|
51
|
-
export interface
|
|
52
|
+
/** Query primitive result */
|
|
53
|
+
export interface QueryPrimitiveResult<T> {
|
|
52
54
|
/** Reactive data accessor */
|
|
53
55
|
data: Accessor<T | null>;
|
|
54
56
|
/** Reactive loading state */
|
|
@@ -59,8 +61,8 @@ export interface QueryHookResult<T> {
|
|
|
59
61
|
refetch: () => void;
|
|
60
62
|
}
|
|
61
63
|
|
|
62
|
-
/** Mutation
|
|
63
|
-
export interface
|
|
64
|
+
/** Mutation primitive options */
|
|
65
|
+
export interface MutationPrimitiveOptions<TOutput> {
|
|
64
66
|
/** Called on successful mutation */
|
|
65
67
|
onSuccess?: (data: TOutput) => void;
|
|
66
68
|
/** Called on mutation error */
|
|
@@ -69,8 +71,8 @@ export interface MutationHookOptions<TOutput> {
|
|
|
69
71
|
onSettled?: () => void;
|
|
70
72
|
}
|
|
71
73
|
|
|
72
|
-
/** Mutation
|
|
73
|
-
export interface
|
|
74
|
+
/** Mutation primitive result */
|
|
75
|
+
export interface MutationPrimitiveResult<TInput, TOutput> {
|
|
74
76
|
/** Execute the mutation */
|
|
75
77
|
mutate: (options: { input: TInput; select?: SelectionObject }) => Promise<TOutput>;
|
|
76
78
|
/** Reactive loading state */
|
|
@@ -83,31 +85,28 @@ export interface MutationHookResult<TInput, TOutput> {
|
|
|
83
85
|
reset: () => void;
|
|
84
86
|
}
|
|
85
87
|
|
|
86
|
-
/** Query endpoint
|
|
88
|
+
/** Query endpoint with SolidJS primitives */
|
|
87
89
|
export interface QueryEndpoint<TInput, TOutput> {
|
|
88
|
-
/**
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
: { input: TInput; select?: TSelect },
|
|
98
|
-
) => Promise<TOutput>;
|
|
90
|
+
/** Vanilla JS call - returns QueryResult (Promise + Observable) */
|
|
91
|
+
(options?: { input?: TInput; select?: SelectionObject }): QueryResult<TOutput>;
|
|
92
|
+
|
|
93
|
+
/** SolidJS primitive for reactive queries */
|
|
94
|
+
createQuery: (
|
|
95
|
+
options?: TInput extends void
|
|
96
|
+
? QueryPrimitiveOptions<void> | void
|
|
97
|
+
: QueryPrimitiveOptions<TInput>,
|
|
98
|
+
) => QueryPrimitiveResult<TOutput>;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
/** Mutation endpoint
|
|
101
|
+
/** Mutation endpoint with SolidJS primitives */
|
|
102
102
|
export interface MutationEndpoint<TInput, TOutput> {
|
|
103
|
-
/**
|
|
104
|
-
(options?:
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}) => Promise<TOutput>;
|
|
103
|
+
/** Vanilla JS call - returns Promise */
|
|
104
|
+
(options: { input: TInput; select?: SelectionObject }): Promise<{ data: TOutput }>;
|
|
105
|
+
|
|
106
|
+
/** SolidJS primitive for mutations */
|
|
107
|
+
createMutation: (
|
|
108
|
+
options?: MutationPrimitiveOptions<TOutput>,
|
|
109
|
+
) => MutationPrimitiveResult<TInput, TOutput>;
|
|
111
110
|
}
|
|
112
111
|
|
|
113
112
|
/** Infer client type from router routes */
|
|
@@ -126,26 +125,18 @@ export type TypedClient<TRouter extends RouterDef> =
|
|
|
126
125
|
TRouter extends RouterDef<infer TRoutes> ? InferTypedClient<TRoutes> : never;
|
|
127
126
|
|
|
128
127
|
// =============================================================================
|
|
129
|
-
//
|
|
128
|
+
// Primitive Factories
|
|
130
129
|
// =============================================================================
|
|
131
130
|
|
|
132
131
|
/**
|
|
133
|
-
* Create
|
|
132
|
+
* Create createQuery primitive for a specific endpoint
|
|
134
133
|
*/
|
|
135
|
-
function
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
let current: unknown = baseClient;
|
|
142
|
-
for (const part of parts) {
|
|
143
|
-
current = (current as Record<string, unknown>)[part];
|
|
144
|
-
}
|
|
145
|
-
return current as (options: unknown) => QueryResult<TOutput>;
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
const useQueryPrimitive = (options?: QueryHookOptions<TInput>): QueryHookResult<TOutput> => {
|
|
134
|
+
function createQueryPrimitiveFactory<TInput, TOutput>(
|
|
135
|
+
getEndpoint: () => (options: unknown) => QueryResult<TOutput>,
|
|
136
|
+
) {
|
|
137
|
+
return function createQuery(
|
|
138
|
+
options?: QueryPrimitiveOptions<TInput>,
|
|
139
|
+
): QueryPrimitiveResult<TOutput> {
|
|
149
140
|
const [data, setData] = createSignal<TOutput | null>(null);
|
|
150
141
|
const [loading, setLoading] = createSignal(!options?.skip);
|
|
151
142
|
const [error, setError] = createSignal<Error | null>(null);
|
|
@@ -165,7 +156,7 @@ function createQueryHook<TInput, TOutput>(
|
|
|
165
156
|
return;
|
|
166
157
|
}
|
|
167
158
|
|
|
168
|
-
const endpoint = getEndpoint(
|
|
159
|
+
const endpoint = getEndpoint();
|
|
169
160
|
const query = endpoint({ input: options?.input, select: options?.select });
|
|
170
161
|
|
|
171
162
|
setLoading(true);
|
|
@@ -191,16 +182,9 @@ function createQueryHook<TInput, TOutput>(
|
|
|
191
182
|
);
|
|
192
183
|
};
|
|
193
184
|
|
|
194
|
-
// Execute initial query
|
|
185
|
+
// Execute initial query
|
|
195
186
|
executeQuery();
|
|
196
187
|
|
|
197
|
-
// Use createEffect for reactive updates when options change
|
|
198
|
-
createEffect(() => {
|
|
199
|
-
// Access options to track them (Solid will re-run when they change)
|
|
200
|
-
const _ = JSON.stringify(options);
|
|
201
|
-
executeQuery();
|
|
202
|
-
});
|
|
203
|
-
|
|
204
188
|
onCleanup(() => {
|
|
205
189
|
if (unsubscribe) {
|
|
206
190
|
unsubscribe();
|
|
@@ -215,7 +199,7 @@ function createQueryHook<TInput, TOutput>(
|
|
|
215
199
|
}
|
|
216
200
|
setLoading(true);
|
|
217
201
|
setError(null);
|
|
218
|
-
const endpoint = getEndpoint(
|
|
202
|
+
const endpoint = getEndpoint();
|
|
219
203
|
const query = endpoint({ input: options?.input, select: options?.select });
|
|
220
204
|
if (query) {
|
|
221
205
|
unsubscribe = query.subscribe((value) => {
|
|
@@ -239,42 +223,17 @@ function createQueryHook<TInput, TOutput>(
|
|
|
239
223
|
|
|
240
224
|
return { data, loading, error, refetch };
|
|
241
225
|
};
|
|
242
|
-
|
|
243
|
-
// Fetch method for promises (SSR)
|
|
244
|
-
const fetch = async (options?: {
|
|
245
|
-
input?: TInput;
|
|
246
|
-
select?: SelectionObject;
|
|
247
|
-
}): Promise<TOutput> => {
|
|
248
|
-
const endpoint = getEndpoint(path);
|
|
249
|
-
const queryResult = endpoint({ input: options?.input, select: options?.select });
|
|
250
|
-
return queryResult.then((data) => data);
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
// Attach fetch method to the hook function
|
|
254
|
-
useQueryPrimitive.fetch = fetch;
|
|
255
|
-
|
|
256
|
-
return useQueryPrimitive as unknown as QueryEndpoint<TInput, TOutput>;
|
|
257
226
|
}
|
|
258
227
|
|
|
259
228
|
/**
|
|
260
|
-
* Create
|
|
229
|
+
* Create createMutation primitive for a specific endpoint
|
|
261
230
|
*/
|
|
262
|
-
function
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
let current: unknown = baseClient;
|
|
269
|
-
for (const part of parts) {
|
|
270
|
-
current = (current as Record<string, unknown>)[part];
|
|
271
|
-
}
|
|
272
|
-
return current as (options: unknown) => QueryResult<{ data: TOutput }>;
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
const useMutationPrimitive = (
|
|
276
|
-
hookOptions?: MutationHookOptions<TOutput>,
|
|
277
|
-
): MutationHookResult<TInput, TOutput> => {
|
|
231
|
+
function createMutationPrimitiveFactory<TInput, TOutput>(
|
|
232
|
+
getEndpoint: () => (options: unknown) => Promise<{ data: TOutput }>,
|
|
233
|
+
) {
|
|
234
|
+
return function createMutation(
|
|
235
|
+
primitiveOptions?: MutationPrimitiveOptions<TOutput>,
|
|
236
|
+
): MutationPrimitiveResult<TInput, TOutput> {
|
|
278
237
|
const [data, setData] = createSignal<TOutput | null>(null);
|
|
279
238
|
const [loading, setLoading] = createSignal(false);
|
|
280
239
|
const [error, setError] = createSignal<Error | null>(null);
|
|
@@ -287,24 +246,23 @@ function createMutationHook<TInput, TOutput>(
|
|
|
287
246
|
setError(null);
|
|
288
247
|
|
|
289
248
|
try {
|
|
290
|
-
const endpoint = getEndpoint(
|
|
249
|
+
const endpoint = getEndpoint();
|
|
291
250
|
const result = await endpoint({ input: options.input, select: options.select });
|
|
292
|
-
const mutationResult = result as unknown as { data: TOutput };
|
|
293
251
|
|
|
294
|
-
setData(() =>
|
|
252
|
+
setData(() => result.data);
|
|
295
253
|
setLoading(false);
|
|
296
254
|
|
|
297
|
-
|
|
298
|
-
|
|
255
|
+
primitiveOptions?.onSuccess?.(result.data);
|
|
256
|
+
primitiveOptions?.onSettled?.();
|
|
299
257
|
|
|
300
|
-
return
|
|
258
|
+
return result.data;
|
|
301
259
|
} catch (err) {
|
|
302
260
|
const mutationError = err instanceof Error ? err : new Error(String(err));
|
|
303
261
|
setError(mutationError);
|
|
304
262
|
setLoading(false);
|
|
305
263
|
|
|
306
|
-
|
|
307
|
-
|
|
264
|
+
primitiveOptions?.onError?.(mutationError);
|
|
265
|
+
primitiveOptions?.onSettled?.();
|
|
308
266
|
|
|
309
267
|
throw mutationError;
|
|
310
268
|
}
|
|
@@ -318,34 +276,20 @@ function createMutationHook<TInput, TOutput>(
|
|
|
318
276
|
|
|
319
277
|
return { mutate, loading, error, data, reset };
|
|
320
278
|
};
|
|
321
|
-
|
|
322
|
-
// Fetch method for promises (SSR)
|
|
323
|
-
const fetch = async (options: { input: TInput; select?: SelectionObject }): Promise<TOutput> => {
|
|
324
|
-
const endpoint = getEndpoint(path);
|
|
325
|
-
const result = await endpoint({ input: options.input, select: options.select });
|
|
326
|
-
const mutationResult = result as unknown as { data: TOutput };
|
|
327
|
-
return mutationResult.data;
|
|
328
|
-
};
|
|
329
|
-
|
|
330
|
-
// Attach fetch method to the hook function
|
|
331
|
-
useMutationPrimitive.fetch = fetch;
|
|
332
|
-
|
|
333
|
-
return useMutationPrimitive as unknown as MutationEndpoint<TInput, TOutput>;
|
|
334
279
|
}
|
|
335
280
|
|
|
336
281
|
// =============================================================================
|
|
337
282
|
// Create Client
|
|
338
283
|
// =============================================================================
|
|
339
284
|
|
|
340
|
-
// Cache for
|
|
341
|
-
const
|
|
285
|
+
// Cache for primitive functions to ensure stable references
|
|
286
|
+
const primitiveCache = new Map<string, unknown>();
|
|
342
287
|
|
|
343
288
|
/**
|
|
344
289
|
* Create a Lens client with SolidJS primitives.
|
|
345
290
|
*
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
* - Via .fetch() for promises: `await client.user.get.fetch({ input: { id } })`
|
|
291
|
+
* Base client methods work in vanilla JS (SSR, utilities, event handlers).
|
|
292
|
+
* SolidJS primitives are available as `.createQuery()` and `.createMutation()`.
|
|
349
293
|
*
|
|
350
294
|
* @example
|
|
351
295
|
* ```tsx
|
|
@@ -358,14 +302,16 @@ const hookCache = new Map<string, unknown>();
|
|
|
358
302
|
* transport: httpTransport({ url: '/api/lens' }),
|
|
359
303
|
* });
|
|
360
304
|
*
|
|
305
|
+
* // Vanilla JS (anywhere)
|
|
306
|
+
* const user = await client.user.get({ input: { id } });
|
|
307
|
+
*
|
|
361
308
|
* // Component usage
|
|
362
309
|
* function UserProfile(props: { id: string }) {
|
|
363
|
-
* const { data, loading, error } = client.user.get({
|
|
310
|
+
* const { data, loading, error } = client.user.get.createQuery({
|
|
364
311
|
* input: { id: props.id },
|
|
365
|
-
* select: { name: true },
|
|
366
312
|
* });
|
|
367
313
|
*
|
|
368
|
-
* const { mutate, loading: saving } = client.user.update({
|
|
314
|
+
* const { mutate, loading: saving } = client.user.update.createMutation({
|
|
369
315
|
* onSuccess: () => console.log('Updated!'),
|
|
370
316
|
* });
|
|
371
317
|
*
|
|
@@ -386,6 +332,7 @@ const hookCache = new Map<string, unknown>();
|
|
|
386
332
|
export function createClient<TRouter extends RouterDef>(
|
|
387
333
|
config: LensClientConfig | TypedClientConfig<{ router: TRouter }>,
|
|
388
334
|
): TypedClient<TRouter> {
|
|
335
|
+
// Create base client for transport
|
|
389
336
|
const baseClient = createBaseClient(config as LensClientConfig);
|
|
390
337
|
|
|
391
338
|
function createProxy(path: string): unknown {
|
|
@@ -394,27 +341,38 @@ export function createClient<TRouter extends RouterDef>(
|
|
|
394
341
|
if (typeof prop === "symbol") return undefined;
|
|
395
342
|
const key = prop as string;
|
|
396
343
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
344
|
+
// Handle .createQuery() - SolidJS primitive for queries
|
|
345
|
+
if (key === "createQuery") {
|
|
346
|
+
const cacheKey = `${path}:createQuery`;
|
|
347
|
+
if (!primitiveCache.has(cacheKey)) {
|
|
348
|
+
const getEndpoint = () => {
|
|
349
|
+
const parts = path.split(".");
|
|
350
|
+
let current: unknown = baseClient;
|
|
351
|
+
for (const part of parts) {
|
|
352
|
+
current = (current as Record<string, unknown>)[part];
|
|
353
|
+
}
|
|
354
|
+
return current as (options: unknown) => QueryResult<unknown>;
|
|
355
|
+
};
|
|
356
|
+
primitiveCache.set(cacheKey, createQueryPrimitiveFactory(getEndpoint));
|
|
357
|
+
}
|
|
358
|
+
return primitiveCache.get(cacheKey);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Handle .createMutation() - SolidJS primitive for mutations
|
|
362
|
+
if (key === "createMutation") {
|
|
363
|
+
const cacheKey = `${path}:createMutation`;
|
|
364
|
+
if (!primitiveCache.has(cacheKey)) {
|
|
365
|
+
const getEndpoint = () => {
|
|
366
|
+
const parts = path.split(".");
|
|
367
|
+
let current: unknown = baseClient;
|
|
368
|
+
for (const part of parts) {
|
|
369
|
+
current = (current as Record<string, unknown>)[part];
|
|
370
|
+
}
|
|
371
|
+
return current as (options: unknown) => Promise<{ data: unknown }>;
|
|
372
|
+
};
|
|
373
|
+
primitiveCache.set(cacheKey, createMutationPrimitiveFactory(getEndpoint));
|
|
374
|
+
}
|
|
375
|
+
return primitiveCache.get(cacheKey);
|
|
418
376
|
}
|
|
419
377
|
|
|
420
378
|
if (key === "then") return undefined;
|
|
@@ -425,47 +383,19 @@ export function createClient<TRouter extends RouterDef>(
|
|
|
425
383
|
},
|
|
426
384
|
|
|
427
385
|
apply(_target, _thisArg, args) {
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
const isMutationOptions =
|
|
434
|
-
!options ||
|
|
435
|
-
(!isQueryOptions &&
|
|
436
|
-
(Object.keys(options).length === 0 ||
|
|
437
|
-
"onSuccess" in options ||
|
|
438
|
-
"onError" in options ||
|
|
439
|
-
"onSettled" in options));
|
|
440
|
-
|
|
441
|
-
const cacheKeyQuery = `${path}:query`;
|
|
442
|
-
const cacheKeyMutation = `${path}:mutation`;
|
|
443
|
-
|
|
444
|
-
if (isQueryOptions) {
|
|
445
|
-
if (!hookCache.has(cacheKeyQuery)) {
|
|
446
|
-
hookCache.set(cacheKeyQuery, createQueryHook(baseClient, path));
|
|
447
|
-
}
|
|
448
|
-
const hook = hookCache.get(cacheKeyQuery) as (opts: unknown) => unknown;
|
|
449
|
-
return hook(options);
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
if (isMutationOptions) {
|
|
453
|
-
if (!hookCache.has(cacheKeyMutation)) {
|
|
454
|
-
hookCache.set(cacheKeyMutation, createMutationHook(baseClient, path));
|
|
455
|
-
}
|
|
456
|
-
const hook = hookCache.get(cacheKeyMutation) as (opts: unknown) => unknown;
|
|
457
|
-
return hook(options);
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
if (!hookCache.has(cacheKeyQuery)) {
|
|
461
|
-
hookCache.set(cacheKeyQuery, createQueryHook(baseClient, path));
|
|
386
|
+
// Direct call - delegate to base client (returns QueryResult or Promise)
|
|
387
|
+
const parts = path.split(".");
|
|
388
|
+
let current: unknown = baseClient;
|
|
389
|
+
for (const part of parts) {
|
|
390
|
+
current = (current as Record<string, unknown>)[part];
|
|
462
391
|
}
|
|
463
|
-
const
|
|
464
|
-
return
|
|
392
|
+
const endpoint = current as (options: unknown) => unknown;
|
|
393
|
+
return endpoint(args[0]);
|
|
465
394
|
},
|
|
466
395
|
};
|
|
467
396
|
|
|
468
|
-
|
|
397
|
+
const proxy = new Proxy((() => {}) as (...args: unknown[]) => unknown, handler);
|
|
398
|
+
return proxy;
|
|
469
399
|
}
|
|
470
400
|
|
|
471
401
|
return createProxy("") as TypedClient<TRouter>;
|
package/src/index.ts
CHANGED
|
@@ -15,11 +15,13 @@
|
|
|
15
15
|
* transport: httpTransport({ url: '/api/lens' }),
|
|
16
16
|
* });
|
|
17
17
|
*
|
|
18
|
-
* //
|
|
19
|
-
* const
|
|
18
|
+
* // Vanilla JS (anywhere - SSR, utilities, event handlers)
|
|
19
|
+
* const user = await client.user.get({ input: { id } });
|
|
20
|
+
* client.user.get({ input: { id } }).subscribe(data => console.log(data));
|
|
20
21
|
*
|
|
21
|
-
* //
|
|
22
|
-
* const
|
|
22
|
+
* // SolidJS primitives (in components)
|
|
23
|
+
* const { data, loading } = client.user.get.createQuery({ input: { id } });
|
|
24
|
+
* const { mutate } = client.user.create.createMutation();
|
|
23
25
|
* ```
|
|
24
26
|
*/
|
|
25
27
|
|
|
@@ -30,11 +32,11 @@
|
|
|
30
32
|
export {
|
|
31
33
|
createClient,
|
|
32
34
|
type MutationEndpoint,
|
|
33
|
-
type
|
|
34
|
-
type
|
|
35
|
+
type MutationPrimitiveOptions,
|
|
36
|
+
type MutationPrimitiveResult,
|
|
35
37
|
type QueryEndpoint,
|
|
36
|
-
type
|
|
37
|
-
type
|
|
38
|
+
type QueryPrimitiveOptions,
|
|
39
|
+
type QueryPrimitiveResult,
|
|
38
40
|
type TypedClient,
|
|
39
41
|
} from "./create.js";
|
|
40
42
|
|