@helyx/sdk
v0.8.4
Published
Deployment-neutral contracts for building Helyx modules.
Readme
@helyx/sdk
Deployment-neutral contracts for official Helyx modules.
Requirements
- Node.js 24–26
- npm 11 or newer
The SDK defines module lifecycle, service access, interactions, modals, Components V2 messages, events, logging and dashboard actions. Modal contracts support text fields and Discord-native string, user, role, mentionable and channel selectors. defineModule preserves the typed module definition without coupling feature packages to the hosted bot.
Shard-neutral contract
Modules consume deployment-neutral services and remain unaware of shard IDs, worker routing and process topology. They must not import Redis, Discord.js, shard managers, process IPC, application-private code or hosted deployment infrastructure.
- A module runtime may be instantiated once per shard worker. Lifecycle hooks must be repeatable and must not create an uncoordinated global side effect.
- Worker-local Discord state is valid only for guilds owned by that worker. Discord guild operations are routed to the owning worker through SDK services.
- Cross-guild state, whole-bot statistics, shared rate limits, sessions, uniqueness controls and globally owned jobs use core-provided durable, distributed or aggregation contracts.
- SDK service documentation must state whether a contract is worker-local, guild-owner-routed or deployment-wide, including its ownership, consistency, idempotency, retry and expiry semantics where relevant.
- Worker caches are bounded optimizations rather than sources of truth. Event and task contracts require bounded concurrency and backpressure.
- Module tests mock SDK contracts and cover concurrent workers, retries, duplicate delivery, restart and stale ownership when those failure modes apply.
Durable scheduled work
helyx.scheduled-tasks is deployment-wide and PostgreSQL-backed. Modules
declare versioned one-shot or coalesced task handlers and submit only bounded
ID payloads. Delivery is at least once, so handlers must make business-state
changes idempotent and render external state from authoritative records.
One-shot schedules and coalesced signals may be attached to
replaceOwnedSet so the domain write and required delayed or refresh work
commit together. Expected-state updates may attach a required audit and
bounded record-retention descriptors; core resolves and persists them in the
same transaction. The core retention executor remains available after module
disablement or removal and never exposes table names or SQL to modules.
The record service also supports allowlisted server-side text search, bounded single-field prefix lookup and exact distinct counts. Search and prefix fields must be declared readable strings; distinct fields must be declared readable and groupable. Modules never receive SQL or a database connection.
aggregateCounts returns grouped counts, total rows and one distinct total
from a single database snapshot so retention or privacy work cannot produce a
torn public result.
Parent-and-owned-set writes can declare bounded quota guards. Core serializes matching quota scopes with transaction-scoped advisory locks, checks the authoritative count and inserts the parent in the same transaction. Modules do not own counters or lock keys.
Guarded owned-set writes also support a 100,000-row relationship quota, required-row locks, module-enabled fencing and up to 20 bounded child rows. These constraints let high-volume entry and winner relationships serialize with lifecycle, disablement and Privacy deletion without exposing locks or SQL to modules. Expected-state updates may atomically attach replacement one-shot or coalesced work.
Secure outcome selection
helyx.secure-random is deployment-wide and uses operating-system
cryptographic entropy. Bounded integers use rejection sampling. Weighted
selection starts with an opaque, operating-system-random operation reference.
Core combines a server-held 32-byte key with that reference and framed context
to derive separate scoring and checkpoint-integrity keys. Candidate scores and
tie-breakers are deterministic only to Core; the reference exposed to a module
cannot predict outcomes or forge a checkpoint. Selection remains streamed
through a versioned reservoir and returns only selected candidate IDs plus an
audit-safe algorithm version, operation reference and digest.
Long-running handlers may call checkpoint() and persist the returned bounded,
JSON-serialisable value. Supplying that checkpoint to
createWeightedSelection resumes the same operation across fixed database-page
budgets without storing raw entropy or raw selection scores. Core validates the
algorithm, context digest, winner count, canonical cursor, counts, totals,
integrity digest and reservoir before resuming. A checkpoint holds at most the
requested reservoir of 20 candidate IDs and weights. Candidates supplied after
resume must continue in canonical, strictly increasing ID order.
The receipt field entropyDigest is retained for compatibility; for weighted
selection version 3 it contains the final candidate hash-chain audit digest.
Production entropy and scoring primitives are not injectable through the SDK
contract; deterministic platform construction exists only for tests.
The server-held key must remain stable while checkpointed draws are in
progress. Rotating it invalidates their checkpoints, so deployments must drain
or complete those draws before rotation.
Exact member snapshots are guild-owner-routed through
helyx.discord-resources. A bounded lookup returns current membership, bot
state, role IDs and joinedAt without storing a Discord profile. Modules must
fail closed when an eligibility snapshot cannot be obtained.
Publication status
Published as a public scoped package under the Helyx Source Available Licence.
Read the packaged LICENSE before installing, using, modifying, or distributing
the software.
