Compare commits

..

No commits in common. "469d970654fd206f8d0a92b8dc64720c187551f6" and "c2684a48fcdd244926990f37f3ef98ceb298a34b" have entirely different histories.

55 changed files with 7559 additions and 9513 deletions

View File

@ -1,32 +0,0 @@
{
"name": "@entityseven/rage-fw-browser",
"version": "0.2.0",
"main": "dist/index.js",
"types": "dist/src/index.d.ts",
"files": [
"dist/**/*",
"readme.md"
],
"scripts": {
"build": "tsup"
},
"dependencies": {
"@entityseven/rage-fw-rpc": "latest"
},
"peerDependencies": {
"@entityseven/rage-fw-shared-types": "workspace:^",
"@ragempcommunity/types-cef": "^2.1.8"
},
"description": "RageFW CEF side",
"keywords": [],
"author": "SashaGoncharov19",
"contributors": [
{
"name": "rilaxik",
"email": "dev.rilaxik@gmail.com",
"url": "https://github.com/rilaxik"
}
],
"license": "MIT",
"gitHead": "ffd542c1deddb3033e16e0dae7557313ae09b05f"
}

View File

@ -1,187 +0,0 @@
import { Helper } from './helper'
import { rpc } from './rpc'
import type * as T from '../types'
import {
RageFW_BrowserEvent,
RageFW_ClientEvent,
RageFW_ServerEvent,
} from '../types'
/** Browser-side interactions */
export class Browser extends Helper {
constructor() {
super()
}
/**
* Setter. Enables console debug logs for events
*/
set debugLogs(debug: boolean) {
this.debugLogs_ = debug
}
/**
* Setter. Provides an ability to specify custom logger function to get special formatting. Using this enables ``debugLogs``
*/
set customLogger(
fn: (method: string, eventName: string, ...args: unknown[]) => unknown,
) {
this.customLogger_ = fn
}
/**
* Registers a browser event with an associated callback
*
* @param eventName - The name of the event to register
* @param callback - The callback function to be executed when the event is triggered
* @returns {Browser} The current browser instance, enabling method chaining
*
* @example
* // Registering an event
* fw.event.register("showNotification", (message, color) => {
* // do something
* })
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
public register<EventName extends T.RageFW_BrowserEvent>(
eventName: EventName,
callback: T.RageFW_BrowserCallback<EventName>,
): Browser {
this.log_('register', eventName, callback)
rpc.register<
Parameters<typeof callback>,
ReturnType<typeof callback>,
EventName
>(eventName, async (...data) => await callback(...data))
return this
}
/**
* Unregisters a browser event, removing the associated callback
*
* @param eventName - The name of the event to unregister
* @returns {Browser} The current browser instance, enabling method chaining
*
* @example
* // Unregistering an event
* fw.event.unregister("showNotification")
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
public unregister<EventName extends T.RageFW_BrowserEvent>(
eventName: EventName,
): Browser {
rpc.unregister<EventName>(eventName)
return this
}
/**
* Triggers a browser event from the browser with arguments from shared types
*
* Formerly known as ``call`` or ``emit``
*
* @param eventName - The name of the browser event to trigger
* @param [args] - Arguments for the browser event, if present
* @returns {Promise} resolving to the browser's response for the event
*
* @example
* // Triggering a browser event without arguments
* fw.event.trigger("browserEventName")
*
* @example
* // Triggering a browser event with arguments
* fw.event.trigger("browserEventName", ["message to me"])
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
public async trigger<EventName extends T.RageFW_BrowserEvent>(
eventName: EventName,
...args: T._BrowserEventHasArgs<EventName> extends true
? [T.RageFW_BrowserArgs<EventName>]
: []
): Promise<T.RageFW_BrowserReturn<EventName>> {
this.log_('[RPC](trigger):', eventName, ...args)
return await rpc.call<
typeof args,
EventName,
T.RageFW_BrowserReturn<EventName>
>(eventName, args)
}
/**
* Triggers a server event from the browser with arguments from shared types
*
* Formerly known as ``callServer`` or ``emitServer``
*
* @param eventName - The name of the server event to trigger
* @param [args] - Arguments for the server event, if present
* @returns {Promise} resolving to the server's response for the event
*
* @example
* // Triggering a server event without arguments
* fw.event.triggerServer("serverEventName")
*
* @example
* // Triggering a server event with arguments
* fw.event.triggerServer("serverEventName", ["message to server"])
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
public async triggerServer<EventName extends T.RageFW_ServerEvent>(
eventName: EventName,
...args: T._ServerEventHasArgs<EventName> extends true
? [T.RageFW_ServerArgs<EventName>]
: []
): Promise<T.RageFW_ServerReturn<EventName>> {
this.log_('[RPC](triggerServer):', eventName, ...args)
return await rpc.callServer<
typeof args,
EventName,
T.RageFW_ServerReturn<EventName>
>(eventName, args)
}
/**
* Triggers a client event from the browser with arguments from shared types
*
* Formerly known as ``callClient`` or ``emitClient``
*
* @param eventName - The name of the client event to trigger
* @param [args] - Arguments for the client event, if present
* @returns {Promise} resolving to the client's response for the event
*
* @example
* // Triggering a client event without arguments
* fw.event.triggerClient("clientEventName")
*
* @example
* // Triggering a client event with arguments
* fw.event.triggerClient("clientEventName", ["message to client"])
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
public async triggerClient<EventName extends T.RageFW_ClientEvent>(
eventName: EventName,
...args: T._ClientEventHasArgs<EventName> extends true
? [T.RageFW_ClientArgs<EventName>]
: []
): Promise<T.RageFW_ClientReturn<EventName>> {
this.log_('[RPC](triggerClient):', eventName, ...args)
return await rpc.callClient<
typeof args,
EventName,
T.RageFW_ClientReturn<EventName>
>(eventName, args)
}
}
// new Browser()
// .register('customCefEvent', async (a, b) => true)
// .triggerServer('customServerEvent', ['', 1])

View File

@ -1,21 +0,0 @@
export class Helper {
protected debugLogs_: boolean = false
protected customLogger_:
| undefined
| ((method: string, eventName: string, ...args: unknown[]) => unknown) =
undefined
constructor() {}
protected log_(
method: string,
eventName: string,
...args: unknown[]
): void {
if (this.customLogger_) {
this.customLogger_(method, eventName, ...args)
} else if (this.debugLogs_) {
console.log('[RPC](' + method + ')', eventName + ':', ...args)
}
}
}

View File

@ -1,3 +0,0 @@
export * from './browser'
export * from './helper'
export * from './rpc'

View File

@ -1,6 +0,0 @@
import { Rpc } from '@entityseven/rage-fw-rpc'
export const rpc = new Rpc({
forceBrowserDevMode: process.env.RageFW_forceBrowserDevMode === 'true',
debugLogs: false,
})

View File

@ -1,16 +0,0 @@
import { Browser, rpc } from './core'
/**
* Package used on a browser-side of your Rage:MP Server
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
export const fw = {
/** Browser-side interactions */
event: new Browser(),
/** ``rage-fw-rpc`` instance used under the hood. It is highly recommended to use this one if you need it instead of creating a new instance */
rpc,
}
;(async () => {
await fw.event.triggerClient('cefReady')
})()

View File

@ -1,40 +0,0 @@
import type { RageFW_ICustomBrowserEvent } from '@entityseven/rage-fw-shared-types'
export type { RageFW_ICustomBrowserEvent } from '@entityseven/rage-fw-shared-types'
/**
* Union of all available browser event names
* These only include custom events
*/
export type RageFW_BrowserEvent = keyof RageFW_ICustomBrowserEvent
/**
* Array of arguments of an event you pass as a generic
* These only include custom browser events
*/
export type RageFW_BrowserArgs<K extends RageFW_BrowserEvent> = Parameters<
RageFW_ICustomBrowserEvent[K]
>
/**
* Return type of event you pass as a generic
* These only include custom browser events
*/
export type RageFW_BrowserReturn<K extends RageFW_BrowserEvent> = ReturnType<
RageFW_ICustomBrowserEvent[K]
>
/**
* Callback (function) of event you pass as a generic
* These only include custom browser events
*/
export type RageFW_BrowserCallback<K extends keyof RageFW_ICustomBrowserEvent> =
(...args: RageFW_BrowserArgs<K>) => Promise<RageFW_BrowserReturn<K>>
export type _BrowserEventHasArgs<
EventName extends keyof RageFW_ICustomBrowserEvent,
> = keyof RageFW_ICustomBrowserEvent extends never
? false
: Parameters<RageFW_ICustomBrowserEvent[EventName]>[0] extends undefined
? false
: true

29
cef/package.json Normal file
View File

@ -0,0 +1,29 @@
{
"name": "rage-fw-cef",
"version": "0.1.0",
"main": "dist/index.js",
"types": "dist/src/index.d.ts",
"files": [
"dist/**/*",
"readme.md"
],
"scripts": {
"build": "tsup"
},
"dependencies": {
"rage-fw-rpc": "workspace:^"
},
"peerDependencies": {
"@ragempcommunity/types-cef": "^2.1.8",
"rage-fw-shared-types": "workspace:^"
},
"description": "RageFW CEF side",
"keywords": [],
"author": "SashaGoncharov19",
"contributors": [{
"name": "rilaxik",
"email": "dev.rilaxik@gmail.com",
"url": "https://github.com/rilaxik"
}],
"license": "MIT"
}

113
cef/src/index.ts Normal file
View File

@ -0,0 +1,113 @@
import { Rpc } from 'rage-fw-rpc'
import type {
_CefEventHasArgs,
_ClientEventHasArgs,
_ServerEventHasArgs,
RageFW_CefArgs,
RageFW_CefCallback,
RageFW_CefReturn,
RageFW_ClientArgs,
RageFW_ClientReturn,
RageFW_ICustomCefEvent,
RageFW_ICustomClientEvent,
RageFW_ICustomServerEvent,
RageFW_ServerArgs,
RageFW_ServerReturn,
} from './types'
class Cef {
private _debugMode: boolean = false
private _rpc: Rpc = new Rpc()
constructor() {}
set debug(debug: boolean) {
this._debugMode = debug
}
get rpc(): Rpc {
return this._rpc
}
public register<EventName extends keyof RageFW_ICustomCefEvent>(
eventName: EventName,
callback: RageFW_CefCallback<EventName>,
): void {
if (this._debugMode) {
console.log('[RPC](register):', eventName, callback)
}
if ('mp' in window) {
this._rpc.register(eventName, callback)
}
}
public async trigger<EventName extends keyof RageFW_ICustomCefEvent>(
eventName: EventName,
...args: _CefEventHasArgs<EventName> extends true
? [RageFW_CefArgs<EventName>]
: []
): Promise<RageFW_CefReturn<EventName>> {
if (this._debugMode) {
console.log('[RPC](trigger):', eventName, ...args)
}
if ('mp' in window) {
return await this._rpc.call(eventName, args)
}
return Promise.reject(
'RageFW was started in window which does not contain MP',
)
}
public async triggerServer<
EventName extends keyof RageFW_ICustomServerEvent,
>(
eventName: EventName,
...args: _ServerEventHasArgs<EventName> extends true
? [RageFW_ServerArgs<EventName>]
: []
): Promise<RageFW_ServerReturn<EventName>> {
if (this._debugMode) {
console.log('[RPC](triggerServer):', eventName, ...args)
}
if ('mp' in window) {
return await this._rpc.callServer(eventName, args)
}
return Promise.reject(
'RageFW was started in window which does not contain MP',
)
}
public async triggerClient<
EventName extends keyof RageFW_ICustomClientEvent,
>(
eventName: EventName,
...args: _ClientEventHasArgs<EventName> extends true
? [RageFW_ClientArgs<EventName>]
: []
): Promise<RageFW_ClientReturn<EventName>> {
if (this._debugMode) {
console.log('[RPC](triggerClient):', eventName, ...args)
}
if ('mp' in window) {
return await this._rpc.callClient(eventName, args)
}
return Promise.reject(
'RageFW was started in window which does not contain MP',
)
}
}
export const fw = {
event: new Cef(),
}
;(async () => {
await fw.event.triggerClient('cefReady')
})()

40
cef/src/types/cef.ts Normal file
View File

@ -0,0 +1,40 @@
import { RageFW_ICustomCefEvent } from 'rage-fw-shared-types'
export { RageFW_ICustomCefEvent } from 'rage-fw-shared-types'
/**
* Union of all available cef event names
* These only include custom events
*/
export type RageFW_CefEvent = keyof RageFW_ICustomCefEvent
/**
* Array of arguments of an event you pass as a generic
* These only include custom cef events
*/
export type RageFW_CefArgs<K extends RageFW_CefEvent> = Parameters<
RageFW_ICustomCefEvent[K]
>
/**
* Return type of event you pass as a generic
* These only include custom cef events
*/
export type RageFW_CefReturn<K extends RageFW_CefEvent> = ReturnType<
RageFW_ICustomCefEvent[K]
>
/**
* Callback (function) of event you pass as a generic
* These only include custom cef events
*/
export type RageFW_CefCallback<K extends keyof RageFW_ICustomCefEvent> = (
args: RageFW_CefArgs<K>,
) => Promise<RageFW_CefReturn<K>>
export type _CefEventHasArgs<EventName extends keyof RageFW_ICustomCefEvent> =
keyof RageFW_ICustomCefEvent extends never
? false
: Parameters<RageFW_ICustomCefEvent[EventName]>[0] extends undefined
? false
: true

View File

@ -1,6 +1,6 @@
import type { RageFW_ICustomClientEvent } from '@entityseven/rage-fw-shared-types'
import type { RageFW_ICustomClientEvent } from 'rage-fw-shared-types'
export type { RageFW_ICustomClientEvent } from '@entityseven/rage-fw-shared-types'
export type { RageFW_ICustomClientEvent } from 'rage-fw-shared-types'
/**
* Union of all available client event names

View File

@ -1,3 +1,3 @@
export * from './browser'
export * from './cef'
export * from './client'
export * from './server'

View File

@ -1,6 +1,6 @@
import type { RageFW_ICustomServerEvent } from '@entityseven/rage-fw-shared-types'
import type { RageFW_ICustomServerEvent } from 'rage-fw-shared-types'
export type { RageFW_ICustomServerEvent } from '@entityseven/rage-fw-shared-types'
export type { RageFW_ICustomServerEvent } from 'rage-fw-shared-types'
/**
* Union of all available server event names

View File

@ -1,6 +1,6 @@
{
"name": "@entityseven/create-rage-fw",
"version": "0.1.1",
"name": "create-rage-fw",
"version": "0.1.0",
"bin": {
"rage-fw": "dist/index.js"
},

View File

@ -2,7 +2,7 @@
To make you life easier while using RageFW we created a basic CLI. At the moment automation we have only works via [pnpm](https://pnpm.io/)
``pnpm create @entityseven/rage-fw@latest``
``pnpm create rage-fw@latest``
## TL;DR
- ``Initialize new project`` - create new template project

View File

@ -1,6 +1,6 @@
{
"name": "@entityseven/rage-fw-client",
"version": "0.2.0",
"name": "rage-fw-client",
"version": "0.1.0",
"main": "dist/index.js",
"types": "dist/src/index.d.ts",
"files": [
@ -11,22 +11,20 @@
"build": "tsup"
},
"dependencies": {
"@entityseven/rage-fw-rpc": "latest"
"rage-fw-rpc": "workspace:^"
},
"peerDependencies": {
"@entityseven/rage-fw-shared-types": "workspace:^",
"@ragempcommunity/types-client": "^2.1.8"
"@ragempcommunity/types-client": "^2.1.8",
"rage-fw-shared-types": "workspace:^"
},
"description": "RageFW Client side",
"keywords": [],
"author": "SashaGoncharov19",
"contributors": [
{
"name": "rilaxik",
"email": "dev.rilaxik@gmail.com",
"url": "https://github.com/rilaxik"
}
],
"contributors": [{
"name": "rilaxik",
"email": "dev.rilaxik@gmail.com",
"url": "https://github.com/rilaxik"
}],
"license": "MIT",
"gitHead": "ffd542c1deddb3033e16e0dae7557313ae09b05f"
"gitHead": "053e4fd12aa120d53e11e0d2009c0df78c1a2ad0"
}

View File

@ -1,86 +1,33 @@
import { rpc } from './rpc'
import { Middleware } from './middleware'
import type * as T from '../types'
import { Rpc } from 'rage-fw-rpc'
import type {
RageFW_ClientArgs,
RageFW_ClientCallback,
RageFW_ClientEvent,
} from '../types'
/** Client-side interactions */
export class Client {
/**
* Registers a client event with an associated callback
*
* @param eventName - The name of the event to register
* @param callback - The callback function to be executed when the event is triggered
* @param [options] - Optional settings for callback execution
* @param [options.middlewares] - Middleware functions to be checked before the callback executes
* @returns {Client} The current client instance, enabling method chaining
*
* @example
* // Registering an event
* fw.event.register("playerDeath", (player, reason, killer) => {
* fw.system.log.info(player, reason, killer)
* })
*
* @example
* // Registering an event with middlewares
* fw.event.register("playerDeath", (player, reason, killer) => {
* fw.system.log.info(player, reason, killer)
* }, {
* middlewares: [ignoreSuicide] // <- your middlewares here
* })
*
* // or
*
* fw.event.register("playerDeath", (player, reason, killer) => {
* fw.system.log.info(player, reason, killer)
* }, {
* middlewares: {
* executables: [ignoreSuicide], // <- your middlewares here
* onError: (msg) => fw.system.log.info(`${player.socialClub} has commited suicide`)
* }
* })
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
public register<EventName extends T.RageFW_ClientEvent>(
eventName: EventName,
callback: T.RageFW_ClientCallback<EventName>,
options?: {
middlewares?: T.RageFW_MiddlewareOptions<EventName>
},
): Client {
rpc.register<
Parameters<typeof callback>,
ReturnType<typeof callback> | Promise<unknown>,
EventName
>(eventName, async (...data) => {
if (!options?.middlewares) return await callback(...data)
private _rpc: Rpc = new Rpc()
await Middleware.process(options.middlewares, callback, data)
})
return this
get rpc(): Rpc {
return this._rpc
}
/**
* Unregisters a client event, removing the associated callback
*
* @param eventName - The name of the event to unregister
* @returns {Client} The current client instance, enabling method chaining
*
* @example
* // Unregistering an event
* fw.event.unregister("playerDeath")
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
public unregister<EventName extends T.RageFW_ClientEvent>(
public register<EventName extends RageFW_ClientEvent>(
eventName: EventName,
): Client {
rpc.unregister<EventName>(eventName)
callback: RageFW_ClientCallback<EventName>,
): void {
this._rpc.register(
eventName,
async (data: RageFW_ClientArgs<EventName>) => {
return await callback(data)
},
)
}
return this
public unregister<EventName extends RageFW_ClientEvent>(
eventName: EventName,
): void {
this._rpc.unregister(eventName)
}
}
// new Client()
// .register('customClientEvent', async (a, b) => true)
// .unregister('customClientEvent')

View File

@ -1,5 +1,3 @@
export * from './client'
export * from './logger'
export * from './middleware'
export * from './player'
export * from './rpc'
export * from './logger'

View File

@ -1,40 +1,19 @@
/**
* Used to log to a client in-game console
*/
export class Logger {
/**
* Informational logs. Colored in white
*
* @example
* fw.system.log.info('some information to be logged')
*/
public info(...message: unknown[]) {
mp.console.logInfo(
`[${new Date().toLocaleTimeString()}] [INFO] ${message.join(' ')}`,
public error(...message: unknown[]) {
mp.console.logError(
`[${new Date().toLocaleTimeString()}] [ERROR] ${message.join(' ')}`,
)
}
/**
* Warning logs. Colored in yellow
*
* @example
* fw.system.log.warn('warning message')
*/
public warn(...message: unknown[]) {
mp.console.logWarning(
`[${new Date().toLocaleTimeString()}] [WARN] ${message.join(' ')}`,
)
}
/**
* Error logs. Colored in red
*
* @example
* fw.system.log.info('some error information')
*/
public error(...message: unknown[]) {
mp.console.logError(
`[${new Date().toLocaleTimeString()}] [ERROR] ${message.join(' ')}`,
public info(...message: unknown[]) {
mp.console.logInfo(
`[${new Date().toLocaleTimeString()}] [INFO] ${message.join(' ')}`,
)
}
}

View File

@ -1,54 +0,0 @@
import type * as T from '../types'
export class Middleware {
constructor() {}
private static async execute<EventName extends T.RageFW_ClientEvent>(
middlewares: T.RageFW_MiddlewareFunction<EventName>[],
args: T.RageFW_ClientArgs<EventName>,
): Promise<T.RageFW_MiddlewareResponseInternal> {
for (let i = 0; i < middlewares.length; i++) {
const result = await middlewares[i](...args)
if (typeof result === 'boolean' && !result)
return { success: result, id: i }
if (typeof result !== 'boolean' && !result.success)
return { ...result, id: i }
}
return {
success: true,
}
}
public static async process<EventName extends T.RageFW_ClientEvent>(
middlewareOptions: T.RageFW_MiddlewareOptions<EventName>,
callback: T.RageFW_ClientCallback<EventName>,
args: T.RageFW_ClientArgs<EventName>,
) {
if (Array.isArray(middlewareOptions)) {
const middlewaresResponse = await Middleware.execute(
middlewareOptions,
args,
)
if (middlewaresResponse.success) return await callback(...args)
} else {
const middlewaresResponse = await Middleware.execute(
middlewareOptions.executables,
args,
)
if (middlewaresResponse.success) {
return await callback(...args)
} else {
middlewareOptions.onError(
middlewaresResponse.message ??
'Middleware with id ' +
middlewaresResponse.id +
' failed',
)
}
}
}
}

View File

@ -1,118 +1,53 @@
import { rpc } from './rpc'
import type * as T from '../types'
import { Rpc } from 'rage-fw-rpc'
import type { RageFW_ICustomClientEvent } from 'rage-fw-shared-types'
import {
_CefEventHasArgs,
_ClientEventHasArgs,
_ServerEventHasArgs,
RageFW_CefArgs,
RageFW_CefEvent,
RageFW_CefReturn,
RageFW_ClientArgs,
RageFW_ClientReturn,
RageFW_ClientServerEvent,
RageFW_ClientServerArgs,
RageFW_ClientServerReturn,
} from '../types'
/** Handles event manipulations that require player to be present in context */
export class Player {
private _browser: BrowserMp | undefined = undefined
private _rpc: Rpc = new Rpc()
public browser: BrowserMp | undefined
/**
* Setter. Also shares browser with ``rage-fw-rpc``
*/
set browser(browser: BrowserMp) {
this._browser = browser
rpc.browser = browser
get rpc(): Rpc {
return this._rpc
}
public trigger<EventName extends keyof RageFW_ICustomClientEvent>(
eventName: EventName,
...args: _ClientEventHasArgs<EventName> extends true
? [RageFW_ClientArgs<EventName>]
: []
): Promise<RageFW_ClientReturn<EventName>> {
return this._rpc.call(eventName, args)
}
/**
* Triggers a client event from the client with arguments from shared types
*
* Formerly known as ``call`` or ``emit``
*
* @param eventName - The name of the client event to trigger
* @param [args] - Arguments for the client event, if present
* @returns {Promise} resolving to the client's response for the event
*
* @example
* // Triggering a client event without arguments
* fw.player.trigger("clientEventName")
*
* @example
* // Triggering a client event with arguments
* fw.player.trigger("clientEventName", ["message to me"])
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
public async trigger<EventName extends keyof T.RageFW_ICustomClientEvent>(
public triggerServer<EventName extends RageFW_ClientServerEvent>(
eventName: EventName,
...args: T._ClientEventHasArgs<EventName> extends true
? [T.RageFW_ClientArgs<EventName>]
...args: _ServerEventHasArgs<EventName> extends true
? [RageFW_ClientServerArgs<EventName>]
: []
): Promise<T.RageFW_ClientReturn<EventName>> {
return await rpc.call<
typeof args,
EventName,
T.RageFW_ClientReturn<EventName>
>(eventName, args)
): Promise<RageFW_ClientServerReturn<EventName>> {
return this._rpc.callServer(eventName, args)
}
/**
* Triggers a server event from the client with arguments from shared types
*
* Formerly known as ``callServer`` or ``emitServer``
*
* @param eventName - The name of the server event to trigger
* @param [args] - Arguments for the server event, if present
* @returns {Promise} resolving to the server's response for the event
*
* @example
* // Triggering a server event without arguments
* fw.player.triggerServer("serverEventName")
*
* @example
* // Triggering a server event with arguments
* fw.player.triggerServer("serverEventName", ["message to server"])
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
public async triggerServer<EventName extends T.RageFW_ServerEvent>(
public triggerBrowser<EventName extends RageFW_CefEvent>(
eventName: EventName,
...args: T._ServerEventHasArgs<EventName> extends true
? [T.RageFW_ServerArgs<EventName>]
...args: _CefEventHasArgs<EventName> extends true
? [RageFW_CefArgs<EventName>]
: []
): Promise<T.RageFW_ClientServerReturn<EventName>> {
return await rpc.callServer<
typeof args,
EventName,
T.RageFW_ClientServerReturn<EventName>
>(eventName, args)
}
/**
* Triggers a browser event from the client with arguments from shared types
*
* Formerly known as ``callBrowser`` or ``emitBrowser``
*
* @param eventName - The name of the browser event to trigger
* @param [args] - Arguments for the browser event, if present
* @returns {Promise} resolving to the browser's response for the event
*
* @example
* // Triggering a browser event without arguments
* fw.player.triggerBrowser("browserEventName")
*
* @example
* // Triggering a browser event with arguments
* fw.player.triggerBrowser("browserEventName", ["message to browser"])
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
public async triggerBrowser<EventName extends T.RageFW_BrowserEvent>(
eventName: EventName,
...args: T._BrowserEventHasArgs<EventName> extends true
? [T.RageFW_BrowserArgs<EventName>]
: []
): Promise<T.RageFW_BrowserReturn<EventName>> {
if (!this._browser)
): Promise<RageFW_CefReturn<EventName>> {
if (!this.browser)
throw new Error('You need to initialize browser first')
return await rpc.callBrowser<
typeof args,
EventName,
T.RageFW_BrowserReturn<EventName>
>(eventName, args)
return this._rpc.callBrowser(this.browser, eventName, args)
}
}
// new Player().trigger('customClientEvent', ['', 1])
// new Player().triggerServer('customServerEvent', ['', 1])
// new Player().triggerBrowser('customCefEvent', ['', 1])

View File

@ -1,5 +0,0 @@
import { Rpc } from '@entityseven/rage-fw-rpc'
export const rpc = new Rpc({
debugLogs: false,
})

View File

@ -1,22 +1,9 @@
import { Client, Logger, Player, rpc } from './core'
import { Client, Logger, Player } from './core'
export type { RageFW_MiddlewareFunction } from './types'
/**
* Package used on a client-side of your Rage:MP Server
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
export const fw = {
/** Client-side interactions */
event: new Client(),
/** Handles event manipulations that require player to be present in context */
player: new Player(),
/** Handles functions used to interact with the client environment */
system: {
/** Used to log in a client in-game console */
log: new Logger(),
},
/** ``rage-fw-rpc`` instance used under the hood. It is highly recommended to use this one if you need it instead of creating a new instance */
rpc,
}

View File

@ -1,29 +1,20 @@
/// <reference types="@ragempcommunity/types-client" />
import type { RageFW_ICustomBrowserEvent } from '@entityseven/rage-fw-shared-types'
import type { RageFW_ICustomCefEvent } from 'rage-fw-shared-types'
/**
* Union of all available browser event names callable from client
* These only include custom events
*/
export type RageFW_BrowserEvent = keyof RageFW_ICustomBrowserEvent
export type RageFW_CefEvent = keyof RageFW_ICustomCefEvent
/**
* Array of arguments for an event, name of which you pass as a generic
* These only include custom events
*/
export type RageFW_BrowserArgs<K extends RageFW_BrowserEvent> = Parameters<
RageFW_ICustomBrowserEvent[K]
export type RageFW_CefArgs<K extends RageFW_CefEvent> = Parameters<
RageFW_ICustomCefEvent[K]
>
export type RageFW_BrowserReturn<K extends RageFW_BrowserEvent> = ReturnType<
RageFW_ICustomBrowserEvent[K]
export type RageFW_CefReturn<K extends RageFW_CefEvent> = ReturnType<
RageFW_ICustomCefEvent[K]
>
export type _BrowserEventHasArgs<
EventName extends keyof RageFW_ICustomBrowserEvent,
> = keyof RageFW_ICustomBrowserEvent extends never
? false
: Parameters<RageFW_ICustomBrowserEvent[EventName]>[0] extends undefined
? false
: true
export type _CefEventHasArgs<EventName extends keyof RageFW_ICustomCefEvent> =
keyof RageFW_ICustomCefEvent extends never
? false
: Parameters<RageFW_ICustomCefEvent[EventName]>[0] extends undefined
? false
: true

View File

@ -1,8 +1,6 @@
/// <reference types="@ragempcommunity/types-client" />
import type { RageFW_ICustomClientEvent } from '@entityseven/rage-fw-shared-types'
export type { RageFW_ICustomClientEvent } from '@entityseven/rage-fw-shared-types'
import type { RageFW_ICustomClientEvent } from 'rage-fw-shared-types'
/**
* Union of all available client event names
@ -23,28 +21,23 @@ export type RageFW_ClientArgs<K extends RageFW_ClientEvent> =
? Parameters<IClientEvents[K]>
: never
/**
* Callback (function) for an event, name of which you pass as a generic
* These only include custom events
*/
export type RageFW_ClientCallback<K extends RageFW_ClientEvent> = (
args: RageFW_ClientArgs<K>,
) => Promise<RageFW_ClientReturn<K>>
/**
* Return type for an event, name of which you pass as a generic
* These include custom and system events
* These only include custom events
*/
export type RageFW_ClientReturn<K extends RageFW_ClientEvent> =
K extends keyof RageFW_ICustomClientEvent
? ReturnType<RageFW_ICustomClientEvent[K]>
: K extends keyof IClientEvents
? ReturnType<IClientEvents[K]>
: void
: void
/**
* Callback (function) for an event, name of which you pass as a generic
* These include custom and system events
*/
export type RageFW_ClientCallback<K extends RageFW_ClientEvent> = (
...args: RageFW_ClientArgs<K>
) => Promise<RageFW_ClientReturn<K>>
/**
*
*/
export type _ClientEventHasArgs<
EventName extends keyof RageFW_ICustomClientEvent,
> = keyof RageFW_ICustomClientEvent extends never

View File

@ -1,4 +1,3 @@
export * from './browser'
export * from './client'
export * from './middleware'
export * from './server'
export * from './browser'

View File

@ -1,26 +0,0 @@
import type * as T from './client'
export type RageFW_MiddlewareResponse =
| {
success: boolean
message?: string
}
| boolean
export type RageFW_MiddlewareResponseInternal = {
success: boolean
message?: string
id?: number
}
export type RageFW_MiddlewareFunction<EventName extends T.RageFW_ClientEvent> =
(
...args: T.RageFW_ClientArgs<EventName>
) => Promise<RageFW_MiddlewareResponse>
export type RageFW_MiddlewareOptions<EventName extends T.RageFW_ClientEvent> =
| RageFW_MiddlewareFunction<EventName>[]
| {
executables: RageFW_MiddlewareFunction<EventName>[]
onError: (error: string) => unknown
}

View File

@ -3,19 +3,19 @@
import type {
RageFW_ICustomClientEvent,
RageFW_ICustomServerEvent,
} from '@entityseven/rage-fw-shared-types'
} from 'rage-fw-shared-types'
/**
* Union of all available server event names callable from client
* These only include custom events
*/
export type RageFW_ServerEvent = keyof RageFW_ICustomServerEvent
export type RageFW_ClientServerEvent = keyof RageFW_ICustomServerEvent
/**
* Array of arguments for an event, name of which you pass as a generic
* These only include custom events
*/
export type RageFW_ServerArgs<K extends RageFW_ServerEvent> =
export type RageFW_ClientServerArgs<K extends RageFW_ClientServerEvent> =
K extends keyof RageFW_ICustomServerEvent
? Parameters<RageFW_ICustomServerEvent[K]>
: never
@ -24,7 +24,7 @@ export type RageFW_ServerArgs<K extends RageFW_ServerEvent> =
* Return type for an event, name of which you pass as a generic
* These only include custom events
*/
export type RageFW_ClientServerReturn<K extends RageFW_ServerEvent> =
export type RageFW_ClientServerReturn<K extends RageFW_ClientServerEvent> =
K extends keyof RageFW_ICustomServerEvent
? ReturnType<RageFW_ICustomServerEvent[K]>
: never

View File

@ -1,5 +1,5 @@
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"version": "0.2.1-0.2.0-alpha.2.0",
"version": "0.1.0",
"npmClient": "pnpm"
}

View File

@ -1,14 +1,13 @@
{
"private": true,
"scripts": {
"publish": "lerna publish --force-publish",
"publish": "pnpm build && lerna publish --force-publish",
"build": "lerna run build",
"lint": "eslint --c .eslintrc.yaml --ext .ts client/ server/ shared-types/",
"rebuild:browser": "cd browser && pnpm build",
"rebuild:cef": "cd cef && pnpm build",
"rebuild:client": "cd client && pnpm build",
"rebuild:server": "cd server && pnpm build",
"rebuild": "pnpm rebuild:browser && pnpm rebuild:client && pnpm rebuild:server"
"rebuild": "pnpm rebuild:cef && pnpm rebuild:client && pnpm rebuild:server"
},
"dependencies": {
"@microsoft/api-extractor": "^7.47.0",
@ -17,7 +16,6 @@
"@ragempcommunity/types-server": "^2.1.8",
"@typescript-eslint/eslint-plugin": "^7.13.0",
"@typescript-eslint/parser": "^7.13.0",
"@types/node": "^22.8.1",
"eslint": "^8.56.0",
"lerna": "^8.1.3",
"prettier": "^3.3.1",

15501
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,7 @@
packages:
- "server"
- "client"
- "browser"
- "cef"
- "rpc"
- "cli"
- "shared-types"

View File

@ -13,7 +13,7 @@ You can find out more about our CLI [here](https://git.entityseven.com/entitysev
At the moment automation we have only works via [pnpm](https://pnpm.io/). To scaffold a basic project with minor settings you can use our CLI:
``pnpm create @entityseven/rage-fw``
``pnpm create rage-fw@latest``
This will give you a few options, among them, you can find ``Initialize new project``. Use that option to scaffold a new project for yourself using the preferred frontend framework

View File

@ -1,7 +1,7 @@
{
"name": "@entityseven/rage-fw-rpc",
"description": "Rage FW RPC",
"version": "0.2.5",
"name": "rage-fw-rpc",
"description": "RageFW RPC",
"version": "0.2.1",
"scripts": {
"build": "tsup",
"start": "npx ./dist create"
@ -17,13 +17,7 @@
"peerDependencies": {
"typescript": "^5"
},
"keywords": [
"ragemp",
"rage",
"rpc",
"rage-rpc",
"ragerpc"
],
"keywords": ["ragemp", "rage", "rpc", "rage-rpc", "ragerpc"],
"main": "dist/index.js",
"types": "dist/src/index.d.ts",
"author": {
@ -37,6 +31,5 @@
"url": "https://github.com/SashaGoncharov19"
}
],
"license": "MIT",
"gitHead": "04eb7240735c4a0e4855ebabbe8d5b326819fa76"
"license": "MIT"
}

View File

@ -14,17 +14,12 @@ yarn add rage-fw-rpc
Import installed package and initialize rpc:
```ts
// lib/rpc.js
// lib/rpc.js
import { Rpc } from 'rage-fw-rpc'
export const rpc = new Rpc(/* options */)
import { Rpc } from 'rage-fw-rpc'
export const rpc = new Rpc(/* options */)
```
# Motivation
The idea was to create an extensible package, with various features to simplify the development process and provide as much comfort as possible. It should also be using similar architecture as the framework it was specially built for
Inspired by usage of [rage-rpc](https://github.com/micaww/rage-rpc)
# Features
- Type-safe events via [TS generics](https://www.typescriptlang.org/docs/handbook/2/generics.html), avoiding type wrappers
- Built-in logging options for each environment
@ -33,7 +28,7 @@ Inspired by usage of [rage-rpc](https://github.com/micaww/rage-rpc)
- Actual human-readable errors
# Docs
## [Extended version available here](https://git.entityseven.com/entityseven/rage-framework/wiki/RPC%400.2.5)
*Extended version with details coming soon*
## register
Registers a callback function for a specified event

View File

@ -1,6 +1,6 @@
{
"name": "@entityseven/rage-fw-server",
"version": "0.2.0",
"name": "rage-fw-server",
"version": "0.1.0",
"main": "dist/index.js",
"types": "dist/src/index.d.ts",
"files": [
@ -11,22 +11,20 @@
"build": "tsup"
},
"dependencies": {
"@entityseven/rage-fw-rpc": "latest"
"rage-fw-rpc": "workspace:^"
},
"peerDependencies": {
"@entityseven/rage-fw-shared-types": "workspace:^",
"@ragempcommunity/types-server": "^2.1.8"
"@ragempcommunity/types-server": "^2.1.8",
"rage-fw-shared-types": "workspace:^"
},
"description": "RageFW Server side",
"keywords": [],
"author": "SashaGoncharov19",
"contributors": [
{
"name": "rilaxik",
"email": "dev.rilaxik@gmail.com",
"url": "https://github.com/rilaxik"
}
],
"contributors": [{
"name": "rilaxik",
"email": "dev.rilaxik@gmail.com",
"url": "https://github.com/rilaxik"
}],
"license": "MIT",
"gitHead": "ffd542c1deddb3033e16e0dae7557313ae09b05f"
"gitHead": "053e4fd12aa120d53e11e0d2009c0df78c1a2ad0"
}

View File

@ -1,5 +1,3 @@
export * from './logger'
export * from './middleware'
export * from './player'
export * from './rpc'
export * from './server'
export * from './logger'

View File

@ -2,7 +2,6 @@ import winston, { format } from 'winston'
const { timestamp, printf, colorize } = format
/** Used to log in a server console */
export class Logger {
private format = printf(({ message, level, timestamp }) => {
return `[${new Date(timestamp).toLocaleTimeString()}] [${level}]: ${message}`
@ -24,32 +23,14 @@ export class Logger {
),
})
/**
* Informational logs. Colored in white
*
* @example
* fw.system.log.info('some information to be logged')
*/
public info(...message: unknown[]) {
this.systemLogger.info(message.join(' '))
}
/**
* Warning logs. Colored in yellow
*
* @example
* fw.system.log.warn('warning message')
*/
public warn(...message: unknown[]) {
this.systemLogger.warn(message.join(' '))
}
/**
* Error logs. Colored in red
*
* @example
* fw.system.log.info('some error information')
*/
public error(...message: unknown[]) {
this.systemLogger.error(message.join(' '))
}

View File

@ -1,54 +0,0 @@
import type * as T from '../types'
export class Middleware {
constructor() {}
private static async execute<EventName extends T.RageFW_ServerEvent>(
middlewares: T.RageFW_MiddlewareFunction<EventName>[],
args: T.RageFW_ServerArgs<EventName>,
): Promise<T.RageFW_MiddlewareResponseInternal> {
for (let i = 0; i < middlewares.length; i++) {
const result = await middlewares[i](...args)
if (typeof result === 'boolean' && !result)
return { success: result, id: i }
if (typeof result !== 'boolean' && !result.success)
return { ...result, id: i }
}
return {
success: true,
}
}
public static async process<EventName extends T.RageFW_ServerEvent>(
middlewareOptions: T.RageFW_MiddlewareOptions<EventName>,
callback: T.RageFW_ServerCallback<EventName>,
args: T.RageFW_ServerArgs<EventName>,
) {
if (Array.isArray(middlewareOptions)) {
const middlewaresResponse = await Middleware.execute(
middlewareOptions,
args,
)
if (middlewaresResponse.success) return await callback(...args)
} else {
const middlewaresResponse = await Middleware.execute(
middlewareOptions.executables,
args,
)
if (middlewaresResponse.success) {
return await callback(...args)
} else {
middlewareOptions.onError(
middlewaresResponse.message ??
'Middleware with id ' +
middlewaresResponse.id +
' failed',
)
}
}
}
}

View File

@ -1,68 +1,40 @@
import { rpc } from './rpc'
import type * as T from '../types'
import { Rpc } from 'rage-fw-rpc'
import type {
_CefEventHasArgs,
_ClientEventHasArgs,
RageFW_CefArgs,
RageFW_CefEvent,
RageFW_CefReturn,
RageFW_ClientEvent,
RageFW_ServerClientArgs,
RageFW_ServerClientReturn,
} from '../types'
/** Handles event manipulations that require player to be present in context */
export class Player {
/**
* Triggers a client event from the server with arguments from shared types
*
* Formerly known as ``callClient`` or ``emitClient``
*
* @param {PlayerMp} player - Player object as an event target
* @param eventName - The name of the client event to trigger
* @param [args] - Arguments for the client event, if present
* @returns {Promise} resolving to the client's response for the event
*
* @example
* // Triggering a client event without arguments
* fw.player.triggerClient("clientEventName")
*
* @example
* // Triggering a client event with arguments
* fw.player.triggerClient("clientEventName", ["message to client"])
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
public async triggerClient<EventName extends T.RageFW_ClientEvent>(
player: PlayerMp,
eventName: EventName,
...args: T._ClientEventHasArgs<EventName> extends true
? [T.RageFW_ClientArgs<EventName>]
: []
): Promise<T.RageFW_ClientReturn<EventName>> {
return await rpc.callClient(player, eventName, args)
private _rpc: Rpc = new Rpc()
get rpc(): Rpc {
return this._rpc
}
/**
* Triggers a browser event from the server with arguments from shared types
*
* Formerly known as ``callBrowser`` or ``emitBrowser``
*
* @param {PlayerMp} player - Player object as an event target
* @param eventName - The name of the browser event to trigger
* @param [args] - Arguments for the browser event, if present
* @returns {Promise} resolving to the browser's response for the event
*
* @example
* // Triggering a browser event without arguments
* fw.player.triggerBrowser("browserEventName")
*
* @example
* // Triggering a browser event with arguments
* fw.player.triggerBrowser("browserEventName", ["message to browser"])
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
public async triggerBrowser<EventName extends T.RageFW_BrowserEvent>(
public triggerClient<EventName extends RageFW_ClientEvent>(
player: PlayerMp,
eventName: EventName,
...args: T._BrowserEventHasArgs<EventName> extends true
? [T.RageFW_BrowserArgs<EventName>]
...args: _ClientEventHasArgs<EventName> extends true
? [RageFW_ServerClientArgs<EventName>]
: []
): Promise<T.RageFW_BrowserReturn<EventName>> {
return await rpc.callBrowser(player, eventName, args)
): Promise<RageFW_ServerClientReturn<EventName>> {
return this._rpc.callClient(player, eventName, args)
}
public triggerBrowser<EventName extends RageFW_CefEvent>(
player: PlayerMp,
eventName: EventName,
...args: _CefEventHasArgs<EventName> extends true
? [RageFW_CefArgs<EventName>]
: []
): Promise<RageFW_CefReturn<EventName>> {
return this._rpc.callBrowser(player, eventName, args)
}
}
// new Player().triggerBrowser({} as PlayerMp, 'customCefEvent', ['', 1])
// new Player().triggerClient({} as PlayerMp, 'customClientEvent', ['', 1])

View File

@ -1,5 +0,0 @@
import { Rpc } from '@entityseven/rage-fw-rpc'
export const rpc = new Rpc({
debugLogs: false,
})

View File

@ -1,96 +1,117 @@
import { rpc } from './rpc'
import { Middleware } from './middleware'
import type * as T from '../types'
import { Rpc } from 'rage-fw-rpc'
import { RageFW_ICustomServerEvent } from 'rage-fw-shared-types'
import { nativeEvents } from '../native.events'
import type {
_ServerEventHasArgs,
RageFW_ServerArgs,
RageFW_ServerCallback,
RageFW_ServerCallbackCustom,
RageFW_ServerCallbackNative,
RageFW_ServerEvent,
RageFW_ServerReturn,
} from '../types'
/** Server-side interactions */
export class Server {
/**
* Registers a server event with an associated callback
*
* @param eventName - The name of the event to register
* @param callback - The callback function to be executed when the event is triggered
* @param [options] - Optional settings for callback execution
* @param [options.middlewares] - Middleware functions to be checked before the callback executes
* @returns {Server} The current server instance, enabling method chaining
*
* @example
* // Registering an event
* fw.event.register("playerJoin", (player) => {
* fw.system.log.info(`${player.socialClub} has joined the game`)
* })
*
* @example
* // Registering an event with middlewares
* fw.event.register("playerJoin", (player) => {
* fw.system.log.info(`${player.name} has joined the game`)
* }, {
* middlewares: [ignoreBots] // <- your middlewares here
* })
*
* // or
*
* fw.event.register("playerJoin", (player) => {
* fw.system.log.info(`${player.socialClub} has joined the game`)
* }, {
* middlewares: {
* executables: [ignoreBots], // <- your middlewares here
* onError: (msg) => fw.system.log.info(`[BOT] ${player.socialClub} has joined the game`)
* }
* })
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
public register<EventName extends T.RageFW_ServerEvent>(
eventName: EventName,
callback: T.RageFW_ServerCallback<EventName>,
options?: {
middlewares?: T.RageFW_MiddlewareOptions<EventName>
},
): Server {
rpc.register<
Parameters<typeof callback>,
ReturnType<typeof callback> | Promise<unknown>,
EventName
>(eventName, async (...data) => {
if (!options?.middlewares) return await callback(...data)
private _rpc: Rpc = new Rpc()
await Middleware.process(options.middlewares, callback, data)
})
return this
get rpc(): Rpc {
return this._rpc
}
/**
* Unregisters a server event, removing the associated callback
*
* @param eventName - The name of the event to unregister
* @returns {Server} The current server instance, enabling method chaining
*
* @example
* // Unregistering an event
* fw.event.unregister("playerJoin")
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
public unregister<EventName extends T.RageFW_ServerEvent>(
eventName: EventName,
): Server {
rpc.unregister<EventName>(eventName)
return this
private isNativeEvent(eventName: string): eventName is keyof IServerEvents {
return nativeEvents.includes(eventName)
}
// fixme
// public trigger<EventName extends keyof T.RageFW_ICustomServerEvent>(
// eventName: EventName,
// ...args: T._ServerEventHasArgs<EventName> extends true
// ? [T.RageFW_ServerArgs<EventName>]
// : []
// ): Promise<T.RageFW_ServerReturn<EventName>> {
// return rpc.call(eventName, args)
// }
private registerCustom<EventName extends keyof RageFW_ICustomServerEvent>(
eventName: EventName,
callback: RageFW_ServerCallbackCustom<EventName>,
): void {
this._rpc.register(
eventName,
// fixme
async (args: RageFW_ServerArgs<EventName>, info) => {
await callback([info.player as PlayerMp, ...args])
},
)
}
private registerNative<EventName extends keyof IServerEvents>(
eventName: EventName,
callback: RageFW_ServerCallbackNative<EventName>,
): void {
mp.events.add(
eventName,
(...args: Parameters<IServerEvents[EventName]>) =>
callback([...args]),
)
}
public register<EventName extends RageFW_ServerEvent>(
eventName: EventName,
callback: RageFW_ServerCallback<EventName>,
): void {
if (this.isNativeEvent(eventName)) {
this.registerNative(
eventName,
callback as RageFW_ServerCallbackNative,
)
} else {
this.registerCustom(
eventName,
callback as unknown as RageFW_ServerCallbackCustom,
)
}
}
public registerMany<EventName extends RageFW_ServerEvent>(events: {
[event in EventName]: RageFW_ServerCallback<event>
}): void {
Object.entries<RageFW_ServerCallback<EventName>>(events).map(
([eventName, callback]) => {
if (this.isNativeEvent(eventName)) {
this.registerNative(
eventName,
callback as RageFW_ServerCallbackNative,
)
} else {
this.registerCustom(
eventName as keyof RageFW_ICustomServerEvent,
callback as unknown as RageFW_ServerCallbackCustom,
)
}
},
)
}
private unregisterCustom<EventName extends keyof RageFW_ICustomServerEvent>(
eventName: EventName,
): void {
this._rpc.unregister(eventName)
}
private unregisterNative<EventName extends keyof IServerEvents>(
eventName: EventName,
): void {
mp.events.remove(eventName)
}
public unregister<EventName extends RageFW_ServerEvent>(
eventName: EventName,
): void {
if (this.isNativeEvent(eventName)) {
this.unregisterNative(eventName)
} else {
this.unregisterCustom(eventName)
}
}
public trigger<EventName extends keyof RageFW_ICustomServerEvent>(
eventName: EventName,
...args: _ServerEventHasArgs<EventName> extends true
? [RageFW_ServerArgs<EventName>]
: []
): Promise<RageFW_ServerReturn<EventName>> {
return this._rpc.call(eventName, args)
}
}
// new Server()
// .register('customServerEvent', async (a, b, c) => true)
// .unregister('customServerEvent')

View File

@ -1,24 +1,11 @@
import { Logger, Player, Server, rpc } from './core'
import { Logger, Player, Server } from './core'
export type { RageFW_MiddlewareFunction } from './types'
/**
* Package used on a server-side of your Rage:MP Server
*
* @see {@link https://git.entityseven.com/entityseven/rage-framework/wiki Wiki}
*/
export const fw = {
/** Server-side interactions */
event: new Server(),
/** Handles event manipulations that require player to be present in context */
player: new Player(),
/** Handles functions used to interact with the client environment */
system: {
/** Used to log in a server console */
log: new Logger(),
},
/** ``rage-fw-rpc`` instance used under the hood. It is highly recommended to use this one if you need it instead of creating a new instance */
rpc,
}
fw.system.log.info(

View File

@ -1,34 +1,18 @@
import type { RageFW_ICustomBrowserEvent } from '@entityseven/rage-fw-shared-types'
import type { RageFW_ICustomCefEvent } from 'rage-fw-shared-types'
/**
* Union of all available browser event names
* These only include custom events
*/
export type RageFW_BrowserEvent = keyof RageFW_ICustomBrowserEvent
export type RageFW_CefEvent = keyof RageFW_ICustomCefEvent
/**
* Array of arguments of an event you pass as a generic
* These only include custom events
*/
export type RageFW_BrowserArgs<K extends RageFW_BrowserEvent> = Parameters<
RageFW_ICustomBrowserEvent[K]
export type RageFW_CefArgs<K extends RageFW_CefEvent> = Parameters<
RageFW_ICustomCefEvent[K]
>
/**
* Return type of event you pass as a generic
* These only include custom events
*/
export type RageFW_BrowserReturn<K extends RageFW_BrowserEvent> = ReturnType<
RageFW_ICustomBrowserEvent[K]
export type RageFW_CefReturn<K extends RageFW_CefEvent> = ReturnType<
RageFW_ICustomCefEvent[K]
>
/**
*
*/
export type _BrowserEventHasArgs<
EventName extends keyof RageFW_ICustomBrowserEvent,
> = keyof RageFW_ICustomBrowserEvent extends never
? false
: Parameters<RageFW_ICustomBrowserEvent[EventName]>[0] extends undefined
? false
: true
export type _CefEventHasArgs<EventName extends keyof RageFW_ICustomCefEvent> =
keyof RageFW_ICustomCefEvent extends never
? false
: Parameters<RageFW_ICustomCefEvent[EventName]>[0] extends undefined
? false
: true

View File

@ -1,6 +1,6 @@
/// <reference types="@ragempcommunity/types-server" />
import type { RageFW_ICustomClientEvent } from '@entityseven/rage-fw-shared-types'
import type { RageFW_ICustomClientEvent } from 'rage-fw-shared-types'
/**
* Union of all available client event names
@ -12,7 +12,7 @@ export type RageFW_ClientEvent = keyof RageFW_ICustomClientEvent
* Array of arguments of an event you pass as a generic
* These only include custom events
*/
export type RageFW_ClientArgs<K extends RageFW_ClientEvent> =
export type RageFW_ServerClientArgs<K extends RageFW_ClientEvent> =
K extends RageFW_ClientEvent
? Parameters<RageFW_ICustomClientEvent[K]>
: never
@ -21,14 +21,11 @@ export type RageFW_ClientArgs<K extends RageFW_ClientEvent> =
* Return type of event you pass as a generic
* These only include custom events
*/
export type RageFW_ClientReturn<K extends RageFW_ClientEvent> =
export type RageFW_ServerClientReturn<K extends RageFW_ClientEvent> =
K extends RageFW_ClientEvent
? ReturnType<RageFW_ICustomClientEvent[K]>
: never
/**
*
*/
export type _ClientEventHasArgs<
EventName extends keyof RageFW_ICustomClientEvent,
> = keyof RageFW_ICustomClientEvent extends never

View File

@ -1,4 +1,3 @@
export * from './browser'
export * from './client'
export * from './middleware'
export * from './server'
export * from './browser'

View File

@ -1,26 +0,0 @@
import type * as T from './server'
export type RageFW_MiddlewareResponse =
| {
success: boolean
message?: string
}
| boolean
export type RageFW_MiddlewareResponseInternal = {
success: boolean
message?: string
id?: number
}
export type RageFW_MiddlewareFunction<EventName extends T.RageFW_ServerEvent> =
(
...args: T.RageFW_ServerArgs<EventName>
) => Promise<RageFW_MiddlewareResponse>
export type RageFW_MiddlewareOptions<EventName extends T.RageFW_ServerEvent> =
| RageFW_MiddlewareFunction<EventName>[]
| {
executables: RageFW_MiddlewareFunction<EventName>[]
onError: (error: string) => unknown
}

View File

@ -3,9 +3,8 @@
import type {
RageFW_ICustomClientEvent,
RageFW_ICustomServerEvent,
} from '@entityseven/rage-fw-shared-types'
export type { RageFW_ICustomServerEvent } from '@entityseven/rage-fw-shared-types'
} from 'rage-fw-shared-types'
export type { RageFW_ICustomServerEvent } from 'rage-fw-shared-types'
/**
* Union of all available server event names
@ -21,9 +20,20 @@ export type RageFW_ServerEvent =
*/
export type RageFW_ServerArgs<K extends RageFW_ServerEvent> =
K extends keyof RageFW_ICustomServerEvent
? [PlayerMp, ...Parameters<RageFW_ICustomServerEvent[K]>]
? Parameters<RageFW_ICustomServerEvent[K]>
: K extends keyof IServerEvents
? [PlayerMp, Parameters<IServerEvents[K]>]
? Parameters<IServerEvents[K]>
: never
/**
* Callback (function) for an event, name of which you pass as a generic
* These include system and custom events
*/
export type RageFW_ServerCallback<K extends RageFW_ServerEvent> =
K extends keyof RageFW_ICustomServerEvent
? RageFW_ServerCallbackCustom<K>
: K extends keyof IServerEvents
? RageFW_ServerCallbackNative<K>
: never
/**
@ -35,19 +45,28 @@ export type RageFW_ServerReturn<K extends RageFW_ServerEvent> =
? ReturnType<RageFW_ICustomServerEvent[K]>
: K extends keyof IServerEvents
? ReturnType<IServerEvents[K]>
: void
: never
/**
* Callback (function) for an event, name of which you pass as a generic
* These include system and custom events
* Array of arguments for an event, name of which you pass as a generic
* These only include custom events
*/
export type RageFW_ServerCallback<K extends RageFW_ServerEvent> = (
...args: RageFW_ServerArgs<K>
export type RageFW_ServerCallbackCustom<
K extends keyof RageFW_ICustomServerEvent = keyof RageFW_ICustomServerEvent,
> = (
payload: [player: PlayerMp, ...args: RageFW_ServerArgs<K>],
) => Promise<RageFW_ServerReturn<K>>
/**
*
* Array of arguments for an event, name of which you pass as a generic
* These only include system events
*/
export type RageFW_ServerCallbackNative<
K extends keyof IServerEvents = keyof IServerEvents,
> = (
payload: Parameters<IServerEvents[K]>,
) => Promise<ReturnType<IServerEvents[K]>>
export type _ServerEventHasArgs<EventName extends RageFW_ServerEvent> =
EventName extends keyof RageFW_ICustomServerEvent
? keyof RageFW_ICustomClientEvent extends never

View File

@ -1,6 +1,6 @@
{
"name": "@entityseven/rage-fw-shared-types",
"version": "0.2.0",
"name": "rage-fw-shared-types",
"version": "0.1.0",
"types": "types/types/index.d.ts",
"files": [
"types/**/*"
@ -8,5 +8,5 @@
"author": "SashaGoncharov19",
"license": "MIT",
"type": "module",
"gitHead": "ffd542c1deddb3033e16e0dae7557313ae09b05f"
"gitHead": "053e4fd12aa120d53e11e0d2009c0df78c1a2ad0"
}

View File

@ -1,14 +1,9 @@
declare module '@entityseven/rage-fw-shared-types' {
export interface RageFW_ICustomServerEvent {
customServerEvent(arg1: string, arg2: number): boolean
}
declare module 'rage-fw-shared-types' {
export interface RageFW_ICustomServerEvent {}
export interface RageFW_ICustomClientEvent {
cefReady(): void
customClientEvent(arg1: string, arg2: number): boolean
}
export interface RageFW_ICustomBrowserEvent {
customCefEvent(arg1: string, arg2: number): boolean
}
export interface RageFW_ICustomCefEvent {}
}