mirror of
https://github.com/rilaxik/fivem-rpc.git
synced 2026-09-28 01:29:13 +00:00
docs: bump readme.md + metadata
This commit is contained in:
@@ -0,0 +1,53 @@
|
|||||||
|
# Migrating from 0.1 to 1.0
|
||||||
|
|
||||||
|
Upgrade server, client and webview together. The payload format changed, so 0.1 and 1.0 cannot talk to each other
|
||||||
|
|
||||||
|
## Creating the instance
|
||||||
|
|
||||||
|
`RPCFactory` is gone, use `createRPC`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// 0.1
|
||||||
|
import { RPCFactory } from '@entityseven/fivem-rpc'
|
||||||
|
export const rpc = new RPCFactory({ env: 'server' }).get()
|
||||||
|
|
||||||
|
// 1.0
|
||||||
|
import { createRPC } from '@entityseven/fivem-rpc'
|
||||||
|
export const rpc = createRPC({ env: 'server' })
|
||||||
|
```
|
||||||
|
|
||||||
|
## Errors and timeouts
|
||||||
|
|
||||||
|
- a failed call now rejects on the caller with `RPCError` (`code`, `message`, `details`). In 0.1 the error was thrown on the receiving side and the call never settled
|
||||||
|
- every call times out after 5000 ms by default. Change it with `RPCConfig.timeout`, `0` restores the 0.1 behaviour (wait forever)
|
||||||
|
- `RPCErrors.INVALID_DATA` and `RPCErrors.NO_PLAYER` are removed (invalid payloads are dropped), `RPCErrors.TIMEOUT` and `RPCErrors.HANDLER_ERROR` are new
|
||||||
|
- the texts of `RPCErrors.UNKNOWN_NATIVE` and `RPCErrors.UNKNOWN_ENVIRONMENT` changed. Compare `error.code` with `RPCErrors`, not message strings
|
||||||
|
|
||||||
|
See [Errors](rpc/readme.md#errors) and [How it works](rpc/readme.md#how-it-works)
|
||||||
|
|
||||||
|
## Typing
|
||||||
|
|
||||||
|
Declarations are now module augmentation of interfaces, the `types` / `typeRoots` tsconfig setup is no longer needed. Follow the [shared-types readme](shared-types/readme.md), then:
|
||||||
|
|
||||||
|
- commands are interface keys instead of string unions:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// 0.1
|
||||||
|
export type RPCCommands_Server = 'ban' | 'kick'
|
||||||
|
|
||||||
|
// 1.0
|
||||||
|
interface RPCCommands_Server {
|
||||||
|
ban: true
|
||||||
|
kick: true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- remove placeholder members such as `_(): void`. An interface with any member is strict, an empty one accepts everything
|
||||||
|
|
||||||
|
## Other API changes
|
||||||
|
|
||||||
|
- `onCommand` callbacks get `args` as `string[]` (the generic argument type is gone)
|
||||||
|
- `RPCNativeClientNetworksEvents` is renamed to `RPCNativeClientNetworkEvents`
|
||||||
|
- internal types are no longer exported: `RPCEnvironmentResolved`, `RPCEventType`, `RPCEvents`, `RPCState`, `RPCStateRaw`, `RPCStateWeb`, `RPCStateWebRaw`. Use `RPCInstanceServer`, `RPCInstanceClient` or `RPCInstanceWebview` for the instance type
|
||||||
|
- server listeners get the player id from FiveM's `source`. Ids a client puts into the payload are ignored
|
||||||
|
- `emitClientEveryone` is one-way: clients run their listener but no longer send a response
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# FiveM RPC
|
# FiveM RPC
|
||||||
|
|
||||||
is an all-in-one package with asynchronous RPC implementation for FiveM servers in JS/TS
|
Call FiveM server, client and NUI listeners like async functions: typed, with timeouts, no event ping-pong
|
||||||
|
|
||||||
## Motivation
|
## Motivation
|
||||||
|
|
||||||
@@ -31,6 +31,8 @@ yarn add -D @entityseven/fivem-rpc-shared-types
|
|||||||
bun add -d @entityseven/fivem-rpc-shared-types
|
bun add -d @entityseven/fivem-rpc-shared-types
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Upgrading from 0.1: [migration guide](migration.md)
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
|
|
||||||
Create exactly one instance per environment and import it from your own module, not from the library. The client needs one even if it only relays between server and webview.
|
Create exactly one instance per environment and import it from your own module, not from the library. The client needs one even if it only relays between server and webview.
|
||||||
@@ -70,11 +72,13 @@ All methods: [API reference](rpc/readme.md).
|
|||||||
|
|
||||||
Issues and pull requests are very welcome
|
Issues and pull requests are very welcome
|
||||||
|
|
||||||
|
Releases are published with `bun publish`, which replaces the `workspace:^` dependency on shared-types with its version (`npm publish` would not)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Licensed under Custom Attribution-NoDerivs Software License
|
Licensed under the [Custom Attribution-NoDerivs Software License](license.md)
|
||||||
|
|
||||||
## WIP
|
## Roadmap
|
||||||
|
|
||||||
- client observers to catch events between server and webview (subscribe-like behaviour)
|
- client observers to catch events between server and webview (subscribe-like behaviour)
|
||||||
- client observers to prevent events (middleware-like behaviour)
|
- client observers to prevent events (middleware-like behaviour)
|
||||||
|
|||||||
+6
-3
@@ -1,12 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "@entityseven/fivem-rpc",
|
"name": "@entityseven/fivem-rpc",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"description": "FiveM RPC is an all-in-one package with asynchronous RPC implementation for FiveM servers in JS/TS",
|
"description": "Call FiveM server, client and NUI listeners like async functions: typed, with timeouts, no event ping-pong",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
"cfx",
|
||||||
"fivem",
|
"fivem",
|
||||||
"fivem-rpc",
|
"fivem-rpc",
|
||||||
"fivem-rpc-shared-types",
|
"gta",
|
||||||
"gta"
|
"nui",
|
||||||
|
"rpc",
|
||||||
|
"typescript"
|
||||||
],
|
],
|
||||||
"license": "SEE LICENSE IN license.md",
|
"license": "SEE LICENSE IN license.md",
|
||||||
"author": "Entity Seven Group",
|
"author": "Entity Seven Group",
|
||||||
|
|||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
# FiveM RPC
|
# FiveM RPC
|
||||||
|
|
||||||
is an all-in-one package with asynchronous RPC implementation for FiveM servers in JS/TS
|
Call FiveM server, client and NUI listeners like async functions: typed, with timeouts, no event ping-pong
|
||||||
|
|
||||||
Installation, quick start and package overview: [main readme](../readme.md). Typed events: [shared-types](../shared-types/readme.md).
|
Installation, quick start and package overview: [main readme](../readme.md). Typed events: [shared-types](../shared-types/readme.md). Upgrading from 0.1: [migration guide](../migration.md).
|
||||||
|
|
||||||
## Exports
|
## Exports
|
||||||
|
|
||||||
@@ -404,4 +404,4 @@ const response = await rpc.emitSelf('webviewEvent', someData)
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Licensed under Custom Attribution-NoDerivs Software License
|
Licensed under the [Custom Attribution-NoDerivs Software License](license.md)
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "@entityseven/fivem-rpc-shared-types",
|
"name": "@entityseven/fivem-rpc-shared-types",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"description": "Shared (enhanced) types for @entityseven/fivem-rpc. Highly recommended to install together",
|
"description": "Event and command declarations for @entityseven/fivem-rpc, for typed events",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
"cfx",
|
||||||
"fivem",
|
"fivem",
|
||||||
"fivem-rpc",
|
"fivem-rpc",
|
||||||
"fivem-rpc-shared-types",
|
"types",
|
||||||
"gta"
|
"typescript"
|
||||||
],
|
],
|
||||||
"license": "SEE LICENSE IN license.md",
|
"license": "SEE LICENSE IN license.md",
|
||||||
"author": "Entity Seven Group",
|
"author": "Entity Seven Group",
|
||||||
|
|||||||
+59
-157
@@ -1,173 +1,75 @@
|
|||||||
# FiveM RPC Shared Types
|
# FiveM RPC Shared Types
|
||||||
|
|
||||||
### [Docs & Info](../readme.md)
|
Event and command declarations for [`@entityseven/fivem-rpc`](../rpc/readme.md). With nothing declared, every rpc method accepts any event name, any arguments and any result. Declare your events once and every `on*` and `emit*` call gets checked names, arguments and results
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
See the [main readme](../readme.md#installation).
|
See the [main readme](../readme.md#installation). The declaration file below imports this package, so it must resolve from that file (in a workspace: install it in the root)
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
This package is an enhanced type support for `@entityseven/fivem-rpc`. It provides ability to strictly type your events for better dx.
|
1. Create one declaration file shared by server, client and webview code, e.g. `shared/rpc.d.ts`:
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
This example is neat way to follow up but you can change it as you wish. It will use bun workspaces, pnpm workspaces work in a similar manner. Referring the following folder structure:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
apps/
|
|
||||||
- server/
|
|
||||||
- package.json
|
|
||||||
- tsconfig.json
|
|
||||||
- client/
|
|
||||||
- package.json
|
|
||||||
- tsconfig.json
|
|
||||||
- webview/
|
|
||||||
- package.json
|
|
||||||
- tsconfig.json
|
|
||||||
- shared/ (this must be available in server, client and webview)
|
|
||||||
- package.json
|
|
||||||
|
|
||||||
- package.json (root package)
|
|
||||||
- pnpm-workspace.yaml (only if using pnpm)
|
|
||||||
```
|
|
||||||
|
|
||||||
- Environment folder: folder with server, client or webview code in it
|
|
||||||
|
|
||||||
1. Install this package as dev dependency in your root package or in each environment folder separately
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
apps/
|
|
||||||
- server/ <- (if not installed root)
|
|
||||||
- client/ <- (if not installed root)
|
|
||||||
- webview/ <- (if not installed root)
|
|
||||||
- shared/
|
|
||||||
|
|
||||||
- package.json <- here
|
|
||||||
```
|
|
||||||
|
|
||||||
2. In `shared/` create folder `fivem-rpc` (or similar), inside it create `index.d.ts`
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
apps/
|
|
||||||
- server/
|
|
||||||
- client/
|
|
||||||
- webview/
|
|
||||||
- shared/
|
|
||||||
- fivem-rpc/
|
|
||||||
- index.d.ts <- here
|
|
||||||
|
|
||||||
- package.json
|
|
||||||
```
|
|
||||||
|
|
||||||
3. In `index.d.ts` add following:
|
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import '@entityseven/fivem-rpc-shared-types'
|
||||||
|
|
||||||
declare module '@entityseven/fivem-rpc-shared-types' {
|
declare module '@entityseven/fivem-rpc-shared-types' {
|
||||||
// Client commands names
|
interface RPCEvents_ClientServer {
|
||||||
export type RPCCommands_Client = ''
|
// event name(arguments): value returned by the listener
|
||||||
|
buyItem(item: string, amount: number): boolean
|
||||||
// Server commands names
|
|
||||||
export type RPCCommands_Server = ''
|
|
||||||
|
|
||||||
// Client -> Client events
|
|
||||||
export interface RPCEvents_Client {}
|
|
||||||
|
|
||||||
// Client -> Server events
|
|
||||||
export interface RPCEvents_ClientServer {}
|
|
||||||
|
|
||||||
// Client -> Webview events
|
|
||||||
export interface RPCEvents_ClientWebview {}
|
|
||||||
|
|
||||||
// Server -> Server events
|
|
||||||
export interface RPCEvents_Server {}
|
|
||||||
|
|
||||||
// Server -> Client events
|
|
||||||
export interface RPCEvents_ServerClient {}
|
|
||||||
|
|
||||||
// Server -> Server events
|
|
||||||
export interface RPCEvents_ServerWebview {}
|
|
||||||
|
|
||||||
// Webview -> Webview events
|
|
||||||
export interface RPCEvents_Webview {}
|
|
||||||
|
|
||||||
// Webview -> Client events
|
|
||||||
export interface RPCEvents_WebviewClient {}
|
|
||||||
|
|
||||||
// Webview -> Server events
|
|
||||||
export interface RPCEvents_WebviewServer {}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
4. We just created a declaration which will overwrite types from the package. Now we need our packages to refer to these types when linting `rpc` functions. To do this in each environment folder of your project in `tsconfig.json` do these:
|
|
||||||
```json5
|
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"types": [
|
|
||||||
"../shared/fivem-rpc/" // or your specific folder
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
interface RPCCommands_Server {
|
||||||
```
|
ban: true
|
||||||
5. We also need to populate interfaces we created in step 3.
|
|
||||||
|
|
||||||
- `RPCCommands_Client` and `RPCCommands_Server` will include your commands names an union strings:
|
|
||||||
```ts
|
|
||||||
export type RPCCommands_Client = 'afk' | 'vanish' | '...' // example names
|
|
||||||
export type RPCCommands_Server = 'report' | 'ban' | '...' // example names
|
|
||||||
```
|
|
||||||
- Other interfaces will include your events types. The example will show one but all of the work same way
|
|
||||||
|
|
||||||
```ts
|
|
||||||
export interface RPCEvents_ClientServer {
|
|
||||||
clientToServerEventName(data: string, moreData: boolean): number
|
|
||||||
"client-to-server-event-name"(data: string, moreData: boolean): number // can also include characters you cannot use as variable or function names
|
|
||||||
}
|
|
||||||
```
|
|
||||||
- `clientToServerEventName` or `client-to-server-event-name` is an event name
|
|
||||||
- `data` and `moreData` are the arguments you need to pass when calling an event and argument you will receive when listening (may also include extra, as player, check type hints)
|
|
||||||
- `number` is a return type that will be forwarded back to caller
|
|
||||||
|
|
||||||
Doing this will create type hints for you:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// assuming this is in client
|
|
||||||
const response /* number */ = await rpc.emitServer(
|
|
||||||
'clientToServerEventName', /* suggested name */
|
|
||||||
'data', /* will pass typecheck */
|
|
||||||
'moreData', /* will NOT pass typecheck, since required type is `boolean` */
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Example (alternative)
|
|
||||||
|
|
||||||
If previous example does not work or you do not like you can also try it this way. Steps that are not mentioned are the same as previous
|
|
||||||
|
|
||||||
2. In `shared/` create folders `declarations/fivem-rpc`, inside it create `index.d.ts`
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
apps/
|
|
||||||
- server/
|
|
||||||
- client/
|
|
||||||
- webview/
|
|
||||||
- shared/
|
|
||||||
- declarations/
|
|
||||||
- fivem-rpc/
|
|
||||||
- index.d.ts <- here
|
|
||||||
|
|
||||||
- package.json
|
|
||||||
```
|
|
||||||
|
|
||||||
3. We just created a declaration which will overwrite types from the package. Now we need our packages to refer to these types when linting `rpc` functions. To do this in each environment folder of your project in `tsconfig.json` do these:
|
|
||||||
```json5
|
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"typeRoots": [
|
|
||||||
"../shared/declarations/", // or your specific folder
|
|
||||||
"../../node_modules/@types", // you may also want to add this if some of your other libraries are not showing types now
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
If a any point this stops working for you, do your research on how to redeclare library types and refer to it
|
The `import` line makes the file a module, so `declare module` adds to the package's interfaces instead of replacing them
|
||||||
|
|
||||||
|
2. Add the file to `include` in the `tsconfig.json` of every environment:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"include": ["src", "../shared/rpc.d.ts"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Calls are checked from now on:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// server
|
||||||
|
rpc.onClient('buyItem', (player, item, amount) => {
|
||||||
|
// item: string, amount: number, must return boolean
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
// client
|
||||||
|
const bought = await rpc.emitServer('buyItem', 'water', 2) // boolean
|
||||||
|
await rpc.emitServer('buyItem', 'water') // error: missing `amount`
|
||||||
|
await rpc.emitServer('buyItme', 'water', 2) // error: unknown event
|
||||||
|
```
|
||||||
|
|
||||||
|
## Interfaces
|
||||||
|
|
||||||
|
Each interface is one direction. An interface you leave empty stays loose (any name, arguments and result), so you can declare them one at a time
|
||||||
|
|
||||||
|
| Interface | Direction | Caller | Listener |
|
||||||
|
| ------------------------- | ------------------ | ------------------------------------------- | -------------------- |
|
||||||
|
| `RPCEvents_Client` | client -> client | `emitSelf` (client) | `onSelf` (client) |
|
||||||
|
| `RPCEvents_ClientServer` | client -> server | `emitServer` (client) | `onClient` (server) |
|
||||||
|
| `RPCEvents_ClientWebview` | client -> webview | `emitWebview` (client) | `onClient` (webview) |
|
||||||
|
| `RPCEvents_Server` | server -> server | `emitSelf` (server) | `onSelf` (server) |
|
||||||
|
| `RPCEvents_ServerClient` | server -> client | `emitClient`, `emitClientEveryone` (server) | `onServer` (client) |
|
||||||
|
| `RPCEvents_ServerWebview` | server -> webview | `emitWebview` (server) | `onServer` (webview) |
|
||||||
|
| `RPCEvents_Webview` | webview -> webview | `emitSelf` (webview) | `onSelf` (webview) |
|
||||||
|
| `RPCEvents_WebviewClient` | webview -> client | `emitClient` (webview) | `onWebview` (client) |
|
||||||
|
| `RPCEvents_WebviewServer` | webview -> server | `emitServer` (webview) | `onWebview` (server) |
|
||||||
|
| `RPCCommands_Client` | - | - | `onCommand` (client) |
|
||||||
|
| `RPCCommands_Server` | - | - | `onCommand` (server) |
|
||||||
|
|
||||||
|
- events: the member name is the event name, its parameters are the arguments, its return type is what `emit*` resolves with. Server listeners get the player id before the declared arguments. Names that are not identifiers work too: `'buy-item'(item: string): boolean`
|
||||||
|
- commands: the key is the command name, the value is not used (`true`)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Licensed under the [Custom Attribution-NoDerivs Software License](license.md)
|
||||||
|
|||||||
Reference in New Issue
Block a user