registerCommand -> exposeCommand

This commit is contained in:
nvms 2025-04-21 08:05:20 -04:00
parent 978fd71d85
commit 6e153b1b44
6 changed files with 32 additions and 32 deletions

View File

@ -58,7 +58,7 @@ const server = new MeshServer({
redisOptions: { host: "localhost", port: 6379 },
});
server.registerCommand("echo", async (ctx) => {
server.exposeCommand("echo", async (ctx) => {
return `echo: ${ctx.payload}`;
});
```
@ -296,7 +296,7 @@ These can be used to implement custom commands or manage room state manually if
You can guard room joins using command middleware, just like any other command. The built-in room join command is "mesh/join-room", and the payload contains a `roomName` string:
```ts
server.addMiddleware(async (ctx) => {
server.useMiddleware(async (ctx) => {
if (ctx.command === "mesh/join-room") {
const { roomName } = ctx.payload;
const meta = await server.connectionManager.getMetadata(ctx.connection);
@ -444,7 +444,7 @@ You can associate data like user IDs, tokens, or custom attributes with a connec
Metadata can be any JSON-serializable object, including nested structures. Updates fully replace the previous value—partial updates (patches) are not supported. While there is no hard size limit, large metadata objects may impact Redis performance.
```ts
server.registerCommand("authenticate", async (ctx) => {
server.exposeCommand("authenticate", async (ctx) => {
// maybe do some actual authentication here
const { userId } = ctx.payload;
const token = encode({
@ -711,11 +711,11 @@ Middleware can be applied globally to all commands or specifically to individual
Applied to every command received by the server.
```ts
server.addMiddleware(async (ctx) => {
server.useMiddleware(async (ctx) => {
console.log(`Received command: ${ctx.command} from ${ctx.connection.id}`);
});
server.addMiddleware(async (ctx) => {
server.useMiddleware(async (ctx) => {
const metadata = await server.connectionManager.getMetadata(ctx.connection);
if (!metadata?.userId) {
throw new Error("Unauthorized");
@ -741,7 +741,7 @@ const validateProfileUpdate = async (ctx) => {
}
};
server.registerCommand(
server.exposeCommand(
"update-profile",
async (ctx) => {
// ..

View File

@ -25,7 +25,7 @@ export class CommandManager {
* @param {SocketMiddleware[]} [middlewares=[]] - An optional array of middleware functions to apply to the command. Defaults to an empty array.
* @throws {Error} May throw an error if the command registration or middleware addition fails.
*/
registerCommand<T = any, U = any>(
exposeCommand<T = any, U = any>(
command: string,
callback: (context: MeshContext<T>) => Promise<U> | U,
middlewares: SocketMiddleware[] = []
@ -33,7 +33,7 @@ export class CommandManager {
this.commands[command] = callback;
if (middlewares.length > 0) {
this.addMiddlewareToCommand(command, middlewares);
this.useMiddlewareWithCommand(command, middlewares);
}
}
@ -45,7 +45,7 @@ export class CommandManager {
* @returns {void}
* @throws {Error} If the provided middlewares are not valid or fail validation (if applicable).
*/
addMiddleware(...middlewares: SocketMiddleware[]): void {
useMiddleware(...middlewares: SocketMiddleware[]): void {
this.globalMiddlewares.push(...middlewares);
}
@ -56,7 +56,7 @@ export class CommandManager {
* @param {SocketMiddleware[]} middlewares - An array of middleware functions to be added to the command.
* @returns {void}
*/
addMiddlewareToCommand(
useMiddlewareWithCommand(
command: string,
middlewares: SocketMiddleware[]
): void {

View File

@ -216,12 +216,12 @@ export class MeshServer extends WebSocketServer {
* @param {SocketMiddleware[]} [middlewares=[]] - An optional array of middleware functions to apply to the command. Defaults to an empty array.
* @throws {Error} May throw an error if the command registration or middleware addition fails.
*/
registerCommand<T = any, U = any>(
exposeCommand<T = any, U = any>(
command: string,
callback: (context: MeshContext<T>) => Promise<U> | U,
middlewares: SocketMiddleware[] = []
) {
this.commandManager.registerCommand(command, callback, middlewares);
this.commandManager.exposeCommand(command, callback, middlewares);
}
/**
@ -232,8 +232,8 @@ export class MeshServer extends WebSocketServer {
* @returns {void}
* @throws {Error} If the provided middlewares are not valid or fail validation (if applicable).
*/
addMiddleware(...middlewares: SocketMiddleware[]): void {
this.commandManager.addMiddleware(...middlewares);
useMiddleware(...middlewares: SocketMiddleware[]): void {
this.commandManager.useMiddleware(...middlewares);
}
/**
@ -243,11 +243,11 @@ export class MeshServer extends WebSocketServer {
* @param {SocketMiddleware[]} middlewares - An array of middleware functions to be added to the command.
* @returns {void}
*/
addMiddlewareToCommand(
useMiddlewareWithCommand(
command: string,
middlewares: SocketMiddleware[]
): void {
this.commandManager.addMiddlewareToCommand(command, middlewares);
this.commandManager.useMiddlewareWithCommand(command, middlewares);
}
// #endregion
@ -492,7 +492,7 @@ export class MeshServer extends WebSocketServer {
// #region Command Registration
private registerBuiltinCommands() {
this.registerCommand<
this.exposeCommand<
{ channel: string; historyLimit?: number },
{ success: boolean; history?: string[] }
>("mesh/subscribe-channel", async (ctx) => {
@ -527,7 +527,7 @@ export class MeshServer extends WebSocketServer {
}
});
this.registerCommand<{ channel: string }, boolean>(
this.exposeCommand<{ channel: string }, boolean>(
"mesh/unsubscribe-channel",
async (ctx) => {
const { channel } = ctx.payload;
@ -544,7 +544,7 @@ export class MeshServer extends WebSocketServer {
}
);
this.registerCommand<
this.exposeCommand<
{ roomName: string },
{ success: boolean; present: string[] }
>("mesh/join-room", async (ctx) => {
@ -556,7 +556,7 @@ export class MeshServer extends WebSocketServer {
return { success: true, present };
});
this.registerCommand<{ roomName: string }, { success: boolean }>(
this.exposeCommand<{ roomName: string }, { success: boolean }>(
"mesh/leave-room",
async (ctx) => {
const { roomName } = ctx.payload;
@ -567,7 +567,7 @@ export class MeshServer extends WebSocketServer {
}
private registerRecordCommands() {
this.registerCommand<
this.exposeCommand<
{ recordId: string; mode?: "patch" | "full" },
{ success: boolean; record?: any; version?: number }
>("mesh/subscribe-record", async (ctx) => {
@ -600,7 +600,7 @@ export class MeshServer extends WebSocketServer {
}
});
this.registerCommand<{ recordId: string }, boolean>(
this.exposeCommand<{ recordId: string }, boolean>(
"mesh/unsubscribe-record",
async (ctx) => {
const { recordId } = ctx.payload;
@ -612,7 +612,7 @@ export class MeshServer extends WebSocketServer {
}
);
this.registerCommand<
this.exposeCommand<
{ recordId: string; newValue: any },
{ success: boolean }
>("mesh/publish-record-update", async (ctx) => {
@ -639,7 +639,7 @@ export class MeshServer extends WebSocketServer {
}
});
this.registerCommand<
this.exposeCommand<
{ roomName: string },
{ success: boolean; present: string[] }
>("mesh/subscribe-presence", async (ctx) => {
@ -672,7 +672,7 @@ export class MeshServer extends WebSocketServer {
}
});
this.registerCommand<{ roomName: string }, boolean>(
this.exposeCommand<{ roomName: string }, boolean>(
"mesh/unsubscribe-presence",
async (ctx) => {
const { roomName } = ctx.payload;

View File

@ -65,7 +65,7 @@ describe("MeshServer", () => {
});
test("clients can send a command and receive a response", async () => {
server.registerCommand("echo", async (c) => `echo: ${c.payload}`);
server.exposeCommand("echo", async (c) => `echo: ${c.payload}`);
await clientA.connect();
const response = await clientA.command("echo", "Hello, World!");
expect(response).toBe("echo: Hello, World!");

View File

@ -43,7 +43,7 @@ describe("MeshClient", () => {
});
test("command times out when server doesn't respond", async () => {
server.registerCommand("never-responds", async () => new Promise(() => {}));
server.exposeCommand("never-responds", async () => new Promise(() => {}));
await client.connect();
@ -64,7 +64,7 @@ describe("MeshClient", () => {
});
test("thrown servers errors are serialized to the client", async () => {
server.registerCommand("throws-error", async () => {
server.exposeCommand("throws-error", async () => {
throw new Error("This is a test error");
});
@ -79,7 +79,7 @@ describe("MeshClient", () => {
});
test("handles large payloads without issue", async () => {
server.registerCommand("echo", async (ctx) => ctx.payload);
server.exposeCommand("echo", async (ctx) => ctx.payload);
await client.connect();
const largeData = {

View File

@ -56,7 +56,7 @@ describe.sequential("Multiple instances", () => {
});
test("broadcast should work across instances", async () => {
serverA.registerCommand("broadcast", async (ctx) => {
serverA.exposeCommand("broadcast", async (ctx) => {
await serverA.broadcast("hello", "Hello!");
});
@ -97,13 +97,13 @@ describe.sequential("Multiple instances", () => {
test("broadcastRoom should work across instances", async () => {
[serverA, serverB].forEach((server) =>
server.registerCommand("join-room", async (ctx) => {
server.exposeCommand("join-room", async (ctx) => {
await server.addToRoom(ctx.payload.room, ctx.connection);
return { joined: true };
})
);
serverA.registerCommand("broadcast-room", async (ctx) => {
serverA.exposeCommand("broadcast-room", async (ctx) => {
await serverA.broadcastRoom(
ctx.payload.room,
"room-message",