29 symbols from @neontechspace/fluxerly
Functions#
createClient #
Create a bot client from a token, initially Disconnected
createClient<
F extends MessageFields | undefined = undefined
>(options: ClientOptions<F>): Client<SelectedMessage<F>>createClient<
F extends
| MessageFields | undefined
= undefined
>(
options: ClientOptions<F>
): Client<SelectedMessage<F>>Use run or connect to receive gateway events. HTTP requests work without connecting.
Always finish with shutdown unless an accepted run already manages the client's full lifetime
Parameters
options-
ClientOptions<F>
- Returns
Client<SelectedMessage<F>>
Creation and configuration
Creation validates configuration synchronously without authenticating the token or opening sockets.
No timers or process signal handlers are started.
Invalid options throw Configuration without the rejected value.
An unsupported option key, such as a misspelled logging, throws with a hint naming the closest supported key.
A missing or blank token, such as an unset environment variable, throws Configuration with a hint naming that likely cause.
Unexpected creation failures throw Sdk. An option getter that throws produces code application with the thrown value as the cause
Instance and caching
Hosted Fluxer is selected by default.
For a self-hosted instance, pass its root and let the SDK discover API, gateway and URL endpoints when first needed.
HTTPS and WSS are required unless that explicit instance enables allow for HTTP and WS
Caching is disabled by default.
Cache settings are copied and validated without calling retention policies or reporters.
Unknown cache or message-cache keys fail validation.
The message option selects received message fields once for this client's lifetime
Connection and sharding
Gateway startup defaults to a 30,000 ms overall budget and three total attempts per assigned shard. An explicit sharding plan fixes this client's assigned IDs for its lifetime, while automatic sharding and a client without sharding settings may move to a larger plan when Fluxer asks for more shards. Shard zero receives direct-message gateway traffic. Request and cache limits still apply across the whole client, not separately to each shard
import { createClient } from "@neontechspace/fluxerly"
export function shardingExample(token) {
return createClient({ token, sharding: { totalShards: 4, shardIds: [0, 2] } })
}
import { createClient } from "@neontechspace/fluxerly"
export function shardingExample(token: string) {
return createClient({ token, sharding: { totalShards: 4, shardIds: [0, 2] } })
}
defineBot #
Define a bot's run options without its token, so a module can export them for both run and create from the testing entry point
Returns the same object unchanged, without copying, reading or validating it. run and create check the options when they are called, as they do for an inline object. The function exists for type inference: Command arguments keep their declared types, such as a text argument's value as a string, which an object annotated with Bot loses. TypeScript rejects a token here, so the program passes it to run, usually from an environment variable
defineBot<
F extends MessageFields | undefined = undefined,
S extends Readonly<Record<string, unknown>>
= Readonly<
Record<
string,
| Readonly<
Record<string, CommandArgumentDescriptor>
>
| undefined
>
>
>(
options: Omit<BotOptions<F, S>, "token">
): Omit<BotOptions<F, S>, "token">defineBot<
F extends
| MessageFields | undefined
= undefined,
S extends Readonly<
Record<string, unknown>
>
= Readonly<
Record<
string,
| Readonly<
Record<
string,
CommandArgumentDescriptor
>
>
| undefined
>
>
>(
options:
Omit<BotOptions<F, S>, "token">
): Omit<BotOptions<F, S>, "token">Parameters
options-
Omit<BotOptions<F, S>, "token">
- Returns
Omit<BotOptions<F, S>, "token">
import { defineBot, runBot } from "@neontechspace/fluxerly"
// A test imports bot and passes it to createTestBot from @neontechspace/fluxerly/testing
export const bot = defineBot({
commands: {
prefix: "!",
commands: {
greet: {
arguments: { name: { type: "text", rest: true } },
execute: ({ reply, values }) => reply(`Hello, ${values.name}!`),
},
},
},
})
// Running this file starts the bot, while importing it from a test does not
if (import.meta.main)
await runBot({ token: process.env.FLUXER_BOT_TOKEN, ...bot })
import { defineBot, runBot } from "@neontechspace/fluxerly"
// A test imports bot and passes it to createTestBot from @neontechspace/fluxerly/testing
export const bot = defineBot({
commands: {
prefix: "!",
commands: {
greet: {
arguments: { name: { type: "text", rest: true } },
execute: ({ reply, values }) => reply(`Hello, ${values.name}!`),
},
},
},
})
// Running this file starts the bot, while importing it from a test does not
if (import.meta.main) await runBot({ token: process.env.FLUXER_BOT_TOKEN, ...bot })
runBot #
Start a bot from event handlers and prefix commands, and watch its connection and subscriptions
The client is created and every handler and command is registered synchronously, before this function returns and before the gateway connects, so no event is missed and no handler runs before registration and setup complete. Invalid options, such as a misspelled option key, an unknown event name, invalid delivery settings or an invalid command, throw Configuration at once. Every option is checked before any client, signal listener or request exists, even when the signal is already aborted, so misuse leaves nothing to clean up. A missing or empty token, usually from an unset environment variable, is reported like a failed run instead: Once every other option is valid, run returns an Err Configuration with field token before any client exists. The returned ResultAsync then runs the bot until it stops. Handler contexts expose the full client. Message-create contexts also expose message and a cancellation-aware reply. Handler and command failures are reported to on, or logged in full, without restarting them or stopping the bot. By default, SIGINT and SIGTERM request a normal stop and messages written by bots skip the events handlers and prefix commands. Set process or ignore to false to opt out. Stopping waits for SDK cleanup, not unrelated application Promises. Expected runner failures return Err, including Application when the setup callback or a commands register callback fails and Configuration for a missing token, and SDK defects reject with Sdk. By default a failed run is also logged once, with code lifecycle unless the client already logged that error, and sets process to 1, so await run needs no further handling. Set report to false when the application handles the returned failure and exit status itself. A missing token or a commands-registration failure reported before client creation uses the configured logging settings, prints no stack for the missing token and masks the token after removing surrounding whitespace and one pair of matching quotes. Unusable logging settings are misuse. An option getter that throws while the options are checked throws Sdk with code application and the thrown value as the cause, before any client exists. Other misuse and option-getter failures throw synchronously without a runner report or exit-status change, regardless of report
runBot<
F extends MessageFields | undefined = undefined,
S extends Readonly<Record<string, unknown>>
= Readonly<
Record<
string,
| Readonly<
Record<string, CommandArgumentDescriptor>
>
| undefined
>
>
>(options: BotOptions<F, S>): ResultAsync<
void,
| ConfigurationError | CriticalWorkerStoppedError
| CancelledError | ApplicationError | ConnectError
>runBot<
F extends
| MessageFields | undefined
= undefined,
S extends Readonly<
Record<string, unknown>
>
= Readonly<
Record<
string,
| Readonly<
Record<
string,
CommandArgumentDescriptor
>
>
| undefined
>
>
>(
options: BotOptions<F, S>
): ResultAsync<
void,
| ConfigurationError
| CriticalWorkerStoppedError
| CancelledError
| ApplicationError | ConnectError
>Parameters
options-
BotOptions<F, S>
- Returns
ResultAsync< void, | ConfigurationError | CriticalWorkerStoppedError | CancelledError | ApplicationError | ConnectError >ResultAsync< void, | ConfigurationError | CriticalWorkerStoppedError | CancelledError | ApplicationError | ConnectError >
Aborting the optional signal requests a normal stop, not a cancellation Err. A requested stop first stops accepting
events and lets running handlers, scheduled tasks and their requests finish for up to drain, default 5,000 ms. Success means the client has
stopped and cleanup has finished. The runner always shuts down its client, including after a failure.
If an event or command subscription closes while the bot is still running, the result fails with
Critical. That includes a handler or command router set to overflow "stop" whose queue overflows.
The overflow is still reported to on or logged, and the error names the event and the exceeded capacity, with
the Event as its cause.
Process signal listeners are removed when the run finishes, and the runner never exits the process
import { runBot } from "@neontechspace/fluxerly"
export function pingBot(token) {
return runBot({
token,
commands: {
prefix: "!",
commands: {
ping: { execute: ({ reply }) => reply("Pong!") },
roll: {
arguments: { sides: { type: "integer", min: 2, max: 100, default: 6 } },
execute: ({ reply, values }) => reply(`${1 + Math.floor(Math.random() * values.sides)}`),
},
},
},
})
}
import { runBot } from "@neontechspace/fluxerly"
export function pingBot(token: string | undefined) {
return runBot({
token,
commands: {
prefix: "!",
commands: {
ping: { execute: ({ reply }) => reply("Pong!") },
roll: {
arguments: { sides: { type: "integer", min: 2, max: 100, default: 6 } },
execute: ({ reply, values }) => reply(`${1 + Math.floor(Math.random() * values.sides)}`),
},
},
},
})
}
Interfaces#
BotApplication #
Application details returned by application for this client's bot token
Use id to build an installation link. The bot flags show the current installation settings, and owner identifies the account that owns the application. The SDK freezes this result but does not cache it. Of the owner it keeps only the user ID, and it contains no redirect URIs, verification keys, client secrets or nested bot account
interface BotApplicationbot#Public -
Whether Fluxer currently permits non-owners to install this bot
boolean bot#Require Code Grant -
Whether Fluxer currently requires its OAuth2 code-grant flow for this bot
boolean description#-
Provider's application description, sourced from the bot bio and null when absent
string | null icon#-
Provider's application icon hash, null when the bot has no avatar
string | null id#-
Decimal application ID, suitable for
links.installation string name#-
Provider application name
string owner#Id -
Decimal user ID of the account that owns the application, the ID that
guardsallows when called without IDs.owner Only() string
BotEventOptions #
A run event handler with its own delivery settings
Omitted settings use the run defaults: Overflow drop, concurrency 8 for message or a partitioned handler and 1 otherwise, and the client queue limits
interface BotEventOptions<
K extends EventName,
M extends MessageCore = Message
>
extends HandlerOptions<EventMap<M>[K]>interface BotEventOptions<
K extends EventName,
M extends MessageCore = Message
>
extends HandlerOptions<
EventMap<M>[K]
>handler#-
Called for each event
BotEventHandler<K, M> onoptional#Error -
(report: FailureReport) => unknown partitionoptional#Ready -
Hold the events of a partition key until its own setup is done, as the
clientoption.on partitiondoesReady Valid only together with partition, otherwise
runthrowsBot Configurationbefore any client existsError (key: string, signal: AbortSignal) => unknown(key: string, signal: AbortSignal) => unknown
Inherited from Handler: concurrency, max, max, overflow, partition
BotOptions #
Configure a bot: Client settings, event handlers, prefix commands, optional startup work and stop signals
A missing token or a commands-registration failure reported before client creation uses the configured logging settings and masks the normalized token, including a token enclosed in matching quotes. Other misuse and option-getter failures instead throw synchronously without a runner report or exit-status change
interface BotOptions<
F extends MessageFields | undefined = undefined,
S extends Readonly<Record<string, unknown>>
= Readonly<
Record<string, CommandArgumentSchema | undefined>
>
>
extends ClientOptions<F>, RunBotOptionsinterface BotOptions<
F extends
| MessageFields | undefined
= undefined,
S extends Readonly<
Record<string, unknown>
>
= Readonly<
Record<
string,
| CommandArgumentSchema
| undefined
>
>
>
extends ClientOptions<
F
>, RunBotOptionscommandsoptional#-
Prefix commands registered and attached before connecting
BotCommandsOptions<SelectedMessage<F>, S>BotCommandsOptions< SelectedMessage<F>, S > eventsoptional#-
Handlers registered before connecting and closed when the bot stops
Own enumerable entries are read once when
runis called. Undefined handlers are skipped. Pass a function, or an object with a handler and its own delivery settings. By defaultBot messageand partitioned handlers run up to 8 callbacks at a time and other events 1. When a queue fills, the oldest waiting event is dropped with a Warn record, and the bot keeps running. With a partition, the overflow option's rule decides which event is dropped. Bot-authoredCreate messageandCreate messageevents skip these handlers unlessUpdate ignoreis falseBots BotEvents<SelectedMessage<F>> ignoreoptional#Bots -
Skip
messageandCreate messageevents whose author is a bot, including this bot's own messages, before they reach the events handlers or prefix commandsUpdate Defaults to true, so a reply cannot trigger its own handler. Set false for a bridge or logging bot that handles every message, and check
messagewhere needed. Prefix commands follow the same setting unless.author .is Bot commandssets its own. A value other than a boolean throws.ignore Bots ConfigurationError boolean setupoptional#-
Startup work after events and commands are registered and before the gateway connects, such as extra subscriptions, cache warm-up or scheduled tasks
The bot connects only after a returned promise settles, so no handler runs before setup finishes. Start timers and background work with
client, whose tasks belong to the bot: A requested stop lets their running work finish within.schedule drain, every stop cancels the rest, and a failure reachesMs onor the log. The signal aborts when the bot begins stopping for any reason, including a requested stop before its drain, a failure and a stop while setup is still running. Pass it to SDK operations, or listen for its abort event to end other work started here, which the runner does not track or await. A throw, rejection or returned or resolved Err result stops the bot before connecting, andError runreturns an ErrBot Applicationwhose source is "Error runsetup" and whose cause is the original value, such as theBot Guildof a failed read. A thrownOperation Error Sdkremains a defect and rejects withDefect Sdk. The Effect API runs setup in the bot's Scope instead, so its finalizers and scoped fibers end with the botDefect ( client: Client<SelectedMessage<F>>, context: { readonly signal: AbortSignal } ) => unknown( client: Client<SelectedMessage<F>>, context: { readonly signal: AbortSignal } ) => unknown
Inherited from Client: cache, connection, gateway, instance, logging, message, observe, on, rest, sharding, token, transport, uploads
Inherited from Run: drain, process, report, signal
CurrentBotApplication #
Read the authenticated bot's application identity, its owner's user ID and selected public settings
No gateway connection, application management or authorization-page navigation is performed. The GET uses shared request limits, the client's default deadline (rest, 30,000 ms unless configured) and at most two transient read retries. The frozen result is not cached. Of the owner only the user ID is kept, and redirect URIs, verification keys, client secrets and nested bot fields are excluded. Fluxer decides application visibility and installability. Input, HTTP and malformed-response failures return Bot. Closure returns Client. Abort waits for cleanup and returns Cancelled. Unexpected failures reject with Sdk
interface CurrentBotApplicationimport { links } from "@neontechspace/fluxerly"
export async function applicationExample(client) {
const application = await client.application.fetch()
return application.isErr() ? application : links.installation(application.value.id, { permissions: 0n })
}
import { links, type Client } from "@neontechspace/fluxerly"
export async function applicationExample(client: Client) {
const application = await client.application.fetch()
return application.isErr() ? application : links.installation(application.value.id, { permissions: 0n })
}
fetch#
Fetch this bot token's application data from /oauth2/
Only the documented fields are returned, frozen, without cache storage, gateway events, owner profile lookup or follow-up requests. The timeout option bounds this read only and does not change the gateway startup deadline. Cancelling it affects only this read and never changes the application
fetch(options?: RequestOptions): ResultAsync<
BotApplication,
| ConfigurationError | BotApplicationOperationFailure
| CancelledError
>fetch(
options?: RequestOptions
): ResultAsync<
BotApplication,
| ConfigurationError
| BotApplicationOperationFailure
| CancelledError
>Parameters
optionsoptional-
RequestOptions
- Returns
ResultAsync< BotApplication, | ConfigurationError | BotApplicationOperationFailure | CancelledError >ResultAsync< BotApplication, | ConfigurationError | BotApplicationOperationFailure | CancelledError >
CustomStatusInput #
Text, emoji and optional expiration for the bot's custom status
Fluxer makes the final checks for emoji availability, Unicode emoji semantics and whether expiration is still in the future
interface CustomStatusInputemojioptional#-
An explicit custom-emoji ID or one Unicode emoji
CustomStatusEmoji expiresoptional#At -
Future ISO-8601 expiration time
Impossible calendar dates are rejected before retaining the update. Fluxer rejects an expiry that passes before it receives the update
string textoptional#-
Status text, from 1 through 128 UTF-16 code units
string
GatewayCommands #
Send gateway commands that have no SDK method, on this client's ready shards
This is an advanced escape hatch: The SDK validates the frame locally but does not know the command's meaning, and Fluxer closes the connection, ending the client, for commands it rejects. Observe replies to these commands through the raw event, subscribing before sending
interface GatewayCommandssend#
Send one command frame { op, d } on a Connected local shard
The data is copied through JSON encoding when the operation starts, so later changes to it have no effect, and the encoded frame must be at most 4,096 UTF-8 bytes, Fluxer's message limit. Undefined data is invalid. Pass null instead. Data JSON cannot encode, such as a cycle or a BigInt, fails with reason input. Heartbeat, Identify, Resume and server-only opcodes fail with reason reserved. Commands share the shard's outbound pacing with presence and request commands: At most 500 paced commands per rolling 60 seconds per session, retained across Resume and reset for a fresh Identify, sent in call order. Heartbeats, Identify and Resume are never delayed. At most 500 gateway commands may wait per shard, and further submissions fail with reason busy until transmission or cancellation releases queue capacity. Completion means the frame was handed to the connection, not that Fluxer received or accepted it. A sent Request Guild Members command, opcode 8, counts toward the 12 member requests that members allows this client in any 11 seconds, or the children of one supervisor together, but this method never refuses one for that limit. Fluxer answers an opcode it does not define, missing data or invalid command fields with close code 4001 or 4002. The SDK treats both as permanent, so the client ends. Data must match Fluxer's command schema exactly. Observe any reply through the raw event, which receives every dispatch the session accepts. A shard that loses its connection before sending fails a waiting command with reason not, and the SDK never replays it after reconnecting. Each sent command is logged at Debug with code gateway
send(
shardId: number,
op: number,
d: unknown,
options?: OperationOptions
): ResultAsync<
void,
ConfigurationError | CancelledError | GatewaySendFailure
>send(
shardId: number,
op: number,
d: unknown,
options?: OperationOptions
): ResultAsync<
void,
| ConfigurationError
| CancelledError
| GatewaySendFailure
>Parameters
shardId -
number op-
number d-
unknown optionsoptional-
OperationOptions
- Returns
ResultAsync< void, ConfigurationError | CancelledError | GatewaySendFailure >ResultAsync< void, | ConfigurationError | CancelledError | GatewaySendFailure >
Cancellation through options withdraws a command that is still waiting for the pacing budget and returns
Cancelled. Withdrawal immediately releases its local queue capacity.
A command already handed to the connection cannot be withdrawn.
A malformed signal returns Configuration before anything is queued. A throw from the data's own getters or
to rejects with Sdk code application and the thrown value as its cause.
Other unexpected failures reject with Sdk
// Commands with an SDK method, such as community counts through client.guilds.fetchCounts, use that method instead
export async function sendCustomCommand(client, command, onReply) {
// Subscribe before sending so the raw reply cannot be missed
const replies = client.on("raw", (dispatch) => {
if (dispatch.t === command.replyType)
onReply(dispatch)
})
try {
const result = await client.gateway.send(0, command.op, command.data)
if (result.isErr())
replies.close()
// Close the returned subscription once the reply has arrived
return result.map(() => replies)
}
catch (error) {
replies.close()
throw error
}
}
import type { Client, RawDispatch } from "@neontechspace/fluxerly"
// Commands with an SDK method, such as community counts through client.guilds.fetchCounts, use that method instead
export async function sendCustomCommand(
client: Client,
command: { op: number; data: unknown; replyType: string },
onReply: (reply: RawDispatch) => void,
) {
// Subscribe before sending so the raw reply cannot be missed
const replies = client.on("raw", (dispatch) => {
if (dispatch.t === command.replyType) onReply(dispatch)
})
try {
const result = await client.gateway.send(0, command.op, command.data)
if (result.isErr()) replies.close()
// Close the returned subscription once the reply has arrived
return result.map(() => replies)
} catch (error) {
replies.close()
throw error
}
}
Instance#
Find the selected Fluxer instance's endpoints and build links and asset URLs for it
The resolve method fetches the unauthenticated well-known document only when needed. Concurrent callers share that request. A successful frozen result is retained until client shutdown, without background refresh. Cancelling one caller leaves other callers using the request. The last departing caller waits for discovery cleanup
interface Instanceexport async function instanceExample(client) {
const resolved = await client.instance.resolve({ timeoutMs: 10_000 })
if (resolved.isErr())
return resolved
const channel = resolved.value.links.channel({ id: "1750000000000000000" })
return { api: resolved.value.endpoints.apiPublic, channel }
}
import type { Client } from "@neontechspace/fluxerly"
export async function instanceExample(client: Client) {
const resolved = await client.instance.resolve({ timeoutMs: 10_000 })
if (resolved.isErr()) return resolved
const channel = resolved.value.links.channel({ id: "1750000000000000000" })
return { api: resolved.value.endpoints.apiPublic, channel }
}
resolve#
Resolve this client's instance endpoints and its pure link and asset URL helpers
The unauthenticated discovery request is shared with other resolves, REST work or gateway startup. The timeout option defaults to 30,000 for this wait only. Cancellation releases only this wait, while other users can keep the shared discovery read alive. Document, rate-limit, timeout, closure and invalid timeout-option failures are expected failures
resolve(options?: RequestOptions): ResultAsync<
ResolvedInstance,
InstanceResolveError | CancelledError
>resolve(
options?: RequestOptions
): ResultAsync<
ResolvedInstance,
| InstanceResolveError
| CancelledError
>Parameters
optionsoptional-
RequestOptions
- Returns
ResultAsync<ResolvedInstance, InstanceResolveError | CancelledError>ResultAsync< ResolvedInstance, | InstanceResolveError | CancelledError >- Fails with
Unexpected cleanup failures reject with Sdk, retaining safe details of any accompanying failure or interruption
InstanceDomainMigration #
A web domain migration announced by instance discovery, such as hosted Fluxer moving its web app to a new domain
The SDK records an enabled migration at Info when a client first resolves the instance. It changes no endpoint itself
interface InstanceDomainMigrationanonymous#Rollout Basis Points -
Share of signed-out web visitors moved to the new domain, in basis points from 0 through 10,000, or null when not supplied
number | null enabled#-
Whether the instance switched the migration on
boolean standalone#Forwarding -
Whether standalone app installs are forwarded to the new domain, or null when not supplied
boolean | null
InstanceEndpoints #
Where the selected Fluxer instance hosts its services, validated from its discovery document
Services may use different origins, which selecting that instance trusts
interface InstanceEndpointsapi#Public -
Public HTTP API base
The SDK appends its documented
/v1route once, preserving any advertised prefixstring gateway#-
Gateway WebSocket base
The SDK adds its required protocol query without deriving another host
string invite#-
Invite base for instance-specific invite and vanity URLs
string media#-
Public media base for instance-specific generated asset URLs
string static#Cdn -
Static CDN base for instance-specific generated default-asset URLs
string webapp#-
Web application base for instance-specific generated navigation and installation links
string
Presence#
Set the bot's displayed status or request updates for selected community members
Outgoing status is sent to live shards assigned to this client, at least four seconds apart per shard. Member selections use separate bounded gateway requests. Neither operation has a provider acknowledgement or recipient-delivery guarantee. The SDK does not fetch membership or filter out self. Fluxer decides access and which updates are visible
interface Presenceset#
Set the bot's requested status and optional custom status, including before connecting
The input is validated and frozen when the call runs. Omitted custom keeps the previous request, and null clears it. Expired custom statuses are not restored after reconnect. Each shard retains at most one unsent status update, replacing it with the latest intent even while gateway pacing waits. The four-second interval starts when an update reaches the socket, not when it is queued. Success means the request was accepted locally and scheduled for each shard, not acknowledged by Fluxer. Shutdown releases this intent and its timer
set(input: PresenceInput): Result<void, PresenceFailure>set(
input: PresenceInput
): Result<void, PresenceFailure>Parameters
input-
PresenceInput
- Returns
Result<void, PresenceFailure>- Fails with
Returns a Result synchronously.
A throwing input getter throws Sdk with code application and the thrown value as its cause, and other
unexpected failures throw Sdk with code sdk
import { MemberMentionPreferences } from "@neontechspace/fluxerly"
export async function botProfileExample(client, guildId) {
const presence = client.presence.set({ status: "online", customStatus: { text: "Ready", emoji: { name: "🌱" } } })
if (presence.isErr())
return presence
return client.members.editSelf(guildId, { nickname: "Support", mentionFlags: MemberMentionPreferences.PreferNoMention })
}
import { MemberMentionPreferences, type Client } from "@neontechspace/fluxerly"
export async function botProfileExample(client: Client, guildId: string) {
const presence = client.presence.set({ status: "online", customStatus: { text: "Ready", emoji: { name: "🌱" } } })
if (presence.isErr()) return presence
return client.members.editSelf(guildId, { nickname: "Support", mentionFlags: MemberMentionPreferences.PreferNoMention })
}
setMembers #
Request presence updates for selected members in one community
Register a presence listener, then pass accessible non-self member IDs. Pass [] to clear the selection. Closing the listener does not clear it. No full-member subscription, member lookup or presence cache is created, and Fluxer remains authoritative for access and filtering. The community must belong to a shard assigned to this client, or the call fails with Presence reason input
setMembers(
guildId: string,
memberIds: readonly string[]
): Result<void, PresenceFailure>setMembers(
guildId: string,
memberIds: readonly string[]
): Result<void, PresenceFailure>Inputs are copied and retained when the call runs. Up to 1,000 distinct decimal IDs are accepted, but the full UTF-8 gateway frame must fit 4,096 bytes. Long IDs therefore reduce the effective per-community maximum. The client retains selections for at most 100 communities and 10,000 IDs. Clearing an unsent selection withdraws its queued command and releases its slot immediately. Changes to a selection that has not reached the socket replace that unsent request. Clearing a selection already sent keeps one bounded session slot until fresh Identify or confirmed community leave, because a local socket write cannot confirm that Fluxer applied a clear
After READY or RESUMED, the latest selection or clear is combined and sent at most once per 125 ms per shard.
This interval starts at actual socket transmission, and at most one member-selection command waits per shard.
Sending the same list again deliberately requests a refresh.
A matching guild creation also retries the latest selection or a previously sent clear.
None of these attempts guarantees an event or proves provider acceptance.
Initial state and transitions can be missed during recovery.
Loss of shared channel visibility can remove the provider subscription, so resend the selection after access returns.
Clear explicitly or shut down the client to release local intent.
Input or limit failures fail with Presence, and closing clients fail with Client.
The community and member IDs must be positive decimal strings without leading zeros, no greater than 9223372036854775807.
The member IDs are copied once, and that copy is validated and subscribed
Parameters
guildId -
string memberIds -
readonly string[]
- Returns
Result<void, PresenceFailure>- Fails with
Returns a Result synchronously.
A throwing ID getter throws Sdk with code application and the thrown value as its cause, and other
unexpected failures throw Sdk with code sdk
export function watchSelectedMember(client, guildId, memberId) {
const subscription = client.on("presenceUpdate", (presence) => {
if (presence.guildId === guildId && presence.userId === memberId)
void presence.status
})
const selected = client.presence.setMembers(guildId, [memberId])
if (selected.isErr())
subscription.close()
return selected.map(() => subscription)
}
import type { Client } from "@neontechspace/fluxerly"
export function watchSelectedMember(client: Client, guildId: string, memberId: string) {
const subscription = client.on("presenceUpdate", (presence) => {
if (presence.guildId === guildId && presence.userId === memberId) void presence.status
})
const selected = client.presence.setMembers(guildId, [memberId])
if (selected.isErr()) subscription.close()
return selected.map(() => subscription)
}
PresenceInput #
Set the status this bot should publish on its gateway connections
Use custom to request clearing the custom status. Omission preserves this client's latest custom-status request, or leaves the provider value unchanged if there is no retained request. The client copies the latest accepted settings and retains at most one unsent update per local shard, replacing its payload with the latest intent. Status updates are at least four seconds apart, measured from each actual socket transmission, not queue admission. It publishes those settings on ready local shards and restores them after READY or RESUMED. A successful call means the client accepted the settings. It does not mean every shard published them at once or that another user can see them. Shutdown clears the saved settings and pending local timers
interface PresenceInputcustomoptional#Status -
New custom status, null to clear it, or omission to retain the latest custom-status request made by this client
CustomStatusInput | null status#-
Visible status to publish on the bot's live gateway connections
PresenceStatus
ResolvedInstance #
The selected server's service addresses and matching URL helpers
This frozen result is retained for one client, not refreshed on each later resolve. Use assets and links to build URLs for this instance rather than the hosted default. These helpers make no requests, inspect no credentials and do not refresh discovery or change caches
interface ResolvedInstanceapi#Code Version -
Provider code-version indicator from discovery
It is not an API path version
number assets#-
Pure asset URL helpers bound to this instance's media and static-CDN bases
They follow the assets namespace's input-field and fallback rules, return URLs directly and throw
Assetfor invalid inputUrl Error AssetHelpers discovery#Enabled -
Whether this instance has community directory discovery switched on
True when discovery omits the flag, as Fluxer documents. A present value that is not a boolean makes the discovery document invalid. When false, the discovery namespace's search, apply, edit and withdraw operations fail with reason rejected, HTTP
400anddetailsDISCOVERY_DISABLED, while.provider Code fetchandStatus fetchstill answer. The value is a snapshot from when the client resolved the instance, so an operator's later change appears only in a new clientCategories boolean domain#Migration -
The web domain migration that discovery announced, or null when the instance announced none
Links and OAuth URLs always use the discovered web application base in endpoints, so they follow a migrated domain
InstanceDomainMigration | null endpoints#-
Exact validated service bases from discovery
InstanceEndpoints links#-
Pure application-link helpers bound to this instance's web application base
They return URLs directly, throw
Helperfor invalid input and perform no navigation or access checkError LinkHelpers presigned#Attachment Uploads -
Whether this instance advertises temporary upload URLs for attachment transfers
boolean
RestRequest #
One request to a Fluxer API route that the SDK does not wrap, sent with the client's bot credential through the same queue, rate-limit learning, 429 waits, deadline, logging and cancellation as wrapped operations
Invalid input fails before dispatch with Rest reason input. A GET that fails with a network error or HTTP 500, 502, 503 or 504 is retried at most twice. Another method is sent again only after Fluxer confirms a rate limit with HTTP 429, so a write with an unknown outcome is never repeated automatically. Message and resource caches are neither read nor updated, and Fluxer's rate limits and permissions still apply
interface RestRequest extends OperationOptionsinterface RestRequest
extends OperationOptionsAborting the signal stops waiting and cancels the HTTP exchange, but cannot undo a request Fluxer already received
export async function currentUserName(client) {
const result = await client.rest.request({ method: "GET", path: "/users/@me" })
return result.isOk() ? result.value.body.username : undefined
}
import type { Client } from "@neontechspace/fluxerly"
export async function currentUserName(client: Client): Promise<string | undefined> {
const result = await client.rest.request<{ username: string }>({ method: "GET", path: "/users/@me" })
return result.isOk() ? result.value.body.username : undefined
}
auditoptional#Reason -
Audit-log reason sent as the X-Audit-Log-Reason header, 1 through 512 printable ASCII characters after trimming
Omission sends no header. Never included in errors, logs or diagnostics
string bodyoptional#-
JSON body, serialized when the request starts
A value JSON cannot represent fails with reason input. Its size counts against the client's queued JSON budget while the request waits. Not allowed with GET
unknown filesoptional#-
Files sent inline as multipart/form-data, with the JSON body as payload_json and each file as files[n] in order
Accepts the same byte, file and stream inputs as message attachments, with the same size, filename and upload-budget rules. The body must then be omitted or a JSON object without attachments, because the SDK sets attachments to the files' metadata as Fluxer's message routes expect. A request whose file source cannot be read again fails with reason
rateinstead of waiting out a 429. Not allowed with GETLimit readonly AttachmentInput[] method#-
HTTP method
Only POST, PUT, PATCH and DELETE may carry a body or files
"GET" | "POST" | "PUT" | "PATCH" | "DELETE"| "GET" | "POST" | "PUT" | "PATCH" | "DELETE" path#-
API path after /v1, such as /users/@me, of at most 2,048 characters
It must start with one slash and contain only URL path characters with valid percent escapes, without empty, dot or dot-dot segments, a query or a fragment. The /v1 prefix and token-authenticated webhook routes (/
webhooks/{id}/{token}) are rejected, including percent-encoded unreserved characters in those route names. These checks are case-sensitive and do not decode reserved characters. Logs, metrics and spans name the route with numeric IDs and other non-word segments replaced by placeholders string queryoptional#-
Query parameters appended to the path in insertion order
Undefined values are omitted, numbers must be finite, and booleans are sent as true or false. The encoded query may contain at most 8,192 characters
Readonly<Record<string, string | number | boolean | undefined>>Readonly< Record< string, | string | number | boolean | undefined > > timeoutoptional#Ms -
Total milliseconds across local queueing, rate-limit waits, retries and HTTP
An integer from 1 through 2,147,483,647, defaulting to the client's
rest(30,000 unless configured). Owned cleanup is awaited afterward, so completion can take longer.default Timeout Ms number
Inherited from Operation: signal
RestRequests #
Send requests to Fluxer API routes that the SDK does not wrap, with the client's bot credential and its REST scheduler
Calls start immediately, need no gateway connection and default to the client's rest deadline. Abort waits for cleanup and returns Cancelled. Unexpected failures reject with Sdk
interface RestRequestsrequest#
Send one request to a route under /v1 and resolve with its status, lower-case headers and parsed JSON body
The request waits in the client's queue and learned rate-limit windows like wrapped operations, and fails at once with reason rate and the remaining wait as retry when a window outlasts the deadline. A 429 is waited out and sent again while the deadline allows. A GET is also retried at most twice after a network error, including a connection lost while the response body arrives, or HTTP 500, 502, 503 or 504. Another method is never sent again after an uncertain outcome. The body is sent as given, including a lone surrogate, which Fluxer answers with HTTP 503. Invalid input fails with Rest reason input before any request, a non-2xx status fails with its status and sanitized api, and closure fails with Client. Message and resource caches are not updated. Percent-encoded unreserved letters cannot bypass the reserved /v1 prefix or token-webhook route checks, which remain case-sensitive. Network causes retain sanitized transport facts, not raw errors. Unknown uppercase provider codes remain in details, including on HTTP 429 when its wait exceeds the deadline. Logs, metrics and spans name only the route template, never the query, body or response
request<T = unknown>(input: RestRequest): ResultAsync<
RestResponse<T>,
ConfigurationError | RestRequestFailure | CancelledError
>request<T = unknown>(
input: RestRequest
): ResultAsync<
RestResponse<T>,
| ConfigurationError
| RestRequestFailure
| CancelledError
>Parameters
input-
RestRequest
- Returns
ResultAsync< RestResponse<T>, ConfigurationError | RestRequestFailure | CancelledError >ResultAsync< RestResponse<T>, | ConfigurationError | RestRequestFailure | CancelledError >
RestResponse #
A successful response from client, for any 2xx status
interface RestResponse<T = unknown>body#-
The parsed JSON body, or undefined when the response has no body
The type parameter is not checked at runtime, so decode the value before trusting its shape. A body over 16 MiB or one that is not valid JSON fails the request with reason response
T headers#-
Response headers with lower-case names
Repeated headers are joined with a comma and space as fetch does
Readonly<Record<string, string>> status#-
HTTP status from 200 through 299
number
ScheduleOptions #
Choose when client runs a task, in both entry points
Without options the task runs once, as soon as possible
interface ScheduleOptionsdelayoptional#Ms -
Milliseconds before the first run, an integer from 0 through 2,147,483,647
A repeating task waits
intervalby default, like an interval timer, and a task that runs once waits 0Ms number intervaloptional#Ms -
Repeat the task, waiting this many milliseconds after each run ends before the next one starts, an integer from 1 through 2,147,483,647
Runs therefore never overlap. Without it the task runs once
number
ScheduledTask #
A task started with client
It ends by itself after its only run, or when the client shuts down
interface ScheduledTaskclose#
Cancel every later run
A run in progress continues, and a draining shutdown still waits for it. The task can close itself from its own run. Repeated calls do nothing
close(): voidShutdownOptions #
Choose how shutdown treats work that is still running, in both entry points
interface ShutdownOptionsdrainoptional#Ms -
Milliseconds to let running work finish before shutdown cancels it, an integer from 0 through 2,147,483,647
The default 0 cancels running handlers at once. The
runfunction drains for 5,000 ms by default when asked to stopBot numberDuring the drain the client accepts no new events. New subscriptions and event waits start closed, as after shutdown. Running handlers and commands continue, events already waiting in on handler queues still run, and REST requests continue, including new ones that handlers send. Scheduled task runs in progress continue, while tasks start no new run and new tasks are refused. The connection state stays as it was until the drain ends. The drain ends as soon as no handler or scheduled task is running, no event is waiting and no REST request is in progress, logging
lifecycle, or when the time runs out. Then shutdown continues as usual and cancels what is left, logging how many handlers, events, tasks and requests it cut off as a.drained lifecycleWarn record. Collectors and subscribe subscriptions receive no events during the drain and end with the shutdown. A shutdown call while another is in progress shares that shutdown and its drain..drain Timed Out A default API handler or scheduled task that awaits a draining shutdown of its own client keeps the drain waiting until the time runs out, so start the shutdown without awaiting it there. A native handler, collector callback or scheduled task that calls shutdown ends at once, and the drain continues for the other work. An invalid value throws
Configurationin the default API and dies with it in the Effect API, before shutdown startsError
StateObserver #
Stop receiving connection-state updates from client
Use using to close the observer when the enclosing block ends
interface StateObserver[dispose]#
Close this observer, as using does at the end of a block
[dispose](): voidclose#
Stop delivering states and drop a pending one
Listener code already running is not cancelled. Repeated calls do nothing
close(): voidType Aliases#
BotEventContext #
type BotEventContext<
K extends EventName,
M extends MessageCore = Message
> =
& {
readonly client: Client<M>
readonly context: EventContext<K, M>
readonly event: EventMap<M>[K]
readonly signal: AbortSignal
}
& (K extends "messageCreate"
? {
readonly message: M
readonly reply: (
input: ReplyInput | string,
options?: Omit<RequestOptions, "signal">
) => ReturnType<Client<M>["messages"]["reply"]>
}
: { … })type BotEventContext<
K extends EventName,
M extends MessageCore = Message
> =
& {
readonly client: Client<M>
readonly context:
EventContext<K, M>
readonly event:
EventMap<M>[K]
readonly signal: AbortSignal
}
& (K extends "messageCreate"
? {
readonly message: M
readonly reply: (
input:
| ReplyInput
| string,
options?: Omit<
RequestOptions,
"signal"
>
) => ReturnType<
Client<M>["messages"][
"reply"
]
>
}
: { … })BotEventHandler #
A returned or resolved Err result is reported like a thrown error, and other return values are ignored
type BotEventHandler<
K extends EventName,
M extends MessageCore = Message
> = (context: BotEventContext<K, M>) => unknowntype BotEventHandler<
K extends EventName,
M extends MessageCore = Message
> = (
context: BotEventContext<K, M>
) => unknownBotEvents #
One optional handler per event, as a function or an object with a handler and delivery settings
When a queue fills, run drops the oldest waiting event, logs a Warn record and counts the drop, and the bot keeps running. With a partition, the overflow option's rule decides which event is dropped. Handlers for message run up to eight at a time by default, so they can finish out of order, and other events run one at a time. A failed handler is reported with its original error to on, or logged in full, without stopping the bot or retrying that handler
type BotEvents<M extends MessageCore = Message> = {
readonly [K in EventName]?:
BotEventHandler<K, M> | BotEventOptions<K, M>
}type BotEvents<
M extends MessageCore = Message
> = {
readonly [K in EventName]?:
| BotEventHandler<K, M>
| BotEventOptions<K, M>
}ConnectionState #
The client's current gateway connection state, not a history of events
Disconnected permits startup. Connecting includes startup retries until every shard owned by this client is ready at the same time. Connected means every local shard is ready. Recovering means an established shard lost readiness and lasts until all shards owned by this client are ready again. Other ready shards can continue work during Recovering. Closing means permanent cleanup is underway, and Closed requires a new client to connect again
type ConnectionState =
| "Disconnected" | "Connecting" | "Connected" | "Recovering"
| "Closing" | "Closed"type ConnectionState =
| "Disconnected" | "Connecting"
| "Connected" | "Recovering"
| "Closing" | "Closed"CustomStatusEmoji #
One custom-status emoji
The variants cannot be combined
type CustomStatusEmoji =
{ readonly id: string } | { readonly name: string }type CustomStatusEmoji =
| { readonly id: string }
| { readonly name: string }PresenceStatus #
The bot's visible status while connected, with dnd meaning do not disturb
Use invisible to hide online status, not to disconnect the client. The status offline is excluded because Fluxer normalizes it to invisible on a connected session
type PresenceStatus = "online" | "idle" | "dnd" | "invisible"type PresenceStatus =
| "online" | "idle" | "dnd"
| "invisible"