ws-asyncapi API / core / Channel
Class: Channel<Query, Headers, WebsocketClientData, WebsocketServerData, Topics, Path, Params, Data, RpcMap, ServerRpcMap, StreamMap, AuthCredentials, PresenceState>
Defined in: .api-entries/core/index.d.ts:689
Type Parameters
Query
Query extends unknown | undefined
Headers
Headers extends unknown | undefined
WebsocketClientData
WebsocketClientData extends WebsocketDataType["client"] = { }
WebsocketServerData
WebsocketServerData extends WebsocketDataType["server"] = { }
Topics
Topics extends string = string
Path
Path extends `/${string}` = `/${string}`
Params
Params extends unknown | undefined = ExtractRouteParams<Path>
Data
Data extends unknown | undefined = { }
RpcMap
RpcMap extends Record<string, { input: unknown; output: unknown; errors: Record<string, unknown>; }> = { }
ServerRpcMap
ServerRpcMap extends Record<string, { input: unknown; output: unknown; }> = { }
StreamMap
StreamMap extends Record<string, { input: unknown; output: unknown; }> = { }
AuthCredentials
AuthCredentials = undefined
PresenceState
PresenceState = undefined
Constructors
Constructor
new Channel<
Query,Headers,WebsocketClientData,WebsocketServerData,Topics,Path,Params,Data,RpcMap,ServerRpcMap,StreamMap,AuthCredentials,PresenceState>(address,name,schema?):Channel<Query,Headers,WebsocketClientData,WebsocketServerData,Topics,Path,Params,Data,RpcMap,ServerRpcMap,StreamMap,AuthCredentials,PresenceState>
Defined in: .api-entries/core/index.d.ts:757
Parameters
address
Path
name
string
schema?
ChannelObject
Returns
Channel<Query, Headers, WebsocketClientData, WebsocketServerData, Topics, Path, Params, Data, RpcMap, ServerRpcMap, StreamMap, AuthCredentials, PresenceState>
Properties
address
address:
Path
Defined in: .api-entries/core/index.d.ts:700
name
name:
string
Defined in: .api-entries/core/index.d.ts:701
schema
schema:
ChannelObject
Defined in: .api-entries/core/index.d.ts:702
~
~:
object
Defined in: .api-entries/core/index.d.ts:703
client
client:
Map<string,MessageHandlerSchema<WebsocketDataType,Topics,any,Query,Headers,Params,Data>>
server
server:
Map<string,AnySchema>
rpc
rpc:
Map<string,RpcDefinition>
serverRpc
serverRpc:
Map<string,ServerRpcDefinition>
stream
stream:
Map<string,StreamDefinition>
history
history:
Map<string,number>
sockets
sockets:
Map<string,Connection>
plugins
plugins:
Set<string>
serverPlugins
serverPlugins:
ServerPlugin[]
serverEvents
serverEvents:
Map<string, (data) =>void>
sendCommand
sendCommand: (
cmd) =>void
Parameters
cmd
Returns
void
query
query:
AnySchema
headers
headers:
AnySchema
onOpen
onOpen:
OnOpenHandler<WebsocketDataType,Topics,Query,Headers,Params,Data>
onClose
onClose:
OnCloseHandler<WebsocketDataType,Topics,Query,Headers,Params,Data>
globalPublish
globalPublish: (
topic,type,message) =>void
Parameters
topic
any
type
any
message
any
Returns
void
fetchSockets
fetchSockets: (
room?) =>Promise<RemoteSocketInfo[]>
Parameters
room?
string
Returns
Promise<RemoteSocketInfo[]>
beforeUpgrade
beforeUpgrade:
BeforeUpgradeHandler<Query,Headers,Params,Data>
derives
derives: (
ctx) =>any[]
Parameters
ctx
request
RequestData<Query, Headers, Params>
data
any
Returns
any
middlewares
middlewares: (
ctx) =>any[]
Parameters
ctx
ws
any
type
string
message
any
request
RequestData<Query, Headers, Params>
data
any
Returns
any
onError
onError: (
ctx) =>void
Parameters
ctx
ws
any
error
unknown
type
string
data
any
Returns
void
publishFrame
publishFrame: (
topic,frame,except?) =>void
Parameters
topic
string
frame
AnyFrame
except?
string[]
Returns
void
presence
presence:
object
presence.state
state:
AnySchema
presence.room
room: (
ctx) =>string
Parameters
ctx
request
RequestData<Query, Headers, Params>
data
any
Returns
string
auth
auth:
object
auth.credentials
credentials:
AnySchema
auth.handler
handler: (
ctx) =>any
Parameters
ctx
ws
any
credentials
any
request
RequestData<Query, Headers, Params>
data
any
Returns
any
Methods
query()
query<
QueryObject>(query):Channel<InferOut<QueryObject>,Headers,WebsocketClientData,WebsocketServerData,Topics,Path,Params,Data,RpcMap,ServerRpcMap,StreamMap,AuthCredentials,PresenceState>
Defined in: .api-entries/core/index.d.ts:758
Type Parameters
QueryObject
QueryObject extends AnySchema
Parameters
query
QueryObject
Returns
Channel<InferOut<QueryObject>, Headers, WebsocketClientData, WebsocketServerData, Topics, Path, Params, Data, RpcMap, ServerRpcMap, StreamMap, AuthCredentials, PresenceState>
headers()
headers<
HeadersObject>(headers):Channel<Query,InferOut<HeadersObject>,WebsocketClientData,WebsocketServerData,Topics,Path,Params,Data,RpcMap,ServerRpcMap,StreamMap,AuthCredentials,PresenceState>
Defined in: .api-entries/core/index.d.ts:759
Type Parameters
HeadersObject
HeadersObject extends AnySchema
Parameters
headers
HeadersObject
Returns
Channel<Query, InferOut<HeadersObject>, WebsocketClientData, WebsocketServerData, Topics, Path, Params, Data, RpcMap, ServerRpcMap, StreamMap, AuthCredentials, PresenceState>
serverMessage()
serverMessage<
Name,Validation>(name,validation?):Channel<Query,Headers,WebsocketClientData,WebsocketServerData&{ [k in string]: Validation extends AnySchema ? InferOut<Validation> : never },Topics,Path,Params,Data,RpcMap,ServerRpcMap,StreamMap,AuthCredentials,PresenceState>
Defined in: .api-entries/core/index.d.ts:760
Type Parameters
Name
Name extends string
Validation
Validation extends AnySchema = undefined
Parameters
name
Name
validation?
Validation
Returns
Channel<Query, Headers, WebsocketClientData, WebsocketServerData & { [k in string]: Validation extends AnySchema ? InferOut<Validation> : never }, Topics, Path, Params, Data, RpcMap, ServerRpcMap, StreamMap, AuthCredentials, PresenceState>
clientMessage()
clientMessage<
Name,Validation,Message>(name,handler,validation?):Channel<Query,Headers,WebsocketClientData&{ [k in string]: InferIn<Validation> },WebsocketServerData,Topics,Path,Params,Data,RpcMap,ServerRpcMap,StreamMap,AuthCredentials,PresenceState>
Defined in: .api-entries/core/index.d.ts:763
Type Parameters
Name
Name extends string
Validation
Validation extends AnySchema
Message
Message = InferOut<Validation>
Parameters
name
Name
handler
MessageHandler<{ client: WebsocketClientData; server: WebsocketServerData; serverRpc: ServerRpcMap; }, Topics, Message, Query, Headers, Params, Data>
validation?
Validation
Returns
Channel<Query, Headers, WebsocketClientData & { [k in string]: InferIn<Validation> }, WebsocketServerData, Topics, Path, Params, Data, RpcMap, ServerRpcMap, StreamMap, AuthCredentials, PresenceState>
rpc()
rpc<
Name,Input,Output,Errors>(name,input,output,handler,errors?):Channel<Query,Headers,WebsocketClientData,WebsocketServerData,Topics,Path,Params,Data,RpcMap& { [k in string]: { input: InferIn<Input>; output: InferOut<Output>; errors: { [C in string | number | symbol]: InferOut<Errors[C]> } } },ServerRpcMap,StreamMap,AuthCredentials,PresenceState>
Defined in: .api-entries/core/index.d.ts:781
Declares a request/response message (acknowledged RPC). Unlike clientMessage (fire-and-forget), the handler returns a value that is validated against output and sent back to the caller as a typed reply. The client awaits it via client.request(name, input).
Pass an optional errors map (code → data schema) to declare expected failures in the contract. The handler throws new RpcError(code, message, data); the generated client surfaces them as a typed, discriminated union via client.safeRequest(name, input).
Type Parameters
Name
Name extends string
Input
Input extends AnySchema
Output
Output extends AnySchema
Errors
Errors extends Record<string, AnySchema> = { }
Parameters
name
Name
input
Input
output
Output
handler
RpcHandler<{ client: WebsocketClientData; server: WebsocketServerData; serverRpc: ServerRpcMap; }, Topics, InferOut<Input>, InferOut<Output>, Query, Headers, Params, Data>
errors?
Errors
Returns
Channel<Query, Headers, WebsocketClientData, WebsocketServerData, Topics, Path, Params, Data, RpcMap & { [k in string]: { input: InferIn<Input>; output: InferOut<Output>; errors: { [C in string | number | symbol]: InferOut<Errors[C]> } } }, ServerRpcMap, StreamMap, AuthCredentials, PresenceState>
serverRpc()
serverRpc<
Name,Input,Output>(name,input,output):Channel<Query,Headers,WebsocketClientData,WebsocketServerData,Topics,Path,Params,Data,RpcMap,ServerRpcMap&{ [k in string]: { input: InferIn<Input>; output: InferOut<Output> } },StreamMap,AuthCredentials,PresenceState>
Defined in: .api-entries/core/index.d.ts:801
Declares a server→client request/response (acknowledged RPC). The server calls it on a connection via ws.request(name, input) and awaits the client's typed reply; the client answers it with client.onRequest(name, (input) => output). The reverse direction of rpc.
Type Parameters
Name
Name extends string
Input
Input extends AnySchema
Output
Output extends AnySchema
Parameters
name
Name
input
Input
output
Output
Returns
Channel<Query, Headers, WebsocketClientData, WebsocketServerData, Topics, Path, Params, Data, RpcMap, ServerRpcMap & { [k in string]: { input: InferIn<Input>; output: InferOut<Output> } }, StreamMap, AuthCredentials, PresenceState>
stream()
stream<
Name,Input,Output>(name,input,output,handler):Channel<Query,Headers,WebsocketClientData,WebsocketServerData,Topics,Path,Params,Data,RpcMap,ServerRpcMap,StreamMap&{ [k in string]: { input: InferIn<Input>; output: InferOut<Output> } },AuthCredentials,PresenceState>
Defined in: .api-entries/core/index.d.ts:823
Declares a stream: the client opens it with client.stream(name, input) and consumes a sequence of typed values with for await. The handler is an async generator — each yield is validated against output and pushed to the client as it arrives; returning ends the stream, throwing fails it with a typed error. If the consumer stops iterating (or disconnects), the handler is cancelled (its signal aborts and the generator is return()-ed, so a try/finally can clean up).
.stream("ticks", z.object({}), z.object({ n: z.number() }),
async function* ({ signal }) {
for (let n = 0; !signal.aborted; n++) { yield { n }; await sleep(1000); }
})Type Parameters
Name
Name extends string
Input
Input extends AnySchema
Output
Output extends AnySchema
Parameters
name
Name
input
Input
output
Output
handler
StreamHandler<{ client: WebsocketClientData; server: WebsocketServerData; serverRpc: ServerRpcMap; }, Topics, InferOut<Input>, InferOut<Output>, Query, Headers, Params, Data>
Returns
Channel<Query, Headers, WebsocketClientData, WebsocketServerData, Topics, Path, Params, Data, RpcMap, ServerRpcMap, StreamMap & { [k in string]: { input: InferIn<Input>; output: InferOut<Output> } }, AuthCredentials, PresenceState>
onOpen()
onOpen(
handler):this
Defined in: .api-entries/core/index.d.ts:833
Parameters
handler
OnOpenHandler<{ client: WebsocketClientData; server: WebsocketServerData; serverRpc: ServerRpcMap; }, Topics, Query, Headers, Params, Data>
Returns
this
onClose()
onClose(
handler):this
Defined in: .api-entries/core/index.d.ts:838
Parameters
handler
OnCloseHandler<{ client: WebsocketClientData; server: WebsocketServerData; serverRpc: ServerRpcMap; }, Topics, Query, Headers, Params, Data>
Returns
this
publish()
publish<
Name>(topic,name, ...message):void
Defined in: .api-entries/core/index.d.ts:847
! Be careful this public method does not see to what channel it belongs to. This function can be changed in the near future.
Type Parameters
Name
Name extends string
Parameters
topic
Topics
name
Name
message
...WebsocketServerData[Name] extends never ? [] : [WebsocketServerData[Name]]
Returns
void
toSocket()
toSocket<
Name>(socketId,name, ...message):void
Defined in: .api-entries/core/index.d.ts:853
Send an event to a single socket by id, anywhere in the cluster (the Socket.IO io.to(socketId).emit(...) equivalent). Routed through the socket's reserved per-socket room.
Type Parameters
Name
Name extends string
Parameters
socketId
string
name
Name
message
...WebsocketServerData[Name] extends never ? [] : [WebsocketServerData[Name]]
Returns
void
fetchSockets()
fetchSockets(
room?):Promise<RemoteSocketInfo[]>
Defined in: .api-entries/core/index.d.ts:858
List sockets cluster-wide (presence). With room, only sockets in that room; otherwise every connected socket. Returns ids + their rooms.
Parameters
room?
Topics
Returns
Promise<RemoteSocketInfo[]>
disconnectSockets()
disconnectSockets(
room?):void
Defined in: .api-entries/core/index.d.ts:860
Disconnect sockets cluster-wide — all, or only those in room.
Parameters
room?
Topics
Returns
void
socketsJoin()
socketsJoin(
rooms,room?):void
Defined in: .api-entries/core/index.d.ts:862
Make sockets (all, or those in room) join rooms, cluster-wide.
Parameters
rooms
Topics | Topics[]
room?
Topics
Returns
void
socketsLeave()
socketsLeave(
rooms,room?):void
Defined in: .api-entries/core/index.d.ts:864
Make sockets (all, or those in room) leave rooms, cluster-wide.
Parameters
rooms
Topics | Topics[]
room?
Topics
Returns
void
serverSideEmit()
serverSideEmit(
event,data?):void
Defined in: .api-entries/core/index.d.ts:870
Emit an event to the other server nodes in the cluster (not clients). Handlers are registered with onServerEvent. The emitting node does not receive its own event.
Parameters
event
string
data?
unknown
Returns
void
onServerEvent()
onServerEvent<
T>(event,handler):this
Defined in: .api-entries/core/index.d.ts:872
Handle a serverSideEmit event from another node.
Type Parameters
T
T = unknown
Parameters
event
string
handler
(data) => void
Returns
this
$typeChannels()
$typeChannels<
T>():Channel<Query,Headers,WebsocketClientData,WebsocketServerData,T,Path,Params,Data,RpcMap,ServerRpcMap,StreamMap,AuthCredentials,PresenceState>
Defined in: .api-entries/core/index.d.ts:876
This function can be changed in the near future.
Type Parameters
T
T extends string
Returns
Channel<Query, Headers, WebsocketClientData, WebsocketServerData, T, Path, Params, Data, RpcMap, ServerRpcMap, StreamMap, AuthCredentials, PresenceState>
beforeUpgrade()
beforeUpgrade<
DataThis>(handler):Channel<Query,Headers,WebsocketClientData,WebsocketServerData,Topics,Path,Params,Data&DataThis,RpcMap,ServerRpcMap,StreamMap,AuthCredentials,PresenceState>
Defined in: .api-entries/core/index.d.ts:877
Type Parameters
DataThis
DataThis
Parameters
handler
BeforeUpgradeHandler<Query, Headers, Params, DataThis>
Returns
Channel<Query, Headers, WebsocketClientData, WebsocketServerData, Topics, Path, Params, Data & DataThis, RpcMap, ServerRpcMap, StreamMap, AuthCredentials, PresenceState>
use()
Call Signature
use<
Result>(plugin):Result
Defined in: .api-entries/core/index.d.ts:900
Apply a plugin — a function that receives this channel and returns an extended one. Because every builder method threads the channel's generics, the plugin's return type is the widened channel, so typed context, hooks, and contract additions a plugin contributes flow straight through. Use it to package reusable behavior (auth, rate-limit, logging) as an installable, typed unit.
// reusable plugin (generic over the channel it's applied to)
const withUser = <C extends AnyChannel>(c: C) =>
c.resolve(async ({ request }) => ({ user: await verify(request.query.token) }));
// configurable plugin (curried)
const rateLimit = (opts: { max: number }) => <C extends AnyChannel>(c: C) =>
c.beforeMessage(({ ws }) => { if (over(ws.id, opts)) throw new RpcError("OVERLOADED", "slow down"); });
const chat = new Channel("/chat/:room", "chat")
.use(withUser) // handlers now see `user`, typed
.use(rateLimit({ max: 100 }));Type Parameters
Result
Result
Parameters
plugin
(channel) => Result
Returns
Result
Call Signature
use<
PluginClient,PluginServer,PluginData,PluginRpc,PluginServerRpc,PluginStream>(plugin):Channel<Query,Headers,WebsocketClientData&PluginClient,WebsocketServerData&PluginServer,Topics,Path,Params,Data&PluginData,RpcMap&PluginRpc,ServerRpcMap&PluginServerRpc,StreamMap&PluginStream,AuthCredentials,PresenceState>
Defined in: .api-entries/core/index.d.ts:901
Apply a plugin — a function that receives this channel and returns an extended one. Because every builder method threads the channel's generics, the plugin's return type is the widened channel, so typed context, hooks, and contract additions a plugin contributes flow straight through. Use it to package reusable behavior (auth, rate-limit, logging) as an installable, typed unit.
// reusable plugin (generic over the channel it's applied to)
const withUser = <C extends AnyChannel>(c: C) =>
c.resolve(async ({ request }) => ({ user: await verify(request.query.token) }));
// configurable plugin (curried)
const rateLimit = (opts: { max: number }) => <C extends AnyChannel>(c: C) =>
c.beforeMessage(({ ws }) => { if (over(ws.id, opts)) throw new RpcError("OVERLOADED", "slow down"); });
const chat = new Channel("/chat/:room", "chat")
.use(withUser) // handlers now see `user`, typed
.use(rateLimit({ max: 100 }));Type Parameters
PluginClient
PluginClient extends Record<string, any>
PluginServer
PluginServer extends Record<string, any>
PluginData
PluginData
PluginRpc
PluginRpc extends Record<string, { input: unknown; output: unknown; errors: Record<string, unknown>; }>
PluginServerRpc
PluginServerRpc extends Record<string, { input: unknown; output: unknown; }>
PluginStream
PluginStream extends Record<string, { input: unknown; output: unknown; }>
Parameters
plugin
Channel<any, any, PluginClient, PluginServer, any, any, any, PluginData, PluginRpc, PluginServerRpc, PluginStream, any, any>
Returns
Channel<Query, Headers, WebsocketClientData & PluginClient, WebsocketServerData & PluginServer, Topics, Path, Params, Data & PluginData, RpcMap & PluginRpc, ServerRpcMap & PluginServerRpc, StreamMap & PluginStream, AuthCredentials, PresenceState>
derive()
derive<
Derived>(fn):Channel<Query,Headers,WebsocketClientData,WebsocketServerData,Topics,Path,Params,Data&Derived,RpcMap,ServerRpcMap,StreamMap,AuthCredentials,PresenceState>
Defined in: .api-entries/core/index.d.ts:917
Extend the connection context with typed fields (auth, db handles, the decoded user, ...). Runs once on open; the returned object is merged into data and visible to every handler. Chainable — each call widens data.
Type Parameters
Derived
Derived extends Record<string, unknown>
Parameters
fn
(ctx) => Derived
Returns
Channel<Query, Headers, WebsocketClientData, WebsocketServerData, Topics, Path, Params, Data & Derived, RpcMap, ServerRpcMap, StreamMap, AuthCredentials, PresenceState>
resolve()
resolve<
Derived>(fn):Channel<Query,Headers,WebsocketClientData,WebsocketServerData,Topics,Path,Params,Data&Derived,RpcMap,ServerRpcMap,StreamMap,AuthCredentials,PresenceState>
Defined in: .api-entries/core/index.d.ts:922
Async variant of derive (e.g. fetch the user from a token).
Type Parameters
Derived
Derived extends Record<string, unknown>
Parameters
fn
(ctx) => Promise<Derived>
Returns
Channel<Query, Headers, WebsocketClientData, WebsocketServerData, Topics, Path, Params, Data & Derived, RpcMap, ServerRpcMap, StreamMap, AuthCredentials, PresenceState>
onAuth()
onAuth<
Creds>(credentials,handler):Channel<Query,Headers,WebsocketClientData,WebsocketServerData,Topics,Path,Params,Data,RpcMap,ServerRpcMap,StreamMap,InferIn<Creds>,PresenceState>
Defined in: .api-entries/core/index.d.ts:948
Declares mid-connection credential refresh. A WebSocket can outlive its initial bearer token; .onAuth lets the client present fresh credentials on the live connection (via client.authenticate(creds)) without dropping and re-handshaking.
credentials validates the incoming payload; the handler receives the parsed credentials plus the current context, and returns the fields to merge into that context (typically the re-decoded user) — visible to every subsequent handler. Throw new RpcError(code, message, data) to reject the refresh; the client's authenticate promise rejects with that typed error.
The resilient client also re-sends the last credentials automatically after a reconnect, so the refreshed identity survives transient drops.
.resolve(async ({ request }) => ({ user: await verify(request.headers.token) }))
.onAuth(z.object({ token: z.string() }), async ({ credentials }) => ({
user: await verify(credentials.token), // replaces the stale user
}))Type Parameters
Creds
Creds extends AnySchema
Parameters
credentials
Creds
handler
AuthHandler<{ client: WebsocketClientData; server: WebsocketServerData; serverRpc: ServerRpcMap; }, Topics, InferOut<Creds>, Query, Headers, Params, Data>
Returns
Channel<Query, Headers, WebsocketClientData, WebsocketServerData, Topics, Path, Params, Data, RpcMap, ServerRpcMap, StreamMap, InferIn<Creds>, PresenceState>
presence()
presence<
State>(state,options?):Channel<Query,Headers,WebsocketClientData,WebsocketServerData,Topics,Path,Params,Data,RpcMap,ServerRpcMap,StreamMap,AuthCredentials,InferOut<State>>
Defined in: .api-entries/core/index.d.ts:973
Enables typed presence — a per-room roster of who's connected and their live state (cursor, status, "typing…"). state is the per-member state schema, typed end-to-end. Each connection belongs to one presence room, derived server-side (so the client never names a room): by default the connection's concrete address (/doc/:id → #presence:/doc/42); override with options.room to key it however you like.
The client drives it with client.presence.set(state) / .subscribe(cb) / .clear(); join/leave/update diffs ride the normal room fan-out, so it works across a cluster for free, and a (re)connecting client fetches the current roster via a snapshot (backed by backplane.getPresence).
.presence(z.object({ name: z.string(), typing: z.boolean() }))
// client:
client.presence.set({ name: "Alice", typing: false });
client.presence.subscribe((members) => render(members)); // Map<id, state>Type Parameters
State
State extends AnySchema
Parameters
state
State
options?
room?
(ctx) => string
Returns
Channel<Query, Headers, WebsocketClientData, WebsocketServerData, Topics, Path, Params, Data, RpcMap, ServerRpcMap, StreamMap, AuthCredentials, InferOut<State>>
history()
history<
Name>(name,options?):this
Defined in: .api-entries/core/index.d.ts:996
Retains recent events of name per room (history / rewind), so a (re)connecting client can fetch a backlog with client.history(room) — the chat-backlog / last-N-ticks pattern. Different from connection-state-recovery (which replays only your gap during a brief blip): history is room-scoped and any subscribed client can read it.
Call once per event you want retained; keep bounds the per-room buffer (default 100). Retention is in the backplane (in-memory for LocalBackplane); a client can only read history for rooms it is in.
.serverMessage("message", z.object({ text: z.string() }))
.history("message", { keep: 50 })
// client: const recent = await client.history("room:42", { limit: 50 });Type Parameters
Name
Name extends string
Parameters
name
Name
options?
keep?
number
Returns
this
beforeMessage()
beforeMessage(
fn):this
Defined in: .api-entries/core/index.d.ts:1004
Per-message middleware (auth, rate-limit, logging). Runs before each command/rpc handler. Throw to reject: on an rpc the caller receives a typed Error frame; on a command it routes to onError.
Parameters
fn
(ctx) => unknown
Returns
this
onError()
onError(
fn):this
Defined in: .api-entries/core/index.d.ts:1016
Handle errors thrown by command handlers or middleware.
Parameters
fn
(ctx) => void
Returns
this