lenix 1.7.24 → 1.8.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/client/_init.ts +52 -0
- package/client/nui.ts +3 -3
- package/nui/fetch.ts +21 -3
- package/nui/on.ts +11 -11
- package/package.json +1 -1
- package/server/index.ts +2 -1
- package/server/nui.ts +25 -0
- package/shared/types.ts +6 -1
package/client/_init.ts
CHANGED
|
@@ -1,6 +1,58 @@
|
|
|
1
|
+
import { asserts, JsonValue } from '@lenix/lenix'
|
|
1
2
|
import type { Request } from '../shared/types.ts'
|
|
2
3
|
import { onNui } from './nui.ts'
|
|
3
4
|
|
|
5
|
+
type Resolve = {
|
|
6
|
+
success: true,
|
|
7
|
+
returned: JsonValue
|
|
8
|
+
} | {
|
|
9
|
+
success: false
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const DEFAULT_TIMEOUT = 5000
|
|
13
|
+
const pendingResolves: Record<number, (resolve: Resolve) => void> = {}
|
|
14
|
+
const requests: string[] = []
|
|
15
|
+
let requestId = 0
|
|
16
|
+
|
|
17
|
+
onNui<Request<JsonValue, '__nuiServer', {
|
|
18
|
+
id: string
|
|
19
|
+
data: {
|
|
20
|
+
requestData: JsonValue
|
|
21
|
+
timeout?: number
|
|
22
|
+
}
|
|
23
|
+
}>>('__nuiServer', async ({ id, data }) => {
|
|
24
|
+
const { timeout = DEFAULT_TIMEOUT, requestData } = data
|
|
25
|
+
|
|
26
|
+
const response = await new Promise<Resolve>(resolve => {
|
|
27
|
+
requestId = requestId + 1
|
|
28
|
+
const currentRequestId = requestId
|
|
29
|
+
pendingResolves[currentRequestId] = resolve
|
|
30
|
+
|
|
31
|
+
if (!requests.includes(id)) {
|
|
32
|
+
requests.push(id)
|
|
33
|
+
onNet(`lenix/nui:${id}`, (selfrequestId: number, response: JsonValue) => {
|
|
34
|
+
if (!pendingResolves[selfrequestId]) return
|
|
35
|
+
|
|
36
|
+
pendingResolves[selfrequestId]({ success: true, returned: response })
|
|
37
|
+
delete pendingResolves[selfrequestId]
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
emitNet(`lenix/nui:${id}`, currentRequestId, requestData)
|
|
42
|
+
|
|
43
|
+
setTimeout(() => {
|
|
44
|
+
if (pendingResolves[currentRequestId]) {
|
|
45
|
+
pendingResolves[currentRequestId]({ success: false })
|
|
46
|
+
delete pendingResolves[currentRequestId]
|
|
47
|
+
}
|
|
48
|
+
}, timeout)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
asserts(response.success, `server nui<${id}> timed out after ${timeout}ms, possible slow respose or request does not exist`)
|
|
52
|
+
|
|
53
|
+
return response.returned
|
|
54
|
+
})
|
|
55
|
+
|
|
4
56
|
onNui<Request<true, '__nuiFocus', {
|
|
5
57
|
keyboard: boolean,
|
|
6
58
|
cursor: boolean
|
package/client/nui.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { NuiFetchGeneric } from '../shared/types.ts'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Sends an event from the game client to the NUI browser.
|
|
5
5
|
*/
|
|
6
|
-
export const
|
|
6
|
+
export const emitNui = <T extends [string, unknown[]]>(id: T[0], ...params: T[1]): void => {
|
|
7
7
|
if (
|
|
8
8
|
!SendNuiMessage(
|
|
9
9
|
JSON.stringify({
|
|
@@ -19,7 +19,7 @@ export const emitEvent = <T extends [string, unknown[]]>(id: T[0], ...params: T[
|
|
|
19
19
|
/**
|
|
20
20
|
* Registers a typed NUI callback on the game client.
|
|
21
21
|
*/
|
|
22
|
-
export const onNui = <T extends
|
|
22
|
+
export const onNui = <T extends NuiFetchGeneric>(
|
|
23
23
|
id: T[1],
|
|
24
24
|
cb: (data: T[2]) => T[0] | Promise<T[0]>
|
|
25
25
|
): void => {
|
package/nui/fetch.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { Request } from '../shared/types.ts'
|
|
1
|
+
import type { NuiFetchGeneric, Request } from '../shared/types.ts'
|
|
3
2
|
|
|
4
3
|
declare function GetParentResourceName(): string
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* Fetchs a typed request from the NUI browser to the game client.
|
|
8
7
|
*/
|
|
9
|
-
export const fetchNui = async <T extends
|
|
8
|
+
export const fetchNui = async <T extends NuiFetchGeneric>(
|
|
10
9
|
id: T[1],
|
|
11
10
|
data: T[2]
|
|
12
11
|
): Promise<T[0]> => {
|
|
@@ -23,3 +22,22 @@ export const fetchNui = async <T extends Request<JsonValue, string, object>>(
|
|
|
23
22
|
throw `Error occured while emiting an nui<${id}>.\n${e}`
|
|
24
23
|
}
|
|
25
24
|
}
|
|
25
|
+
|
|
26
|
+
export const fetchNuiServer = <T extends NuiFetchGeneric>(
|
|
27
|
+
id: T[1],
|
|
28
|
+
requestData: T[2],
|
|
29
|
+
timeout?: number,
|
|
30
|
+
): Promise<T[0]> => fetchNui<Request<T[0], '__nuiServer', {
|
|
31
|
+
id: T[1]
|
|
32
|
+
data: {
|
|
33
|
+
timeout?: number
|
|
34
|
+
requestData: T[2]
|
|
35
|
+
}
|
|
36
|
+
}>>(
|
|
37
|
+
'__nuiServer', {
|
|
38
|
+
id,
|
|
39
|
+
data: {
|
|
40
|
+
timeout,
|
|
41
|
+
requestData,
|
|
42
|
+
}
|
|
43
|
+
})
|
package/nui/on.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { Event } from '../shared/types.ts'
|
|
2
2
|
|
|
3
|
-
interface
|
|
3
|
+
interface Logger<T extends unknown[]> {
|
|
4
4
|
callback: (...params: T) => void
|
|
5
5
|
log?: true
|
|
6
6
|
}
|
|
7
|
-
const events = new Map<string, Set<
|
|
7
|
+
const events = new Map<string, Set<Logger<unknown[]>>>()
|
|
8
8
|
|
|
9
9
|
const handler = (event: MessageEvent) => {
|
|
10
10
|
const { id, params } = event.data
|
|
@@ -24,34 +24,34 @@ const handler = (event: MessageEvent) => {
|
|
|
24
24
|
/**
|
|
25
25
|
* Registers a typed browser-side handler for events sent from the game client.
|
|
26
26
|
*/
|
|
27
|
-
export const
|
|
27
|
+
export const onNuiEmit = <
|
|
28
28
|
T extends Event<string, unknown[]>
|
|
29
29
|
>(
|
|
30
30
|
id: T[0],
|
|
31
31
|
cb: (...params: T[1]) => void,
|
|
32
|
-
|
|
32
|
+
log?: true
|
|
33
33
|
): () => void => {
|
|
34
34
|
if (events.size === 0) {
|
|
35
35
|
window.addEventListener('message', handler)
|
|
36
|
-
|
|
36
|
+
log && console.info(`Event<${id}> is the first on the window`)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
const callbacks = events.get(id) ?? new Set<
|
|
40
|
-
const listenerCb = { callback: cb, log:
|
|
39
|
+
const callbacks = events.get(id) ?? new Set<Logger<unknown[]>>()
|
|
40
|
+
const listenerCb = { callback: cb, log: log }
|
|
41
41
|
callbacks.add(listenerCb)
|
|
42
42
|
events.set(id, callbacks)
|
|
43
|
-
|
|
43
|
+
log && console.info(`Event<${id}> was registered`)
|
|
44
44
|
|
|
45
45
|
return () => {
|
|
46
|
-
|
|
46
|
+
log && console.info(`Event<${id}> was unregistered`)
|
|
47
47
|
callbacks.delete(listenerCb)
|
|
48
48
|
if (callbacks.size === 0) {
|
|
49
49
|
events.delete(id)
|
|
50
|
-
|
|
50
|
+
log && console.info(`Event<${id}> got no callbacks left, memory cleared successfully`)
|
|
51
51
|
}
|
|
52
52
|
if (events.size === 0) {
|
|
53
53
|
window.removeEventListener('message', handler)
|
|
54
|
-
|
|
54
|
+
log && console.info(`No events left, this event<${id}> was the last, opting out the listen...`)
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
}
|
package/package.json
CHANGED
package/server/index.ts
CHANGED
package/server/nui.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { asserts } from "@lenix/lenix";
|
|
2
|
+
import { NuiFetchGeneric } from "../shared";
|
|
3
|
+
|
|
4
|
+
const clientRequests: string[] = []
|
|
5
|
+
|
|
6
|
+
export const onNuiServer = <T extends NuiFetchGeneric>(
|
|
7
|
+
id: T[1],
|
|
8
|
+
cb: (client: number, data: T[2]) => T[0] | Promise<T[0]>
|
|
9
|
+
) => {
|
|
10
|
+
asserts(!clientRequests.includes(id), `server nui<${id}> is already defined`)
|
|
11
|
+
|
|
12
|
+
clientRequests.push(id)
|
|
13
|
+
|
|
14
|
+
onNet(`lenix/nui:${id}`, async(requestId: number, parameters: Parameters<typeof cb>[1]) => {
|
|
15
|
+
const clientSource = source
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
const result = await cb(clientSource, parameters)
|
|
19
|
+
emitNet(`lenix/nui:${id}`, clientSource, requestId, result)
|
|
20
|
+
} catch (error) {
|
|
21
|
+
emitNet(`lenix/nui:${id}`, clientSource, requestId)
|
|
22
|
+
throw error
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
}
|
package/shared/types.ts
CHANGED
|
@@ -18,9 +18,14 @@ export type Event<Id extends string, Params extends unknown[] = never> = [Id, Pa
|
|
|
18
18
|
/**
|
|
19
19
|
* Typed request tuple containing a response type, request id, and object payload.
|
|
20
20
|
*/
|
|
21
|
+
interface JsonObject {
|
|
22
|
+
[key: string]: JsonValue
|
|
23
|
+
}
|
|
21
24
|
export type Request<
|
|
22
25
|
Response extends JsonValue,
|
|
23
26
|
Id extends string,
|
|
24
|
-
Params extends
|
|
27
|
+
Params extends JsonObject = JsonObject
|
|
25
28
|
> = Params extends readonly unknown[] ? never
|
|
26
29
|
: [Response, Id, Params]
|
|
30
|
+
|
|
31
|
+
export type NuiFetchGeneric = Request<JsonValue, string, JsonObject>
|