@fivem-nui/core 0.0.0-stage → 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 +230 -2
- package/dist/CallbackRegistry.d.ts +30 -0
- package/dist/CallbackRegistry.d.ts.map +1 -0
- package/dist/CallbackRegistry.js +37 -0
- package/dist/CallbackRegistry.js.map +1 -0
- package/dist/EventBus.d.ts +44 -0
- package/dist/EventBus.d.ts.map +1 -0
- package/dist/EventBus.js +98 -0
- package/dist/EventBus.js.map +1 -0
- package/dist/MessageTransport.d.ts +32 -0
- package/dist/MessageTransport.d.ts.map +1 -0
- package/dist/MessageTransport.js +70 -0
- package/dist/MessageTransport.js.map +1 -0
- package/dist/NuiClient.d.ts +155 -0
- package/dist/NuiClient.d.ts.map +1 -0
- package/dist/NuiClient.js +425 -0
- package/dist/NuiClient.js.map +1 -0
- package/dist/NuiClientOptions.d.ts +48 -0
- package/dist/NuiClientOptions.d.ts.map +1 -0
- package/dist/NuiClientOptions.js +14 -0
- package/dist/NuiClientOptions.js.map +1 -0
- package/dist/RequestCoordinator.d.ts +46 -0
- package/dist/RequestCoordinator.d.ts.map +1 -0
- package/dist/RequestCoordinator.js +77 -0
- package/dist/RequestCoordinator.js.map +1 -0
- package/dist/diagnostics/NuiDiagnostics.d.ts +29 -0
- package/dist/diagnostics/NuiDiagnostics.d.ts.map +1 -0
- package/dist/diagnostics/NuiDiagnostics.js +2 -0
- package/dist/diagnostics/NuiDiagnostics.js.map +1 -0
- package/dist/diagnostics/index.d.ts +11 -0
- package/dist/diagnostics/index.d.ts.map +1 -0
- package/dist/diagnostics/index.js +2 -0
- package/dist/diagnostics/index.js.map +1 -0
- package/dist/errors.d.ts +41 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +50 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +22 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +42 -0
- package/dist/logger.js.map +1 -0
- package/dist/testing/fake-fetch.d.ts +30 -0
- package/dist/testing/fake-fetch.d.ts.map +1 -0
- package/dist/testing/fake-fetch.js +34 -0
- package/dist/testing/fake-fetch.js.map +1 -0
- package/dist/testing/index.d.ts +39 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +37 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/make-client.d.ts +77 -0
- package/dist/testing/make-client.d.ts.map +1 -0
- package/dist/testing/make-client.js +117 -0
- package/dist/testing/make-client.js.map +1 -0
- package/dist/types.d.ts +128 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +60 -3
- package/src/CallbackRegistry.ts +46 -0
- package/src/EventBus.ts +119 -0
- package/src/MessageTransport.ts +88 -0
- package/src/NuiClient.ts +617 -0
- package/src/NuiClientOptions.ts +57 -0
- package/src/RequestCoordinator.ts +105 -0
- package/src/diagnostics/NuiDiagnostics.ts +28 -0
- package/src/diagnostics/index.ts +10 -0
- package/src/errors.ts +58 -0
- package/src/fivem.d.ts +5 -0
- package/src/index.ts +33 -0
- package/src/logger.ts +53 -0
- package/src/testing/fake-fetch.ts +64 -0
- package/src/testing/index.ts +38 -0
- package/src/testing/make-client.ts +215 -0
- package/src/types.ts +151 -0
package/README.md
CHANGED
|
@@ -1,3 +1,231 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @fivem-nui/core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Strongly typed TypeScript bridge between FiveM NUI panel and C#/.NET client script.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/rian-be/FiveM.Nui/blob/main/LICENSE)
|
|
6
|
+
[](#requirements)
|
|
7
|
+
[](#requirements)
|
|
8
|
+
[](#requirements)
|
|
9
|
+
[](#contributing)
|
|
10
|
+
|
|
11
|
+
`@fivem-nui/core` is the TypeScript half of [FiveM.Nui](../../../README.md): typed request/response, C#-callable callbacks, events, and window notifications, with no framework and no runtime dependencies. Use it with Svelte, React, Vue, or plain TypeScript.
|
|
12
|
+
|
|
13
|
+
## Highlights
|
|
14
|
+
|
|
15
|
+
- **Typed request/response**: correlation IDs, deadlines, and cancellation.
|
|
16
|
+
- **Callbacks**: handlers C# can invoke, with clean unregistration.
|
|
17
|
+
- **Events**: one-way C# → UI subscriptions, isolated per handler.
|
|
18
|
+
- **Window notifications**: `open` / `close` / `focus` / `unfocus`.
|
|
19
|
+
- **Error codes, not text**: branch on `NuiRequestError.code`.
|
|
20
|
+
- **Diagnostics**: message counters for a dev panel.
|
|
21
|
+
- **Zero runtime dependencies**, no framework lock-in.
|
|
22
|
+
|
|
23
|
+
## Requirements
|
|
24
|
+
|
|
25
|
+
- Node.js `>= 22.12.0`
|
|
26
|
+
- TypeScript `7.x` (the package ships ESM output and `.d.ts` declarations)
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install @fivem-nui/core
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or add it to your `package.json`:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@fivem-nui/core": "^1.0.0"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Entry points
|
|
45
|
+
|
|
46
|
+
One package, three import paths:
|
|
47
|
+
|
|
48
|
+
| Import path | Use for |
|
|
49
|
+
|-------------------------------|----------------------------------|
|
|
50
|
+
| `@fivem-nui/core` | Production UI |
|
|
51
|
+
| `@fivem-nui/core/testing` | Tests, no FiveM needed |
|
|
52
|
+
| `@fivem-nui/core/diagnostics` | Dev panels, counters |
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { makeClient } from '@fivem-nui/core/testing';
|
|
56
|
+
import type { NuiDiagnostics } from '@fivem-nui/core/diagnostics';
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
See [Package Entry Points](../../../docs/api/typescript.md#11-package-entry-points) for the full map, and
|
|
60
|
+
[Testing Guide](../../../docs/developers/testing.md) for testing recipes.
|
|
61
|
+
|
|
62
|
+
## Quick start
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { nui } from '@fivem-nui/core';
|
|
66
|
+
|
|
67
|
+
// Once, on page start. Idempotent.
|
|
68
|
+
nui.listen();
|
|
69
|
+
|
|
70
|
+
// C# -> UI: handle a request and answer it.
|
|
71
|
+
nui.callback<void, GetPlayerDataResponse>('player:get', async () => ({
|
|
72
|
+
success: true,
|
|
73
|
+
value: { name: 'NuiPlayer', health: 100 },
|
|
74
|
+
}));
|
|
75
|
+
|
|
76
|
+
// C# -> UI: react to an event. Keep the unsubscribe for teardown.
|
|
77
|
+
const unsubscribe = nui.on<InventoryUpdated>('inventory:update', render);
|
|
78
|
+
|
|
79
|
+
// UI -> C#: fire and forget.
|
|
80
|
+
nui.notify('demo:action', { action: 'send' });
|
|
81
|
+
|
|
82
|
+
// UI -> C#: call a callback registered in C# and await the response.
|
|
83
|
+
const result = await nui.request<UseItemRequest, UseItemResponse>('inventory:use', { itemId });
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`GetPlayerDataResponse`, `InventoryUpdated`, `UseItemRequest`, and `UseItemResponse` are application defined types. The C# side must expose the matching callbacks and handlers.
|
|
87
|
+
|
|
88
|
+
## Generated contracts (optional)
|
|
89
|
+
|
|
90
|
+
The event name strings above are unchecked: a typo compiles and fails at runtime. To make every call statically checked against the C# contract, generate a TypeScript map with the [`FiveM.Nui.Contracts`](../../../tools/FiveM.Nui.Contracts) tool from C# types annotated with `[NuiContract]` and `[NuiEvent]`:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
fivem-nui-contracts -a path/to/MyProject.dll -o src/contracts.ts
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The generated file ends with a module augmentation:
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
declare module '@fivem-nui/core' {
|
|
100
|
+
interface NuiEventMap {
|
|
101
|
+
'inventory:use': { request: UseItemRequest; response: UseItemResponse };
|
|
102
|
+
'player:healthChanged': { payload: HealthChanged };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Import it once for its side effect so the map is part of the program:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import './contracts';
|
|
111
|
+
import { nui } from '@fivem-nui/core';
|
|
112
|
+
|
|
113
|
+
// request/response are inferred from the contract.
|
|
114
|
+
const response = await nui.request('inventory:use', { itemId });
|
|
115
|
+
response.ok; // typed as boolean
|
|
116
|
+
|
|
117
|
+
// A name that is not in the map is a compile error.
|
|
118
|
+
await nui.request('inventory:usee', { itemId }); // Error: not assignable to 'never'
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
While no map is generated `NuiEventMap` stays empty and the client keeps its permissive, string-based signatures, so this is opt-in. When the map is augmented, `request`, `send`, `sendAndWait`, `callback`, `on`, and `once` check the name, the request payload, and the response type; explicit type arguments remain available as an escape hatch. Use `--core-module <module>` if the package is imported under a different specifier.
|
|
122
|
+
|
|
123
|
+
## API
|
|
124
|
+
|
|
125
|
+
| Method | Direction | Purpose |
|
|
126
|
+
|--------------------------------------------------|-----------|-----------------------------------------------------------------------------------------------------------------------|
|
|
127
|
+
| `listen(target?)` | - | Start receiving messages from C#. Idempotent; returns a function that stops listening. |
|
|
128
|
+
| `on<T>(event, handler)` | C# → UI | Subscribe to an event. Returns `unsubscribe`. |
|
|
129
|
+
| `once<T>(event, handler)` | C# → UI | Subscribe to the next matching event only. Returns `unsubscribe`. |
|
|
130
|
+
| `off(event, handler?)` | C# → UI | Remove one handler, or all handlers for the event. |
|
|
131
|
+
| `callback<TReq, TRes>(event, handler)` | C# → UI | Handle C# request the handler returns a `NuiResult`. A thrown handler is answered with `CALLBACK_ERROR`. |
|
|
132
|
+
| `unregisterCallback(event)` | C# → UI | Remove handler, so C# gets `UNKNOWN_CALLBACK` again. Returns `boolean`. |
|
|
133
|
+
| `request<TReq, TRes>(event, payload?, timeout?, signal?)` | UI → C# | Send request and await the response; rejects with `TIMEOUT` after `timeout` (default `30000` ms), or `ABORTED` when `signal` aborts. |
|
|
134
|
+
| `send(event, payload?)` | UI → C# | Fire and forget the HTTP reply is not read. |
|
|
135
|
+
| `sendAndWait(event, payload?)` | UI → C# | Resolve once the POST lands, reject on `POST_TIMEOUT`/`TRANSPORT`. Delivery confirmation only not C# acknowledgement. |
|
|
136
|
+
| `notify(callback, payload?)` | UI → C# | POST to a named resource callback; fire and forget. |
|
|
137
|
+
| `notifyAndWait(callback, payload?)` | UI → C# | Same, but resolve once the resource answers. |
|
|
138
|
+
| `onWindow(handler)` | C# → UI | Receive `(action, window)` for `open` / `close` / `focus` / `unfocus`. |
|
|
139
|
+
| `getDiagnostics()` | - | Counter snapshot (`sent`, `received`, `pending`, `listeners`, …). |
|
|
140
|
+
| `dispose()` | - | Drop listeners, callbacks and pending requests; reject the latter with `DISPOSED`. |
|
|
141
|
+
|
|
142
|
+
## Errors
|
|
143
|
+
|
|
144
|
+
Failed operations reject with a `NuiRequestError`. Read `error.code`; `error.message` is for logs and may change. `isNuiRequestError(error)` narrows it inside `catch`.
|
|
145
|
+
|
|
146
|
+
| Code | Meaning |
|
|
147
|
+
|--------------------|-----------------------------------------------------------------------------------|
|
|
148
|
+
| `UNKNOWN_CALLBACK` | No handler is registered for the event on the side that had to answer. |
|
|
149
|
+
| `CALLBACK_ERROR` | A callback handler threw. |
|
|
150
|
+
| `TIMEOUT` | `request()` exceeded its deadline. |
|
|
151
|
+
| `ABORTED` | The caller aborted the request through its `AbortSignal`. |
|
|
152
|
+
| `POST_TIMEOUT` | A single POST was aborted after `postTimeoutMs`. |
|
|
153
|
+
| `TRANSPORT` | The POST failed for another reason (for example, the resource stopped answering). |
|
|
154
|
+
| `DISPOSED` | `dispose()` was called while the operation was attempted or pending. |
|
|
155
|
+
| `UNKNOWN_ERROR` | A failure was reported without a code. |
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
import { nui, NuiErrorCodes, isNuiRequestError } from '@fivem-nui/core';
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
await nui.request('inventory:use', { itemId });
|
|
162
|
+
} catch (error) {
|
|
163
|
+
if (!isNuiRequestError(error)) throw error;
|
|
164
|
+
|
|
165
|
+
if (error.code === NuiErrorCodes.Timeout) {
|
|
166
|
+
showToast('The server did not respond');
|
|
167
|
+
} else {
|
|
168
|
+
showToast('The request could not be completed');
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
A `TIMEOUT` rejects the promise but does **not** cancel or roll back the operation: the POST may already have reached C#, and late response is dropped. If the operation has side effects, handle retries and duplicates in your application.
|
|
174
|
+
|
|
175
|
+
Pass an `AbortSignal` as the fourth argument to `request()` to stop waiting for one request without disposing the client. It rejects with `ABORTED`, and a response that arrives later is dropped.
|
|
176
|
+
|
|
177
|
+
## Configuration
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
new NuiClient({
|
|
181
|
+
resource: 'panel_orders', // default: GetParentResourceName(), else 'unknown_resource'
|
|
182
|
+
callback: 'nui', // resource callback endpoint (default: 'nui')
|
|
183
|
+
window: 'panel_orders', // filter for onWindow (default: every window)
|
|
184
|
+
postTimeoutMs: 10_000, // per POST abort deadline (default: 10000)
|
|
185
|
+
requestTimeoutMs: 30_000, // default request() deadline (default: 30000)
|
|
186
|
+
logger: nullNuiLogger, // consoleNuiLogger (default) or your own NuiLogger
|
|
187
|
+
fetch: myFetch, // injection seam; default: globalThis.fetch
|
|
188
|
+
});
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
The default export `nui` is bound to the ambient resource. Create an instance when you need different options or your own lifecycle.
|
|
192
|
+
|
|
193
|
+
## Design notes
|
|
194
|
+
|
|
195
|
+
- **`notify` never awaits its reply.** The browser reads nothing from the HTTP response, so awaiting would only stall the page for the whole POST timeout. Use `notifyAndWait` when delivery matters.
|
|
196
|
+
- **`notifyAndWait` exists for the `ready` handshake.** A silent failure there leaves the panel dead for the rest of the session.
|
|
197
|
+
- **`request` is for C# callbacks.** If the UI owns the handler for an event, ask C# with `request`, not `notify`: `notify` discards the reply.
|
|
198
|
+
- **Dispose on teardown.** Call `dispose()` when the page unmounts (remount, HMR) so a stale client cannot keep answering C# on behalf of dead page. After `dispose()` the client is inert; create a new instance to continue.
|
|
199
|
+
- **Handlers are isolated.** A throwing event handler is logged and skipped; its siblings still receive the event. A throwing `callback` handler is answered with `CALLBACK_ERROR` rather than leaving C# waiting.
|
|
200
|
+
|
|
201
|
+
## Architecture
|
|
202
|
+
|
|
203
|
+
`NuiClient` is a thin facade over four collaborators, mirroring the C# side of the bridge:
|
|
204
|
+
|
|
205
|
+
| File | Class | Responsibility |
|
|
206
|
+
|-------------------------|------------------------------------------|------------------------------------------------------------------------------|
|
|
207
|
+
| `MessageTransport.ts` | `MessageTransport` | POSTs to `https://<resource>/<callback>` with an `AbortController` deadline. |
|
|
208
|
+
| `RequestCoordinator.ts` | `RequestCoordinator` | In flight requests, correlation IDs, deadlines, settlement. |
|
|
209
|
+
| `CallbackRegistry.ts` | `CallbackRegistry` | C# request handler lookup. |
|
|
210
|
+
| `EventBus.ts` | `EventBus` | C# → UI subscription and dispatch, with error isolation. |
|
|
211
|
+
| `NuiClientOptions.ts` | `NuiClientOptions`, `readResourceName()` | Configuration and resource-name detection. |
|
|
212
|
+
| `NuiClient.ts` | `NuiClient` | Orchestration: message dispatch, counters, lifecycle. |
|
|
213
|
+
|
|
214
|
+
## Development
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
npm install
|
|
218
|
+
npm run build # tsc -> dist/
|
|
219
|
+
npm run check # tsc --noEmit, plus the type-level contract tests
|
|
220
|
+
npm test # vitest run
|
|
221
|
+
npm run coverage # vitest run --coverage
|
|
222
|
+
npm run watch # rebuild on change
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Contributing
|
|
226
|
+
|
|
227
|
+
Issues and pull requests are welcome at [github.com/rian-be/FiveM.Nui](https://github.com/rian-be/FiveM.Nui). Keep changes focused, add or update tests for new behavior, and update the docs when a public API or its behavior changes.
|
|
228
|
+
|
|
229
|
+
## License
|
|
230
|
+
|
|
231
|
+
[MIT](../../../LICENSE) © 2026 Rian.be
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { NuiMessage } from './types';
|
|
2
|
+
/** Internal storage shape for a registered callback handler. */
|
|
3
|
+
export type CallbackHandler = (request: unknown) => Promise<NuiMessage>;
|
|
4
|
+
/**
|
|
5
|
+
* Registry for C# request handlers.
|
|
6
|
+
*
|
|
7
|
+
* Stores handlers keyed by event name, providing typ safe registration
|
|
8
|
+
* and O(1) lookup by name. A handler that throws is caught by the caller
|
|
9
|
+
* (via {@link NuiClient.handleRequest}) and reported back to C# as
|
|
10
|
+
* `CALLBACK_ERROR` instead of being left unanswered.
|
|
11
|
+
*
|
|
12
|
+
* Mirrors C# `NuiCallbackRegistry`.
|
|
13
|
+
*/
|
|
14
|
+
export declare class CallbackRegistry {
|
|
15
|
+
private callbacks;
|
|
16
|
+
/** Registers (or replaces) a handler for `eventName`. */
|
|
17
|
+
register(eventName: string, handler: CallbackHandler): void;
|
|
18
|
+
/**
|
|
19
|
+
* Removes the handler for `eventName`.
|
|
20
|
+
* @returns `true` if a handler was removed.
|
|
21
|
+
*/
|
|
22
|
+
unregister(eventName: string): boolean;
|
|
23
|
+
/** Retrieves the handler for `eventName`, or `undefined` if none. */
|
|
24
|
+
get(eventName: string): CallbackHandler | undefined;
|
|
25
|
+
/** Number of registered callbacks. */
|
|
26
|
+
get count(): number;
|
|
27
|
+
/** Removes every registered callback. Called during `dispose()`. */
|
|
28
|
+
clear(): void;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=CallbackRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallbackRegistry.d.ts","sourceRoot":"","sources":["../src/CallbackRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,gEAAgE;AAChE,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AAExE;;;;;;;;;GASG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAsC;IAEvD,yDAAyD;IACzD,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CAE1D;IAED;;;OAGG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAErC;IAED,qEAAqE;IACrE,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAElD;IAED,sCAAsC;IACtC,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,oEAAoE;IACpE,KAAK,IAAI,IAAI,CAEZ;CACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry for C# request handlers.
|
|
3
|
+
*
|
|
4
|
+
* Stores handlers keyed by event name, providing typ safe registration
|
|
5
|
+
* and O(1) lookup by name. A handler that throws is caught by the caller
|
|
6
|
+
* (via {@link NuiClient.handleRequest}) and reported back to C# as
|
|
7
|
+
* `CALLBACK_ERROR` instead of being left unanswered.
|
|
8
|
+
*
|
|
9
|
+
* Mirrors C# `NuiCallbackRegistry`.
|
|
10
|
+
*/
|
|
11
|
+
export class CallbackRegistry {
|
|
12
|
+
callbacks = new Map();
|
|
13
|
+
/** Registers (or replaces) a handler for `eventName`. */
|
|
14
|
+
register(eventName, handler) {
|
|
15
|
+
this.callbacks.set(eventName, handler);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Removes the handler for `eventName`.
|
|
19
|
+
* @returns `true` if a handler was removed.
|
|
20
|
+
*/
|
|
21
|
+
unregister(eventName) {
|
|
22
|
+
return this.callbacks.delete(eventName);
|
|
23
|
+
}
|
|
24
|
+
/** Retrieves the handler for `eventName`, or `undefined` if none. */
|
|
25
|
+
get(eventName) {
|
|
26
|
+
return this.callbacks.get(eventName);
|
|
27
|
+
}
|
|
28
|
+
/** Number of registered callbacks. */
|
|
29
|
+
get count() {
|
|
30
|
+
return this.callbacks.size;
|
|
31
|
+
}
|
|
32
|
+
/** Removes every registered callback. Called during `dispose()`. */
|
|
33
|
+
clear() {
|
|
34
|
+
this.callbacks.clear();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=CallbackRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallbackRegistry.js","sourceRoot":"","sources":["../src/CallbackRegistry.ts"],"names":[],"mappings":"AAKA;;;;;;;;;GASG;AACH,MAAM,OAAO,gBAAgB;IACnB,SAAS,GAAG,IAAI,GAAG,EAA2B,CAAC;IAEvD,yDAAyD;IACzD,QAAQ,CAAC,SAAiB,EAAE,OAAwB;QAClD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,SAAiB;QAC1B,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;IAED,qEAAqE;IACrE,GAAG,CAAC,SAAiB;QACnB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;IAED,sCAAsC;IACtC,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;IAC7B,CAAC;IAED,oEAAoE;IACpE,KAAK;QACH,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;CACF"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { NuiLogger } from './logger';
|
|
2
|
+
/** Internal listener type: accepts any payload, callers cast as needed. */
|
|
3
|
+
export type EventHandler = (data: unknown) => void;
|
|
4
|
+
/**
|
|
5
|
+
* Type safe event subscription and dispatch.
|
|
6
|
+
*
|
|
7
|
+
* Maintains multiple listeners per event name, supports one-shot
|
|
8
|
+
* subscriptions (`once`), and isolates handler errors so a throwing
|
|
9
|
+
* listener cannot prevent its siblings from receiving the payload.
|
|
10
|
+
*
|
|
11
|
+
* Mirrors C# `EventManager`.
|
|
12
|
+
*/
|
|
13
|
+
export declare class EventBus {
|
|
14
|
+
private readonly listeners;
|
|
15
|
+
private readonly logger;
|
|
16
|
+
constructor(logger: NuiLogger);
|
|
17
|
+
/**
|
|
18
|
+
* Subscribes to `eventName`.
|
|
19
|
+
* @returns an unsubscribe function.
|
|
20
|
+
*/
|
|
21
|
+
on<T>(eventName: string, handler: (data: T) => void): () => void;
|
|
22
|
+
/**
|
|
23
|
+
* Subscribes to the next occurrence of `eventName` only.
|
|
24
|
+
* @returns an unsubscribe function (also valid after the handler fired).
|
|
25
|
+
*/
|
|
26
|
+
once<T>(eventName: string, handler: (data: T) => void): () => void;
|
|
27
|
+
/**
|
|
28
|
+
* Unsubscribes from `eventName`.
|
|
29
|
+
* If `handler` is omitted, removes every listener for that event.
|
|
30
|
+
*/
|
|
31
|
+
off(eventName: string, handler?: EventHandler): void;
|
|
32
|
+
/**
|
|
33
|
+
* Dispatches `payload` to every listener of `eventName`.
|
|
34
|
+
*
|
|
35
|
+
* Copies the listener set first so a handler that unsubscribes itself
|
|
36
|
+
* (or removes a sibling) cannot skip the next listener.
|
|
37
|
+
*/
|
|
38
|
+
emit(eventName: string, payload: unknown): void;
|
|
39
|
+
/** Total listeners across all events. */
|
|
40
|
+
get listenerCount(): number;
|
|
41
|
+
/** Removes every listener. Called during `dispose()`. */
|
|
42
|
+
clear(): void;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=EventBus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventBus.d.ts","sourceRoot":"","sources":["../src/EventBus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,2EAA2E;AAC3E,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;AAEnD;;;;;;;;GAQG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwC;IAClE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IAEnC,YAAY,MAAM,EAAE,SAAS,EAE5B;IAED;;;OAGG;IACH,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAkB/D;IAED;;;OAGG;IACH,IAAI,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAOjE;IAED;;;OAGG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAgBnD;IAED;;;;;OAKG;IACH,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAc9C;IAED,yCAAyC;IACzC,IAAI,aAAa,IAAI,MAAM,CAQ1B;IAED,yDAAyD;IACzD,KAAK,IAAI,IAAI,CAEZ;CACF"}
|
package/dist/EventBus.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type safe event subscription and dispatch.
|
|
3
|
+
*
|
|
4
|
+
* Maintains multiple listeners per event name, supports one-shot
|
|
5
|
+
* subscriptions (`once`), and isolates handler errors so a throwing
|
|
6
|
+
* listener cannot prevent its siblings from receiving the payload.
|
|
7
|
+
*
|
|
8
|
+
* Mirrors C# `EventManager`.
|
|
9
|
+
*/
|
|
10
|
+
export class EventBus {
|
|
11
|
+
listeners = new Map();
|
|
12
|
+
logger;
|
|
13
|
+
constructor(logger) {
|
|
14
|
+
this.logger = logger;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Subscribes to `eventName`.
|
|
18
|
+
* @returns an unsubscribe function.
|
|
19
|
+
*/
|
|
20
|
+
on(eventName, handler) {
|
|
21
|
+
let set = this.listeners.get(eventName);
|
|
22
|
+
if (!set) {
|
|
23
|
+
set = new Set();
|
|
24
|
+
this.listeners.set(eventName, set);
|
|
25
|
+
}
|
|
26
|
+
const listener = handler;
|
|
27
|
+
set.add(listener);
|
|
28
|
+
return () => {
|
|
29
|
+
set.delete(listener);
|
|
30
|
+
if (set.size === 0) {
|
|
31
|
+
this.listeners.delete(eventName);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Subscribes to the next occurrence of `eventName` only.
|
|
37
|
+
* @returns an unsubscribe function (also valid after the handler fired).
|
|
38
|
+
*/
|
|
39
|
+
once(eventName, handler) {
|
|
40
|
+
const unsubscribe = this.on(eventName, data => {
|
|
41
|
+
unsubscribe();
|
|
42
|
+
handler(data);
|
|
43
|
+
});
|
|
44
|
+
return unsubscribe;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Unsubscribes from `eventName`.
|
|
48
|
+
* If `handler` is omitted, removes every listener for that event.
|
|
49
|
+
*/
|
|
50
|
+
off(eventName, handler) {
|
|
51
|
+
const set = this.listeners.get(eventName);
|
|
52
|
+
if (!set) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (handler) {
|
|
56
|
+
set.delete(handler);
|
|
57
|
+
if (set.size === 0) {
|
|
58
|
+
this.listeners.delete(eventName);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
this.listeners.delete(eventName);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Dispatches `payload` to every listener of `eventName`.
|
|
67
|
+
*
|
|
68
|
+
* Copies the listener set first so a handler that unsubscribes itself
|
|
69
|
+
* (or removes a sibling) cannot skip the next listener.
|
|
70
|
+
*/
|
|
71
|
+
emit(eventName, payload) {
|
|
72
|
+
const set = this.listeners.get(eventName);
|
|
73
|
+
if (!set) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
for (const listener of [...set]) {
|
|
77
|
+
try {
|
|
78
|
+
listener(payload);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
this.logger.error(`Error in event handler for: ${eventName}`, error);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/** Total listeners across all events. */
|
|
86
|
+
get listenerCount() {
|
|
87
|
+
let total = 0;
|
|
88
|
+
for (const set of this.listeners.values()) {
|
|
89
|
+
total += set.size;
|
|
90
|
+
}
|
|
91
|
+
return total;
|
|
92
|
+
}
|
|
93
|
+
/** Removes every listener. Called during `dispose()`. */
|
|
94
|
+
clear() {
|
|
95
|
+
this.listeners.clear();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=EventBus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventBus.js","sourceRoot":"","sources":["../src/EventBus.ts"],"names":[],"mappings":"AAKA;;;;;;;;GAQG;AACH,MAAM,OAAO,QAAQ;IACF,SAAS,GAAG,IAAI,GAAG,EAA6B,CAAC;IACjD,MAAM,CAAY;IAEnC,YAAY,MAAiB;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED;;;OAGG;IACH,EAAE,CAAI,SAAiB,EAAE,OAA0B;QACjD,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAExC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;YAChB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC;QAED,MAAM,QAAQ,GAAG,OAAuB,CAAC;QACzC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAElB,OAAO,GAAG,EAAE;YACV,GAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAEtB,IAAI,GAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACpB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACnC,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,IAAI,CAAI,SAAiB,EAAE,OAA0B;QACnD,MAAM,WAAW,GAAG,IAAI,CAAC,EAAE,CAAI,SAAS,EAAE,IAAI,CAAC,EAAE;YAC/C,WAAW,EAAE,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;OAGG;IACH,GAAG,CAAC,SAAiB,EAAE,OAAsB;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAE1C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO;QACT,CAAC;QAED,IAAI,OAAO,EAAE,CAAC;YACZ,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAEpB,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACnB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,IAAI,CAAC,SAAiB,EAAE,OAAgB;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAE1C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO;QACT,CAAC;QAED,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC;gBACH,QAAQ,CAAC,OAAO,CAAC,CAAC;YACpB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,SAAS,EAAE,EAAE,KAAK,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,IAAI,aAAa;QACf,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1C,KAAK,IAAI,GAAG,CAAC,IAAI,CAAC;QACpB,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,yDAAyD;IACzD,KAAK;QACH,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;CACF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { NuiLogger } from './logger';
|
|
2
|
+
export type FetchImpl = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
3
|
+
/**
|
|
4
|
+
* HTTP transport for FiveM NUI.
|
|
5
|
+
*
|
|
6
|
+
* Posts envelopes to `https://<resource>/<callback>` using `fetch`.
|
|
7
|
+
* Each POST is bounded by an `AbortController` deadline so a resource
|
|
8
|
+
* that stops answering (restart, shutdown) does not hang the page forever.
|
|
9
|
+
*
|
|
10
|
+
* Mirrors C# `FiveMNuiTransport`.
|
|
11
|
+
*/
|
|
12
|
+
export declare class MessageTransport {
|
|
13
|
+
private readonly resource;
|
|
14
|
+
private readonly callbackName;
|
|
15
|
+
private readonly postTimeoutMs;
|
|
16
|
+
private readonly logger;
|
|
17
|
+
private readonly fetchImpl;
|
|
18
|
+
constructor(resource: string, callbackName: string, postTimeoutMs: number, logger: NuiLogger, fetchImpl: FetchImpl);
|
|
19
|
+
/** URL of the main resource callback. */
|
|
20
|
+
get mainCallbackUrl(): string;
|
|
21
|
+
/** Builds the URL for an arbitrary callback on the same resource. */
|
|
22
|
+
callbackUrl(callbackName: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Raw POST to `url` with the configured timeout deadline.
|
|
25
|
+
*
|
|
26
|
+
* @throws {NuiRequestError} with code `POST_TIMEOUT` when the resource
|
|
27
|
+
* stops answering within `postTimeoutMs`.
|
|
28
|
+
* @throws {NuiRequestError} with code `TRANSPORT` for any other failure.
|
|
29
|
+
*/
|
|
30
|
+
post(url: string, body: unknown): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=MessageTransport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageTransport.d.ts","sourceRoot":"","sources":["../src/MessageTransport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG1C,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE5F;;;;;;;;GAQG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IAEtC,YACE,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,SAAS,EAOrB;IAED,yCAAyC;IACzC,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED,qEAAqE;IACrE,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAExC;IAED;;;;;;OAMG;IACG,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAiCpD;CACF"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { NuiErrorCodes, NuiRequestError } from './errors';
|
|
2
|
+
/**
|
|
3
|
+
* HTTP transport for FiveM NUI.
|
|
4
|
+
*
|
|
5
|
+
* Posts envelopes to `https://<resource>/<callback>` using `fetch`.
|
|
6
|
+
* Each POST is bounded by an `AbortController` deadline so a resource
|
|
7
|
+
* that stops answering (restart, shutdown) does not hang the page forever.
|
|
8
|
+
*
|
|
9
|
+
* Mirrors C# `FiveMNuiTransport`.
|
|
10
|
+
*/
|
|
11
|
+
export class MessageTransport {
|
|
12
|
+
resource;
|
|
13
|
+
callbackName;
|
|
14
|
+
postTimeoutMs;
|
|
15
|
+
logger;
|
|
16
|
+
fetchImpl;
|
|
17
|
+
constructor(resource, callbackName, postTimeoutMs, logger, fetchImpl) {
|
|
18
|
+
this.resource = resource;
|
|
19
|
+
this.callbackName = callbackName;
|
|
20
|
+
this.postTimeoutMs = postTimeoutMs;
|
|
21
|
+
this.logger = logger;
|
|
22
|
+
this.fetchImpl = fetchImpl;
|
|
23
|
+
}
|
|
24
|
+
/** URL of the main resource callback. */
|
|
25
|
+
get mainCallbackUrl() {
|
|
26
|
+
return `https://${this.resource}/${encodeURIComponent(this.callbackName)}`;
|
|
27
|
+
}
|
|
28
|
+
/** Builds the URL for an arbitrary callback on the same resource. */
|
|
29
|
+
callbackUrl(callbackName) {
|
|
30
|
+
return `https://${this.resource}/${encodeURIComponent(callbackName)}`;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Raw POST to `url` with the configured timeout deadline.
|
|
34
|
+
*
|
|
35
|
+
* @throws {NuiRequestError} with code `POST_TIMEOUT` when the resource
|
|
36
|
+
* stops answering within `postTimeoutMs`.
|
|
37
|
+
* @throws {NuiRequestError} with code `TRANSPORT` for any other failure.
|
|
38
|
+
*/
|
|
39
|
+
async post(url, body) {
|
|
40
|
+
// Without an abort, a resource that stops answering leaves this promise
|
|
41
|
+
// pending forever and the caller's await never returns.
|
|
42
|
+
const controller = new AbortController();
|
|
43
|
+
const deadline = setTimeout(() => controller.abort(), this.postTimeoutMs);
|
|
44
|
+
try {
|
|
45
|
+
await this.fetchImpl(url, {
|
|
46
|
+
method: 'POST',
|
|
47
|
+
headers: { 'Content-Type': 'application/json; charset=UTF-8' },
|
|
48
|
+
body: JSON.stringify(body),
|
|
49
|
+
signal: controller.signal,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
// A timeout abort surfaces as an error whose `name` is 'AbortError'.
|
|
54
|
+
// In browsers that is a DOMException, but some fetch polyfills throw a
|
|
55
|
+
// plain Error, so match on the name instead of the constructor. Checking
|
|
56
|
+
// only `controller.signal.aborted` is unsafe: a race between the deadline
|
|
57
|
+
// firing and an unrelated network error would misclassify the network
|
|
58
|
+
// error as POST_TIMEOUT.
|
|
59
|
+
const isAbortError = error?.name === 'AbortError';
|
|
60
|
+
if (isAbortError) {
|
|
61
|
+
throw new NuiRequestError(NuiErrorCodes.PostTimeout, `POST ${url} timed out after ${this.postTimeoutMs}ms`);
|
|
62
|
+
}
|
|
63
|
+
throw new NuiRequestError(NuiErrorCodes.Transport, String(error));
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
clearTimeout(deadline);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=MessageTransport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageTransport.js","sourceRoot":"","sources":["../src/MessageTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAM1D;;;;;;;;GAQG;AACH,MAAM,OAAO,gBAAgB;IACV,QAAQ,CAAS;IACjB,YAAY,CAAS;IACrB,aAAa,CAAS;IACtB,MAAM,CAAY;IAClB,SAAS,CAAY;IAEtC,YACE,QAAgB,EAChB,YAAoB,EACpB,aAAqB,EACrB,MAAiB,EACjB,SAAoB;QAEpB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED,yCAAyC;IACzC,IAAI,eAAe;QACjB,OAAO,WAAW,IAAI,CAAC,QAAQ,IAAI,kBAAkB,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;IAC7E,CAAC;IAED,qEAAqE;IACrE,WAAW,CAAC,YAAoB;QAC9B,OAAO,WAAW,IAAI,CAAC,QAAQ,IAAI,kBAAkB,CAAC,YAAY,CAAC,EAAE,CAAC;IACxE,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,IAAa;QACnC,wEAAwE;QACxE,wDAAwD;QACxD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAE1E,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;gBACxB,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,iCAAiC,EAAE;gBAC9D,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC1B,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,qEAAqE;YACrE,uEAAuE;YACvE,yEAAyE;YACzE,0EAA0E;YAC1E,sEAAsE;YACtE,yBAAyB;YACzB,MAAM,YAAY,GAAI,KAAkC,EAAE,IAAI,KAAK,YAAY,CAAC;YAEhF,IAAI,YAAY,EAAE,CAAC;gBACjB,MAAM,IAAI,eAAe,CACvB,aAAa,CAAC,WAAW,EACzB,QAAQ,GAAG,oBAAoB,IAAI,CAAC,aAAa,IAAI,CACtD,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,eAAe,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACpE,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;CACF"}
|