diff --git a/packages/actor-core/src/actor/action.ts b/packages/actor-core/src/actor/action.ts index 846dc1870..87eca69d6 100644 --- a/packages/actor-core/src/actor/action.ts +++ b/packages/actor-core/src/actor/action.ts @@ -8,6 +8,20 @@ import type { SaveStateOptions } from "./instance"; import { Actions } from "./config"; import { ActorContext } from "./context"; +/** + * Options for the `_broadcast` method. + */ +interface BroadcastOptions { + /** + * The connection IDs to be excluded from the broadcast. + */ + exclude?: ConnId[]; + /** + * Excludes the current connection from the broadcast. + */ + excludeSelf?: boolean; +} + /** * Context for a remote procedure call. * @@ -50,6 +64,28 @@ export class ActionContext { this.#actorContext.broadcast(name, ...args); } + /** + * Broadcasts an event to all connected clients with options. + */ + broadcastWithOptions>(opts: BroadcastOptions, name: string, ...args: Args) { + const exclude = opts.exclude ?? []; + + if (opts.excludeSelf) { + exclude.push(this.conn.id); + } + + // @ts-ignore - Access protected method + this.#actorContext.broadcastWithOptions({ exclude }, name, ...args); + return; + } + + /** + * Alias for `broadcastWithOptions` + */ + broadcastWith>(opts: BroadcastOptions, name: string, ...args: Args) { + return this.broadcastWithOptions(opts, name, ...args); + } + /** * Gets the logger instance. */ diff --git a/packages/actor-core/src/actor/context.ts b/packages/actor-core/src/actor/context.ts index 8a32798c6..8887c90af 100644 --- a/packages/actor-core/src/actor/context.ts +++ b/packages/actor-core/src/actor/context.ts @@ -1,6 +1,6 @@ import { Logger } from "@/common/log"; import { Actions } from "./config"; -import { ActorInstance, SaveStateOptions } from "./instance"; +import { ActorInstance, BroadcastInstanceOptions, SaveStateOptions } from "./instance"; import { Conn, ConnId } from "./connection"; import { ActorTags } from "@/common/utils"; import { Schedule } from "./schedule"; @@ -41,6 +41,18 @@ export class ActorContext { return; } + /** + * Broadcasts an event to all connected clients with options. + * @param opts - Options for the broadcast. + * @param name - The name of the event. + * @param args - The arguments to send with the event. + */ + broadcastWithOptions>(opts: BroadcastInstanceOptions, name: string, ...args: Args) { + // @ts-ignore - Access protected method + this.#actor._broadcastWithOptions(opts, name, ...args); + return; + } + /** * Gets the logger instance. */ diff --git a/packages/actor-core/src/actor/instance.ts b/packages/actor-core/src/actor/instance.ts index 803e541f3..ec17f7f42 100644 --- a/packages/actor-core/src/actor/instance.ts +++ b/packages/actor-core/src/actor/instance.ts @@ -36,6 +36,16 @@ export interface SaveStateOptions { immediate?: boolean; } +/** + * Options for the `_broadcastWithOptions` method. + */ +export interface BroadcastInstanceOptions { + /** + * The connection IDs to be excluded from the broadcast. + */ + exclude?: string[]; +} + /** Actor type alias with all `any` types. Used for `extends` in classes referencing this actor. */ // biome-ignore lint/suspicious/noExplicitAny: Needs to be used in `extends` export type AnyActorInstance = ActorInstance; @@ -1013,6 +1023,16 @@ export class ActorInstance { * @param args - The arguments to send with the event. */ _broadcast>(name: string, ...args: Args) { + return this._broadcastWithOptions({}, name, ...args); + } + + /** + * Broadcasts an event to all connected clients with options. + * @param opts - Options for the broadcast. + * @param name - The name of the event. + * @param args - The arguments to send with the event. + */ + _broadcastWithOptions>(opts: BroadcastInstanceOptions, name: string, ...args: Args) { this.#assertReady(); // Send to all connected clients @@ -1028,8 +1048,14 @@ export class ActorInstance { }, }); + const excludeList = opts.exclude ?? []; + // Send message to clients for (const connection of subscriptions) { + if (excludeList.includes(connection.id)) { + continue; + } + connection._sendMessage(toClientSerializer); } }