@sylphx/lens-react 1.2.5 → 1.2.7

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 ADDED
@@ -0,0 +1,44 @@
1
+ # @sylphx/lens-react
2
+
3
+ React hooks for the Lens API framework.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @sylphx/lens-react
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { LensProvider, useQuery, useMutation } from "@sylphx/lens-react";
15
+ import { client } from "./client";
16
+
17
+ function App() {
18
+ return (
19
+ <LensProvider client={client}>
20
+ <UserProfile />
21
+ </LensProvider>
22
+ );
23
+ }
24
+
25
+ function UserProfile() {
26
+ const { data, loading, error } = useQuery(client.user.get({ id: "1" }));
27
+ const [createUser, { loading: creating }] = useMutation(client.user.create);
28
+
29
+ if (loading) return <div>Loading...</div>;
30
+ if (error) return <div>Error: {error.message}</div>;
31
+
32
+ return <div>{data.name}</div>;
33
+ }
34
+ ```
35
+
36
+ ## License
37
+
38
+ MIT
39
+
40
+ ---
41
+
42
+ Built with [@sylphx/lens-client](https://github.com/SylphxAI/Lens).
43
+
44
+ ✨ Powered by Sylphx
package/package.json CHANGED
@@ -1,46 +1,47 @@
1
1
  {
2
- "name": "@sylphx/lens-react",
3
- "version": "1.2.5",
4
- "description": "React bindings for Lens API framework",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "import": "./dist/index.js",
11
- "types": "./dist/index.d.ts"
12
- }
13
- },
14
- "scripts": {
15
- "build": "bunup",
16
- "typecheck": "tsc --noEmit",
17
- "test": "bun test"
18
- },
19
- "files": [
20
- "dist",
21
- "src"
22
- ],
23
- "keywords": [
24
- "lens",
25
- "react",
26
- "hooks",
27
- "reactive"
28
- ],
29
- "author": "SylphxAI",
30
- "license": "MIT",
31
- "dependencies": {
32
- "@sylphx/lens-client": "^1.0.9"
33
- },
34
- "peerDependencies": {
35
- "react": ">=18.0.0"
36
- },
37
- "devDependencies": {
38
- "@happy-dom/global-registrator": "^20.0.10",
39
- "@testing-library/react": "^16.2.0",
40
- "@types/react": "^18.3.12",
41
- "happy-dom": "^17.4.7",
42
- "react": "^18.3.1",
43
- "react-dom": "^18.3.1",
44
- "typescript": "^5.9.3"
45
- }
2
+ "name": "@sylphx/lens-react",
3
+ "version": "1.2.7",
4
+ "description": "React bindings for Lens API framework",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "scripts": {
15
+ "build": "bunup",
16
+ "typecheck": "tsc --noEmit",
17
+ "test": "bun test",
18
+ "prepack": "bun run build"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "src"
23
+ ],
24
+ "keywords": [
25
+ "lens",
26
+ "react",
27
+ "hooks",
28
+ "reactive"
29
+ ],
30
+ "author": "SylphxAI",
31
+ "license": "MIT",
32
+ "dependencies": {
33
+ "@sylphx/lens-client": "^1.6.0"
34
+ },
35
+ "peerDependencies": {
36
+ "react": ">=18.0.0"
37
+ },
38
+ "devDependencies": {
39
+ "@happy-dom/global-registrator": "^20.0.10",
40
+ "@testing-library/react": "^16.2.0",
41
+ "@types/react": "^19.1.6",
42
+ "happy-dom": "^20.0.10",
43
+ "react": "^19.1.0",
44
+ "react-dom": "^19.1.0",
45
+ "typescript": "^5.9.3"
46
+ }
46
47
  }
package/src/context.tsx CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import type { LensClient } from "@sylphx/lens-client";
8
- import { type ReactElement, type ReactNode, createContext, useContext } from "react";
8
+ import { createContext, type ReactElement, type ReactNode, useContext } from "react";
9
9
 
10
10
  // =============================================================================
11
11
  // Context
@@ -15,7 +15,6 @@ import { type ReactElement, type ReactNode, createContext, useContext } from "re
15
15
  * Context for Lens client
16
16
  * Using any for internal storage to avoid type constraint issues
17
17
  */
18
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
18
  const LensContext = createContext<LensClient<any, any> | null>(null);
20
19
 
21
20
  // =============================================================================
@@ -24,7 +23,6 @@ const LensContext = createContext<LensClient<any, any> | null>(null);
24
23
 
25
24
  export interface LensProviderProps {
26
25
  /** Lens client instance */
27
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
26
  client: LensClient<any, any>;
29
27
  /** Children */
30
28
  children: ReactNode;
@@ -74,7 +72,6 @@ export function LensProvider({ client, children }: LensProviderProps): ReactElem
74
72
  * }
75
73
  * ```
76
74
  */
77
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
78
75
  export function useLensClient<TRouter = any>(): LensClient<any, any> & TRouter {
79
76
  const client = useContext(LensContext);
80
77
 
@@ -85,6 +82,5 @@ export function useLensClient<TRouter = any>(): LensClient<any, any> & TRouter {
85
82
  );
86
83
  }
87
84
 
88
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
89
85
  return client as LensClient<any, any> & TRouter;
90
86
  }
@@ -1,10 +1,19 @@
1
1
  /**
2
2
  * Tests for React Hooks (Operations-based API)
3
+ *
4
+ * NOTE: These tests require DOM environment (happy-dom).
5
+ * Run from packages/react directory: cd packages/react && bun test
3
6
  */
4
7
 
5
- import { describe, expect, test } from "bun:test";
6
- import { signal } from "@sylphx/lens-client";
8
+ // Skip all tests if DOM is not available (when run from root)
9
+ const hasDom = typeof document !== "undefined";
10
+
11
+ import { test as bunTest, describe, expect } from "bun:test";
12
+
13
+ const test = hasDom ? bunTest : bunTest.skip;
14
+
7
15
  import type { MutationResult, QueryResult } from "@sylphx/lens-client";
16
+ import { signal } from "@sylphx/lens-client";
8
17
  import { act, renderHook, waitFor } from "@testing-library/react";
9
18
  import { useLazyQuery, useMutation, useQuery } from "./hooks";
10
19
 
@@ -17,7 +26,7 @@ function createMockQueryResult<T>(initialValue: T | null = null): QueryResult<T>
17
26
  _setError: (error: Error) => void;
18
27
  } {
19
28
  let currentValue = initialValue;
20
- let currentError: Error | null = null;
29
+ let _currentError: Error | null = null;
21
30
  const subscribers: Array<(value: T) => void> = [];
22
31
  let resolved = false;
23
32
  let resolvePromise: ((value: T) => void) | null = null;
@@ -66,14 +75,14 @@ function createMockQueryResult<T>(initialValue: T | null = null): QueryResult<T>
66
75
  result.signal.value = value;
67
76
  result.loading.value = false;
68
77
  result.error.value = null;
69
- subscribers.forEach((cb) => cb(value));
78
+ for (const cb of subscribers) cb(value);
70
79
  if (!resolved && resolvePromise) {
71
80
  resolved = true;
72
81
  resolvePromise(value);
73
82
  }
74
83
  },
75
84
  _setError(error: Error) {
76
- currentError = error;
85
+ _currentError = error;
77
86
  result.loading.value = false;
78
87
  result.error.value = error;
79
88
  if (!resolved && rejectPromise) {
@@ -180,9 +189,7 @@ describe("useQuery", () => {
180
189
 
181
190
  describe("useMutation", () => {
182
191
  test("executes mutation and returns result", async () => {
183
- const mutationFn = async (input: { name: string }): Promise<
184
- MutationResult<{ id: string; name: string }>
185
- > => {
192
+ const mutationFn = async (input: { name: string }): Promise<MutationResult<{ id: string; name: string }>> => {
186
193
  return {
187
194
  data: { id: "new-id", name: input.name },
188
195
  };
@@ -204,9 +211,7 @@ describe("useMutation", () => {
204
211
  });
205
212
 
206
213
  test("handles mutation error", async () => {
207
- const mutationFn = async (_input: { name: string }): Promise<
208
- MutationResult<{ id: string; name: string }>
209
- > => {
214
+ const mutationFn = async (_input: { name: string }): Promise<MutationResult<{ id: string; name: string }>> => {
210
215
  throw new Error("Mutation failed");
211
216
  };
212
217
 
@@ -226,9 +231,7 @@ describe("useMutation", () => {
226
231
 
227
232
  test("shows loading state during mutation", async () => {
228
233
  let resolveMutation: ((value: MutationResult<{ id: string }>) => void) | null = null;
229
- const mutationFn = async (_input: { name: string }): Promise<
230
- MutationResult<{ id: string }>
231
- > => {
234
+ const mutationFn = async (_input: { name: string }): Promise<MutationResult<{ id: string }>> => {
232
235
  return new Promise((resolve) => {
233
236
  resolveMutation = resolve;
234
237
  });
@@ -255,9 +258,7 @@ describe("useMutation", () => {
255
258
  });
256
259
 
257
260
  test("reset clears mutation state", async () => {
258
- const mutationFn = async (input: { name: string }): Promise<
259
- MutationResult<{ id: string; name: string }>
260
- > => {
261
+ const mutationFn = async (input: { name: string }): Promise<MutationResult<{ id: string; name: string }>> => {
261
262
  return { data: { id: "new-id", name: input.name } };
262
263
  };
263
264
 
package/src/index.ts CHANGED
@@ -9,23 +9,23 @@
9
9
  // Context & Provider
10
10
  // =============================================================================
11
11
 
12
- export { LensProvider, useLensClient, type LensProviderProps } from "./context";
12
+ export { LensProvider, type LensProviderProps, useLensClient } from "./context";
13
13
 
14
14
  // =============================================================================
15
15
  // Hooks (Operations-based API)
16
16
  // =============================================================================
17
17
 
18
18
  export {
19
- // Query hooks
20
- useQuery,
21
- useLazyQuery,
22
- // Mutation hook
23
- useMutation,
19
+ type MutationFn,
24
20
  // Types
25
21
  type QueryInput,
26
- type UseQueryResult,
27
22
  type UseLazyQueryResult,
28
23
  type UseMutationResult,
29
24
  type UseQueryOptions,
30
- type MutationFn,
25
+ type UseQueryResult,
26
+ useLazyQuery,
27
+ // Mutation hook
28
+ useMutation,
29
+ // Query hooks
30
+ useQuery,
31
31
  } from "./hooks";