Compare commits

...

2 Commits

Author SHA1 Message Date
30d125ce8e version bump 2024-10-29 17:06:14 +00:00
622676d189 feat core
- server/client middlewares
2024-10-29 17:03:07 +00:00
18 changed files with 199 additions and 16 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@entityseven/rage-fw-browser", "name": "@entityseven/rage-fw-browser",
"version": "0.1.2", "version": "0.2.0",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/src/index.d.ts", "types": "dist/src/index.d.ts",
"files": [ "files": [

View File

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

View File

@ -1,6 +1,6 @@
{ {
"name": "@entityseven/rage-fw-client", "name": "@entityseven/rage-fw-client",
"version": "0.1.2", "version": "0.2.0",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/src/index.d.ts", "types": "dist/src/index.d.ts",
"files": [ "files": [

View File

@ -1,16 +1,24 @@
import { rpc } from './rpc' import { rpc } from './rpc'
import { Middleware } from './middleware'
import type * as T from '../types' import type * as T from '../types'
export class Client { export class Client {
public register<EventName extends T.RageFW_ClientEvent>( public register<EventName extends T.RageFW_ClientEvent>(
eventName: EventName, eventName: EventName,
callback: T.RageFW_ClientCallback<EventName>, callback: T.RageFW_ClientCallback<EventName>,
options?: {
middlewares?: T.RageFW_MiddlewareOptions<EventName>
},
): Client { ): Client {
rpc.register< rpc.register<
Parameters<typeof callback>, Parameters<typeof callback>,
ReturnType<typeof callback>, ReturnType<typeof callback> | Promise<unknown>,
EventName EventName
>(eventName, async (...data) => await callback(...data)) >(eventName, async (...data) => {
if (!options?.middlewares) return await callback(...data)
await Middleware.process(options.middlewares, callback, data)
})
return this return this
} }

View File

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

View File

@ -0,0 +1,54 @@
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,5 +1,7 @@
import { Client, Logger, Player, rpc } from './core' import { Client, Logger, Player, rpc } from './core'
export type { RageFW_MiddlewareFunction } from './types'
export const fw = { export const fw = {
event: new Client(), event: new Client(),
player: new Player(), player: new Player(),

View File

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

View File

@ -0,0 +1,26 @@
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

@ -5,10 +5,10 @@
"build": "lerna run build", "build": "lerna run build",
"lint": "eslint --c .eslintrc.yaml --ext .ts client/ server/ shared-types/", "lint": "eslint --c .eslintrc.yaml --ext .ts client/ server/ shared-types/",
"rebuild:cef": "cd cef && pnpm build", "rebuild:browser": "cd browser && pnpm build",
"rebuild:client": "cd client && pnpm build", "rebuild:client": "cd client && pnpm build",
"rebuild:server": "cd server && pnpm build", "rebuild:server": "cd server && pnpm build",
"rebuild": "pnpm rebuild:cef && pnpm rebuild:client && pnpm rebuild:server" "rebuild": "pnpm rebuild:browser && pnpm rebuild:client && pnpm rebuild:server"
}, },
"dependencies": { "dependencies": {
"@microsoft/api-extractor": "^7.47.0", "@microsoft/api-extractor": "^7.47.0",

View File

@ -1,6 +1,6 @@
{ {
"name": "@entityseven/rage-fw-server", "name": "@entityseven/rage-fw-server",
"version": "0.1.2", "version": "0.2.0",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/src/index.d.ts", "types": "dist/src/index.d.ts",
"files": [ "files": [

View File

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

View File

@ -0,0 +1,54 @@
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,16 +1,24 @@
import { rpc } from './rpc' import { rpc } from './rpc'
import { Middleware } from './middleware'
import type * as T from '../types' import type * as T from '../types'
export class Server { export class Server {
public register<EventName extends T.RageFW_ServerEvent>( public register<EventName extends T.RageFW_ServerEvent>(
eventName: EventName, eventName: EventName,
callback: T.RageFW_ServerCallback<EventName>, callback: T.RageFW_ServerCallback<EventName>,
options?: {
middlewares?: T.RageFW_MiddlewareOptions<EventName>
},
): Server { ): Server {
rpc.register< rpc.register<
Parameters<typeof callback>, Parameters<typeof callback>,
ReturnType<typeof callback>, ReturnType<typeof callback> | Promise<unknown>,
EventName EventName
>(eventName, async (...data) => await callback(...data)) >(eventName, async (...data) => {
if (!options?.middlewares) return await callback(...data)
await Middleware.process(options.middlewares, callback, data)
})
return this return this
} }

View File

@ -1,5 +1,7 @@
import { Logger, Player, Server, rpc } from './core' import { Logger, Player, Server, rpc } from './core'
export type { RageFW_MiddlewareFunction } from './types'
export const fw = { export const fw = {
event: new Server(), event: new Server(),
player: new Player(), player: new Player(),

View File

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

View File

@ -0,0 +1,26 @@
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

@ -1,6 +1,6 @@
{ {
"name": "@entityseven/rage-fw-shared-types", "name": "@entityseven/rage-fw-shared-types",
"version": "0.1.2", "version": "0.2.0",
"types": "types/types/index.d.ts", "types": "types/types/index.d.ts",
"files": [ "files": [
"types/**/*" "types/**/*"