fivem-nui-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.
- package/README.md +268 -0
- package/dist/index.d.mts +74 -0
- package/dist/index.d.ts +74 -0
- package/dist/index.js +105 -0
- package/dist/index.mjs +78 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# fivem-nui-react
|
|
2
|
+
|
|
3
|
+
React hooks and utilities for FiveM NUI development.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install fivem-nui-react
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **useNuiEvent** - Listen for NUI messages from Lua
|
|
14
|
+
- **fetchNui** - Send requests to Lua client and receive responses
|
|
15
|
+
- **useNuiCallback** - Hook for NUI requests with loading/error states
|
|
16
|
+
- **isEnvBrowser** - Check if running in browser (debug mode)
|
|
17
|
+
- **Mock data support** - Test your UI in browser with simulated responses
|
|
18
|
+
|
|
19
|
+
## API Reference
|
|
20
|
+
|
|
21
|
+
### useNuiEvent
|
|
22
|
+
|
|
23
|
+
Listen for NUI messages sent from Lua.
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
useNuiEvent<T>(action: string, handler: (data: T) => void, options?: UseNuiEventOptions<T>): void
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Parameters:**
|
|
30
|
+
|
|
31
|
+
- `action` - The action name to listen for
|
|
32
|
+
- `handler` - Callback function executed when message is received
|
|
33
|
+
- `options` - Optional mock data configuration for browser testing
|
|
34
|
+
|
|
35
|
+
**Example:**
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import { useNuiEvent } from "fivem-nui-react";
|
|
39
|
+
|
|
40
|
+
function App() {
|
|
41
|
+
const [visible, setVisible] = useState(false);
|
|
42
|
+
|
|
43
|
+
useNuiEvent<{ show: boolean }>("toggleUI", (data) => {
|
|
44
|
+
setVisible(data.show);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// With mock data for browser testing
|
|
48
|
+
useNuiEvent<{ show: boolean }>("toggleUI", (data) => setVisible(data.show), {
|
|
49
|
+
mockData: { show: true },
|
|
50
|
+
mockDelay: 1000,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return visible ? <div>UI Content</div> : null;
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Fivem client side:**
|
|
58
|
+
|
|
59
|
+
```lua
|
|
60
|
+
SendNUIMessage({
|
|
61
|
+
action = "toggleUI",
|
|
62
|
+
data = { show = true }
|
|
63
|
+
})
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
### fetchNui
|
|
69
|
+
|
|
70
|
+
Send a request to the Fivem client and receive a response.
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
fetchNui<T, D>(eventName: string, data?: D, options?: FetchNuiOptions<T>): Promise<T>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Parameters:**
|
|
77
|
+
|
|
78
|
+
- `eventName` - The NUI callback event name
|
|
79
|
+
- `data` - Data to send to Lua
|
|
80
|
+
- `options` - Optional mock data configuration for browser testing
|
|
81
|
+
|
|
82
|
+
**Example:**
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
import { fetchNui } from "fivem-nui-react";
|
|
86
|
+
|
|
87
|
+
interface PlayerData {
|
|
88
|
+
name: string;
|
|
89
|
+
level: number;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function getPlayer() {
|
|
93
|
+
const player = await fetchNui<PlayerData>("getPlayerData", { id: 1 });
|
|
94
|
+
console.log(player.name, player.level);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// With mock data for browser testing
|
|
98
|
+
async function getPlayerMocked() {
|
|
99
|
+
const player = await fetchNui<PlayerData>(
|
|
100
|
+
"getPlayerData",
|
|
101
|
+
{ id: 1 },
|
|
102
|
+
{
|
|
103
|
+
mockData: { name: "John", level: 10 },
|
|
104
|
+
mockDelay: 500,
|
|
105
|
+
},
|
|
106
|
+
);
|
|
107
|
+
console.log(player.name, player.level);
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Lua side:**
|
|
112
|
+
|
|
113
|
+
```lua
|
|
114
|
+
RegisterNUICallback("getPlayerData", function(data, cb)
|
|
115
|
+
local playerId = data.id
|
|
116
|
+
-- Fetch player data...
|
|
117
|
+
cb({ name = "John", level = 10 })
|
|
118
|
+
end)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
### useNuiCallback
|
|
124
|
+
|
|
125
|
+
A hook that wraps `fetchNui` with loading and error state management.
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
useNuiCallback<T, D>(
|
|
129
|
+
eventName: string,
|
|
130
|
+
callback: (data: T) => void,
|
|
131
|
+
options?: UseNuiCallbackOptions<T>
|
|
132
|
+
): [fetchFn: (data?: D) => Promise<T>, state: { loading: boolean, error: Error | null }]
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Parameters:**
|
|
136
|
+
|
|
137
|
+
- `eventName` - The NUI callback event name
|
|
138
|
+
- `callback` - Callback function executed when response is received
|
|
139
|
+
- `options` - Optional mock data configuration for browser testing
|
|
140
|
+
|
|
141
|
+
**Returns:**
|
|
142
|
+
|
|
143
|
+
- `fetchFn` - Function to trigger the request
|
|
144
|
+
- `state.loading` - Boolean indicating if request is in progress
|
|
145
|
+
- `state.error` - Error object if request failed
|
|
146
|
+
|
|
147
|
+
**Example:**
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
import { useNuiCallback } from "fivem-nui-react";
|
|
151
|
+
|
|
152
|
+
interface PlayerData {
|
|
153
|
+
name: string;
|
|
154
|
+
level: number;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function PlayerInfo() {
|
|
158
|
+
const [player, setPlayer] = useState<PlayerData | null>(null);
|
|
159
|
+
|
|
160
|
+
const [fetchPlayer, { loading, error }] = useNuiCallback<PlayerData>(
|
|
161
|
+
"getPlayerData",
|
|
162
|
+
(data) => setPlayer(data),
|
|
163
|
+
{
|
|
164
|
+
mockData: { name: "John", level: 10 },
|
|
165
|
+
mockDelay: 500,
|
|
166
|
+
},
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
useEffect(() => {
|
|
170
|
+
fetchPlayer({ id: 1 });
|
|
171
|
+
}, [fetchPlayer]);
|
|
172
|
+
|
|
173
|
+
if (loading) return <div>Loading...</div>;
|
|
174
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
175
|
+
if (!player) return null;
|
|
176
|
+
|
|
177
|
+
return (
|
|
178
|
+
<div>
|
|
179
|
+
<p>Name: {player.name}</p>
|
|
180
|
+
<p>Level: {player.level}</p>
|
|
181
|
+
</div>
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
### isEnvBrowser
|
|
189
|
+
|
|
190
|
+
Check if running in browser (outside FiveM).
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
isEnvBrowser(): boolean
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Example:**
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
import { isEnvBrowser } from "fivem-nui-react";
|
|
200
|
+
|
|
201
|
+
if (isEnvBrowser()) {
|
|
202
|
+
console.log("Running in browser - debug mode");
|
|
203
|
+
} else {
|
|
204
|
+
console.log("Running in FiveM");
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Browser Testing (Mock Data)
|
|
211
|
+
|
|
212
|
+
All hooks and functions support mock data for testing your UI in a regular browser without FiveM.
|
|
213
|
+
|
|
214
|
+
When `isEnvBrowser()` returns `true`:
|
|
215
|
+
|
|
216
|
+
- `useNuiEvent` will trigger the handler with `mockData` after `mockDelay` milliseconds
|
|
217
|
+
- `fetchNui` will return `mockData` after `mockDelay` milliseconds
|
|
218
|
+
- `useNuiCallback` will call the callback with `mockData` after `mockDelay` milliseconds
|
|
219
|
+
|
|
220
|
+
**Options:**
|
|
221
|
+
|
|
222
|
+
- `mockData` - The data to return in browser mode
|
|
223
|
+
- `mockDelay` - Delay in milliseconds before returning data (default: 500ms)
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## TypeScript Support
|
|
228
|
+
|
|
229
|
+
All functions are fully typed with generics:
|
|
230
|
+
|
|
231
|
+
```tsx
|
|
232
|
+
// Define your types
|
|
233
|
+
interface ShowUIData {
|
|
234
|
+
visible: boolean;
|
|
235
|
+
title: string;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
interface PlayerRequest {
|
|
239
|
+
id: number;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
interface PlayerResponse {
|
|
243
|
+
name: string;
|
|
244
|
+
level: number;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Use with type parameters
|
|
248
|
+
useNuiEvent<ShowUIData>("showUI", (data) => {
|
|
249
|
+
// data is typed as ShowUIData
|
|
250
|
+
console.log(data.visible, data.title);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
const player = await fetchNui<PlayerResponse, PlayerRequest>("getPlayer", {
|
|
254
|
+
id: 1,
|
|
255
|
+
});
|
|
256
|
+
// player is typed as PlayerResponse
|
|
257
|
+
|
|
258
|
+
const [fetchPlayer, { loading }] = useNuiCallback<
|
|
259
|
+
PlayerResponse,
|
|
260
|
+
PlayerRequest
|
|
261
|
+
>("getPlayer", (data) => console.log(data.name));
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## License
|
|
267
|
+
|
|
268
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
interface NuiMessageEvent<T = unknown> {
|
|
2
|
+
action: string;
|
|
3
|
+
data: T;
|
|
4
|
+
}
|
|
5
|
+
type NuiEventHandler<T = unknown> = (data: T) => void;
|
|
6
|
+
interface UseNuiEventOptions<T = unknown> {
|
|
7
|
+
mockData?: T;
|
|
8
|
+
mockDelay?: number;
|
|
9
|
+
}
|
|
10
|
+
interface FetchNuiOptions<T = unknown> {
|
|
11
|
+
mockData?: T;
|
|
12
|
+
mockDelay?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Checks if running in browser debug mode
|
|
16
|
+
*/
|
|
17
|
+
declare function isEnvBrowser(): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* React hook for listening to NUI messages from Lua
|
|
20
|
+
* @param action - The action name to listen for
|
|
21
|
+
* @param handler - Callback function to execute when message is received
|
|
22
|
+
* @param options - Options for mock data in browser mode
|
|
23
|
+
* @example
|
|
24
|
+
* useNuiEvent("showUI", (data) => {
|
|
25
|
+
* setVisible(data.visible);
|
|
26
|
+
* }, { mockData: { visible: true }, mockDelay: 1000 });
|
|
27
|
+
*/
|
|
28
|
+
declare function useNuiEvent<T = unknown>(action: string, handler: NuiEventHandler<T>, options?: UseNuiEventOptions<T>): void;
|
|
29
|
+
/**
|
|
30
|
+
* Sends a request to NUI callback (fivem client)
|
|
31
|
+
* @param eventName - The callback event name
|
|
32
|
+
* @param data - Data to send
|
|
33
|
+
* @param options - Options for mock data in browser mode
|
|
34
|
+
* @returns Promise<T> - Response from fivem client
|
|
35
|
+
* @example
|
|
36
|
+
* const result = await fetchNui("getPlayerData", { id: 1 }, {
|
|
37
|
+
* mockData: { name: "John", level: 10 },
|
|
38
|
+
* mockDelay: 500
|
|
39
|
+
* });
|
|
40
|
+
*/
|
|
41
|
+
declare function fetchNui<T = unknown, D = unknown>(eventName: string, data?: D, options?: FetchNuiOptions<T>): Promise<T>;
|
|
42
|
+
interface UseNuiCallbackOptions<T = unknown> {
|
|
43
|
+
mockData?: T;
|
|
44
|
+
mockDelay?: number;
|
|
45
|
+
}
|
|
46
|
+
interface UseNuiCallbackState {
|
|
47
|
+
loading: boolean;
|
|
48
|
+
error: Error | null;
|
|
49
|
+
}
|
|
50
|
+
type UseNuiCallbackReturn<T, D> = [
|
|
51
|
+
(data?: D) => Promise<T>,
|
|
52
|
+
UseNuiCallbackState
|
|
53
|
+
];
|
|
54
|
+
/**
|
|
55
|
+
* React hook for making NUI callback requests with loading and error states
|
|
56
|
+
* @param eventName - The callback event name
|
|
57
|
+
* @param callback - Callback function to execute when response is received
|
|
58
|
+
* @param options - Options for mock data in browser mode
|
|
59
|
+
* @returns [fetchFunction, { loading, error }]
|
|
60
|
+
* @example
|
|
61
|
+
* const [fetchPlayer, { loading, error }] = useNuiCallback<PlayerData>("getPlayer", (data) => {
|
|
62
|
+
* setPlayer(data);
|
|
63
|
+
* }, {
|
|
64
|
+
* mockData: { name: "John", level: 10 },
|
|
65
|
+
* mockDelay: 500
|
|
66
|
+
* });
|
|
67
|
+
*
|
|
68
|
+
* useEffect(() => {
|
|
69
|
+
* fetchPlayer({ id: 1 });
|
|
70
|
+
* }, [fetchPlayer]);
|
|
71
|
+
*/
|
|
72
|
+
declare function useNuiCallback<T = unknown, D = unknown>(eventName: string, callback: (data: T) => void, options?: UseNuiCallbackOptions<T>): UseNuiCallbackReturn<T, D>;
|
|
73
|
+
|
|
74
|
+
export { type FetchNuiOptions, type NuiEventHandler, type NuiMessageEvent, type UseNuiCallbackOptions, type UseNuiCallbackReturn, type UseNuiCallbackState, type UseNuiEventOptions, fetchNui, isEnvBrowser, useNuiCallback, useNuiEvent };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
interface NuiMessageEvent<T = unknown> {
|
|
2
|
+
action: string;
|
|
3
|
+
data: T;
|
|
4
|
+
}
|
|
5
|
+
type NuiEventHandler<T = unknown> = (data: T) => void;
|
|
6
|
+
interface UseNuiEventOptions<T = unknown> {
|
|
7
|
+
mockData?: T;
|
|
8
|
+
mockDelay?: number;
|
|
9
|
+
}
|
|
10
|
+
interface FetchNuiOptions<T = unknown> {
|
|
11
|
+
mockData?: T;
|
|
12
|
+
mockDelay?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Checks if running in browser debug mode
|
|
16
|
+
*/
|
|
17
|
+
declare function isEnvBrowser(): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* React hook for listening to NUI messages from Lua
|
|
20
|
+
* @param action - The action name to listen for
|
|
21
|
+
* @param handler - Callback function to execute when message is received
|
|
22
|
+
* @param options - Options for mock data in browser mode
|
|
23
|
+
* @example
|
|
24
|
+
* useNuiEvent("showUI", (data) => {
|
|
25
|
+
* setVisible(data.visible);
|
|
26
|
+
* }, { mockData: { visible: true }, mockDelay: 1000 });
|
|
27
|
+
*/
|
|
28
|
+
declare function useNuiEvent<T = unknown>(action: string, handler: NuiEventHandler<T>, options?: UseNuiEventOptions<T>): void;
|
|
29
|
+
/**
|
|
30
|
+
* Sends a request to NUI callback (fivem client)
|
|
31
|
+
* @param eventName - The callback event name
|
|
32
|
+
* @param data - Data to send
|
|
33
|
+
* @param options - Options for mock data in browser mode
|
|
34
|
+
* @returns Promise<T> - Response from fivem client
|
|
35
|
+
* @example
|
|
36
|
+
* const result = await fetchNui("getPlayerData", { id: 1 }, {
|
|
37
|
+
* mockData: { name: "John", level: 10 },
|
|
38
|
+
* mockDelay: 500
|
|
39
|
+
* });
|
|
40
|
+
*/
|
|
41
|
+
declare function fetchNui<T = unknown, D = unknown>(eventName: string, data?: D, options?: FetchNuiOptions<T>): Promise<T>;
|
|
42
|
+
interface UseNuiCallbackOptions<T = unknown> {
|
|
43
|
+
mockData?: T;
|
|
44
|
+
mockDelay?: number;
|
|
45
|
+
}
|
|
46
|
+
interface UseNuiCallbackState {
|
|
47
|
+
loading: boolean;
|
|
48
|
+
error: Error | null;
|
|
49
|
+
}
|
|
50
|
+
type UseNuiCallbackReturn<T, D> = [
|
|
51
|
+
(data?: D) => Promise<T>,
|
|
52
|
+
UseNuiCallbackState
|
|
53
|
+
];
|
|
54
|
+
/**
|
|
55
|
+
* React hook for making NUI callback requests with loading and error states
|
|
56
|
+
* @param eventName - The callback event name
|
|
57
|
+
* @param callback - Callback function to execute when response is received
|
|
58
|
+
* @param options - Options for mock data in browser mode
|
|
59
|
+
* @returns [fetchFunction, { loading, error }]
|
|
60
|
+
* @example
|
|
61
|
+
* const [fetchPlayer, { loading, error }] = useNuiCallback<PlayerData>("getPlayer", (data) => {
|
|
62
|
+
* setPlayer(data);
|
|
63
|
+
* }, {
|
|
64
|
+
* mockData: { name: "John", level: 10 },
|
|
65
|
+
* mockDelay: 500
|
|
66
|
+
* });
|
|
67
|
+
*
|
|
68
|
+
* useEffect(() => {
|
|
69
|
+
* fetchPlayer({ id: 1 });
|
|
70
|
+
* }, [fetchPlayer]);
|
|
71
|
+
*/
|
|
72
|
+
declare function useNuiCallback<T = unknown, D = unknown>(eventName: string, callback: (data: T) => void, options?: UseNuiCallbackOptions<T>): UseNuiCallbackReturn<T, D>;
|
|
73
|
+
|
|
74
|
+
export { type FetchNuiOptions, type NuiEventHandler, type NuiMessageEvent, type UseNuiCallbackOptions, type UseNuiCallbackReturn, type UseNuiCallbackState, type UseNuiEventOptions, fetchNui, isEnvBrowser, useNuiCallback, useNuiEvent };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/index.ts
|
|
20
|
+
var index_exports = {};
|
|
21
|
+
__export(index_exports, {
|
|
22
|
+
fetchNui: () => fetchNui,
|
|
23
|
+
isEnvBrowser: () => isEnvBrowser,
|
|
24
|
+
useNuiCallback: () => useNuiCallback,
|
|
25
|
+
useNuiEvent: () => useNuiEvent
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(index_exports);
|
|
28
|
+
var import_react = require("react");
|
|
29
|
+
var resourceName = window.GetParentResourceName ? window.GetParentResourceName() : "nui-frame-app";
|
|
30
|
+
function isEnvBrowser() {
|
|
31
|
+
return !window.invokeNative;
|
|
32
|
+
}
|
|
33
|
+
function useNuiEvent(action, handler, options) {
|
|
34
|
+
const savedHandler = (0, import_react.useRef)(handler);
|
|
35
|
+
(0, import_react.useEffect)(() => {
|
|
36
|
+
savedHandler.current = handler;
|
|
37
|
+
}, [handler]);
|
|
38
|
+
(0, import_react.useEffect)(() => {
|
|
39
|
+
if (isEnvBrowser()) {
|
|
40
|
+
if ((options == null ? void 0 : options.mockData) === void 0) return;
|
|
41
|
+
const delay = options.mockDelay ?? 500;
|
|
42
|
+
const timeout = setTimeout(
|
|
43
|
+
() => savedHandler.current(options.mockData),
|
|
44
|
+
delay
|
|
45
|
+
);
|
|
46
|
+
return () => clearTimeout(timeout);
|
|
47
|
+
}
|
|
48
|
+
const eventListener = (event) => {
|
|
49
|
+
const { action: eventAction, data } = event.data;
|
|
50
|
+
if (eventAction === action) savedHandler.current(data);
|
|
51
|
+
};
|
|
52
|
+
window.addEventListener("message", eventListener);
|
|
53
|
+
return () => window.removeEventListener("message", eventListener);
|
|
54
|
+
}, [action, options == null ? void 0 : options.mockData, options == null ? void 0 : options.mockDelay]);
|
|
55
|
+
}
|
|
56
|
+
async function fetchNui(eventName, data, options) {
|
|
57
|
+
if (isEnvBrowser()) {
|
|
58
|
+
if ((options == null ? void 0 : options.mockData) === void 0) return Promise.resolve(null);
|
|
59
|
+
const delay = options.mockDelay ?? 500;
|
|
60
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
61
|
+
return options.mockData;
|
|
62
|
+
}
|
|
63
|
+
const response = await fetch(`https://${resourceName}/${eventName}`, {
|
|
64
|
+
method: "POST",
|
|
65
|
+
headers: {
|
|
66
|
+
"Content-Type": "application/json; charset=UTF-8"
|
|
67
|
+
},
|
|
68
|
+
body: JSON.stringify(data ?? {})
|
|
69
|
+
});
|
|
70
|
+
return response.json();
|
|
71
|
+
}
|
|
72
|
+
function useNuiCallback(eventName, callback, options) {
|
|
73
|
+
const [state, setState] = (0, import_react.useState)({
|
|
74
|
+
loading: false,
|
|
75
|
+
error: null
|
|
76
|
+
});
|
|
77
|
+
const callbackRef = (0, import_react.useRef)(callback);
|
|
78
|
+
(0, import_react.useEffect)(() => {
|
|
79
|
+
callbackRef.current = callback;
|
|
80
|
+
}, [callback]);
|
|
81
|
+
const fetch2 = (0, import_react.useCallback)(
|
|
82
|
+
async (data) => {
|
|
83
|
+
setState({ loading: true, error: null });
|
|
84
|
+
try {
|
|
85
|
+
const result = await fetchNui(eventName, data, options);
|
|
86
|
+
callbackRef.current(result);
|
|
87
|
+
setState({ loading: false, error: null });
|
|
88
|
+
return result;
|
|
89
|
+
} catch (err) {
|
|
90
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
91
|
+
setState({ loading: false, error });
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
[eventName, options]
|
|
96
|
+
);
|
|
97
|
+
return [fetch2, state];
|
|
98
|
+
}
|
|
99
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
100
|
+
0 && (module.exports = {
|
|
101
|
+
fetchNui,
|
|
102
|
+
isEnvBrowser,
|
|
103
|
+
useNuiCallback,
|
|
104
|
+
useNuiEvent
|
|
105
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
+
var resourceName = window.GetParentResourceName ? window.GetParentResourceName() : "nui-frame-app";
|
|
4
|
+
function isEnvBrowser() {
|
|
5
|
+
return !window.invokeNative;
|
|
6
|
+
}
|
|
7
|
+
function useNuiEvent(action, handler, options) {
|
|
8
|
+
const savedHandler = useRef(handler);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
savedHandler.current = handler;
|
|
11
|
+
}, [handler]);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (isEnvBrowser()) {
|
|
14
|
+
if ((options == null ? void 0 : options.mockData) === void 0) return;
|
|
15
|
+
const delay = options.mockDelay ?? 500;
|
|
16
|
+
const timeout = setTimeout(
|
|
17
|
+
() => savedHandler.current(options.mockData),
|
|
18
|
+
delay
|
|
19
|
+
);
|
|
20
|
+
return () => clearTimeout(timeout);
|
|
21
|
+
}
|
|
22
|
+
const eventListener = (event) => {
|
|
23
|
+
const { action: eventAction, data } = event.data;
|
|
24
|
+
if (eventAction === action) savedHandler.current(data);
|
|
25
|
+
};
|
|
26
|
+
window.addEventListener("message", eventListener);
|
|
27
|
+
return () => window.removeEventListener("message", eventListener);
|
|
28
|
+
}, [action, options == null ? void 0 : options.mockData, options == null ? void 0 : options.mockDelay]);
|
|
29
|
+
}
|
|
30
|
+
async function fetchNui(eventName, data, options) {
|
|
31
|
+
if (isEnvBrowser()) {
|
|
32
|
+
if ((options == null ? void 0 : options.mockData) === void 0) return Promise.resolve(null);
|
|
33
|
+
const delay = options.mockDelay ?? 500;
|
|
34
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
35
|
+
return options.mockData;
|
|
36
|
+
}
|
|
37
|
+
const response = await fetch(`https://${resourceName}/${eventName}`, {
|
|
38
|
+
method: "POST",
|
|
39
|
+
headers: {
|
|
40
|
+
"Content-Type": "application/json; charset=UTF-8"
|
|
41
|
+
},
|
|
42
|
+
body: JSON.stringify(data ?? {})
|
|
43
|
+
});
|
|
44
|
+
return response.json();
|
|
45
|
+
}
|
|
46
|
+
function useNuiCallback(eventName, callback, options) {
|
|
47
|
+
const [state, setState] = useState({
|
|
48
|
+
loading: false,
|
|
49
|
+
error: null
|
|
50
|
+
});
|
|
51
|
+
const callbackRef = useRef(callback);
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
callbackRef.current = callback;
|
|
54
|
+
}, [callback]);
|
|
55
|
+
const fetch2 = useCallback(
|
|
56
|
+
async (data) => {
|
|
57
|
+
setState({ loading: true, error: null });
|
|
58
|
+
try {
|
|
59
|
+
const result = await fetchNui(eventName, data, options);
|
|
60
|
+
callbackRef.current(result);
|
|
61
|
+
setState({ loading: false, error: null });
|
|
62
|
+
return result;
|
|
63
|
+
} catch (err) {
|
|
64
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
65
|
+
setState({ loading: false, error });
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
[eventName, options]
|
|
70
|
+
);
|
|
71
|
+
return [fetch2, state];
|
|
72
|
+
}
|
|
73
|
+
export {
|
|
74
|
+
fetchNui,
|
|
75
|
+
isEnvBrowser,
|
|
76
|
+
useNuiCallback,
|
|
77
|
+
useNuiEvent
|
|
78
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fivem-nui-react",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "React hooks and utilities for FiveM NUI development",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
20
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"fivem",
|
|
24
|
+
"nui",
|
|
25
|
+
"react",
|
|
26
|
+
"hooks",
|
|
27
|
+
"cfx"
|
|
28
|
+
],
|
|
29
|
+
"author": "",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"type": "commonjs",
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"react": ">=19.0.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/react": "^19.2.8",
|
|
37
|
+
"@types/react-dom": "^19.2.3",
|
|
38
|
+
"react": "^19.2.3",
|
|
39
|
+
"react-dom": "^19.2.3",
|
|
40
|
+
"tsup": "^8.5.1",
|
|
41
|
+
"typescript": "^5.9.3"
|
|
42
|
+
}
|
|
43
|
+
}
|