@vira-ui/react 1.0.0

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.
@@ -0,0 +1,70 @@
1
+ interface UseViraStateOptions<T = any> {
2
+ /** Initial value for the state */
3
+ initial?: T | null;
4
+ /** Enable msgId support for idempotency */
5
+ enableMsgId?: boolean;
6
+ /** Callback when connection opens */
7
+ onOpen?: () => void;
8
+ /** Callback when connection closes */
9
+ onClose?: (event: CloseEvent) => void;
10
+ /** Callback when connection error occurs */
11
+ onError?: (error: Error) => void;
12
+ /** Use deep merge for diff patches (default: true) */
13
+ deepMerge?: boolean;
14
+ /** API URL (defaults to VITE_API_URL env or 'http://localhost:8080') */
15
+ apiUrl?: string;
16
+ /** Auth token for handshake */
17
+ authToken?: string;
18
+ }
19
+ /**
20
+ * Unified hook for Vira Reactive Protocol state management.
21
+ * Replaces both useViraState and useViraStream.
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * // Basic usage
26
+ * const { data, sendUpdate } = useViraState<MyType>('my-channel');
27
+ *
28
+ * // With options
29
+ * const { data, sendUpdate, sendDiff } = useViraState<User>('user:123', {
30
+ * initial: { name: 'Guest' },
31
+ * enableMsgId: true,
32
+ * onOpen: () => console.log('Connected'),
33
+ * deepMerge: true
34
+ * });
35
+ * ```
36
+ */
37
+ declare function useViraState<T = any, C extends string = string>(channel: C, initialOrOptions?: T | null | UseViraStateOptions<T>): {
38
+ /** Current state data */
39
+ data: T | null;
40
+ /** Send an event to the server */
41
+ sendEvent: (name: string, payload: any, msgId?: string) => void;
42
+ /** Send a full update (replaces state) */
43
+ sendUpdate: (payload: T, msgId?: string) => void;
44
+ /** Send a partial diff (merges with current state) */
45
+ sendDiff: (patch: Partial<T>, msgId?: string) => void;
46
+ /** Connection status */
47
+ isConnected: boolean;
48
+ /** Connection error, if any */
49
+ error: Error | null;
50
+ };
51
+ /**
52
+ * Legacy hook - use useViraState instead.
53
+ * @deprecated Use useViraState with options instead
54
+ */
55
+ declare function useViraStream<T = any, C extends string = string>(channel: C, options?: UseViraStateOptions<T>): {
56
+ /** Current state data */
57
+ data: T | null;
58
+ /** Send an event to the server */
59
+ sendEvent: (name: string, payload: any, msgId?: string) => void;
60
+ /** Send a full update (replaces state) */
61
+ sendUpdate: (payload: T, msgId?: string) => void;
62
+ /** Send a partial diff (merges with current state) */
63
+ sendDiff: (patch: Partial<T>, msgId?: string) => void;
64
+ /** Connection status */
65
+ isConnected: boolean;
66
+ /** Connection error, if any */
67
+ error: Error | null;
68
+ };
69
+
70
+ export { type UseViraStateOptions, useViraState, useViraStream };
@@ -0,0 +1,70 @@
1
+ interface UseViraStateOptions<T = any> {
2
+ /** Initial value for the state */
3
+ initial?: T | null;
4
+ /** Enable msgId support for idempotency */
5
+ enableMsgId?: boolean;
6
+ /** Callback when connection opens */
7
+ onOpen?: () => void;
8
+ /** Callback when connection closes */
9
+ onClose?: (event: CloseEvent) => void;
10
+ /** Callback when connection error occurs */
11
+ onError?: (error: Error) => void;
12
+ /** Use deep merge for diff patches (default: true) */
13
+ deepMerge?: boolean;
14
+ /** API URL (defaults to VITE_API_URL env or 'http://localhost:8080') */
15
+ apiUrl?: string;
16
+ /** Auth token for handshake */
17
+ authToken?: string;
18
+ }
19
+ /**
20
+ * Unified hook for Vira Reactive Protocol state management.
21
+ * Replaces both useViraState and useViraStream.
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * // Basic usage
26
+ * const { data, sendUpdate } = useViraState<MyType>('my-channel');
27
+ *
28
+ * // With options
29
+ * const { data, sendUpdate, sendDiff } = useViraState<User>('user:123', {
30
+ * initial: { name: 'Guest' },
31
+ * enableMsgId: true,
32
+ * onOpen: () => console.log('Connected'),
33
+ * deepMerge: true
34
+ * });
35
+ * ```
36
+ */
37
+ declare function useViraState<T = any, C extends string = string>(channel: C, initialOrOptions?: T | null | UseViraStateOptions<T>): {
38
+ /** Current state data */
39
+ data: T | null;
40
+ /** Send an event to the server */
41
+ sendEvent: (name: string, payload: any, msgId?: string) => void;
42
+ /** Send a full update (replaces state) */
43
+ sendUpdate: (payload: T, msgId?: string) => void;
44
+ /** Send a partial diff (merges with current state) */
45
+ sendDiff: (patch: Partial<T>, msgId?: string) => void;
46
+ /** Connection status */
47
+ isConnected: boolean;
48
+ /** Connection error, if any */
49
+ error: Error | null;
50
+ };
51
+ /**
52
+ * Legacy hook - use useViraState instead.
53
+ * @deprecated Use useViraState with options instead
54
+ */
55
+ declare function useViraStream<T = any, C extends string = string>(channel: C, options?: UseViraStateOptions<T>): {
56
+ /** Current state data */
57
+ data: T | null;
58
+ /** Send an event to the server */
59
+ sendEvent: (name: string, payload: any, msgId?: string) => void;
60
+ /** Send a full update (replaces state) */
61
+ sendUpdate: (payload: T, msgId?: string) => void;
62
+ /** Send a partial diff (merges with current state) */
63
+ sendDiff: (patch: Partial<T>, msgId?: string) => void;
64
+ /** Connection status */
65
+ isConnected: boolean;
66
+ /** Connection error, if any */
67
+ error: Error | null;
68
+ };
69
+
70
+ export { type UseViraStateOptions, useViraState, useViraStream };
package/dist/index.js ADDED
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ useViraState: () => useViraState,
24
+ useViraStream: () => useViraStream
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/useViraState.ts
29
+ var import_react = require("react");
30
+ var import_core = require("@vira-ui/core");
31
+ function useViraState(channel, initialOrOptions) {
32
+ const options = (0, import_react.useMemo)(() => {
33
+ if (initialOrOptions === null || initialOrOptions === void 0) {
34
+ return {};
35
+ }
36
+ if (typeof initialOrOptions === "object" && !Array.isArray(initialOrOptions) && ("enableMsgId" in initialOrOptions || "onOpen" in initialOrOptions || "onClose" in initialOrOptions || "onError" in initialOrOptions || "deepMerge" in initialOrOptions || "initial" in initialOrOptions || "apiUrl" in initialOrOptions || "authToken" in initialOrOptions)) {
37
+ return initialOrOptions;
38
+ }
39
+ return { initial: initialOrOptions };
40
+ }, [initialOrOptions]);
41
+ const {
42
+ initial = null,
43
+ enableMsgId = false,
44
+ onOpen,
45
+ onClose,
46
+ onError,
47
+ deepMerge: useDeepMerge = true,
48
+ apiUrl: apiUrlOption,
49
+ authToken: authTokenOption
50
+ } = options;
51
+ const [data, setData] = (0, import_react.useState)(initial);
52
+ const [isConnected, setIsConnected] = (0, import_react.useState)(false);
53
+ const [error, setError] = (0, import_react.useState)(null);
54
+ const clientRef = (0, import_react.useRef)(null);
55
+ const sessionRef = (0, import_react.useRef)(null);
56
+ const msgIdCounterRef = (0, import_react.useRef)(0);
57
+ const apiUrl = (0, import_react.useMemo)(() => {
58
+ if (apiUrlOption) return apiUrlOption;
59
+ try {
60
+ const env = globalThis.import?.meta?.env || globalThis.process?.env;
61
+ if (env?.VITE_API_URL) return env.VITE_API_URL;
62
+ } catch {
63
+ }
64
+ return "http://localhost:8080";
65
+ }, [apiUrlOption]);
66
+ const authToken = (0, import_react.useMemo)(() => {
67
+ if (authTokenOption !== void 0) return authTokenOption;
68
+ try {
69
+ const env = globalThis.import?.meta?.env || globalThis.process?.env;
70
+ return env?.VITE_AUTH_TOKEN || "";
71
+ } catch {
72
+ return "";
73
+ }
74
+ }, [authTokenOption]);
75
+ (0, import_react.useEffect)(() => {
76
+ if (!channel) return;
77
+ const handleMessage = (msg) => {
78
+ switch (msg.type) {
79
+ case "update":
80
+ case "event":
81
+ if (msg.channel === channel) {
82
+ setData(msg.data);
83
+ }
84
+ break;
85
+ case "diff":
86
+ if (msg.channel === channel) {
87
+ setData((prev) => {
88
+ if (!prev) {
89
+ return msg.patch || null;
90
+ }
91
+ if (typeof prev === "object" && typeof msg.patch === "object") {
92
+ if (useDeepMerge) {
93
+ return (0, import_core.deepMerge)(prev, msg.patch);
94
+ } else {
95
+ return { ...prev, ...msg.patch };
96
+ }
97
+ }
98
+ return msg.patch || prev;
99
+ });
100
+ }
101
+ break;
102
+ }
103
+ };
104
+ const handleConnect = () => {
105
+ setIsConnected(true);
106
+ setError(null);
107
+ onOpen?.();
108
+ };
109
+ const handleDisconnect = (event) => {
110
+ setIsConnected(false);
111
+ onClose?.(event);
112
+ };
113
+ const handleError = (err) => {
114
+ setError(err);
115
+ onError?.(err);
116
+ };
117
+ const client = (0, import_core.createViraClient)({
118
+ url: apiUrl,
119
+ channel,
120
+ onMessage: handleMessage,
121
+ onConnect: handleConnect,
122
+ onDisconnect: handleDisconnect,
123
+ onError: handleError,
124
+ session: sessionRef.current,
125
+ authToken,
126
+ onSessionChange: (newSession) => {
127
+ sessionRef.current = newSession;
128
+ }
129
+ });
130
+ clientRef.current = client;
131
+ return () => {
132
+ client.close();
133
+ clientRef.current = null;
134
+ setIsConnected(false);
135
+ setError(null);
136
+ };
137
+ }, [channel, apiUrl, authToken, onOpen, onClose, onError, useDeepMerge]);
138
+ const generateMsgId = (0, import_react.useCallback)(() => {
139
+ if (!enableMsgId) return void 0;
140
+ msgIdCounterRef.current++;
141
+ return `${channel}:${Date.now()}:${msgIdCounterRef.current}`;
142
+ }, [channel, enableMsgId]);
143
+ const sendEvent = (0, import_react.useCallback)(
144
+ (name, payload, msgId) => {
145
+ clientRef.current?.sendEvent(name, payload, msgId ?? generateMsgId());
146
+ },
147
+ [generateMsgId]
148
+ );
149
+ const sendUpdate = (0, import_react.useCallback)(
150
+ (payload, msgId) => {
151
+ clientRef.current?.sendUpdate(payload, msgId ?? generateMsgId());
152
+ },
153
+ [generateMsgId]
154
+ );
155
+ const sendDiff = (0, import_react.useCallback)(
156
+ (patch, msgId) => {
157
+ clientRef.current?.sendDiff(patch, msgId ?? generateMsgId());
158
+ },
159
+ [generateMsgId]
160
+ );
161
+ return {
162
+ data,
163
+ sendEvent,
164
+ sendUpdate,
165
+ sendDiff,
166
+ isConnected,
167
+ error
168
+ };
169
+ }
170
+ function useViraStream(channel, options) {
171
+ return useViraState(channel, { ...options, initial: null });
172
+ }
173
+ // Annotate the CommonJS export names for ESM import in node:
174
+ 0 && (module.exports = {
175
+ useViraState,
176
+ useViraStream
177
+ });
178
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/useViraState.ts"],"sourcesContent":["/**\r\n * @vira-ui/react\r\n * \r\n * Vira Framework - React hooks for Vira Reactive Protocol\r\n * \r\n * This package provides React hooks for VRP, built on top of @vira-ui/core.\r\n */\r\n\r\nexport {\r\n useViraState,\r\n useViraStream,\r\n} from './useViraState';\r\nexport type {\r\n UseViraStateOptions,\r\n} from './useViraState';\r\n\r\n","import { useEffect, useMemo, useRef, useState, useCallback } from 'react';\r\nimport { createViraClient, deepMerge, type ViraClient, type Message } from '@vira-ui/core';\r\n\r\nexport interface UseViraStateOptions<T = any> {\r\n /** Initial value for the state */\r\n initial?: T | null;\r\n /** Enable msgId support for idempotency */\r\n enableMsgId?: boolean;\r\n /** Callback when connection opens */\r\n onOpen?: () => void;\r\n /** Callback when connection closes */\r\n onClose?: (event: CloseEvent) => void;\r\n /** Callback when connection error occurs */\r\n onError?: (error: Error) => void;\r\n /** Use deep merge for diff patches (default: true) */\r\n deepMerge?: boolean;\r\n /** API URL (defaults to VITE_API_URL env or 'http://localhost:8080') */\r\n apiUrl?: string;\r\n /** Auth token for handshake */\r\n authToken?: string;\r\n}\r\n\r\n/**\r\n * Unified hook for Vira Reactive Protocol state management.\r\n * Replaces both useViraState and useViraStream.\r\n *\r\n * @example\r\n * ```tsx\r\n * // Basic usage\r\n * const { data, sendUpdate } = useViraState<MyType>('my-channel');\r\n *\r\n * // With options\r\n * const { data, sendUpdate, sendDiff } = useViraState<User>('user:123', {\r\n * initial: { name: 'Guest' },\r\n * enableMsgId: true,\r\n * onOpen: () => console.log('Connected'),\r\n * deepMerge: true\r\n * });\r\n * ```\r\n */\r\nexport function useViraState<T = any, C extends string = string>(\r\n channel: C,\r\n initialOrOptions?: T | null | UseViraStateOptions<T>\r\n): {\r\n /** Current state data */\r\n data: T | null;\r\n /** Send an event to the server */\r\n sendEvent: (name: string, payload: any, msgId?: string) => void;\r\n /** Send a full update (replaces state) */\r\n sendUpdate: (payload: T, msgId?: string) => void;\r\n /** Send a partial diff (merges with current state) */\r\n sendDiff: (patch: Partial<T>, msgId?: string) => void;\r\n /** Connection status */\r\n isConnected: boolean;\r\n /** Connection error, if any */\r\n error: Error | null;\r\n} {\r\n // Parse options (backward compatibility: second param can be initial value or options)\r\n const options: UseViraStateOptions<T> = useMemo(() => {\r\n if (initialOrOptions === null || initialOrOptions === undefined) {\r\n return {};\r\n }\r\n // If it's an object with known option keys, treat as options\r\n if (\r\n typeof initialOrOptions === 'object' &&\r\n !Array.isArray(initialOrOptions) &&\r\n ('enableMsgId' in initialOrOptions ||\r\n 'onOpen' in initialOrOptions ||\r\n 'onClose' in initialOrOptions ||\r\n 'onError' in initialOrOptions ||\r\n 'deepMerge' in initialOrOptions ||\r\n 'initial' in initialOrOptions ||\r\n 'apiUrl' in initialOrOptions ||\r\n 'authToken' in initialOrOptions)\r\n ) {\r\n return initialOrOptions as UseViraStateOptions<T>;\r\n }\r\n // Otherwise, treat as initial value (backward compatibility)\r\n return { initial: initialOrOptions as T | null };\r\n }, [initialOrOptions]);\r\n\r\n const {\r\n initial = null,\r\n enableMsgId = false,\r\n onOpen,\r\n onClose,\r\n onError,\r\n deepMerge: useDeepMerge = true,\r\n apiUrl: apiUrlOption,\r\n authToken: authTokenOption,\r\n } = options;\r\n\r\n const [data, setData] = useState<T | null>(initial);\r\n const [isConnected, setIsConnected] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n const clientRef = useRef<ViraClient | null>(null);\r\n const sessionRef = useRef<string | null>(null);\r\n const msgIdCounterRef = useRef(0);\r\n\r\n // Use provided apiUrl or fallback to env or default\r\n // Note: import.meta is only available in ESM, so we check safely\r\n const apiUrl = useMemo(() => {\r\n if (apiUrlOption) return apiUrlOption;\r\n // Try to get from env if available (Vite/bundler environment)\r\n try {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const env = (globalThis as any).import?.meta?.env || (globalThis as any).process?.env;\r\n if (env?.VITE_API_URL) return env.VITE_API_URL;\r\n } catch {\r\n // Ignore if import.meta is not available\r\n }\r\n return 'http://localhost:8080';\r\n }, [apiUrlOption]);\r\n\r\n // Get authToken from options or try to get from env\r\n const authToken = useMemo(() => {\r\n if (authTokenOption !== undefined) return authTokenOption;\r\n try {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const env = (globalThis as any).import?.meta?.env || (globalThis as any).process?.env;\r\n return env?.VITE_AUTH_TOKEN || '';\r\n } catch {\r\n return '';\r\n }\r\n }, [authTokenOption]);\r\n\r\n useEffect(() => {\r\n if (!channel) return;\r\n\r\n const handleMessage = (msg: Message) => {\r\n switch (msg.type) {\r\n case 'update':\r\n case 'event':\r\n if (msg.channel === channel) {\r\n setData(msg.data as T);\r\n }\r\n break;\r\n\r\n case 'diff':\r\n if (msg.channel === channel) {\r\n setData((prev) => {\r\n if (!prev) {\r\n return (msg.patch as T) || null;\r\n }\r\n\r\n // For objects, merge the patch\r\n if (typeof prev === 'object' && typeof msg.patch === 'object') {\r\n if (useDeepMerge) {\r\n // Deep merge preserves nested structures\r\n return deepMerge(prev as Record<string, any>, msg.patch as Partial<T>) as T;\r\n } else {\r\n // Shallow merge (backward compatible)\r\n return { ...(prev as any), ...(msg.patch as any) };\r\n }\r\n }\r\n\r\n // For primitives, replace entirely\r\n return (msg.patch as T) || prev;\r\n });\r\n }\r\n break;\r\n }\r\n };\r\n\r\n const handleConnect = () => {\r\n setIsConnected(true);\r\n setError(null);\r\n onOpen?.();\r\n };\r\n\r\n const handleDisconnect = (event?: CloseEvent) => {\r\n setIsConnected(false);\r\n onClose?.(event!);\r\n };\r\n\r\n const handleError = (err: Error) => {\r\n setError(err);\r\n onError?.(err);\r\n };\r\n\r\n const client = createViraClient({\r\n url: apiUrl,\r\n channel,\r\n onMessage: handleMessage,\r\n onConnect: handleConnect,\r\n onDisconnect: handleDisconnect,\r\n onError: handleError,\r\n session: sessionRef.current,\r\n authToken,\r\n onSessionChange: (newSession) => {\r\n sessionRef.current = newSession;\r\n },\r\n });\r\n\r\n clientRef.current = client;\r\n\r\n return () => {\r\n client.close();\r\n clientRef.current = null;\r\n setIsConnected(false);\r\n setError(null);\r\n };\r\n }, [channel, apiUrl, authToken, onOpen, onClose, onError, useDeepMerge]);\r\n\r\n // Generate msgId if enabled\r\n const generateMsgId = useCallback((): string | undefined => {\r\n if (!enableMsgId) return undefined;\r\n msgIdCounterRef.current++;\r\n return `${channel}:${Date.now()}:${msgIdCounterRef.current}`;\r\n }, [channel, enableMsgId]);\r\n\r\n const sendEvent = useCallback(\r\n (name: string, payload: any, msgId?: string) => {\r\n clientRef.current?.sendEvent(name, payload, msgId ?? generateMsgId());\r\n },\r\n [generateMsgId]\r\n );\r\n\r\n const sendUpdate = useCallback(\r\n (payload: T, msgId?: string) => {\r\n clientRef.current?.sendUpdate(payload, msgId ?? generateMsgId());\r\n },\r\n [generateMsgId]\r\n );\r\n\r\n const sendDiff = useCallback(\r\n (patch: Partial<T>, msgId?: string) => {\r\n clientRef.current?.sendDiff(patch, msgId ?? generateMsgId());\r\n },\r\n [generateMsgId]\r\n );\r\n\r\n return {\r\n data,\r\n sendEvent,\r\n sendUpdate,\r\n sendDiff,\r\n isConnected,\r\n error,\r\n };\r\n}\r\n\r\n/**\r\n * Legacy hook - use useViraState instead.\r\n * @deprecated Use useViraState with options instead\r\n */\r\nexport function useViraStream<T = any, C extends string = string>(\r\n channel: C,\r\n options?: UseViraStateOptions<T>\r\n) {\r\n return useViraState<T, C>(channel, { ...options, initial: null });\r\n}\r\n\r\n"],"mappings":"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","names":[]}
package/dist/index.mjs ADDED
@@ -0,0 +1,150 @@
1
+ // src/useViraState.ts
2
+ import { useEffect, useMemo, useRef, useState, useCallback } from "react";
3
+ import { createViraClient, deepMerge } from "@vira-ui/core";
4
+ function useViraState(channel, initialOrOptions) {
5
+ const options = useMemo(() => {
6
+ if (initialOrOptions === null || initialOrOptions === void 0) {
7
+ return {};
8
+ }
9
+ if (typeof initialOrOptions === "object" && !Array.isArray(initialOrOptions) && ("enableMsgId" in initialOrOptions || "onOpen" in initialOrOptions || "onClose" in initialOrOptions || "onError" in initialOrOptions || "deepMerge" in initialOrOptions || "initial" in initialOrOptions || "apiUrl" in initialOrOptions || "authToken" in initialOrOptions)) {
10
+ return initialOrOptions;
11
+ }
12
+ return { initial: initialOrOptions };
13
+ }, [initialOrOptions]);
14
+ const {
15
+ initial = null,
16
+ enableMsgId = false,
17
+ onOpen,
18
+ onClose,
19
+ onError,
20
+ deepMerge: useDeepMerge = true,
21
+ apiUrl: apiUrlOption,
22
+ authToken: authTokenOption
23
+ } = options;
24
+ const [data, setData] = useState(initial);
25
+ const [isConnected, setIsConnected] = useState(false);
26
+ const [error, setError] = useState(null);
27
+ const clientRef = useRef(null);
28
+ const sessionRef = useRef(null);
29
+ const msgIdCounterRef = useRef(0);
30
+ const apiUrl = useMemo(() => {
31
+ if (apiUrlOption) return apiUrlOption;
32
+ try {
33
+ const env = globalThis.import?.meta?.env || globalThis.process?.env;
34
+ if (env?.VITE_API_URL) return env.VITE_API_URL;
35
+ } catch {
36
+ }
37
+ return "http://localhost:8080";
38
+ }, [apiUrlOption]);
39
+ const authToken = useMemo(() => {
40
+ if (authTokenOption !== void 0) return authTokenOption;
41
+ try {
42
+ const env = globalThis.import?.meta?.env || globalThis.process?.env;
43
+ return env?.VITE_AUTH_TOKEN || "";
44
+ } catch {
45
+ return "";
46
+ }
47
+ }, [authTokenOption]);
48
+ useEffect(() => {
49
+ if (!channel) return;
50
+ const handleMessage = (msg) => {
51
+ switch (msg.type) {
52
+ case "update":
53
+ case "event":
54
+ if (msg.channel === channel) {
55
+ setData(msg.data);
56
+ }
57
+ break;
58
+ case "diff":
59
+ if (msg.channel === channel) {
60
+ setData((prev) => {
61
+ if (!prev) {
62
+ return msg.patch || null;
63
+ }
64
+ if (typeof prev === "object" && typeof msg.patch === "object") {
65
+ if (useDeepMerge) {
66
+ return deepMerge(prev, msg.patch);
67
+ } else {
68
+ return { ...prev, ...msg.patch };
69
+ }
70
+ }
71
+ return msg.patch || prev;
72
+ });
73
+ }
74
+ break;
75
+ }
76
+ };
77
+ const handleConnect = () => {
78
+ setIsConnected(true);
79
+ setError(null);
80
+ onOpen?.();
81
+ };
82
+ const handleDisconnect = (event) => {
83
+ setIsConnected(false);
84
+ onClose?.(event);
85
+ };
86
+ const handleError = (err) => {
87
+ setError(err);
88
+ onError?.(err);
89
+ };
90
+ const client = createViraClient({
91
+ url: apiUrl,
92
+ channel,
93
+ onMessage: handleMessage,
94
+ onConnect: handleConnect,
95
+ onDisconnect: handleDisconnect,
96
+ onError: handleError,
97
+ session: sessionRef.current,
98
+ authToken,
99
+ onSessionChange: (newSession) => {
100
+ sessionRef.current = newSession;
101
+ }
102
+ });
103
+ clientRef.current = client;
104
+ return () => {
105
+ client.close();
106
+ clientRef.current = null;
107
+ setIsConnected(false);
108
+ setError(null);
109
+ };
110
+ }, [channel, apiUrl, authToken, onOpen, onClose, onError, useDeepMerge]);
111
+ const generateMsgId = useCallback(() => {
112
+ if (!enableMsgId) return void 0;
113
+ msgIdCounterRef.current++;
114
+ return `${channel}:${Date.now()}:${msgIdCounterRef.current}`;
115
+ }, [channel, enableMsgId]);
116
+ const sendEvent = useCallback(
117
+ (name, payload, msgId) => {
118
+ clientRef.current?.sendEvent(name, payload, msgId ?? generateMsgId());
119
+ },
120
+ [generateMsgId]
121
+ );
122
+ const sendUpdate = useCallback(
123
+ (payload, msgId) => {
124
+ clientRef.current?.sendUpdate(payload, msgId ?? generateMsgId());
125
+ },
126
+ [generateMsgId]
127
+ );
128
+ const sendDiff = useCallback(
129
+ (patch, msgId) => {
130
+ clientRef.current?.sendDiff(patch, msgId ?? generateMsgId());
131
+ },
132
+ [generateMsgId]
133
+ );
134
+ return {
135
+ data,
136
+ sendEvent,
137
+ sendUpdate,
138
+ sendDiff,
139
+ isConnected,
140
+ error
141
+ };
142
+ }
143
+ function useViraStream(channel, options) {
144
+ return useViraState(channel, { ...options, initial: null });
145
+ }
146
+ export {
147
+ useViraState,
148
+ useViraStream
149
+ };
150
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useViraState.ts"],"sourcesContent":["import { useEffect, useMemo, useRef, useState, useCallback } from 'react';\r\nimport { createViraClient, deepMerge, type ViraClient, type Message } from '@vira-ui/core';\r\n\r\nexport interface UseViraStateOptions<T = any> {\r\n /** Initial value for the state */\r\n initial?: T | null;\r\n /** Enable msgId support for idempotency */\r\n enableMsgId?: boolean;\r\n /** Callback when connection opens */\r\n onOpen?: () => void;\r\n /** Callback when connection closes */\r\n onClose?: (event: CloseEvent) => void;\r\n /** Callback when connection error occurs */\r\n onError?: (error: Error) => void;\r\n /** Use deep merge for diff patches (default: true) */\r\n deepMerge?: boolean;\r\n /** API URL (defaults to VITE_API_URL env or 'http://localhost:8080') */\r\n apiUrl?: string;\r\n /** Auth token for handshake */\r\n authToken?: string;\r\n}\r\n\r\n/**\r\n * Unified hook for Vira Reactive Protocol state management.\r\n * Replaces both useViraState and useViraStream.\r\n *\r\n * @example\r\n * ```tsx\r\n * // Basic usage\r\n * const { data, sendUpdate } = useViraState<MyType>('my-channel');\r\n *\r\n * // With options\r\n * const { data, sendUpdate, sendDiff } = useViraState<User>('user:123', {\r\n * initial: { name: 'Guest' },\r\n * enableMsgId: true,\r\n * onOpen: () => console.log('Connected'),\r\n * deepMerge: true\r\n * });\r\n * ```\r\n */\r\nexport function useViraState<T = any, C extends string = string>(\r\n channel: C,\r\n initialOrOptions?: T | null | UseViraStateOptions<T>\r\n): {\r\n /** Current state data */\r\n data: T | null;\r\n /** Send an event to the server */\r\n sendEvent: (name: string, payload: any, msgId?: string) => void;\r\n /** Send a full update (replaces state) */\r\n sendUpdate: (payload: T, msgId?: string) => void;\r\n /** Send a partial diff (merges with current state) */\r\n sendDiff: (patch: Partial<T>, msgId?: string) => void;\r\n /** Connection status */\r\n isConnected: boolean;\r\n /** Connection error, if any */\r\n error: Error | null;\r\n} {\r\n // Parse options (backward compatibility: second param can be initial value or options)\r\n const options: UseViraStateOptions<T> = useMemo(() => {\r\n if (initialOrOptions === null || initialOrOptions === undefined) {\r\n return {};\r\n }\r\n // If it's an object with known option keys, treat as options\r\n if (\r\n typeof initialOrOptions === 'object' &&\r\n !Array.isArray(initialOrOptions) &&\r\n ('enableMsgId' in initialOrOptions ||\r\n 'onOpen' in initialOrOptions ||\r\n 'onClose' in initialOrOptions ||\r\n 'onError' in initialOrOptions ||\r\n 'deepMerge' in initialOrOptions ||\r\n 'initial' in initialOrOptions ||\r\n 'apiUrl' in initialOrOptions ||\r\n 'authToken' in initialOrOptions)\r\n ) {\r\n return initialOrOptions as UseViraStateOptions<T>;\r\n }\r\n // Otherwise, treat as initial value (backward compatibility)\r\n return { initial: initialOrOptions as T | null };\r\n }, [initialOrOptions]);\r\n\r\n const {\r\n initial = null,\r\n enableMsgId = false,\r\n onOpen,\r\n onClose,\r\n onError,\r\n deepMerge: useDeepMerge = true,\r\n apiUrl: apiUrlOption,\r\n authToken: authTokenOption,\r\n } = options;\r\n\r\n const [data, setData] = useState<T | null>(initial);\r\n const [isConnected, setIsConnected] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n const clientRef = useRef<ViraClient | null>(null);\r\n const sessionRef = useRef<string | null>(null);\r\n const msgIdCounterRef = useRef(0);\r\n\r\n // Use provided apiUrl or fallback to env or default\r\n // Note: import.meta is only available in ESM, so we check safely\r\n const apiUrl = useMemo(() => {\r\n if (apiUrlOption) return apiUrlOption;\r\n // Try to get from env if available (Vite/bundler environment)\r\n try {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const env = (globalThis as any).import?.meta?.env || (globalThis as any).process?.env;\r\n if (env?.VITE_API_URL) return env.VITE_API_URL;\r\n } catch {\r\n // Ignore if import.meta is not available\r\n }\r\n return 'http://localhost:8080';\r\n }, [apiUrlOption]);\r\n\r\n // Get authToken from options or try to get from env\r\n const authToken = useMemo(() => {\r\n if (authTokenOption !== undefined) return authTokenOption;\r\n try {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const env = (globalThis as any).import?.meta?.env || (globalThis as any).process?.env;\r\n return env?.VITE_AUTH_TOKEN || '';\r\n } catch {\r\n return '';\r\n }\r\n }, [authTokenOption]);\r\n\r\n useEffect(() => {\r\n if (!channel) return;\r\n\r\n const handleMessage = (msg: Message) => {\r\n switch (msg.type) {\r\n case 'update':\r\n case 'event':\r\n if (msg.channel === channel) {\r\n setData(msg.data as T);\r\n }\r\n break;\r\n\r\n case 'diff':\r\n if (msg.channel === channel) {\r\n setData((prev) => {\r\n if (!prev) {\r\n return (msg.patch as T) || null;\r\n }\r\n\r\n // For objects, merge the patch\r\n if (typeof prev === 'object' && typeof msg.patch === 'object') {\r\n if (useDeepMerge) {\r\n // Deep merge preserves nested structures\r\n return deepMerge(prev as Record<string, any>, msg.patch as Partial<T>) as T;\r\n } else {\r\n // Shallow merge (backward compatible)\r\n return { ...(prev as any), ...(msg.patch as any) };\r\n }\r\n }\r\n\r\n // For primitives, replace entirely\r\n return (msg.patch as T) || prev;\r\n });\r\n }\r\n break;\r\n }\r\n };\r\n\r\n const handleConnect = () => {\r\n setIsConnected(true);\r\n setError(null);\r\n onOpen?.();\r\n };\r\n\r\n const handleDisconnect = (event?: CloseEvent) => {\r\n setIsConnected(false);\r\n onClose?.(event!);\r\n };\r\n\r\n const handleError = (err: Error) => {\r\n setError(err);\r\n onError?.(err);\r\n };\r\n\r\n const client = createViraClient({\r\n url: apiUrl,\r\n channel,\r\n onMessage: handleMessage,\r\n onConnect: handleConnect,\r\n onDisconnect: handleDisconnect,\r\n onError: handleError,\r\n session: sessionRef.current,\r\n authToken,\r\n onSessionChange: (newSession) => {\r\n sessionRef.current = newSession;\r\n },\r\n });\r\n\r\n clientRef.current = client;\r\n\r\n return () => {\r\n client.close();\r\n clientRef.current = null;\r\n setIsConnected(false);\r\n setError(null);\r\n };\r\n }, [channel, apiUrl, authToken, onOpen, onClose, onError, useDeepMerge]);\r\n\r\n // Generate msgId if enabled\r\n const generateMsgId = useCallback((): string | undefined => {\r\n if (!enableMsgId) return undefined;\r\n msgIdCounterRef.current++;\r\n return `${channel}:${Date.now()}:${msgIdCounterRef.current}`;\r\n }, [channel, enableMsgId]);\r\n\r\n const sendEvent = useCallback(\r\n (name: string, payload: any, msgId?: string) => {\r\n clientRef.current?.sendEvent(name, payload, msgId ?? generateMsgId());\r\n },\r\n [generateMsgId]\r\n );\r\n\r\n const sendUpdate = useCallback(\r\n (payload: T, msgId?: string) => {\r\n clientRef.current?.sendUpdate(payload, msgId ?? generateMsgId());\r\n },\r\n [generateMsgId]\r\n );\r\n\r\n const sendDiff = useCallback(\r\n (patch: Partial<T>, msgId?: string) => {\r\n clientRef.current?.sendDiff(patch, msgId ?? generateMsgId());\r\n },\r\n [generateMsgId]\r\n );\r\n\r\n return {\r\n data,\r\n sendEvent,\r\n sendUpdate,\r\n sendDiff,\r\n isConnected,\r\n error,\r\n };\r\n}\r\n\r\n/**\r\n * Legacy hook - use useViraState instead.\r\n * @deprecated Use useViraState with options instead\r\n */\r\nexport function useViraStream<T = any, C extends string = string>(\r\n channel: C,\r\n options?: UseViraStateOptions<T>\r\n) {\r\n return useViraState<T, C>(channel, { ...options, initial: null });\r\n}\r\n\r\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@vira-ui/react",
3
+ "version": "1.0.0",
4
+ "description": "Vira Framework - React hooks for Vira Reactive Protocol",
5
+ "author": "Vira Team",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/skrolikov/vira-core"
10
+ },
11
+ "keywords": [
12
+ "vira",
13
+ "react",
14
+ "hooks",
15
+ "vrp",
16
+ "reactive",
17
+ "websocket"
18
+ ],
19
+ "main": "./dist/index.js",
20
+ "module": "./dist/index.mjs",
21
+ "types": "./dist/index.d.ts",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "import": "./dist/index.mjs",
26
+ "require": "./dist/index.js"
27
+ }
28
+ },
29
+ "scripts": {
30
+ "build": "tsup",
31
+ "dev": "tsup --watch",
32
+ "prepublishOnly": "npm run build"
33
+ },
34
+ "dependencies": {
35
+ "@vira-ui/core": "workspace:*",
36
+ "react": "^18.2.0"
37
+ },
38
+ "peerDependencies": {
39
+ "react": "^18.2.0"
40
+ },
41
+ "devDependencies": {
42
+ "@types/react": "^18.2.0",
43
+ "tsup": "^8.0.0",
44
+ "typescript": "^5.3.3"
45
+ },
46
+ "files": [
47
+ "dist"
48
+ ]
49
+ }
50
+