@sylphx/lens-solid 2.0.5 → 2.1.1

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/README.md CHANGED
@@ -1,31 +1,80 @@
1
1
  # @sylphx/lens-solid
2
2
 
3
- Solid.js primitives for the Lens API framework.
3
+ SolidJS primitives for the Lens API framework.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- bun add @sylphx/lens-solid
8
+ bun add @sylphx/lens-solid @sylphx/lens-client
9
9
  ```
10
10
 
11
11
  ## Usage
12
12
 
13
+ ### Setup Client
14
+
13
15
  ```typescript
14
- import { createQuery, createMutation } from "@sylphx/lens-solid";
15
- import { client } from "./client";
16
+ // lib/client.ts
17
+ import { createClient } from "@sylphx/lens-solid";
18
+ import { http } from "@sylphx/lens-client";
19
+ import type { AppRouter } from "@/server/router";
20
+
21
+ export const client = createClient<AppRouter>({
22
+ transport: http({ url: "/api/lens" }),
23
+ });
24
+ ```
25
+
26
+ ### Query (in component)
27
+
28
+ ```tsx
29
+ import { client } from "@/lib/client";
30
+ import { Show } from "solid-js";
16
31
 
17
- function UserProfile() {
18
- const user = createQuery(() => client.user.get({ id: "1" }));
19
- const createUser = createMutation(client.user.create);
32
+ function UserProfile(props: { id: string }) {
33
+ const { data, loading, error, refetch } = client.user.get({
34
+ input: { id: props.id },
35
+ select: { name: true, email: true },
36
+ });
20
37
 
21
38
  return (
22
- <Show when={!user.loading} fallback={<div>Loading...</div>}>
23
- <div>{user.data?.name}</div>
39
+ <Show when={!loading()} fallback={<div>Loading...</div>}>
40
+ <Show when={!error()} fallback={<div>Error: {error()?.message}</div>}>
41
+ <div>{data()?.name}</div>
42
+ </Show>
24
43
  </Show>
25
44
  );
26
45
  }
27
46
  ```
28
47
 
48
+ ### Mutation (in component)
49
+
50
+ ```tsx
51
+ import { client } from "@/lib/client";
52
+
53
+ function CreateUser() {
54
+ const { mutate, loading, error, data, reset } = client.user.create({
55
+ onSuccess: (data) => console.log("Created:", data),
56
+ onError: (error) => console.error("Failed:", error),
57
+ });
58
+
59
+ const handleSubmit = async () => {
60
+ await mutate({ input: { name: "New User" } });
61
+ };
62
+
63
+ return (
64
+ <button onClick={handleSubmit} disabled={loading()}>
65
+ {loading() ? "Creating..." : "Create User"}
66
+ </button>
67
+ );
68
+ }
69
+ ```
70
+
71
+ ### SSR / Server-side
72
+
73
+ ```typescript
74
+ // Use .fetch() for promise-based calls
75
+ const user = await client.user.get.fetch({ input: { id } });
76
+ ```
77
+
29
78
  ## License
30
79
 
31
80
  MIT
@@ -34,4 +83,4 @@ MIT
34
83
 
35
84
  Built with [@sylphx/lens-client](https://github.com/SylphxAI/Lens).
36
85
 
37
- Powered by Sylphx
86
+ Powered by Sylphx
@@ -0,0 +1,149 @@
1
+ /**
2
+ * @sylphx/lens-solid - Create Client
3
+ *
4
+ * Creates a typed Lens client with SolidJS primitives.
5
+ * Each endpoint can be called directly as a primitive or via .fetch() for promises.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * // lib/client.ts
10
+ * import { createClient } from '@sylphx/lens-solid';
11
+ * import { httpTransport } from '@sylphx/lens-client';
12
+ * import type { AppRouter } from '@/server/router';
13
+ *
14
+ * export const client = createClient<AppRouter>({
15
+ * transport: httpTransport({ url: '/api/lens' }),
16
+ * });
17
+ *
18
+ * // In component
19
+ * const { data, loading } = client.user.get({ input: { id } });
20
+ *
21
+ * // In SSR
22
+ * const user = await client.user.get.fetch({ input: { id } });
23
+ * ```
24
+ */
25
+ import { type LensClientConfig, type SelectionObject, type TypedClientConfig } from "@sylphx/lens-client";
26
+ import type { MutationDef, QueryDef, RouterDef, RouterRoutes } from "@sylphx/lens-core";
27
+ import { type Accessor } from "solid-js";
28
+ /** Query hook options */
29
+ export interface QueryHookOptions<TInput> {
30
+ /** Query input parameters */
31
+ input?: TInput;
32
+ /** Field selection */
33
+ select?: SelectionObject;
34
+ /** Skip query execution */
35
+ skip?: boolean;
36
+ }
37
+ /** Query hook result */
38
+ export interface QueryHookResult<T> {
39
+ /** Reactive data accessor */
40
+ data: Accessor<T | null>;
41
+ /** Reactive loading state */
42
+ loading: Accessor<boolean>;
43
+ /** Reactive error state */
44
+ error: Accessor<Error | null>;
45
+ /** Refetch the query */
46
+ refetch: () => void;
47
+ }
48
+ /** Mutation hook options */
49
+ export interface MutationHookOptions<TOutput> {
50
+ /** Called on successful mutation */
51
+ onSuccess?: (data: TOutput) => void;
52
+ /** Called on mutation error */
53
+ onError?: (error: Error) => void;
54
+ /** Called when mutation settles (success or error) */
55
+ onSettled?: () => void;
56
+ }
57
+ /** Mutation hook result */
58
+ export interface MutationHookResult<TInput, TOutput> {
59
+ /** Execute the mutation */
60
+ mutate: (options: {
61
+ input: TInput;
62
+ select?: SelectionObject;
63
+ }) => Promise<TOutput>;
64
+ /** Reactive loading state */
65
+ loading: Accessor<boolean>;
66
+ /** Reactive error state */
67
+ error: Accessor<Error | null>;
68
+ /** Reactive last mutation result */
69
+ data: Accessor<TOutput | null>;
70
+ /** Reset mutation state */
71
+ reset: () => void;
72
+ }
73
+ /** Query endpoint type */
74
+ export interface QueryEndpoint<TInput, TOutput> {
75
+ /** Primitive call (in component) */
76
+ <_TSelect extends SelectionObject = Record<string, never>>(options: TInput extends void ? QueryHookOptions<void> | void : QueryHookOptions<TInput>): QueryHookResult<TOutput>;
77
+ /** Promise call (SSR) */
78
+ fetch: <TSelect extends SelectionObject = Record<string, never>>(options: TInput extends void ? {
79
+ input?: void;
80
+ select?: TSelect;
81
+ } | void : {
82
+ input: TInput;
83
+ select?: TSelect;
84
+ }) => Promise<TOutput>;
85
+ }
86
+ /** Mutation endpoint type */
87
+ export interface MutationEndpoint<TInput, TOutput> {
88
+ /** Primitive call (in component) */
89
+ (options?: MutationHookOptions<TOutput>): MutationHookResult<TInput, TOutput>;
90
+ /** Promise call (SSR) */
91
+ fetch: <TSelect extends SelectionObject = Record<string, never>>(options: {
92
+ input: TInput;
93
+ select?: TSelect;
94
+ }) => Promise<TOutput>;
95
+ }
96
+ /** Infer client type from router routes */
97
+ type InferTypedClient<TRoutes extends RouterRoutes> = {
98
+ [K in keyof TRoutes]: TRoutes[K] extends RouterDef<infer TNestedRoutes> ? InferTypedClient<TNestedRoutes> : TRoutes[K] extends QueryDef<infer TInput, infer TOutput> ? QueryEndpoint<TInput, TOutput> : TRoutes[K] extends MutationDef<infer TInput, infer TOutput> ? MutationEndpoint<TInput, TOutput> : never;
99
+ };
100
+ /** Typed client from router */
101
+ export type TypedClient<TRouter extends RouterDef> = TRouter extends RouterDef<infer TRoutes> ? InferTypedClient<TRoutes> : never;
102
+ /**
103
+ * Create a Lens client with SolidJS primitives.
104
+ *
105
+ * Each endpoint can be called:
106
+ * - Directly as a primitive: `client.user.get({ input: { id } })`
107
+ * - Via .fetch() for promises: `await client.user.get.fetch({ input: { id } })`
108
+ *
109
+ * @example
110
+ * ```tsx
111
+ * // lib/client.ts
112
+ * import { createClient } from '@sylphx/lens-solid';
113
+ * import { httpTransport } from '@sylphx/lens-client';
114
+ * import type { AppRouter } from '@/server/router';
115
+ *
116
+ * export const client = createClient<AppRouter>({
117
+ * transport: httpTransport({ url: '/api/lens' }),
118
+ * });
119
+ *
120
+ * // Component usage
121
+ * function UserProfile(props: { id: string }) {
122
+ * const { data, loading, error } = client.user.get({
123
+ * input: { id: props.id },
124
+ * select: { name: true },
125
+ * });
126
+ *
127
+ * const { mutate, loading: saving } = client.user.update({
128
+ * onSuccess: () => console.log('Updated!'),
129
+ * });
130
+ *
131
+ * return (
132
+ * <Show when={!loading()} fallback={<Spinner />}>
133
+ * <h1>{data()?.name}</h1>
134
+ * <button
135
+ * onClick={() => mutate({ input: { id: props.id, name: 'New' } })}
136
+ * disabled={saving()}
137
+ * >
138
+ * Update
139
+ * </button>
140
+ * </Show>
141
+ * );
142
+ * }
143
+ * ```
144
+ */
145
+ export declare function createClient<TRouter extends RouterDef>(config: LensClientConfig | TypedClientConfig<{
146
+ router: TRouter;
147
+ }>): TypedClient<TRouter>;
148
+ export {};
149
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,7 +3,26 @@
3
3
  *
4
4
  * SolidJS bindings for Lens API framework.
5
5
  * Reactive primitives that integrate with SolidJS fine-grained reactivity.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * // lib/client.ts
10
+ * import { createClient } from '@sylphx/lens-solid';
11
+ * import { httpTransport } from '@sylphx/lens-client';
12
+ * import type { AppRouter } from '@/server/router';
13
+ *
14
+ * export const client = createClient<AppRouter>({
15
+ * transport: httpTransport({ url: '/api/lens' }),
16
+ * });
17
+ *
18
+ * // Component usage
19
+ * const { data, loading } = client.user.get({ input: { id } });
20
+ *
21
+ * // SSR usage
22
+ * const user = await client.user.get.fetch({ input: { id } });
23
+ * ```
6
24
  */
25
+ export { createClient, type MutationEndpoint, type MutationHookOptions, type MutationHookResult, type QueryEndpoint, type QueryHookOptions, type QueryHookResult, type TypedClient, } from "./create.js";
7
26
  export { LensProvider, type LensProviderProps, useLensClient } from "./context.js";
8
27
  export { type CreateLazyQueryResult, type CreateMutationResult, type CreateQueryOptions, type CreateQueryResult, createLazyQuery, createMutation, createQuery, type MutationFn, type QueryInput, } from "./primitives.js";
9
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,OAAO,EACN,YAAY,EACZ,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,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"}