shardwire 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/index.d.mts +12 -6
- package/dist/index.d.ts +12 -6
- package/dist/index.js +31 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +31 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -1
package/README.md
CHANGED
|
@@ -261,6 +261,7 @@ const wire = createShardwire<Commands, {}>({
|
|
|
261
261
|
- `secret` shared secret matching host.
|
|
262
262
|
- `secretId` optional secret id (for example `"s0"`) used during handshake.
|
|
263
263
|
- `clientName` optional identity sent during auth handshake for host-side telemetry.
|
|
264
|
+
- `allowInsecureWs` optional escape hatch to allow `ws://` for non-loopback hosts (defaults to `false`).
|
|
264
265
|
- `requestTimeoutMs` default timeout for `send`.
|
|
265
266
|
- `reconnect` reconnect policy (`enabled`, delays, jitter).
|
|
266
267
|
- `webSocketFactory` optional custom client implementation.
|
|
@@ -326,6 +327,7 @@ Common symptoms:
|
|
|
326
327
|
|
|
327
328
|
- Use strong, rotated secrets via environment variables.
|
|
328
329
|
- Rotate with overlapping `server.secrets` entries and explicit `secretId` cutovers.
|
|
330
|
+
- Use `wss://` for non-localhost deployments. By default, consumer `ws://` is only accepted for loopback hosts.
|
|
329
331
|
- Set payload and timeout limits appropriate for your workload.
|
|
330
332
|
- Configure `server.corsOrigins` when exposing browser consumers.
|
|
331
333
|
|
package/dist/index.d.mts
CHANGED
|
@@ -13,8 +13,8 @@ interface SchemaValidationIssue {
|
|
|
13
13
|
interface RuntimeSchema<T = unknown> {
|
|
14
14
|
parse: (value: unknown) => T;
|
|
15
15
|
}
|
|
16
|
-
type CommandRequestOf<T> = T extends CommandSchema<infer Request,
|
|
17
|
-
type CommandResponseOf<T> = T extends CommandSchema<
|
|
16
|
+
type CommandRequestOf<T> = T extends CommandSchema<infer Request, unknown> ? Request : T;
|
|
17
|
+
type CommandResponseOf<T> = T extends CommandSchema<unknown, infer Response> ? Response : unknown;
|
|
18
18
|
type Unsubscribe = () => void;
|
|
19
19
|
interface ShardwireLogger {
|
|
20
20
|
debug?: (message: string, meta?: Record<string, unknown>) => void;
|
|
@@ -84,16 +84,22 @@ interface HostOptions<C extends CommandMap, E extends EventMap> {
|
|
|
84
84
|
name?: string;
|
|
85
85
|
logger?: ShardwireLogger;
|
|
86
86
|
}
|
|
87
|
-
interface ConsumerOptions
|
|
87
|
+
interface ConsumerOptions {
|
|
88
88
|
url: string;
|
|
89
89
|
secret: string;
|
|
90
90
|
secretId?: string;
|
|
91
91
|
clientName?: string;
|
|
92
|
+
/**
|
|
93
|
+
* Allows plain `ws://` connections to non-loopback hosts.
|
|
94
|
+
*
|
|
95
|
+
* Keep this `false` unless you explicitly terminate TLS upstream and trust the network path.
|
|
96
|
+
*/
|
|
97
|
+
allowInsecureWs?: boolean;
|
|
92
98
|
webSocketFactory?: (url: string) => {
|
|
93
99
|
readyState: number;
|
|
94
100
|
send(data: string): void;
|
|
95
101
|
close(code?: number, reason?: string): void;
|
|
96
|
-
on(event: "open" | "message" | "close" | "error", listener: (...args:
|
|
102
|
+
on(event: "open" | "message" | "close" | "error", listener: (...args: unknown[]) => void): void;
|
|
97
103
|
once(event: "close", listener: () => void): void;
|
|
98
104
|
};
|
|
99
105
|
reconnect?: {
|
|
@@ -141,7 +147,7 @@ interface ConsumerShardwire<C extends CommandMap, E extends EventMap> {
|
|
|
141
147
|
}
|
|
142
148
|
interface CreateShardwire {
|
|
143
149
|
<C extends CommandMap = {}, E extends EventMap = {}>(options: HostOptions<C, E>): HostShardwire<C, E>;
|
|
144
|
-
<C extends CommandMap = {}, E extends EventMap = {}>(options: ConsumerOptions
|
|
150
|
+
<C extends CommandMap = {}, E extends EventMap = {}>(options: ConsumerOptions): ConsumerShardwire<C, E>;
|
|
145
151
|
}
|
|
146
152
|
|
|
147
153
|
interface SafeParseResultSuccess<T> {
|
|
@@ -164,6 +170,6 @@ declare function fromSafeParseSchema<T>(schema: SafeParseSchema<T>): RuntimeSche
|
|
|
164
170
|
declare function fromZodSchema<T>(schema: ZodType<T>): RuntimeSchema<T>;
|
|
165
171
|
|
|
166
172
|
declare function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(options: HostOptions<C, E>): HostShardwire<C, E>;
|
|
167
|
-
declare function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(options: ConsumerOptions
|
|
173
|
+
declare function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(options: ConsumerOptions): ConsumerShardwire<C, E>;
|
|
168
174
|
|
|
169
175
|
export { type CommandContext, type CommandFailure, type CommandMap, type CommandRequestOf, type CommandResponseOf, type CommandResult, type CommandSchema, type CommandSuccess, type ConsumerOptions, type ConsumerShardwire, type CreateShardwire, type DiscordClientLike, type EventMap, type EventMeta, type HostOptions, type HostShardwire, type RuntimeSchema, type SchemaValidationIssue, type ShardwireLogger, type Unsubscribe, createShardwire, fromSafeParseSchema, fromZodSchema };
|
package/dist/index.d.ts
CHANGED
|
@@ -13,8 +13,8 @@ interface SchemaValidationIssue {
|
|
|
13
13
|
interface RuntimeSchema<T = unknown> {
|
|
14
14
|
parse: (value: unknown) => T;
|
|
15
15
|
}
|
|
16
|
-
type CommandRequestOf<T> = T extends CommandSchema<infer Request,
|
|
17
|
-
type CommandResponseOf<T> = T extends CommandSchema<
|
|
16
|
+
type CommandRequestOf<T> = T extends CommandSchema<infer Request, unknown> ? Request : T;
|
|
17
|
+
type CommandResponseOf<T> = T extends CommandSchema<unknown, infer Response> ? Response : unknown;
|
|
18
18
|
type Unsubscribe = () => void;
|
|
19
19
|
interface ShardwireLogger {
|
|
20
20
|
debug?: (message: string, meta?: Record<string, unknown>) => void;
|
|
@@ -84,16 +84,22 @@ interface HostOptions<C extends CommandMap, E extends EventMap> {
|
|
|
84
84
|
name?: string;
|
|
85
85
|
logger?: ShardwireLogger;
|
|
86
86
|
}
|
|
87
|
-
interface ConsumerOptions
|
|
87
|
+
interface ConsumerOptions {
|
|
88
88
|
url: string;
|
|
89
89
|
secret: string;
|
|
90
90
|
secretId?: string;
|
|
91
91
|
clientName?: string;
|
|
92
|
+
/**
|
|
93
|
+
* Allows plain `ws://` connections to non-loopback hosts.
|
|
94
|
+
*
|
|
95
|
+
* Keep this `false` unless you explicitly terminate TLS upstream and trust the network path.
|
|
96
|
+
*/
|
|
97
|
+
allowInsecureWs?: boolean;
|
|
92
98
|
webSocketFactory?: (url: string) => {
|
|
93
99
|
readyState: number;
|
|
94
100
|
send(data: string): void;
|
|
95
101
|
close(code?: number, reason?: string): void;
|
|
96
|
-
on(event: "open" | "message" | "close" | "error", listener: (...args:
|
|
102
|
+
on(event: "open" | "message" | "close" | "error", listener: (...args: unknown[]) => void): void;
|
|
97
103
|
once(event: "close", listener: () => void): void;
|
|
98
104
|
};
|
|
99
105
|
reconnect?: {
|
|
@@ -141,7 +147,7 @@ interface ConsumerShardwire<C extends CommandMap, E extends EventMap> {
|
|
|
141
147
|
}
|
|
142
148
|
interface CreateShardwire {
|
|
143
149
|
<C extends CommandMap = {}, E extends EventMap = {}>(options: HostOptions<C, E>): HostShardwire<C, E>;
|
|
144
|
-
<C extends CommandMap = {}, E extends EventMap = {}>(options: ConsumerOptions
|
|
150
|
+
<C extends CommandMap = {}, E extends EventMap = {}>(options: ConsumerOptions): ConsumerShardwire<C, E>;
|
|
145
151
|
}
|
|
146
152
|
|
|
147
153
|
interface SafeParseResultSuccess<T> {
|
|
@@ -164,6 +170,6 @@ declare function fromSafeParseSchema<T>(schema: SafeParseSchema<T>): RuntimeSche
|
|
|
164
170
|
declare function fromZodSchema<T>(schema: ZodType<T>): RuntimeSchema<T>;
|
|
165
171
|
|
|
166
172
|
declare function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(options: HostOptions<C, E>): HostShardwire<C, E>;
|
|
167
|
-
declare function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(options: ConsumerOptions
|
|
173
|
+
declare function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(options: ConsumerOptions): ConsumerShardwire<C, E>;
|
|
168
174
|
|
|
169
175
|
export { type CommandContext, type CommandFailure, type CommandMap, type CommandRequestOf, type CommandResponseOf, type CommandResult, type CommandSchema, type CommandSuccess, type ConsumerOptions, type ConsumerShardwire, type CreateShardwire, type DiscordClientLike, type EventMap, type EventMeta, type HostOptions, type HostShardwire, type RuntimeSchema, type SchemaValidationIssue, type ShardwireLogger, type Unsubscribe, createShardwire, fromSafeParseSchema, fromZodSchema };
|
package/dist/index.js
CHANGED
|
@@ -148,6 +148,21 @@ function assertConsumerOptions(options) {
|
|
|
148
148
|
if (!isNonEmptyString(options.url)) {
|
|
149
149
|
throw new Error("Consumer mode requires `url`.");
|
|
150
150
|
}
|
|
151
|
+
let parsedUrl;
|
|
152
|
+
try {
|
|
153
|
+
parsedUrl = new URL(options.url);
|
|
154
|
+
} catch {
|
|
155
|
+
throw new Error("Consumer option `url` must be a valid URL.");
|
|
156
|
+
}
|
|
157
|
+
if (parsedUrl.protocol !== "ws:" && parsedUrl.protocol !== "wss:") {
|
|
158
|
+
throw new Error("Consumer option `url` must use `ws://` or `wss://`.");
|
|
159
|
+
}
|
|
160
|
+
const isLoopbackHost = parsedUrl.hostname === "localhost" || parsedUrl.hostname === "127.0.0.1" || parsedUrl.hostname === "::1";
|
|
161
|
+
if (parsedUrl.protocol === "ws:" && !isLoopbackHost && !options.allowInsecureWs) {
|
|
162
|
+
throw new Error(
|
|
163
|
+
"Insecure `ws://` is only allowed for loopback hosts by default. Use `wss://` or set `allowInsecureWs` to true."
|
|
164
|
+
);
|
|
165
|
+
}
|
|
151
166
|
if (!isNonEmptyString(options.secret)) {
|
|
152
167
|
throw new Error("Consumer mode requires `secret`.");
|
|
153
168
|
}
|
|
@@ -627,7 +642,7 @@ async function withTimeout(promise, timeoutMs, timeoutMessage = "Operation timed
|
|
|
627
642
|
resolve(value);
|
|
628
643
|
}).catch((error) => {
|
|
629
644
|
clearTimeout(timeout);
|
|
630
|
-
reject(error);
|
|
645
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
631
646
|
});
|
|
632
647
|
});
|
|
633
648
|
}
|
|
@@ -753,14 +768,25 @@ var HostWebSocketServer = class {
|
|
|
753
768
|
socket.close(CLOSE_AUTH_REQUIRED, "Authentication required.");
|
|
754
769
|
}
|
|
755
770
|
}, this.authTimeoutMs);
|
|
756
|
-
socket.on("message",
|
|
771
|
+
socket.on("message", (raw) => {
|
|
772
|
+
const serialized = typeof raw === "string" ? raw : Buffer.isBuffer(raw) ? raw.toString("utf8") : void 0;
|
|
773
|
+
if (!serialized) {
|
|
774
|
+
this.logger.warn("Invalid message payload from client.", { error: "Unsupported payload type." });
|
|
775
|
+
socket.close(CLOSE_INVALID_PAYLOAD, "Invalid payload.");
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
let parsed;
|
|
757
779
|
try {
|
|
758
|
-
|
|
759
|
-
await this.handleMessage(state, parsed);
|
|
780
|
+
parsed = parseEnvelope(serialized);
|
|
760
781
|
} catch (error) {
|
|
761
782
|
this.logger.warn("Invalid message payload from client.", { error: String(error) });
|
|
762
783
|
socket.close(CLOSE_INVALID_PAYLOAD, "Invalid payload.");
|
|
784
|
+
return;
|
|
763
785
|
}
|
|
786
|
+
void this.handleMessage(state, parsed).catch((error) => {
|
|
787
|
+
this.logger.warn("Invalid message payload from client.", { error: String(error) });
|
|
788
|
+
socket.close(CLOSE_INVALID_PAYLOAD, "Invalid payload.");
|
|
789
|
+
});
|
|
764
790
|
});
|
|
765
791
|
socket.on("close", () => {
|
|
766
792
|
clearTimeout(authTimer);
|
|
@@ -894,7 +920,7 @@ function createHostShardwire(options, runtimeHooks) {
|
|
|
894
920
|
const hostServer = new HostWebSocketServer({
|
|
895
921
|
options,
|
|
896
922
|
onCommandRequest: async (connection, payload, requestId, source) => {
|
|
897
|
-
const cacheKey = `${requestId}:${payload.name}`;
|
|
923
|
+
const cacheKey = `${connection.id}:${requestId}:${payload.name}`;
|
|
898
924
|
const cached = dedupeCache.get(cacheKey);
|
|
899
925
|
if (cached) {
|
|
900
926
|
return cached;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/transport/ws/consumer-socket.ts","../src/utils/id.ts","../src/utils/backoff.ts","../src/utils/logger.ts","../src/core/protocol.ts","../src/runtime/validation.ts","../src/consumer/index.ts","../src/discord/client.ts","../src/runtime/reliability.ts","../src/transport/ws/host-server.ts","../src/runtime/security.ts","../src/host/index.ts","../src/schema/index.ts","../src/schema/zod.ts"],"sourcesContent":["import { createConsumerShardwire } from \"./consumer\";\nimport { resolveDiscordClient } from \"./discord/client\";\nimport { createHostShardwire } from \"./host\";\nimport { assertConsumerOptions, assertHostOptions } from \"./runtime/validation\";\nimport type {\n CommandMap,\n ConsumerOptions,\n ConsumerShardwire,\n EventMap,\n HostOptions,\n HostShardwire,\n} from \"./core/types\";\n\nfunction isHostOptions<C extends CommandMap, E extends EventMap>(\n options: HostOptions<C, E> | ConsumerOptions<C, E>,\n): options is HostOptions<C, E> {\n return \"server\" in options;\n}\n\nexport function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(\n options: HostOptions<C, E>,\n): HostShardwire<C, E>;\nexport function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(\n options: ConsumerOptions<C, E>,\n): ConsumerShardwire<C, E>;\nexport function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(\n options: HostOptions<C, E> | ConsumerOptions<C, E>,\n): HostShardwire<C, E> | ConsumerShardwire<C, E> {\n if (!isHostOptions(options)) {\n assertConsumerOptions(options);\n return createConsumerShardwire<C, E>(options);\n }\n assertHostOptions(options);\n\n let ownedClientPromise: Promise<{ destroy: () => void } | undefined> | undefined;\n\n if (!options.client && options.token) {\n ownedClientPromise = resolveDiscordClient(options)\n .then((state) => {\n if (!state.owned || !state.client) {\n return undefined;\n }\n return {\n destroy: () => state.client?.destroy(),\n };\n })\n .catch((error) => {\n options.logger?.error?.(\"Failed to initialize discord.js client from token.\", {\n error: String(error),\n });\n return undefined;\n });\n }\n\n return createHostShardwire<C, E>(options, {\n onClose: async () => {\n const owned = await ownedClientPromise;\n owned?.destroy();\n },\n });\n}\n\nexport { fromSafeParseSchema } from \"./schema\";\nexport { fromZodSchema } from \"./schema/zod\";\n\nexport type {\n CommandContext,\n CommandFailure,\n CommandMap,\n CommandRequestOf,\n CommandResult,\n CommandResponseOf,\n CommandSchema,\n CommandSuccess,\n ConsumerOptions,\n ConsumerShardwire,\n CreateShardwire,\n DiscordClientLike,\n EventMap,\n EventMeta,\n HostOptions,\n HostShardwire,\n RuntimeSchema,\n SchemaValidationIssue,\n ShardwireLogger,\n Unsubscribe,\n} from \"./core/types\";\n","import { WebSocket } from \"ws\";\n\nexport interface WebSocketLike {\n readyState: number;\n send(data: string): void;\n close(code?: number, reason?: string): void;\n on(event: \"open\", listener: () => void): void;\n on(event: \"message\", listener: (data: unknown) => void): void;\n on(event: \"close\", listener: () => void): void;\n on(event: \"error\", listener: (error: unknown) => void): void;\n once(event: \"close\", listener: () => void): void;\n}\n\nexport function createNodeWebSocket(url: string): WebSocketLike {\n return new WebSocket(url) as unknown as WebSocketLike;\n}\n","import { randomUUID } from \"node:crypto\";\n\nexport function createRequestId(): string {\n return randomUUID();\n}\n\nexport function createConnectionId(): string {\n return randomUUID();\n}\n","export interface BackoffConfig {\n initialDelayMs: number;\n maxDelayMs: number;\n jitter: boolean;\n}\n\nexport function getBackoffDelay(attempt: number, config: BackoffConfig): number {\n const base = Math.min(config.maxDelayMs, config.initialDelayMs * 2 ** attempt);\n if (!config.jitter) {\n return base;\n }\n const spread = Math.floor(base * 0.2);\n const min = Math.max(0, base - spread);\n const max = base + spread;\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n","import type { ShardwireLogger } from \"../core/types\";\n\nexport function withLogger(logger?: ShardwireLogger): Required<ShardwireLogger> {\n return {\n debug: logger?.debug ?? (() => undefined),\n info: logger?.info ?? (() => undefined),\n warn: logger?.warn ?? (() => undefined),\n error: logger?.error ?? (() => undefined),\n };\n}\n","import type { CommandResult } from \"./types\";\n\nexport const PROTOCOL_VERSION = 1 as const;\n\nexport type WireType =\n | \"auth.hello\"\n | \"auth.ok\"\n | \"auth.error\"\n | \"command.request\"\n | \"command.result\"\n | \"command.error\"\n | \"event.emit\"\n | \"ping\"\n | \"pong\";\n\nexport type WireEnvelope<TType extends WireType = WireType, TPayload = unknown> = {\n v: typeof PROTOCOL_VERSION;\n type: TType;\n ts: number;\n requestId?: string;\n source?: string;\n payload: TPayload;\n};\n\nexport interface AuthHelloPayload {\n secret: string;\n secretId?: string;\n clientName?: string;\n}\n\nexport interface AuthOkPayload {\n connectionId: string;\n}\n\nexport interface AuthErrorPayload {\n code: \"UNAUTHORIZED\";\n reason: \"unknown_secret_id\" | \"invalid_secret\";\n message: string;\n}\n\nexport interface CommandRequestPayload {\n name: string;\n data: unknown;\n}\n\nexport interface EventEmitPayload {\n name: string;\n data: unknown;\n}\n\nexport type CommandResultPayload = CommandResult;\n\nexport function makeEnvelope<TType extends WireType, TPayload>(\n type: TType,\n payload: TPayload,\n extras?: { requestId?: string; source?: string },\n): WireEnvelope<TType, TPayload> {\n const envelope: WireEnvelope<TType, TPayload> = {\n v: PROTOCOL_VERSION,\n type,\n ts: Date.now(),\n payload,\n };\n if (extras?.requestId) {\n envelope.requestId = extras.requestId;\n }\n if (extras?.source) {\n envelope.source = extras.source;\n }\n return envelope;\n}\n\nexport function parseEnvelope(raw: string): WireEnvelope {\n const parsed = JSON.parse(raw) as WireEnvelope;\n if (!parsed || parsed.v !== PROTOCOL_VERSION || typeof parsed.type !== \"string\") {\n throw new Error(\"Invalid wire envelope.\");\n }\n return parsed;\n}\n\nexport function stringifyEnvelope(envelope: WireEnvelope): string {\n return JSON.stringify(envelope);\n}\n","import type { ConsumerOptions, HostOptions, RuntimeSchema, SchemaValidationIssue } from \"../core/types\";\n\nexport class PayloadValidationError extends Error {\n constructor(\n message: string,\n public readonly details: {\n name: string;\n stage: \"command.request\" | \"command.response\" | \"event.emit\";\n issues?: SchemaValidationIssue[];\n },\n ) {\n super(message);\n this.name = \"PayloadValidationError\";\n }\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n\nfunction assertPositiveNumber(name: string, value: unknown): void {\n if (typeof value !== \"number\" || Number.isNaN(value) || value <= 0) {\n throw new Error(`${name} must be a positive number.`);\n }\n}\n\nexport function assertHostOptions(options: HostOptions<any, any>): void {\n if (!options.server) {\n throw new Error(\"Host mode requires a server configuration.\");\n }\n assertPositiveNumber(\"server.port\", options.server.port);\n if (!Array.isArray(options.server.secrets) || options.server.secrets.length === 0) {\n throw new Error(\"server.secrets must contain at least one secret.\");\n }\n for (const [index, secret] of options.server.secrets.entries()) {\n if (!isNonEmptyString(secret)) {\n throw new Error(`server.secrets[${index}] must be a non-empty string.`);\n }\n }\n if (\n options.server.primarySecretId !== undefined &&\n !options.server.secrets.some((_, index) => options.server.primarySecretId === `s${index}`)\n ) {\n throw new Error(\"server.primarySecretId must reference an existing secret id.\");\n }\n if (options.server.heartbeatMs !== undefined) {\n assertPositiveNumber(\"server.heartbeatMs\", options.server.heartbeatMs);\n }\n if (options.server.commandTimeoutMs !== undefined) {\n assertPositiveNumber(\"server.commandTimeoutMs\", options.server.commandTimeoutMs);\n }\n if (options.server.maxPayloadBytes !== undefined) {\n assertPositiveNumber(\"server.maxPayloadBytes\", options.server.maxPayloadBytes);\n }\n}\n\nexport function assertConsumerOptions(options: ConsumerOptions<any, any>): void {\n if (!isNonEmptyString(options.url)) {\n throw new Error(\"Consumer mode requires `url`.\");\n }\n if (!isNonEmptyString(options.secret)) {\n throw new Error(\"Consumer mode requires `secret`.\");\n }\n if (options.secretId !== undefined && !isNonEmptyString(options.secretId)) {\n throw new Error(\"Consumer option `secretId` must be a non-empty string.\");\n }\n if (options.clientName !== undefined && !isNonEmptyString(options.clientName)) {\n throw new Error(\"Consumer option `clientName` must be a non-empty string.\");\n }\n if (options.requestTimeoutMs !== undefined) {\n assertPositiveNumber(\"requestTimeoutMs\", options.requestTimeoutMs);\n }\n if (options.reconnect?.initialDelayMs !== undefined) {\n assertPositiveNumber(\"reconnect.initialDelayMs\", options.reconnect.initialDelayMs);\n }\n if (options.reconnect?.maxDelayMs !== undefined) {\n assertPositiveNumber(\"reconnect.maxDelayMs\", options.reconnect.maxDelayMs);\n }\n}\n\nexport function assertMessageName(kind: \"command\" | \"event\", name: string): void {\n if (!isNonEmptyString(name)) {\n throw new Error(`${kind} name must be a non-empty string.`);\n }\n}\n\nexport function assertJsonPayload(kind: \"command\" | \"event\", name: string, payload: unknown): void {\n try {\n JSON.stringify(payload);\n } catch {\n throw new Error(`${kind} \"${name}\" payload must be JSON-serializable.`);\n }\n}\n\nfunction normalizeSchemaIssues(error: unknown): SchemaValidationIssue[] | undefined {\n if (!error || typeof error !== \"object\") {\n return undefined;\n }\n const issues = (error as { issues?: unknown }).issues;\n if (!Array.isArray(issues)) {\n return undefined;\n }\n const normalized = issues\n .map((issue) => {\n if (!issue || typeof issue !== \"object\") {\n return null;\n }\n const message = (issue as { message?: unknown }).message;\n const rawPath = (issue as { path?: unknown }).path;\n if (typeof message !== \"string\") {\n return null;\n }\n const path =\n Array.isArray(rawPath) && rawPath.length > 0\n ? rawPath\n .map((segment) => (typeof segment === \"string\" || typeof segment === \"number\" ? String(segment) : \"\"))\n .filter(Boolean)\n .join(\".\")\n : \"\";\n return { path, message } satisfies SchemaValidationIssue;\n })\n .filter((issue): issue is SchemaValidationIssue => Boolean(issue));\n return normalized.length > 0 ? normalized : undefined;\n}\n\nexport function parsePayloadWithSchema<T>(\n schema: RuntimeSchema<T> | undefined,\n payload: unknown,\n context: {\n name: string;\n stage: \"command.request\" | \"command.response\" | \"event.emit\";\n },\n): T | unknown {\n if (!schema) {\n return payload;\n }\n try {\n return schema.parse(payload);\n } catch (error) {\n const message =\n error instanceof Error && error.message.trim().length > 0\n ? error.message\n : `Payload validation failed for ${context.stage} \"${context.name}\".`;\n const issues = normalizeSchemaIssues(error);\n throw new PayloadValidationError(message, {\n ...context,\n ...(issues ? { issues } : {}),\n });\n }\n}\n","import type {\n CommandFailure,\n CommandMap,\n CommandRequestOf,\n CommandResponseOf,\n CommandResult,\n ConsumerOptions,\n ConsumerShardwire,\n EventMap,\n EventMeta,\n} from \"../core/types\";\nimport { createNodeWebSocket, type WebSocketLike } from \"../transport/ws/consumer-socket\";\nimport { createRequestId } from \"../utils/id\";\nimport { getBackoffDelay } from \"../utils/backoff\";\nimport { withLogger } from \"../utils/logger\";\nimport {\n makeEnvelope,\n parseEnvelope,\n stringifyEnvelope,\n type AuthErrorPayload,\n type CommandResultPayload,\n type EventEmitPayload,\n} from \"../core/protocol\";\nimport { assertJsonPayload, assertMessageName } from \"../runtime/validation\";\n\ntype EventHandler = (payload: unknown, meta: EventMeta) => void;\n\ninterface PendingRequest {\n resolve: (value: CommandResult) => void;\n reject: (error: CommandRequestError) => void;\n timer: NodeJS.Timeout;\n}\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 10000;\n\nclass CommandRequestError extends Error {\n constructor(\n public readonly code: \"TIMEOUT\" | \"DISCONNECTED\" | \"UNAUTHORIZED\",\n message: string,\n ) {\n super(message);\n this.name = \"CommandRequestError\";\n }\n}\n\nexport function createConsumerShardwire<C extends CommandMap, E extends EventMap>(\n options: ConsumerOptions<C, E>,\n): ConsumerShardwire<C, E> {\n const logger = withLogger(options.logger);\n const reconnectEnabled = options.reconnect?.enabled ?? true;\n const initialDelayMs = options.reconnect?.initialDelayMs ?? 500;\n const maxDelayMs = options.reconnect?.maxDelayMs ?? 10000;\n const jitter = options.reconnect?.jitter ?? true;\n const requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n\n let socket: WebSocketLike | null = null;\n let isClosed = false;\n let isAuthed = false;\n let reconnectAttempts = 0;\n let reconnectTimer: NodeJS.Timeout | null = null;\n let connectPromise: Promise<void> | null = null;\n let connectResolve: (() => void) | null = null;\n let connectReject: ((error: Error) => void) | null = null;\n let authTimeoutTimer: NodeJS.Timeout | null = null;\n let currentConnectionId: string | null = null;\n\n const pendingRequests = new Map<string, PendingRequest>();\n const eventHandlers = new Map<string, Set<EventHandler>>();\n const connectedHandlers = new Set<(info: { connectionId: string; connectedAt: number }) => void>();\n const disconnectedHandlers = new Set<\n (info: { reason: string; at: number; willReconnect: boolean }) => void\n >();\n const reconnectingHandlers = new Set<(info: { attempt: number; delayMs: number; at: number }) => void>();\n\n function clearAuthTimeout(): void {\n if (authTimeoutTimer) {\n clearTimeout(authTimeoutTimer);\n authTimeoutTimer = null;\n }\n }\n\n function resolveConnect(): void {\n clearAuthTimeout();\n connectResolve?.();\n connectResolve = null;\n connectReject = null;\n connectPromise = null;\n }\n\n function rejectConnect(message: string): void {\n clearAuthTimeout();\n if (connectReject) {\n connectReject(new Error(message));\n }\n connectResolve = null;\n connectReject = null;\n connectPromise = null;\n }\n\n function sendRaw(data: string): void {\n if (!socket || socket.readyState !== 1) {\n throw new Error(\"Shardwire consumer is not connected.\");\n }\n socket.send(data);\n }\n\n function rejectAllPending(\n code: \"TIMEOUT\" | \"DISCONNECTED\" | \"UNAUTHORIZED\",\n reason: string,\n ): void {\n for (const [requestId, pending] of pendingRequests.entries()) {\n clearTimeout(pending.timer);\n pending.reject(new CommandRequestError(code, reason));\n pendingRequests.delete(requestId);\n }\n }\n\n function scheduleReconnect(): void {\n if (isClosed || !reconnectEnabled || reconnectTimer) {\n return;\n }\n const delay = getBackoffDelay(reconnectAttempts, { initialDelayMs, maxDelayMs, jitter });\n reconnectAttempts += 1;\n for (const handler of reconnectingHandlers) {\n try {\n handler({ attempt: reconnectAttempts, delayMs: delay, at: Date.now() });\n } catch (error) {\n logger.warn(\"Reconnect handler threw an error.\", { error: String(error) });\n }\n }\n reconnectTimer = setTimeout(() => {\n reconnectTimer = null;\n void connect().catch((error) => {\n logger.warn(\"Reconnect attempt failed.\", { error: String(error) });\n });\n }, delay);\n }\n\n function handleEvent(name: string, payload: unknown, meta: EventMeta): void {\n const handlers = eventHandlers.get(name);\n if (!handlers || handlers.size === 0) {\n return;\n }\n for (const handler of handlers) {\n try {\n handler(payload, meta);\n } catch (error) {\n logger.warn(\"Event handler threw an error.\", { name, error: String(error) });\n }\n }\n }\n\n async function connect(): Promise<void> {\n if (isClosed) {\n return;\n }\n if (socket && socket.readyState === 1 && isAuthed) {\n return;\n }\n if (connectPromise) {\n return connectPromise;\n }\n\n connectPromise = new Promise<void>((resolve, reject) => {\n connectResolve = resolve;\n connectReject = reject;\n });\n\n socket = options.webSocketFactory\n ? (options.webSocketFactory(options.url) as WebSocketLike)\n : createNodeWebSocket(options.url);\n\n socket.on(\"open\", () => {\n reconnectAttempts = 0;\n isAuthed = false;\n currentConnectionId = null;\n const hello = makeEnvelope(\"auth.hello\", {\n secret: options.secret,\n secretId: options.secretId,\n clientName: options.clientName,\n });\n socket?.send(stringifyEnvelope(hello));\n authTimeoutTimer = setTimeout(() => {\n if (!isAuthed) {\n rejectConnect(\"Shardwire auth timed out.\");\n socket?.close();\n }\n }, requestTimeoutMs);\n });\n\n socket.on(\"message\", (raw) => {\n try {\n const serialized = typeof raw === \"string\" ? raw : String(raw);\n const envelope = parseEnvelope(serialized);\n switch (envelope.type) {\n case \"auth.ok\":\n isAuthed = true;\n if (\n envelope.payload &&\n typeof envelope.payload === \"object\" &&\n \"connectionId\" in envelope.payload &&\n typeof (envelope.payload as { connectionId?: unknown }).connectionId === \"string\"\n ) {\n currentConnectionId = (envelope.payload as { connectionId: string }).connectionId;\n }\n if (currentConnectionId) {\n for (const handler of connectedHandlers) {\n try {\n handler({ connectionId: currentConnectionId, connectedAt: Date.now() });\n } catch (error) {\n logger.warn(\"Connected handler threw an error.\", { error: String(error) });\n }\n }\n }\n resolveConnect();\n break;\n case \"auth.error\": {\n const payload = envelope.payload as AuthErrorPayload;\n logger.error(\"Authentication failed for consumer.\", {\n code: payload.code,\n message: payload.message,\n });\n rejectConnect(payload.message);\n rejectAllPending(\"UNAUTHORIZED\", \"Shardwire authentication failed.\");\n socket?.close();\n break;\n }\n case \"command.result\":\n case \"command.error\": {\n const requestId = envelope.requestId;\n if (!requestId) {\n return;\n }\n const pending = pendingRequests.get(requestId);\n if (!pending) {\n return;\n }\n clearTimeout(pending.timer);\n pending.resolve(envelope.payload as CommandResultPayload);\n pendingRequests.delete(requestId);\n break;\n }\n case \"event.emit\": {\n const payload = envelope.payload as EventEmitPayload;\n const meta: EventMeta = { ts: envelope.ts };\n if (envelope.source) {\n meta.source = envelope.source;\n }\n handleEvent(payload.name, payload.data, meta);\n break;\n }\n case \"ping\":\n sendRaw(stringifyEnvelope(makeEnvelope(\"pong\", {})));\n break;\n default:\n break;\n }\n } catch (error) {\n logger.warn(\"Failed to parse consumer message.\", { error: String(error) });\n }\n });\n\n socket.on(\"close\", () => {\n const willReconnect = !isClosed && reconnectEnabled;\n rejectConnect(\"Shardwire connection closed.\");\n isAuthed = false;\n currentConnectionId = null;\n rejectAllPending(\"DISCONNECTED\", \"Shardwire connection closed before command completed.\");\n for (const handler of disconnectedHandlers) {\n try {\n handler({\n reason: \"Shardwire connection closed.\",\n at: Date.now(),\n willReconnect,\n });\n } catch (error) {\n logger.warn(\"Disconnected handler threw an error.\", { error: String(error) });\n }\n }\n if (!isClosed) {\n scheduleReconnect();\n }\n });\n\n socket.on(\"error\", (error) => {\n logger.warn(\"Consumer socket error.\", { error: String(error) });\n });\n\n return connectPromise;\n }\n\n void connect().catch((error) => {\n logger.warn(\"Initial connection attempt failed.\", { error: String(error) });\n });\n\n return {\n mode: \"consumer\",\n async send<K extends keyof C & string>(\n name: K,\n payload: CommandRequestOf<C[K]>,\n sendOptions?: { timeoutMs?: number; requestId?: string },\n ): Promise<CommandResult<CommandResponseOf<C[K]>>> {\n assertMessageName(\"command\", name);\n assertJsonPayload(\"command\", name, payload);\n if (!isAuthed) {\n try {\n await connect();\n } catch (error) {\n return {\n ok: false,\n requestId: sendOptions?.requestId ?? \"unknown\",\n ts: Date.now(),\n error: {\n code: \"UNAUTHORIZED\",\n message: error instanceof Error ? error.message : \"Failed to authenticate.\",\n },\n } satisfies CommandFailure;\n }\n }\n if (!socket || socket.readyState !== 1) {\n return {\n ok: false,\n requestId: sendOptions?.requestId ?? \"unknown\",\n ts: Date.now(),\n error: {\n code: \"DISCONNECTED\",\n message: \"Not connected to Shardwire host.\",\n },\n } satisfies CommandFailure;\n }\n\n const requestId = sendOptions?.requestId ?? createRequestId();\n const timeoutMs = sendOptions?.timeoutMs ?? requestTimeoutMs;\n\n const promise = new Promise<CommandResult>((resolve, reject) => {\n const timer = setTimeout(() => {\n pendingRequests.delete(requestId);\n reject(new CommandRequestError(\"TIMEOUT\", `Command \"${name}\" timed out after ${timeoutMs}ms.`));\n }, timeoutMs);\n\n pendingRequests.set(requestId, {\n resolve,\n reject: (error) => reject(error),\n timer,\n });\n });\n\n sendRaw(\n stringifyEnvelope(\n makeEnvelope(\n \"command.request\",\n {\n name,\n data: payload,\n },\n { requestId },\n ),\n ),\n );\n\n try {\n return (await promise) as CommandResult<CommandResponseOf<C[K]>>;\n } catch (error) {\n const failureCode =\n error instanceof CommandRequestError\n ? error.code\n : !socket || socket.readyState !== 1\n ? \"DISCONNECTED\"\n : \"TIMEOUT\";\n return {\n ok: false,\n requestId,\n ts: Date.now(),\n error: {\n code: failureCode,\n message: error instanceof Error ? error.message : \"Command request failed.\",\n },\n } satisfies CommandFailure;\n }\n },\n on(name, handler) {\n assertMessageName(\"event\", name);\n const casted = handler as EventHandler;\n const existing = eventHandlers.get(name);\n if (existing) {\n existing.add(casted);\n } else {\n eventHandlers.set(name, new Set<EventHandler>([casted]));\n }\n return () => {\n const handlers = eventHandlers.get(name);\n if (!handlers) {\n return;\n }\n handlers.delete(casted);\n if (handlers.size === 0) {\n eventHandlers.delete(name);\n }\n };\n },\n off(name, handler) {\n assertMessageName(\"event\", name);\n const handlers = eventHandlers.get(name);\n if (!handlers) {\n return;\n }\n handlers.delete(handler as EventHandler);\n if (handlers.size === 0) {\n eventHandlers.delete(name);\n }\n },\n onConnected(handler) {\n connectedHandlers.add(handler);\n return () => {\n connectedHandlers.delete(handler);\n };\n },\n onDisconnected(handler) {\n disconnectedHandlers.add(handler);\n return () => {\n disconnectedHandlers.delete(handler);\n };\n },\n onReconnecting(handler) {\n reconnectingHandlers.add(handler);\n return () => {\n reconnectingHandlers.delete(handler);\n };\n },\n ready() {\n return connect();\n },\n connected() {\n return Boolean(socket && socket.readyState === 1 && isAuthed);\n },\n connectionId() {\n return currentConnectionId;\n },\n async close() {\n isClosed = true;\n isAuthed = false;\n currentConnectionId = null;\n rejectConnect(\"Shardwire consumer has been closed.\");\n if (reconnectTimer) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n }\n rejectAllPending(\"DISCONNECTED\", \"Shardwire consumer has been closed.\");\n if (!socket) {\n return;\n }\n await new Promise<void>((resolve) => {\n const current = socket;\n if (!current) {\n resolve();\n return;\n }\n current.once(\"close\", () => resolve());\n current.close();\n });\n socket = null;\n },\n };\n}\n","import type { DiscordClientLike, HostOptions } from \"../core/types\";\n\ninterface OwnedClientState {\n client?: DiscordClientLike;\n owned: boolean;\n}\n\nexport async function resolveDiscordClient<C extends Record<string, unknown>, E extends Record<string, unknown>>(\n options: HostOptions<C, E>,\n): Promise<OwnedClientState> {\n if (options.client) {\n return { client: options.client, owned: false };\n }\n\n if (!options.token) {\n return { owned: false };\n }\n\n const discordModule = await import(\"discord.js\");\n const created = new discordModule.Client({\n intents: [],\n });\n await created.login(options.token);\n return { client: created as unknown as DiscordClientLike, owned: true };\n}\n","export async function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n timeoutMessage = \"Operation timed out.\",\n): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(timeoutMessage));\n }, timeoutMs);\n\n promise\n .then((value) => {\n clearTimeout(timeout);\n resolve(value);\n })\n .catch((error) => {\n clearTimeout(timeout);\n reject(error);\n });\n });\n}\n\nexport class DedupeCache<T> {\n private readonly cache = new Map<string, { value: T; expiresAt: number }>();\n\n constructor(private readonly ttlMs: number) {}\n\n get(key: string): T | undefined {\n const entry = this.cache.get(key);\n if (!entry) {\n return undefined;\n }\n if (entry.expiresAt <= Date.now()) {\n this.cache.delete(key);\n return undefined;\n }\n return entry.value;\n }\n\n set(key: string, value: T): void {\n this.cache.set(key, { value, expiresAt: Date.now() + this.ttlMs });\n }\n}\n","import { WebSocketServer, type WebSocket } from \"ws\";\nimport type { IncomingMessage } from \"node:http\";\nimport {\n makeEnvelope,\n parseEnvelope,\n stringifyEnvelope,\n type AuthHelloPayload,\n type CommandRequestPayload,\n type EventEmitPayload,\n type WireEnvelope,\n} from \"../../core/protocol\";\nimport type { CommandFailure, CommandSuccess, HostOptions, ShardwireLogger } from \"../../core/types\";\nimport { withLogger } from \"../../utils/logger\";\nimport { createConnectionId } from \"../../utils/id\";\nimport type { HostConnectionState } from \"../../runtime/state\";\nimport { getSecretId, isSecretValid } from \"../../runtime/security\";\n\nconst CLOSE_AUTH_REQUIRED = 4001;\nconst CLOSE_AUTH_FAILED = 4003;\nconst CLOSE_INVALID_PAYLOAD = 4004;\n\ninterface HostServerConfig {\n options: HostOptions<any, any>;\n onCommandRequest: (\n connection: HostConnectionState,\n payload: CommandRequestPayload,\n requestId: string,\n source?: string,\n ) => Promise<CommandSuccess | CommandFailure>;\n}\n\nexport class HostWebSocketServer {\n private readonly wss: WebSocketServer;\n private readonly connections = new Map<WebSocket, HostConnectionState>();\n private readonly logger: Required<ShardwireLogger>;\n private readonly heartbeatMs: number;\n private readonly authTimeoutMs = 5000;\n private readonly interval: NodeJS.Timeout;\n\n constructor(private readonly config: HostServerConfig) {\n const serverConfig = config.options.server;\n this.heartbeatMs = serverConfig.heartbeatMs ?? 30000;\n this.logger = withLogger(config.options.logger);\n\n this.wss = new WebSocketServer({\n host: serverConfig.host,\n port: serverConfig.port,\n path: serverConfig.path ?? \"/shardwire\",\n maxPayload: serverConfig.maxPayloadBytes ?? 65536,\n });\n\n this.wss.on(\"connection\", (socket, request) => this.handleConnection(socket, request));\n this.wss.on(\"error\", (error) =>\n this.logger.error(\"Shardwire host server error.\", { error: String(error) }),\n );\n\n this.interval = setInterval(() => {\n this.checkHeartbeats();\n }, this.heartbeatMs);\n }\n\n emitEvent(name: string, data: unknown, source?: string): void {\n const envelope = makeEnvelope(\n \"event.emit\",\n { name, data } satisfies EventEmitPayload,\n source ? { source } : undefined,\n );\n const raw = stringifyEnvelope(envelope);\n\n for (const state of this.connections.values()) {\n if (!state.authenticated) {\n continue;\n }\n this.safeSend(state.socket, raw);\n }\n }\n\n async close(): Promise<void> {\n clearInterval(this.interval);\n for (const connection of this.connections.values()) {\n connection.socket.close();\n }\n this.connections.clear();\n await new Promise<void>((resolve, reject) => {\n this.wss.close((error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n }\n\n private handleConnection(socket: WebSocket, request: IncomingMessage): void {\n const allowlist = this.config.options.server.corsOrigins;\n if (allowlist && allowlist.length > 0) {\n const origin = request.headers.origin;\n if (!origin || !allowlist.includes(origin)) {\n socket.close(CLOSE_AUTH_FAILED, \"Origin not allowed.\");\n return;\n }\n }\n\n const state: HostConnectionState = {\n id: createConnectionId(),\n socket,\n authenticated: false,\n lastHeartbeatAt: Date.now(),\n };\n this.connections.set(socket, state);\n\n const authTimer = setTimeout(() => {\n if (!state.authenticated) {\n socket.close(CLOSE_AUTH_REQUIRED, \"Authentication required.\");\n }\n }, this.authTimeoutMs);\n\n socket.on(\"message\", async (raw) => {\n try {\n const parsed = parseEnvelope(raw.toString());\n await this.handleMessage(state, parsed);\n } catch (error) {\n this.logger.warn(\"Invalid message payload from client.\", { error: String(error) });\n socket.close(CLOSE_INVALID_PAYLOAD, \"Invalid payload.\");\n }\n });\n\n socket.on(\"close\", () => {\n clearTimeout(authTimer);\n this.connections.delete(socket);\n });\n\n socket.on(\"error\", (error) =>\n this.logger.warn(\"Socket error.\", { connectionId: state.id, error: String(error) }),\n );\n }\n\n private async handleMessage(state: HostConnectionState, envelope: WireEnvelope): Promise<void> {\n if (envelope.type === \"ping\") {\n state.lastHeartbeatAt = Date.now();\n this.safeSend(state.socket, stringifyEnvelope(makeEnvelope(\"pong\", {})));\n return;\n }\n if (envelope.type === \"pong\") {\n state.lastHeartbeatAt = Date.now();\n return;\n }\n\n if (!state.authenticated) {\n if (envelope.type !== \"auth.hello\") {\n state.socket.close(CLOSE_AUTH_REQUIRED, \"Authentication required.\");\n return;\n }\n\n const payload = envelope.payload as AuthHelloPayload;\n const providedSecret = payload?.secret;\n const knownSecrets = this.config.options.server.secrets;\n const secretId = payload?.secretId;\n let authReason: \"unknown_secret_id\" | \"invalid_secret\" | null = null;\n\n if (!providedSecret) {\n authReason = \"invalid_secret\";\n } else if (secretId) {\n const secretIndex = knownSecrets.findIndex((_, index) => getSecretId(index) === secretId);\n if (secretIndex < 0) {\n authReason = \"unknown_secret_id\";\n } else {\n const expectedSecret = knownSecrets[secretIndex];\n if (!expectedSecret || !isSecretValid(providedSecret, expectedSecret)) {\n authReason = \"invalid_secret\";\n }\n }\n } else if (!knownSecrets.some((secret) => isSecretValid(providedSecret, secret))) {\n authReason = \"invalid_secret\";\n }\n\n if (authReason) {\n this.safeSend(\n state.socket,\n stringifyEnvelope(\n makeEnvelope(\"auth.error\", {\n code: \"UNAUTHORIZED\",\n reason: authReason,\n message: \"Authentication failed.\",\n }),\n ),\n );\n state.socket.close(CLOSE_AUTH_FAILED, \"Invalid secret.\");\n return;\n }\n\n state.authenticated = true;\n state.lastHeartbeatAt = Date.now();\n if (payload.clientName) {\n state.clientName = payload.clientName;\n }\n this.safeSend(\n state.socket,\n stringifyEnvelope(makeEnvelope(\"auth.ok\", { connectionId: state.id })),\n );\n return;\n }\n\n if (envelope.type === \"command.request\") {\n const payload = envelope.payload as CommandRequestPayload;\n if (!envelope.requestId || !payload?.name) {\n const invalid: CommandFailure = {\n ok: false,\n requestId: envelope.requestId ?? \"unknown\",\n ts: Date.now(),\n error: {\n code: \"VALIDATION_ERROR\",\n message: \"Invalid command request envelope.\",\n },\n };\n this.safeSend(\n state.socket,\n stringifyEnvelope(makeEnvelope(\"command.error\", invalid, { requestId: invalid.requestId })),\n );\n return;\n }\n\n const response = await this.config.onCommandRequest(\n state,\n payload,\n envelope.requestId,\n envelope.source,\n );\n const responseType = response.ok ? \"command.result\" : \"command.error\";\n this.safeSend(\n state.socket,\n stringifyEnvelope(makeEnvelope(responseType, response, { requestId: response.requestId })),\n );\n return;\n }\n }\n\n private checkHeartbeats(): void {\n const now = Date.now();\n const threshold = this.heartbeatMs * 2;\n\n for (const state of this.connections.values()) {\n if (!state.authenticated) {\n continue;\n }\n\n if (now - state.lastHeartbeatAt > threshold) {\n state.socket.terminate();\n this.connections.delete(state.socket);\n continue;\n }\n\n this.safeSend(state.socket, stringifyEnvelope(makeEnvelope(\"ping\", {})));\n }\n }\n\n private safeSend(socket: WebSocket, payload: string): void {\n if (socket.readyState === 1) {\n socket.send(payload);\n }\n }\n}\n","import { timingSafeEqual } from \"node:crypto\";\n\nexport function isSecretValid(provided: string, expected: string): boolean {\n const providedBuffer = Buffer.from(provided);\n const expectedBuffer = Buffer.from(expected);\n\n if (providedBuffer.length !== expectedBuffer.length) {\n return false;\n }\n\n return timingSafeEqual(providedBuffer, expectedBuffer);\n}\n\nexport function getSecretId(secretIndex: number): string {\n return `s${secretIndex}`;\n}\n","import type {\n CommandContext,\n CommandFailure,\n CommandMap,\n CommandSuccess,\n EventMap,\n HostOptions,\n HostShardwire,\n} from \"../core/types\";\nimport { withTimeout, DedupeCache } from \"../runtime/reliability\";\nimport type { CommandHandler } from \"../runtime/state\";\nimport { HostWebSocketServer } from \"../transport/ws/host-server\";\nimport {\n assertJsonPayload,\n assertMessageName,\n parsePayloadWithSchema,\n PayloadValidationError,\n} from \"../runtime/validation\";\n\nconst DEFAULT_COMMAND_TIMEOUT_MS = 10000;\n\nexport function createHostShardwire<C extends CommandMap, E extends EventMap>(\n options: HostOptions<C, E>,\n runtimeHooks?: {\n onClose?: () => Promise<void> | void;\n },\n): HostShardwire<C, E> {\n const commandHandlers = new Map<string, CommandHandler>();\n const commandTimeoutMs = options.server.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n const dedupeCache = new DedupeCache<CommandSuccess | CommandFailure>(commandTimeoutMs * 2);\n\n const hostServer = new HostWebSocketServer({\n options,\n onCommandRequest: async (connection, payload, requestId, source) => {\n const cacheKey = `${requestId}:${payload.name}`;\n const cached = dedupeCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n const handler = commandHandlers.get(payload.name);\n if (!handler) {\n const failure: CommandFailure = {\n ok: false,\n requestId,\n ts: Date.now(),\n error: {\n code: \"COMMAND_NOT_FOUND\",\n message: `No command handler registered for \"${payload.name}\".`,\n },\n };\n dedupeCache.set(cacheKey, failure);\n return failure;\n }\n\n const context: CommandContext = {\n requestId,\n connectionId: connection.id,\n receivedAt: Date.now(),\n };\n if (source) {\n context.source = source;\n }\n\n try {\n const commandValidation = options.validation?.commands?.[payload.name];\n const validatedRequest = parsePayloadWithSchema(commandValidation?.request, payload.data, {\n name: payload.name,\n stage: \"command.request\",\n });\n\n const maybePromise = Promise.resolve(handler(validatedRequest, context));\n const value = await withTimeout(\n maybePromise,\n commandTimeoutMs,\n `Command \"${payload.name}\" timed out after ${commandTimeoutMs}ms.`,\n );\n const validatedResponse = parsePayloadWithSchema(commandValidation?.response, value, {\n name: payload.name,\n stage: \"command.response\",\n });\n const success: CommandSuccess = {\n ok: true,\n requestId,\n ts: Date.now(),\n data: validatedResponse,\n };\n dedupeCache.set(cacheKey, success);\n return success;\n } catch (error) {\n if (error instanceof PayloadValidationError) {\n const failure: CommandFailure = {\n ok: false,\n requestId,\n ts: Date.now(),\n error: {\n code: \"VALIDATION_ERROR\",\n message: error.message,\n details: error.details,\n },\n };\n dedupeCache.set(cacheKey, failure);\n return failure;\n }\n const isTimeout = error instanceof Error && /timed out/i.test(error.message);\n const failure: CommandFailure = {\n ok: false,\n requestId,\n ts: Date.now(),\n error: {\n code: isTimeout ? \"TIMEOUT\" : \"INTERNAL_ERROR\",\n message: error instanceof Error ? error.message : \"Unknown command execution error.\",\n },\n };\n dedupeCache.set(cacheKey, failure);\n return failure;\n }\n },\n });\n\n return {\n mode: \"host\",\n onCommand(name, handler) {\n assertMessageName(\"command\", name);\n commandHandlers.set(name, handler as CommandHandler);\n return () => {\n commandHandlers.delete(name);\n };\n },\n emitEvent(name, payload) {\n assertMessageName(\"event\", name);\n const validatedPayload = parsePayloadWithSchema(options.validation?.events?.[name], payload, {\n name,\n stage: \"event.emit\",\n });\n assertJsonPayload(\"event\", name, validatedPayload);\n hostServer.emitEvent(name, validatedPayload, options.name);\n },\n broadcast(name, payload) {\n assertMessageName(\"event\", name);\n const validatedPayload = parsePayloadWithSchema(options.validation?.events?.[name], payload, {\n name,\n stage: \"event.emit\",\n });\n assertJsonPayload(\"event\", name, validatedPayload);\n hostServer.emitEvent(name, validatedPayload, options.name);\n },\n close() {\n return hostServer.close().then(async () => {\n await runtimeHooks?.onClose?.();\n });\n },\n };\n}\n","import type { RuntimeSchema, SchemaValidationIssue } from \"../core/types\";\n\nexport interface SafeParseResultSuccess<T> {\n success: true;\n data: T;\n}\n\nexport interface SafeParseResultFailure {\n success: false;\n error: {\n message: string;\n issues?: SchemaValidationIssue[];\n };\n}\n\nexport type SafeParseResult<T> = SafeParseResultSuccess<T> | SafeParseResultFailure;\n\nexport interface SafeParseSchema<T> {\n safeParse: (value: unknown) => SafeParseResult<T>;\n}\n\nexport function fromSafeParseSchema<T>(schema: SafeParseSchema<T>): RuntimeSchema<T> {\n return {\n parse(value) {\n const result = schema.safeParse(value);\n if (result.success) {\n return result.data;\n }\n const error = new Error(result.error.message) as Error & { issues?: SchemaValidationIssue[] };\n if (result.error.issues) {\n error.issues = result.error.issues;\n }\n throw error;\n },\n };\n}\n","import type { RuntimeSchema, SchemaValidationIssue } from \"../core/types\";\nimport { fromSafeParseSchema } from \"./index\";\nimport type { ZodType } from \"zod\";\n\nfunction normalizeZodPath(path: ReadonlyArray<PropertyKey>): string {\n if (path.length === 0) {\n return \"\";\n }\n return path\n .filter((segment): segment is string | number => typeof segment === \"string\" || typeof segment === \"number\")\n .map((segment) => String(segment))\n .join(\".\");\n}\n\nexport function fromZodSchema<T>(schema: ZodType<T>): RuntimeSchema<T> {\n return fromSafeParseSchema<T>({\n safeParse(value) {\n const result = schema.safeParse(value);\n if (result.success) {\n return { success: true, data: result.data };\n }\n const issues: SchemaValidationIssue[] = result.error.issues.map((issue) => ({\n path: normalizeZodPath(issue.path),\n message: issue.message,\n }));\n return {\n success: false,\n error: {\n message: \"Schema validation failed.\",\n issues,\n },\n };\n },\n });\n}\n"],"mappings":"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","names":["import_ws","import_node_crypto","failure"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/transport/ws/consumer-socket.ts","../src/utils/id.ts","../src/utils/backoff.ts","../src/utils/logger.ts","../src/core/protocol.ts","../src/runtime/validation.ts","../src/consumer/index.ts","../src/discord/client.ts","../src/runtime/reliability.ts","../src/transport/ws/host-server.ts","../src/runtime/security.ts","../src/host/index.ts","../src/schema/index.ts","../src/schema/zod.ts"],"sourcesContent":["import { createConsumerShardwire } from \"./consumer\";\nimport { resolveDiscordClient } from \"./discord/client\";\nimport { createHostShardwire } from \"./host\";\nimport { assertConsumerOptions, assertHostOptions } from \"./runtime/validation\";\nimport type {\n CommandMap,\n ConsumerOptions,\n ConsumerShardwire,\n EventMap,\n HostOptions,\n HostShardwire,\n} from \"./core/types\";\n\nfunction isHostOptions<C extends CommandMap, E extends EventMap>(\n options: HostOptions<C, E> | ConsumerOptions,\n): options is HostOptions<C, E> {\n return \"server\" in options;\n}\n\nexport function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(\n options: HostOptions<C, E>,\n): HostShardwire<C, E>;\nexport function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(\n options: ConsumerOptions,\n): ConsumerShardwire<C, E>;\nexport function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(\n options: HostOptions<C, E> | ConsumerOptions,\n): HostShardwire<C, E> | ConsumerShardwire<C, E> {\n if (!isHostOptions(options)) {\n assertConsumerOptions(options);\n return createConsumerShardwire<C, E>(options);\n }\n assertHostOptions(options);\n\n let ownedClientPromise: Promise<{ destroy: () => void } | undefined> | undefined;\n\n if (!options.client && options.token) {\n ownedClientPromise = resolveDiscordClient(options)\n .then((state) => {\n if (!state.owned || !state.client) {\n return undefined;\n }\n return {\n destroy: () => state.client?.destroy(),\n };\n })\n .catch((error) => {\n options.logger?.error?.(\"Failed to initialize discord.js client from token.\", {\n error: String(error),\n });\n return undefined;\n });\n }\n\n return createHostShardwire<C, E>(options, {\n onClose: async () => {\n const owned = await ownedClientPromise;\n owned?.destroy();\n },\n });\n}\n\nexport { fromSafeParseSchema } from \"./schema\";\nexport { fromZodSchema } from \"./schema/zod\";\n\nexport type {\n CommandContext,\n CommandFailure,\n CommandMap,\n CommandRequestOf,\n CommandResult,\n CommandResponseOf,\n CommandSchema,\n CommandSuccess,\n ConsumerOptions,\n ConsumerShardwire,\n CreateShardwire,\n DiscordClientLike,\n EventMap,\n EventMeta,\n HostOptions,\n HostShardwire,\n RuntimeSchema,\n SchemaValidationIssue,\n ShardwireLogger,\n Unsubscribe,\n} from \"./core/types\";\n","import { WebSocket } from \"ws\";\n\nexport interface WebSocketLike {\n readyState: number;\n send(data: string): void;\n close(code?: number, reason?: string): void;\n on(event: \"open\", listener: () => void): void;\n on(event: \"message\", listener: (data: unknown) => void): void;\n on(event: \"close\", listener: () => void): void;\n on(event: \"error\", listener: (error: unknown) => void): void;\n once(event: \"close\", listener: () => void): void;\n}\n\nexport function createNodeWebSocket(url: string): WebSocketLike {\n return new WebSocket(url) as unknown as WebSocketLike;\n}\n","import { randomUUID } from \"node:crypto\";\n\nexport function createRequestId(): string {\n return randomUUID();\n}\n\nexport function createConnectionId(): string {\n return randomUUID();\n}\n","export interface BackoffConfig {\n initialDelayMs: number;\n maxDelayMs: number;\n jitter: boolean;\n}\n\nexport function getBackoffDelay(attempt: number, config: BackoffConfig): number {\n const base = Math.min(config.maxDelayMs, config.initialDelayMs * 2 ** attempt);\n if (!config.jitter) {\n return base;\n }\n const spread = Math.floor(base * 0.2);\n const min = Math.max(0, base - spread);\n const max = base + spread;\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n","import type { ShardwireLogger } from \"../core/types\";\n\nexport function withLogger(logger?: ShardwireLogger): Required<ShardwireLogger> {\n return {\n debug: logger?.debug ?? (() => undefined),\n info: logger?.info ?? (() => undefined),\n warn: logger?.warn ?? (() => undefined),\n error: logger?.error ?? (() => undefined),\n };\n}\n","import type { CommandResult } from \"./types\";\n\nexport const PROTOCOL_VERSION = 1 as const;\n\nexport type WireType =\n | \"auth.hello\"\n | \"auth.ok\"\n | \"auth.error\"\n | \"command.request\"\n | \"command.result\"\n | \"command.error\"\n | \"event.emit\"\n | \"ping\"\n | \"pong\";\n\nexport type WireEnvelope<TType extends WireType = WireType, TPayload = unknown> = {\n v: typeof PROTOCOL_VERSION;\n type: TType;\n ts: number;\n requestId?: string;\n source?: string;\n payload: TPayload;\n};\n\nexport interface AuthHelloPayload {\n secret: string;\n secretId?: string;\n clientName?: string;\n}\n\nexport interface AuthOkPayload {\n connectionId: string;\n}\n\nexport interface AuthErrorPayload {\n code: \"UNAUTHORIZED\";\n reason: \"unknown_secret_id\" | \"invalid_secret\";\n message: string;\n}\n\nexport interface CommandRequestPayload {\n name: string;\n data: unknown;\n}\n\nexport interface EventEmitPayload {\n name: string;\n data: unknown;\n}\n\nexport type CommandResultPayload = CommandResult;\n\nexport function makeEnvelope<TType extends WireType, TPayload>(\n type: TType,\n payload: TPayload,\n extras?: { requestId?: string; source?: string },\n): WireEnvelope<TType, TPayload> {\n const envelope: WireEnvelope<TType, TPayload> = {\n v: PROTOCOL_VERSION,\n type,\n ts: Date.now(),\n payload,\n };\n if (extras?.requestId) {\n envelope.requestId = extras.requestId;\n }\n if (extras?.source) {\n envelope.source = extras.source;\n }\n return envelope;\n}\n\nexport function parseEnvelope(raw: string): WireEnvelope {\n const parsed = JSON.parse(raw) as WireEnvelope;\n if (!parsed || parsed.v !== PROTOCOL_VERSION || typeof parsed.type !== \"string\") {\n throw new Error(\"Invalid wire envelope.\");\n }\n return parsed;\n}\n\nexport function stringifyEnvelope(envelope: WireEnvelope): string {\n return JSON.stringify(envelope);\n}\n","import type { ConsumerOptions, HostOptions, RuntimeSchema, SchemaValidationIssue } from \"../core/types\";\n\nexport class PayloadValidationError extends Error {\n constructor(\n message: string,\n public readonly details: {\n name: string;\n stage: \"command.request\" | \"command.response\" | \"event.emit\";\n issues?: SchemaValidationIssue[];\n },\n ) {\n super(message);\n this.name = \"PayloadValidationError\";\n }\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n\nfunction assertPositiveNumber(name: string, value: unknown): void {\n if (typeof value !== \"number\" || Number.isNaN(value) || value <= 0) {\n throw new Error(`${name} must be a positive number.`);\n }\n}\n\nexport function assertHostOptions(options: HostOptions<Record<string, unknown>, Record<string, unknown>>): void {\n if (!options.server) {\n throw new Error(\"Host mode requires a server configuration.\");\n }\n assertPositiveNumber(\"server.port\", options.server.port);\n if (!Array.isArray(options.server.secrets) || options.server.secrets.length === 0) {\n throw new Error(\"server.secrets must contain at least one secret.\");\n }\n for (const [index, secret] of options.server.secrets.entries()) {\n if (!isNonEmptyString(secret)) {\n throw new Error(`server.secrets[${index}] must be a non-empty string.`);\n }\n }\n if (\n options.server.primarySecretId !== undefined &&\n !options.server.secrets.some((_, index) => options.server.primarySecretId === `s${index}`)\n ) {\n throw new Error(\"server.primarySecretId must reference an existing secret id.\");\n }\n if (options.server.heartbeatMs !== undefined) {\n assertPositiveNumber(\"server.heartbeatMs\", options.server.heartbeatMs);\n }\n if (options.server.commandTimeoutMs !== undefined) {\n assertPositiveNumber(\"server.commandTimeoutMs\", options.server.commandTimeoutMs);\n }\n if (options.server.maxPayloadBytes !== undefined) {\n assertPositiveNumber(\"server.maxPayloadBytes\", options.server.maxPayloadBytes);\n }\n}\n\nexport function assertConsumerOptions(options: ConsumerOptions): void {\n if (!isNonEmptyString(options.url)) {\n throw new Error(\"Consumer mode requires `url`.\");\n }\n let parsedUrl: URL;\n try {\n parsedUrl = new URL(options.url);\n } catch {\n throw new Error(\"Consumer option `url` must be a valid URL.\");\n }\n if (parsedUrl.protocol !== \"ws:\" && parsedUrl.protocol !== \"wss:\") {\n throw new Error(\"Consumer option `url` must use `ws://` or `wss://`.\");\n }\n const isLoopbackHost =\n parsedUrl.hostname === \"localhost\" || parsedUrl.hostname === \"127.0.0.1\" || parsedUrl.hostname === \"::1\";\n if (parsedUrl.protocol === \"ws:\" && !isLoopbackHost && !options.allowInsecureWs) {\n throw new Error(\n \"Insecure `ws://` is only allowed for loopback hosts by default. Use `wss://` or set `allowInsecureWs` to true.\",\n );\n }\n if (!isNonEmptyString(options.secret)) {\n throw new Error(\"Consumer mode requires `secret`.\");\n }\n if (options.secretId !== undefined && !isNonEmptyString(options.secretId)) {\n throw new Error(\"Consumer option `secretId` must be a non-empty string.\");\n }\n if (options.clientName !== undefined && !isNonEmptyString(options.clientName)) {\n throw new Error(\"Consumer option `clientName` must be a non-empty string.\");\n }\n if (options.requestTimeoutMs !== undefined) {\n assertPositiveNumber(\"requestTimeoutMs\", options.requestTimeoutMs);\n }\n if (options.reconnect?.initialDelayMs !== undefined) {\n assertPositiveNumber(\"reconnect.initialDelayMs\", options.reconnect.initialDelayMs);\n }\n if (options.reconnect?.maxDelayMs !== undefined) {\n assertPositiveNumber(\"reconnect.maxDelayMs\", options.reconnect.maxDelayMs);\n }\n}\n\nexport function assertMessageName(kind: \"command\" | \"event\", name: string): void {\n if (!isNonEmptyString(name)) {\n throw new Error(`${kind} name must be a non-empty string.`);\n }\n}\n\nexport function assertJsonPayload(kind: \"command\" | \"event\", name: string, payload: unknown): void {\n try {\n JSON.stringify(payload);\n } catch {\n throw new Error(`${kind} \"${name}\" payload must be JSON-serializable.`);\n }\n}\n\nfunction normalizeSchemaIssues(error: unknown): SchemaValidationIssue[] | undefined {\n if (!error || typeof error !== \"object\") {\n return undefined;\n }\n const issues = (error as { issues?: unknown }).issues;\n if (!Array.isArray(issues)) {\n return undefined;\n }\n const normalized = issues\n .map((issue) => {\n if (!issue || typeof issue !== \"object\") {\n return null;\n }\n const message = (issue as { message?: unknown }).message;\n const rawPath = (issue as { path?: unknown }).path;\n if (typeof message !== \"string\") {\n return null;\n }\n const path =\n Array.isArray(rawPath) && rawPath.length > 0\n ? rawPath\n .map((segment) => (typeof segment === \"string\" || typeof segment === \"number\" ? String(segment) : \"\"))\n .filter(Boolean)\n .join(\".\")\n : \"\";\n return { path, message } satisfies SchemaValidationIssue;\n })\n .filter((issue): issue is SchemaValidationIssue => Boolean(issue));\n return normalized.length > 0 ? normalized : undefined;\n}\n\nexport function parsePayloadWithSchema<T>(\n schema: RuntimeSchema<T> | undefined,\n payload: unknown,\n context: {\n name: string;\n stage: \"command.request\" | \"command.response\" | \"event.emit\";\n },\n): T | unknown {\n if (!schema) {\n return payload;\n }\n try {\n return schema.parse(payload);\n } catch (error) {\n const message =\n error instanceof Error && error.message.trim().length > 0\n ? error.message\n : `Payload validation failed for ${context.stage} \"${context.name}\".`;\n const issues = normalizeSchemaIssues(error);\n throw new PayloadValidationError(message, {\n ...context,\n ...(issues ? { issues } : {}),\n });\n }\n}\n","import type {\n CommandFailure,\n CommandMap,\n CommandRequestOf,\n CommandResponseOf,\n CommandResult,\n ConsumerOptions,\n ConsumerShardwire,\n EventMap,\n EventMeta,\n} from \"../core/types\";\nimport { createNodeWebSocket, type WebSocketLike } from \"../transport/ws/consumer-socket\";\nimport { createRequestId } from \"../utils/id\";\nimport { getBackoffDelay } from \"../utils/backoff\";\nimport { withLogger } from \"../utils/logger\";\nimport {\n makeEnvelope,\n parseEnvelope,\n stringifyEnvelope,\n type AuthErrorPayload,\n type CommandResultPayload,\n type EventEmitPayload,\n} from \"../core/protocol\";\nimport { assertJsonPayload, assertMessageName } from \"../runtime/validation\";\n\ntype EventHandler = (payload: unknown, meta: EventMeta) => void;\n\ninterface PendingRequest {\n resolve: (value: CommandResult) => void;\n reject: (error: CommandRequestError) => void;\n timer: NodeJS.Timeout;\n}\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 10000;\n\nclass CommandRequestError extends Error {\n constructor(\n public readonly code: \"TIMEOUT\" | \"DISCONNECTED\" | \"UNAUTHORIZED\",\n message: string,\n ) {\n super(message);\n this.name = \"CommandRequestError\";\n }\n}\n\nexport function createConsumerShardwire<C extends CommandMap, E extends EventMap>(\n options: ConsumerOptions,\n): ConsumerShardwire<C, E> {\n const logger = withLogger(options.logger);\n const reconnectEnabled = options.reconnect?.enabled ?? true;\n const initialDelayMs = options.reconnect?.initialDelayMs ?? 500;\n const maxDelayMs = options.reconnect?.maxDelayMs ?? 10000;\n const jitter = options.reconnect?.jitter ?? true;\n const requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n\n let socket: WebSocketLike | null = null;\n let isClosed = false;\n let isAuthed = false;\n let reconnectAttempts = 0;\n let reconnectTimer: NodeJS.Timeout | null = null;\n let connectPromise: Promise<void> | null = null;\n let connectResolve: (() => void) | null = null;\n let connectReject: ((error: Error) => void) | null = null;\n let authTimeoutTimer: NodeJS.Timeout | null = null;\n let currentConnectionId: string | null = null;\n\n const pendingRequests = new Map<string, PendingRequest>();\n const eventHandlers = new Map<string, Set<EventHandler>>();\n const connectedHandlers = new Set<(info: { connectionId: string; connectedAt: number }) => void>();\n const disconnectedHandlers = new Set<\n (info: { reason: string; at: number; willReconnect: boolean }) => void\n >();\n const reconnectingHandlers = new Set<(info: { attempt: number; delayMs: number; at: number }) => void>();\n\n function clearAuthTimeout(): void {\n if (authTimeoutTimer) {\n clearTimeout(authTimeoutTimer);\n authTimeoutTimer = null;\n }\n }\n\n function resolveConnect(): void {\n clearAuthTimeout();\n connectResolve?.();\n connectResolve = null;\n connectReject = null;\n connectPromise = null;\n }\n\n function rejectConnect(message: string): void {\n clearAuthTimeout();\n if (connectReject) {\n connectReject(new Error(message));\n }\n connectResolve = null;\n connectReject = null;\n connectPromise = null;\n }\n\n function sendRaw(data: string): void {\n if (!socket || socket.readyState !== 1) {\n throw new Error(\"Shardwire consumer is not connected.\");\n }\n socket.send(data);\n }\n\n function rejectAllPending(\n code: \"TIMEOUT\" | \"DISCONNECTED\" | \"UNAUTHORIZED\",\n reason: string,\n ): void {\n for (const [requestId, pending] of pendingRequests.entries()) {\n clearTimeout(pending.timer);\n pending.reject(new CommandRequestError(code, reason));\n pendingRequests.delete(requestId);\n }\n }\n\n function scheduleReconnect(): void {\n if (isClosed || !reconnectEnabled || reconnectTimer) {\n return;\n }\n const delay = getBackoffDelay(reconnectAttempts, { initialDelayMs, maxDelayMs, jitter });\n reconnectAttempts += 1;\n for (const handler of reconnectingHandlers) {\n try {\n handler({ attempt: reconnectAttempts, delayMs: delay, at: Date.now() });\n } catch (error) {\n logger.warn(\"Reconnect handler threw an error.\", { error: String(error) });\n }\n }\n reconnectTimer = setTimeout(() => {\n reconnectTimer = null;\n void connect().catch((error) => {\n logger.warn(\"Reconnect attempt failed.\", { error: String(error) });\n });\n }, delay);\n }\n\n function handleEvent(name: string, payload: unknown, meta: EventMeta): void {\n const handlers = eventHandlers.get(name);\n if (!handlers || handlers.size === 0) {\n return;\n }\n for (const handler of handlers) {\n try {\n handler(payload, meta);\n } catch (error) {\n logger.warn(\"Event handler threw an error.\", { name, error: String(error) });\n }\n }\n }\n\n async function connect(): Promise<void> {\n if (isClosed) {\n return;\n }\n if (socket && socket.readyState === 1 && isAuthed) {\n return;\n }\n if (connectPromise) {\n return connectPromise;\n }\n\n connectPromise = new Promise<void>((resolve, reject) => {\n connectResolve = resolve;\n connectReject = reject;\n });\n\n socket = options.webSocketFactory\n ? (options.webSocketFactory(options.url) as WebSocketLike)\n : createNodeWebSocket(options.url);\n\n socket.on(\"open\", () => {\n reconnectAttempts = 0;\n isAuthed = false;\n currentConnectionId = null;\n const hello = makeEnvelope(\"auth.hello\", {\n secret: options.secret,\n secretId: options.secretId,\n clientName: options.clientName,\n });\n socket?.send(stringifyEnvelope(hello));\n authTimeoutTimer = setTimeout(() => {\n if (!isAuthed) {\n rejectConnect(\"Shardwire auth timed out.\");\n socket?.close();\n }\n }, requestTimeoutMs);\n });\n\n socket.on(\"message\", (raw) => {\n try {\n const serialized = typeof raw === \"string\" ? raw : String(raw);\n const envelope = parseEnvelope(serialized);\n switch (envelope.type) {\n case \"auth.ok\":\n isAuthed = true;\n if (\n envelope.payload &&\n typeof envelope.payload === \"object\" &&\n \"connectionId\" in envelope.payload &&\n typeof (envelope.payload as { connectionId?: unknown }).connectionId === \"string\"\n ) {\n currentConnectionId = (envelope.payload as { connectionId: string }).connectionId;\n }\n if (currentConnectionId) {\n for (const handler of connectedHandlers) {\n try {\n handler({ connectionId: currentConnectionId, connectedAt: Date.now() });\n } catch (error) {\n logger.warn(\"Connected handler threw an error.\", { error: String(error) });\n }\n }\n }\n resolveConnect();\n break;\n case \"auth.error\": {\n const payload = envelope.payload as AuthErrorPayload;\n logger.error(\"Authentication failed for consumer.\", {\n code: payload.code,\n message: payload.message,\n });\n rejectConnect(payload.message);\n rejectAllPending(\"UNAUTHORIZED\", \"Shardwire authentication failed.\");\n socket?.close();\n break;\n }\n case \"command.result\":\n case \"command.error\": {\n const requestId = envelope.requestId;\n if (!requestId) {\n return;\n }\n const pending = pendingRequests.get(requestId);\n if (!pending) {\n return;\n }\n clearTimeout(pending.timer);\n pending.resolve(envelope.payload as CommandResultPayload);\n pendingRequests.delete(requestId);\n break;\n }\n case \"event.emit\": {\n const payload = envelope.payload as EventEmitPayload;\n const meta: EventMeta = { ts: envelope.ts };\n if (envelope.source) {\n meta.source = envelope.source;\n }\n handleEvent(payload.name, payload.data, meta);\n break;\n }\n case \"ping\":\n sendRaw(stringifyEnvelope(makeEnvelope(\"pong\", {})));\n break;\n default:\n break;\n }\n } catch (error) {\n logger.warn(\"Failed to parse consumer message.\", { error: String(error) });\n }\n });\n\n socket.on(\"close\", () => {\n const willReconnect = !isClosed && reconnectEnabled;\n rejectConnect(\"Shardwire connection closed.\");\n isAuthed = false;\n currentConnectionId = null;\n rejectAllPending(\"DISCONNECTED\", \"Shardwire connection closed before command completed.\");\n for (const handler of disconnectedHandlers) {\n try {\n handler({\n reason: \"Shardwire connection closed.\",\n at: Date.now(),\n willReconnect,\n });\n } catch (error) {\n logger.warn(\"Disconnected handler threw an error.\", { error: String(error) });\n }\n }\n if (!isClosed) {\n scheduleReconnect();\n }\n });\n\n socket.on(\"error\", (error) => {\n logger.warn(\"Consumer socket error.\", { error: String(error) });\n });\n\n return connectPromise;\n }\n\n void connect().catch((error) => {\n logger.warn(\"Initial connection attempt failed.\", { error: String(error) });\n });\n\n return {\n mode: \"consumer\",\n async send<K extends keyof C & string>(\n name: K,\n payload: CommandRequestOf<C[K]>,\n sendOptions?: { timeoutMs?: number; requestId?: string },\n ): Promise<CommandResult<CommandResponseOf<C[K]>>> {\n assertMessageName(\"command\", name);\n assertJsonPayload(\"command\", name, payload);\n if (!isAuthed) {\n try {\n await connect();\n } catch (error) {\n return {\n ok: false,\n requestId: sendOptions?.requestId ?? \"unknown\",\n ts: Date.now(),\n error: {\n code: \"UNAUTHORIZED\",\n message: error instanceof Error ? error.message : \"Failed to authenticate.\",\n },\n } satisfies CommandFailure;\n }\n }\n if (!socket || socket.readyState !== 1) {\n return {\n ok: false,\n requestId: sendOptions?.requestId ?? \"unknown\",\n ts: Date.now(),\n error: {\n code: \"DISCONNECTED\",\n message: \"Not connected to Shardwire host.\",\n },\n } satisfies CommandFailure;\n }\n\n const requestId = sendOptions?.requestId ?? createRequestId();\n const timeoutMs = sendOptions?.timeoutMs ?? requestTimeoutMs;\n\n const promise = new Promise<CommandResult>((resolve, reject) => {\n const timer = setTimeout(() => {\n pendingRequests.delete(requestId);\n reject(new CommandRequestError(\"TIMEOUT\", `Command \"${name}\" timed out after ${timeoutMs}ms.`));\n }, timeoutMs);\n\n pendingRequests.set(requestId, {\n resolve,\n reject: (error) => reject(error),\n timer,\n });\n });\n\n sendRaw(\n stringifyEnvelope(\n makeEnvelope(\n \"command.request\",\n {\n name,\n data: payload,\n },\n { requestId },\n ),\n ),\n );\n\n try {\n return (await promise) as CommandResult<CommandResponseOf<C[K]>>;\n } catch (error) {\n const failureCode =\n error instanceof CommandRequestError\n ? error.code\n : !socket || socket.readyState !== 1\n ? \"DISCONNECTED\"\n : \"TIMEOUT\";\n return {\n ok: false,\n requestId,\n ts: Date.now(),\n error: {\n code: failureCode,\n message: error instanceof Error ? error.message : \"Command request failed.\",\n },\n } satisfies CommandFailure;\n }\n },\n on(name, handler) {\n assertMessageName(\"event\", name);\n const casted = handler as EventHandler;\n const existing = eventHandlers.get(name);\n if (existing) {\n existing.add(casted);\n } else {\n eventHandlers.set(name, new Set<EventHandler>([casted]));\n }\n return () => {\n const handlers = eventHandlers.get(name);\n if (!handlers) {\n return;\n }\n handlers.delete(casted);\n if (handlers.size === 0) {\n eventHandlers.delete(name);\n }\n };\n },\n off(name, handler) {\n assertMessageName(\"event\", name);\n const handlers = eventHandlers.get(name);\n if (!handlers) {\n return;\n }\n handlers.delete(handler as EventHandler);\n if (handlers.size === 0) {\n eventHandlers.delete(name);\n }\n },\n onConnected(handler) {\n connectedHandlers.add(handler);\n return () => {\n connectedHandlers.delete(handler);\n };\n },\n onDisconnected(handler) {\n disconnectedHandlers.add(handler);\n return () => {\n disconnectedHandlers.delete(handler);\n };\n },\n onReconnecting(handler) {\n reconnectingHandlers.add(handler);\n return () => {\n reconnectingHandlers.delete(handler);\n };\n },\n ready() {\n return connect();\n },\n connected() {\n return Boolean(socket && socket.readyState === 1 && isAuthed);\n },\n connectionId() {\n return currentConnectionId;\n },\n async close() {\n isClosed = true;\n isAuthed = false;\n currentConnectionId = null;\n rejectConnect(\"Shardwire consumer has been closed.\");\n if (reconnectTimer) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n }\n rejectAllPending(\"DISCONNECTED\", \"Shardwire consumer has been closed.\");\n if (!socket) {\n return;\n }\n await new Promise<void>((resolve) => {\n const current = socket;\n if (!current) {\n resolve();\n return;\n }\n current.once(\"close\", () => resolve());\n current.close();\n });\n socket = null;\n },\n };\n}\n","import type { DiscordClientLike, HostOptions } from \"../core/types\";\n\ninterface OwnedClientState {\n client?: DiscordClientLike;\n owned: boolean;\n}\n\nexport async function resolveDiscordClient<C extends Record<string, unknown>, E extends Record<string, unknown>>(\n options: HostOptions<C, E>,\n): Promise<OwnedClientState> {\n if (options.client) {\n return { client: options.client, owned: false };\n }\n\n if (!options.token) {\n return { owned: false };\n }\n\n const discordModule = await import(\"discord.js\");\n const created = new discordModule.Client({\n intents: [],\n });\n await created.login(options.token);\n return { client: created as unknown as DiscordClientLike, owned: true };\n}\n","export async function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n timeoutMessage = \"Operation timed out.\",\n): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(timeoutMessage));\n }, timeoutMs);\n\n promise\n .then((value) => {\n clearTimeout(timeout);\n resolve(value);\n })\n .catch((error) => {\n clearTimeout(timeout);\n reject(error instanceof Error ? error : new Error(String(error)));\n });\n });\n}\n\nexport class DedupeCache<T> {\n private readonly cache = new Map<string, { value: T; expiresAt: number }>();\n\n constructor(private readonly ttlMs: number) {}\n\n get(key: string): T | undefined {\n const entry = this.cache.get(key);\n if (!entry) {\n return undefined;\n }\n if (entry.expiresAt <= Date.now()) {\n this.cache.delete(key);\n return undefined;\n }\n return entry.value;\n }\n\n set(key: string, value: T): void {\n this.cache.set(key, { value, expiresAt: Date.now() + this.ttlMs });\n }\n}\n","import { WebSocketServer, type WebSocket } from \"ws\";\nimport type { IncomingMessage } from \"node:http\";\nimport {\n makeEnvelope,\n parseEnvelope,\n stringifyEnvelope,\n type AuthHelloPayload,\n type CommandRequestPayload,\n type EventEmitPayload,\n type WireEnvelope,\n} from \"../../core/protocol\";\nimport type { CommandFailure, CommandSuccess, HostOptions, ShardwireLogger } from \"../../core/types\";\nimport { withLogger } from \"../../utils/logger\";\nimport { createConnectionId } from \"../../utils/id\";\nimport type { HostConnectionState } from \"../../runtime/state\";\nimport { getSecretId, isSecretValid } from \"../../runtime/security\";\n\nconst CLOSE_AUTH_REQUIRED = 4001;\nconst CLOSE_AUTH_FAILED = 4003;\nconst CLOSE_INVALID_PAYLOAD = 4004;\n\ninterface HostServerConfig {\n options: HostOptions<Record<string, unknown>, Record<string, unknown>>;\n onCommandRequest: (\n connection: HostConnectionState,\n payload: CommandRequestPayload,\n requestId: string,\n source?: string,\n ) => Promise<CommandSuccess | CommandFailure>;\n}\n\nexport class HostWebSocketServer {\n private readonly wss: WebSocketServer;\n private readonly connections = new Map<WebSocket, HostConnectionState>();\n private readonly logger: Required<ShardwireLogger>;\n private readonly heartbeatMs: number;\n private readonly authTimeoutMs = 5000;\n private readonly interval: NodeJS.Timeout;\n\n constructor(private readonly config: HostServerConfig) {\n const serverConfig = config.options.server;\n this.heartbeatMs = serverConfig.heartbeatMs ?? 30000;\n this.logger = withLogger(config.options.logger);\n\n this.wss = new WebSocketServer({\n host: serverConfig.host,\n port: serverConfig.port,\n path: serverConfig.path ?? \"/shardwire\",\n maxPayload: serverConfig.maxPayloadBytes ?? 65536,\n });\n\n this.wss.on(\"connection\", (socket, request) => this.handleConnection(socket, request));\n this.wss.on(\"error\", (error) =>\n this.logger.error(\"Shardwire host server error.\", { error: String(error) }),\n );\n\n this.interval = setInterval(() => {\n this.checkHeartbeats();\n }, this.heartbeatMs);\n }\n\n emitEvent(name: string, data: unknown, source?: string): void {\n const envelope = makeEnvelope(\n \"event.emit\",\n { name, data } satisfies EventEmitPayload,\n source ? { source } : undefined,\n );\n const raw = stringifyEnvelope(envelope);\n\n for (const state of this.connections.values()) {\n if (!state.authenticated) {\n continue;\n }\n this.safeSend(state.socket, raw);\n }\n }\n\n async close(): Promise<void> {\n clearInterval(this.interval);\n for (const connection of this.connections.values()) {\n connection.socket.close();\n }\n this.connections.clear();\n await new Promise<void>((resolve, reject) => {\n this.wss.close((error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n }\n\n private handleConnection(socket: WebSocket, request: IncomingMessage): void {\n const allowlist = this.config.options.server.corsOrigins;\n if (allowlist && allowlist.length > 0) {\n const origin = request.headers.origin;\n if (!origin || !allowlist.includes(origin)) {\n socket.close(CLOSE_AUTH_FAILED, \"Origin not allowed.\");\n return;\n }\n }\n\n const state: HostConnectionState = {\n id: createConnectionId(),\n socket,\n authenticated: false,\n lastHeartbeatAt: Date.now(),\n };\n this.connections.set(socket, state);\n\n const authTimer = setTimeout(() => {\n if (!state.authenticated) {\n socket.close(CLOSE_AUTH_REQUIRED, \"Authentication required.\");\n }\n }, this.authTimeoutMs);\n\n socket.on(\"message\", (raw) => {\n const serialized =\n typeof raw === \"string\" ? raw : Buffer.isBuffer(raw) ? raw.toString(\"utf8\") : undefined;\n if (!serialized) {\n this.logger.warn(\"Invalid message payload from client.\", { error: \"Unsupported payload type.\" });\n socket.close(CLOSE_INVALID_PAYLOAD, \"Invalid payload.\");\n return;\n }\n let parsed: WireEnvelope;\n try {\n parsed = parseEnvelope(serialized);\n } catch (error) {\n this.logger.warn(\"Invalid message payload from client.\", { error: String(error) });\n socket.close(CLOSE_INVALID_PAYLOAD, \"Invalid payload.\");\n return;\n }\n void this.handleMessage(state, parsed).catch((error: unknown) => {\n this.logger.warn(\"Invalid message payload from client.\", { error: String(error) });\n socket.close(CLOSE_INVALID_PAYLOAD, \"Invalid payload.\");\n });\n });\n\n socket.on(\"close\", () => {\n clearTimeout(authTimer);\n this.connections.delete(socket);\n });\n\n socket.on(\"error\", (error) =>\n this.logger.warn(\"Socket error.\", { connectionId: state.id, error: String(error) }),\n );\n }\n\n private async handleMessage(state: HostConnectionState, envelope: WireEnvelope): Promise<void> {\n if (envelope.type === \"ping\") {\n state.lastHeartbeatAt = Date.now();\n this.safeSend(state.socket, stringifyEnvelope(makeEnvelope(\"pong\", {})));\n return;\n }\n if (envelope.type === \"pong\") {\n state.lastHeartbeatAt = Date.now();\n return;\n }\n\n if (!state.authenticated) {\n if (envelope.type !== \"auth.hello\") {\n state.socket.close(CLOSE_AUTH_REQUIRED, \"Authentication required.\");\n return;\n }\n\n const payload = envelope.payload as AuthHelloPayload;\n const providedSecret = payload?.secret;\n const knownSecrets = this.config.options.server.secrets;\n const secretId = payload?.secretId;\n let authReason: \"unknown_secret_id\" | \"invalid_secret\" | null = null;\n\n if (!providedSecret) {\n authReason = \"invalid_secret\";\n } else if (secretId) {\n const secretIndex = knownSecrets.findIndex((_, index) => getSecretId(index) === secretId);\n if (secretIndex < 0) {\n authReason = \"unknown_secret_id\";\n } else {\n const expectedSecret = knownSecrets[secretIndex];\n if (!expectedSecret || !isSecretValid(providedSecret, expectedSecret)) {\n authReason = \"invalid_secret\";\n }\n }\n } else if (!knownSecrets.some((secret) => isSecretValid(providedSecret, secret))) {\n authReason = \"invalid_secret\";\n }\n\n if (authReason) {\n this.safeSend(\n state.socket,\n stringifyEnvelope(\n makeEnvelope(\"auth.error\", {\n code: \"UNAUTHORIZED\",\n reason: authReason,\n message: \"Authentication failed.\",\n }),\n ),\n );\n state.socket.close(CLOSE_AUTH_FAILED, \"Invalid secret.\");\n return;\n }\n\n state.authenticated = true;\n state.lastHeartbeatAt = Date.now();\n if (payload.clientName) {\n state.clientName = payload.clientName;\n }\n this.safeSend(\n state.socket,\n stringifyEnvelope(makeEnvelope(\"auth.ok\", { connectionId: state.id })),\n );\n return;\n }\n\n if (envelope.type === \"command.request\") {\n const payload = envelope.payload as CommandRequestPayload;\n if (!envelope.requestId || !payload?.name) {\n const invalid: CommandFailure = {\n ok: false,\n requestId: envelope.requestId ?? \"unknown\",\n ts: Date.now(),\n error: {\n code: \"VALIDATION_ERROR\",\n message: \"Invalid command request envelope.\",\n },\n };\n this.safeSend(\n state.socket,\n stringifyEnvelope(makeEnvelope(\"command.error\", invalid, { requestId: invalid.requestId })),\n );\n return;\n }\n\n const response = await this.config.onCommandRequest(\n state,\n payload,\n envelope.requestId,\n envelope.source,\n );\n const responseType = response.ok ? \"command.result\" : \"command.error\";\n this.safeSend(\n state.socket,\n stringifyEnvelope(makeEnvelope(responseType, response, { requestId: response.requestId })),\n );\n return;\n }\n }\n\n private checkHeartbeats(): void {\n const now = Date.now();\n const threshold = this.heartbeatMs * 2;\n\n for (const state of this.connections.values()) {\n if (!state.authenticated) {\n continue;\n }\n\n if (now - state.lastHeartbeatAt > threshold) {\n state.socket.terminate();\n this.connections.delete(state.socket);\n continue;\n }\n\n this.safeSend(state.socket, stringifyEnvelope(makeEnvelope(\"ping\", {})));\n }\n }\n\n private safeSend(socket: WebSocket, payload: string): void {\n if (socket.readyState === 1) {\n socket.send(payload);\n }\n }\n}\n","import { timingSafeEqual } from \"node:crypto\";\n\nexport function isSecretValid(provided: string, expected: string): boolean {\n const providedBuffer = Buffer.from(provided);\n const expectedBuffer = Buffer.from(expected);\n\n if (providedBuffer.length !== expectedBuffer.length) {\n return false;\n }\n\n return timingSafeEqual(providedBuffer, expectedBuffer);\n}\n\nexport function getSecretId(secretIndex: number): string {\n return `s${secretIndex}`;\n}\n","import type {\n CommandContext,\n CommandFailure,\n CommandMap,\n CommandSuccess,\n EventMap,\n HostOptions,\n HostShardwire,\n} from \"../core/types\";\nimport { withTimeout, DedupeCache } from \"../runtime/reliability\";\nimport type { CommandHandler } from \"../runtime/state\";\nimport { HostWebSocketServer } from \"../transport/ws/host-server\";\nimport {\n assertJsonPayload,\n assertMessageName,\n parsePayloadWithSchema,\n PayloadValidationError,\n} from \"../runtime/validation\";\n\nconst DEFAULT_COMMAND_TIMEOUT_MS = 10000;\n\nexport function createHostShardwire<C extends CommandMap, E extends EventMap>(\n options: HostOptions<C, E>,\n runtimeHooks?: {\n onClose?: () => Promise<void> | void;\n },\n): HostShardwire<C, E> {\n const commandHandlers = new Map<string, CommandHandler>();\n const commandTimeoutMs = options.server.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n const dedupeCache = new DedupeCache<CommandSuccess | CommandFailure>(commandTimeoutMs * 2);\n\n const hostServer = new HostWebSocketServer({\n options,\n onCommandRequest: async (connection, payload, requestId, source) => {\n const cacheKey = `${connection.id}:${requestId}:${payload.name}`;\n const cached = dedupeCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n const handler = commandHandlers.get(payload.name);\n if (!handler) {\n const failure: CommandFailure = {\n ok: false,\n requestId,\n ts: Date.now(),\n error: {\n code: \"COMMAND_NOT_FOUND\",\n message: `No command handler registered for \"${payload.name}\".`,\n },\n };\n dedupeCache.set(cacheKey, failure);\n return failure;\n }\n\n const context: CommandContext = {\n requestId,\n connectionId: connection.id,\n receivedAt: Date.now(),\n };\n if (source) {\n context.source = source;\n }\n\n try {\n const commandValidation = options.validation?.commands?.[payload.name];\n const validatedRequest = parsePayloadWithSchema(commandValidation?.request, payload.data, {\n name: payload.name,\n stage: \"command.request\",\n });\n\n const maybePromise = Promise.resolve(handler(validatedRequest, context));\n const value = await withTimeout(\n maybePromise,\n commandTimeoutMs,\n `Command \"${payload.name}\" timed out after ${commandTimeoutMs}ms.`,\n );\n const validatedResponse = parsePayloadWithSchema(commandValidation?.response, value, {\n name: payload.name,\n stage: \"command.response\",\n });\n const success: CommandSuccess = {\n ok: true,\n requestId,\n ts: Date.now(),\n data: validatedResponse,\n };\n dedupeCache.set(cacheKey, success);\n return success;\n } catch (error) {\n if (error instanceof PayloadValidationError) {\n const failure: CommandFailure = {\n ok: false,\n requestId,\n ts: Date.now(),\n error: {\n code: \"VALIDATION_ERROR\",\n message: error.message,\n details: error.details,\n },\n };\n dedupeCache.set(cacheKey, failure);\n return failure;\n }\n const isTimeout = error instanceof Error && /timed out/i.test(error.message);\n const failure: CommandFailure = {\n ok: false,\n requestId,\n ts: Date.now(),\n error: {\n code: isTimeout ? \"TIMEOUT\" : \"INTERNAL_ERROR\",\n message: error instanceof Error ? error.message : \"Unknown command execution error.\",\n },\n };\n dedupeCache.set(cacheKey, failure);\n return failure;\n }\n },\n });\n\n return {\n mode: \"host\",\n onCommand(name, handler) {\n assertMessageName(\"command\", name);\n commandHandlers.set(name, handler as CommandHandler);\n return () => {\n commandHandlers.delete(name);\n };\n },\n emitEvent(name, payload) {\n assertMessageName(\"event\", name);\n const validatedPayload = parsePayloadWithSchema(options.validation?.events?.[name], payload, {\n name,\n stage: \"event.emit\",\n });\n assertJsonPayload(\"event\", name, validatedPayload);\n hostServer.emitEvent(name, validatedPayload, options.name);\n },\n broadcast(name, payload) {\n assertMessageName(\"event\", name);\n const validatedPayload = parsePayloadWithSchema(options.validation?.events?.[name], payload, {\n name,\n stage: \"event.emit\",\n });\n assertJsonPayload(\"event\", name, validatedPayload);\n hostServer.emitEvent(name, validatedPayload, options.name);\n },\n close() {\n return hostServer.close().then(async () => {\n await runtimeHooks?.onClose?.();\n });\n },\n };\n}\n","import type { RuntimeSchema, SchemaValidationIssue } from \"../core/types\";\n\nexport interface SafeParseResultSuccess<T> {\n success: true;\n data: T;\n}\n\nexport interface SafeParseResultFailure {\n success: false;\n error: {\n message: string;\n issues?: SchemaValidationIssue[];\n };\n}\n\nexport type SafeParseResult<T> = SafeParseResultSuccess<T> | SafeParseResultFailure;\n\nexport interface SafeParseSchema<T> {\n safeParse: (value: unknown) => SafeParseResult<T>;\n}\n\nexport function fromSafeParseSchema<T>(schema: SafeParseSchema<T>): RuntimeSchema<T> {\n return {\n parse(value) {\n const result = schema.safeParse(value);\n if (result.success) {\n return result.data;\n }\n const error = new Error(result.error.message) as Error & { issues?: SchemaValidationIssue[] };\n if (result.error.issues) {\n error.issues = result.error.issues;\n }\n throw error;\n },\n };\n}\n","import type { RuntimeSchema, SchemaValidationIssue } from \"../core/types\";\nimport { fromSafeParseSchema } from \"./index\";\nimport type { ZodType } from \"zod\";\n\nfunction normalizeZodPath(path: ReadonlyArray<PropertyKey>): string {\n if (path.length === 0) {\n return \"\";\n }\n return path\n .filter((segment): segment is string | number => typeof segment === \"string\" || typeof segment === \"number\")\n .map((segment) => String(segment))\n .join(\".\");\n}\n\nexport function fromZodSchema<T>(schema: ZodType<T>): RuntimeSchema<T> {\n return fromSafeParseSchema<T>({\n safeParse(value) {\n const result = schema.safeParse(value);\n if (result.success) {\n return { success: true, data: result.data };\n }\n const issues: SchemaValidationIssue[] = result.error.issues.map((issue) => ({\n path: normalizeZodPath(issue.path),\n message: issue.message,\n }));\n return {\n success: false,\n error: {\n message: \"Schema validation failed.\",\n issues,\n },\n };\n },\n });\n}\n"],"mappings":"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","names":["import_ws","import_node_crypto","failure"]}
|
package/dist/index.mjs
CHANGED
|
@@ -110,6 +110,21 @@ function assertConsumerOptions(options) {
|
|
|
110
110
|
if (!isNonEmptyString(options.url)) {
|
|
111
111
|
throw new Error("Consumer mode requires `url`.");
|
|
112
112
|
}
|
|
113
|
+
let parsedUrl;
|
|
114
|
+
try {
|
|
115
|
+
parsedUrl = new URL(options.url);
|
|
116
|
+
} catch {
|
|
117
|
+
throw new Error("Consumer option `url` must be a valid URL.");
|
|
118
|
+
}
|
|
119
|
+
if (parsedUrl.protocol !== "ws:" && parsedUrl.protocol !== "wss:") {
|
|
120
|
+
throw new Error("Consumer option `url` must use `ws://` or `wss://`.");
|
|
121
|
+
}
|
|
122
|
+
const isLoopbackHost = parsedUrl.hostname === "localhost" || parsedUrl.hostname === "127.0.0.1" || parsedUrl.hostname === "::1";
|
|
123
|
+
if (parsedUrl.protocol === "ws:" && !isLoopbackHost && !options.allowInsecureWs) {
|
|
124
|
+
throw new Error(
|
|
125
|
+
"Insecure `ws://` is only allowed for loopback hosts by default. Use `wss://` or set `allowInsecureWs` to true."
|
|
126
|
+
);
|
|
127
|
+
}
|
|
113
128
|
if (!isNonEmptyString(options.secret)) {
|
|
114
129
|
throw new Error("Consumer mode requires `secret`.");
|
|
115
130
|
}
|
|
@@ -589,7 +604,7 @@ async function withTimeout(promise, timeoutMs, timeoutMessage = "Operation timed
|
|
|
589
604
|
resolve(value);
|
|
590
605
|
}).catch((error) => {
|
|
591
606
|
clearTimeout(timeout);
|
|
592
|
-
reject(error);
|
|
607
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
593
608
|
});
|
|
594
609
|
});
|
|
595
610
|
}
|
|
@@ -715,14 +730,25 @@ var HostWebSocketServer = class {
|
|
|
715
730
|
socket.close(CLOSE_AUTH_REQUIRED, "Authentication required.");
|
|
716
731
|
}
|
|
717
732
|
}, this.authTimeoutMs);
|
|
718
|
-
socket.on("message",
|
|
733
|
+
socket.on("message", (raw) => {
|
|
734
|
+
const serialized = typeof raw === "string" ? raw : Buffer.isBuffer(raw) ? raw.toString("utf8") : void 0;
|
|
735
|
+
if (!serialized) {
|
|
736
|
+
this.logger.warn("Invalid message payload from client.", { error: "Unsupported payload type." });
|
|
737
|
+
socket.close(CLOSE_INVALID_PAYLOAD, "Invalid payload.");
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
let parsed;
|
|
719
741
|
try {
|
|
720
|
-
|
|
721
|
-
await this.handleMessage(state, parsed);
|
|
742
|
+
parsed = parseEnvelope(serialized);
|
|
722
743
|
} catch (error) {
|
|
723
744
|
this.logger.warn("Invalid message payload from client.", { error: String(error) });
|
|
724
745
|
socket.close(CLOSE_INVALID_PAYLOAD, "Invalid payload.");
|
|
746
|
+
return;
|
|
725
747
|
}
|
|
748
|
+
void this.handleMessage(state, parsed).catch((error) => {
|
|
749
|
+
this.logger.warn("Invalid message payload from client.", { error: String(error) });
|
|
750
|
+
socket.close(CLOSE_INVALID_PAYLOAD, "Invalid payload.");
|
|
751
|
+
});
|
|
726
752
|
});
|
|
727
753
|
socket.on("close", () => {
|
|
728
754
|
clearTimeout(authTimer);
|
|
@@ -856,7 +882,7 @@ function createHostShardwire(options, runtimeHooks) {
|
|
|
856
882
|
const hostServer = new HostWebSocketServer({
|
|
857
883
|
options,
|
|
858
884
|
onCommandRequest: async (connection, payload, requestId, source) => {
|
|
859
|
-
const cacheKey = `${requestId}:${payload.name}`;
|
|
885
|
+
const cacheKey = `${connection.id}:${requestId}:${payload.name}`;
|
|
860
886
|
const cached = dedupeCache.get(cacheKey);
|
|
861
887
|
if (cached) {
|
|
862
888
|
return cached;
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/transport/ws/consumer-socket.ts","../src/utils/id.ts","../src/utils/backoff.ts","../src/utils/logger.ts","../src/core/protocol.ts","../src/runtime/validation.ts","../src/consumer/index.ts","../src/discord/client.ts","../src/runtime/reliability.ts","../src/transport/ws/host-server.ts","../src/runtime/security.ts","../src/host/index.ts","../src/schema/index.ts","../src/schema/zod.ts","../src/index.ts"],"sourcesContent":["import { WebSocket } from \"ws\";\n\nexport interface WebSocketLike {\n readyState: number;\n send(data: string): void;\n close(code?: number, reason?: string): void;\n on(event: \"open\", listener: () => void): void;\n on(event: \"message\", listener: (data: unknown) => void): void;\n on(event: \"close\", listener: () => void): void;\n on(event: \"error\", listener: (error: unknown) => void): void;\n once(event: \"close\", listener: () => void): void;\n}\n\nexport function createNodeWebSocket(url: string): WebSocketLike {\n return new WebSocket(url) as unknown as WebSocketLike;\n}\n","import { randomUUID } from \"node:crypto\";\n\nexport function createRequestId(): string {\n return randomUUID();\n}\n\nexport function createConnectionId(): string {\n return randomUUID();\n}\n","export interface BackoffConfig {\n initialDelayMs: number;\n maxDelayMs: number;\n jitter: boolean;\n}\n\nexport function getBackoffDelay(attempt: number, config: BackoffConfig): number {\n const base = Math.min(config.maxDelayMs, config.initialDelayMs * 2 ** attempt);\n if (!config.jitter) {\n return base;\n }\n const spread = Math.floor(base * 0.2);\n const min = Math.max(0, base - spread);\n const max = base + spread;\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n","import type { ShardwireLogger } from \"../core/types\";\n\nexport function withLogger(logger?: ShardwireLogger): Required<ShardwireLogger> {\n return {\n debug: logger?.debug ?? (() => undefined),\n info: logger?.info ?? (() => undefined),\n warn: logger?.warn ?? (() => undefined),\n error: logger?.error ?? (() => undefined),\n };\n}\n","import type { CommandResult } from \"./types\";\n\nexport const PROTOCOL_VERSION = 1 as const;\n\nexport type WireType =\n | \"auth.hello\"\n | \"auth.ok\"\n | \"auth.error\"\n | \"command.request\"\n | \"command.result\"\n | \"command.error\"\n | \"event.emit\"\n | \"ping\"\n | \"pong\";\n\nexport type WireEnvelope<TType extends WireType = WireType, TPayload = unknown> = {\n v: typeof PROTOCOL_VERSION;\n type: TType;\n ts: number;\n requestId?: string;\n source?: string;\n payload: TPayload;\n};\n\nexport interface AuthHelloPayload {\n secret: string;\n secretId?: string;\n clientName?: string;\n}\n\nexport interface AuthOkPayload {\n connectionId: string;\n}\n\nexport interface AuthErrorPayload {\n code: \"UNAUTHORIZED\";\n reason: \"unknown_secret_id\" | \"invalid_secret\";\n message: string;\n}\n\nexport interface CommandRequestPayload {\n name: string;\n data: unknown;\n}\n\nexport interface EventEmitPayload {\n name: string;\n data: unknown;\n}\n\nexport type CommandResultPayload = CommandResult;\n\nexport function makeEnvelope<TType extends WireType, TPayload>(\n type: TType,\n payload: TPayload,\n extras?: { requestId?: string; source?: string },\n): WireEnvelope<TType, TPayload> {\n const envelope: WireEnvelope<TType, TPayload> = {\n v: PROTOCOL_VERSION,\n type,\n ts: Date.now(),\n payload,\n };\n if (extras?.requestId) {\n envelope.requestId = extras.requestId;\n }\n if (extras?.source) {\n envelope.source = extras.source;\n }\n return envelope;\n}\n\nexport function parseEnvelope(raw: string): WireEnvelope {\n const parsed = JSON.parse(raw) as WireEnvelope;\n if (!parsed || parsed.v !== PROTOCOL_VERSION || typeof parsed.type !== \"string\") {\n throw new Error(\"Invalid wire envelope.\");\n }\n return parsed;\n}\n\nexport function stringifyEnvelope(envelope: WireEnvelope): string {\n return JSON.stringify(envelope);\n}\n","import type { ConsumerOptions, HostOptions, RuntimeSchema, SchemaValidationIssue } from \"../core/types\";\n\nexport class PayloadValidationError extends Error {\n constructor(\n message: string,\n public readonly details: {\n name: string;\n stage: \"command.request\" | \"command.response\" | \"event.emit\";\n issues?: SchemaValidationIssue[];\n },\n ) {\n super(message);\n this.name = \"PayloadValidationError\";\n }\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n\nfunction assertPositiveNumber(name: string, value: unknown): void {\n if (typeof value !== \"number\" || Number.isNaN(value) || value <= 0) {\n throw new Error(`${name} must be a positive number.`);\n }\n}\n\nexport function assertHostOptions(options: HostOptions<any, any>): void {\n if (!options.server) {\n throw new Error(\"Host mode requires a server configuration.\");\n }\n assertPositiveNumber(\"server.port\", options.server.port);\n if (!Array.isArray(options.server.secrets) || options.server.secrets.length === 0) {\n throw new Error(\"server.secrets must contain at least one secret.\");\n }\n for (const [index, secret] of options.server.secrets.entries()) {\n if (!isNonEmptyString(secret)) {\n throw new Error(`server.secrets[${index}] must be a non-empty string.`);\n }\n }\n if (\n options.server.primarySecretId !== undefined &&\n !options.server.secrets.some((_, index) => options.server.primarySecretId === `s${index}`)\n ) {\n throw new Error(\"server.primarySecretId must reference an existing secret id.\");\n }\n if (options.server.heartbeatMs !== undefined) {\n assertPositiveNumber(\"server.heartbeatMs\", options.server.heartbeatMs);\n }\n if (options.server.commandTimeoutMs !== undefined) {\n assertPositiveNumber(\"server.commandTimeoutMs\", options.server.commandTimeoutMs);\n }\n if (options.server.maxPayloadBytes !== undefined) {\n assertPositiveNumber(\"server.maxPayloadBytes\", options.server.maxPayloadBytes);\n }\n}\n\nexport function assertConsumerOptions(options: ConsumerOptions<any, any>): void {\n if (!isNonEmptyString(options.url)) {\n throw new Error(\"Consumer mode requires `url`.\");\n }\n if (!isNonEmptyString(options.secret)) {\n throw new Error(\"Consumer mode requires `secret`.\");\n }\n if (options.secretId !== undefined && !isNonEmptyString(options.secretId)) {\n throw new Error(\"Consumer option `secretId` must be a non-empty string.\");\n }\n if (options.clientName !== undefined && !isNonEmptyString(options.clientName)) {\n throw new Error(\"Consumer option `clientName` must be a non-empty string.\");\n }\n if (options.requestTimeoutMs !== undefined) {\n assertPositiveNumber(\"requestTimeoutMs\", options.requestTimeoutMs);\n }\n if (options.reconnect?.initialDelayMs !== undefined) {\n assertPositiveNumber(\"reconnect.initialDelayMs\", options.reconnect.initialDelayMs);\n }\n if (options.reconnect?.maxDelayMs !== undefined) {\n assertPositiveNumber(\"reconnect.maxDelayMs\", options.reconnect.maxDelayMs);\n }\n}\n\nexport function assertMessageName(kind: \"command\" | \"event\", name: string): void {\n if (!isNonEmptyString(name)) {\n throw new Error(`${kind} name must be a non-empty string.`);\n }\n}\n\nexport function assertJsonPayload(kind: \"command\" | \"event\", name: string, payload: unknown): void {\n try {\n JSON.stringify(payload);\n } catch {\n throw new Error(`${kind} \"${name}\" payload must be JSON-serializable.`);\n }\n}\n\nfunction normalizeSchemaIssues(error: unknown): SchemaValidationIssue[] | undefined {\n if (!error || typeof error !== \"object\") {\n return undefined;\n }\n const issues = (error as { issues?: unknown }).issues;\n if (!Array.isArray(issues)) {\n return undefined;\n }\n const normalized = issues\n .map((issue) => {\n if (!issue || typeof issue !== \"object\") {\n return null;\n }\n const message = (issue as { message?: unknown }).message;\n const rawPath = (issue as { path?: unknown }).path;\n if (typeof message !== \"string\") {\n return null;\n }\n const path =\n Array.isArray(rawPath) && rawPath.length > 0\n ? rawPath\n .map((segment) => (typeof segment === \"string\" || typeof segment === \"number\" ? String(segment) : \"\"))\n .filter(Boolean)\n .join(\".\")\n : \"\";\n return { path, message } satisfies SchemaValidationIssue;\n })\n .filter((issue): issue is SchemaValidationIssue => Boolean(issue));\n return normalized.length > 0 ? normalized : undefined;\n}\n\nexport function parsePayloadWithSchema<T>(\n schema: RuntimeSchema<T> | undefined,\n payload: unknown,\n context: {\n name: string;\n stage: \"command.request\" | \"command.response\" | \"event.emit\";\n },\n): T | unknown {\n if (!schema) {\n return payload;\n }\n try {\n return schema.parse(payload);\n } catch (error) {\n const message =\n error instanceof Error && error.message.trim().length > 0\n ? error.message\n : `Payload validation failed for ${context.stage} \"${context.name}\".`;\n const issues = normalizeSchemaIssues(error);\n throw new PayloadValidationError(message, {\n ...context,\n ...(issues ? { issues } : {}),\n });\n }\n}\n","import type {\n CommandFailure,\n CommandMap,\n CommandRequestOf,\n CommandResponseOf,\n CommandResult,\n ConsumerOptions,\n ConsumerShardwire,\n EventMap,\n EventMeta,\n} from \"../core/types\";\nimport { createNodeWebSocket, type WebSocketLike } from \"../transport/ws/consumer-socket\";\nimport { createRequestId } from \"../utils/id\";\nimport { getBackoffDelay } from \"../utils/backoff\";\nimport { withLogger } from \"../utils/logger\";\nimport {\n makeEnvelope,\n parseEnvelope,\n stringifyEnvelope,\n type AuthErrorPayload,\n type CommandResultPayload,\n type EventEmitPayload,\n} from \"../core/protocol\";\nimport { assertJsonPayload, assertMessageName } from \"../runtime/validation\";\n\ntype EventHandler = (payload: unknown, meta: EventMeta) => void;\n\ninterface PendingRequest {\n resolve: (value: CommandResult) => void;\n reject: (error: CommandRequestError) => void;\n timer: NodeJS.Timeout;\n}\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 10000;\n\nclass CommandRequestError extends Error {\n constructor(\n public readonly code: \"TIMEOUT\" | \"DISCONNECTED\" | \"UNAUTHORIZED\",\n message: string,\n ) {\n super(message);\n this.name = \"CommandRequestError\";\n }\n}\n\nexport function createConsumerShardwire<C extends CommandMap, E extends EventMap>(\n options: ConsumerOptions<C, E>,\n): ConsumerShardwire<C, E> {\n const logger = withLogger(options.logger);\n const reconnectEnabled = options.reconnect?.enabled ?? true;\n const initialDelayMs = options.reconnect?.initialDelayMs ?? 500;\n const maxDelayMs = options.reconnect?.maxDelayMs ?? 10000;\n const jitter = options.reconnect?.jitter ?? true;\n const requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n\n let socket: WebSocketLike | null = null;\n let isClosed = false;\n let isAuthed = false;\n let reconnectAttempts = 0;\n let reconnectTimer: NodeJS.Timeout | null = null;\n let connectPromise: Promise<void> | null = null;\n let connectResolve: (() => void) | null = null;\n let connectReject: ((error: Error) => void) | null = null;\n let authTimeoutTimer: NodeJS.Timeout | null = null;\n let currentConnectionId: string | null = null;\n\n const pendingRequests = new Map<string, PendingRequest>();\n const eventHandlers = new Map<string, Set<EventHandler>>();\n const connectedHandlers = new Set<(info: { connectionId: string; connectedAt: number }) => void>();\n const disconnectedHandlers = new Set<\n (info: { reason: string; at: number; willReconnect: boolean }) => void\n >();\n const reconnectingHandlers = new Set<(info: { attempt: number; delayMs: number; at: number }) => void>();\n\n function clearAuthTimeout(): void {\n if (authTimeoutTimer) {\n clearTimeout(authTimeoutTimer);\n authTimeoutTimer = null;\n }\n }\n\n function resolveConnect(): void {\n clearAuthTimeout();\n connectResolve?.();\n connectResolve = null;\n connectReject = null;\n connectPromise = null;\n }\n\n function rejectConnect(message: string): void {\n clearAuthTimeout();\n if (connectReject) {\n connectReject(new Error(message));\n }\n connectResolve = null;\n connectReject = null;\n connectPromise = null;\n }\n\n function sendRaw(data: string): void {\n if (!socket || socket.readyState !== 1) {\n throw new Error(\"Shardwire consumer is not connected.\");\n }\n socket.send(data);\n }\n\n function rejectAllPending(\n code: \"TIMEOUT\" | \"DISCONNECTED\" | \"UNAUTHORIZED\",\n reason: string,\n ): void {\n for (const [requestId, pending] of pendingRequests.entries()) {\n clearTimeout(pending.timer);\n pending.reject(new CommandRequestError(code, reason));\n pendingRequests.delete(requestId);\n }\n }\n\n function scheduleReconnect(): void {\n if (isClosed || !reconnectEnabled || reconnectTimer) {\n return;\n }\n const delay = getBackoffDelay(reconnectAttempts, { initialDelayMs, maxDelayMs, jitter });\n reconnectAttempts += 1;\n for (const handler of reconnectingHandlers) {\n try {\n handler({ attempt: reconnectAttempts, delayMs: delay, at: Date.now() });\n } catch (error) {\n logger.warn(\"Reconnect handler threw an error.\", { error: String(error) });\n }\n }\n reconnectTimer = setTimeout(() => {\n reconnectTimer = null;\n void connect().catch((error) => {\n logger.warn(\"Reconnect attempt failed.\", { error: String(error) });\n });\n }, delay);\n }\n\n function handleEvent(name: string, payload: unknown, meta: EventMeta): void {\n const handlers = eventHandlers.get(name);\n if (!handlers || handlers.size === 0) {\n return;\n }\n for (const handler of handlers) {\n try {\n handler(payload, meta);\n } catch (error) {\n logger.warn(\"Event handler threw an error.\", { name, error: String(error) });\n }\n }\n }\n\n async function connect(): Promise<void> {\n if (isClosed) {\n return;\n }\n if (socket && socket.readyState === 1 && isAuthed) {\n return;\n }\n if (connectPromise) {\n return connectPromise;\n }\n\n connectPromise = new Promise<void>((resolve, reject) => {\n connectResolve = resolve;\n connectReject = reject;\n });\n\n socket = options.webSocketFactory\n ? (options.webSocketFactory(options.url) as WebSocketLike)\n : createNodeWebSocket(options.url);\n\n socket.on(\"open\", () => {\n reconnectAttempts = 0;\n isAuthed = false;\n currentConnectionId = null;\n const hello = makeEnvelope(\"auth.hello\", {\n secret: options.secret,\n secretId: options.secretId,\n clientName: options.clientName,\n });\n socket?.send(stringifyEnvelope(hello));\n authTimeoutTimer = setTimeout(() => {\n if (!isAuthed) {\n rejectConnect(\"Shardwire auth timed out.\");\n socket?.close();\n }\n }, requestTimeoutMs);\n });\n\n socket.on(\"message\", (raw) => {\n try {\n const serialized = typeof raw === \"string\" ? raw : String(raw);\n const envelope = parseEnvelope(serialized);\n switch (envelope.type) {\n case \"auth.ok\":\n isAuthed = true;\n if (\n envelope.payload &&\n typeof envelope.payload === \"object\" &&\n \"connectionId\" in envelope.payload &&\n typeof (envelope.payload as { connectionId?: unknown }).connectionId === \"string\"\n ) {\n currentConnectionId = (envelope.payload as { connectionId: string }).connectionId;\n }\n if (currentConnectionId) {\n for (const handler of connectedHandlers) {\n try {\n handler({ connectionId: currentConnectionId, connectedAt: Date.now() });\n } catch (error) {\n logger.warn(\"Connected handler threw an error.\", { error: String(error) });\n }\n }\n }\n resolveConnect();\n break;\n case \"auth.error\": {\n const payload = envelope.payload as AuthErrorPayload;\n logger.error(\"Authentication failed for consumer.\", {\n code: payload.code,\n message: payload.message,\n });\n rejectConnect(payload.message);\n rejectAllPending(\"UNAUTHORIZED\", \"Shardwire authentication failed.\");\n socket?.close();\n break;\n }\n case \"command.result\":\n case \"command.error\": {\n const requestId = envelope.requestId;\n if (!requestId) {\n return;\n }\n const pending = pendingRequests.get(requestId);\n if (!pending) {\n return;\n }\n clearTimeout(pending.timer);\n pending.resolve(envelope.payload as CommandResultPayload);\n pendingRequests.delete(requestId);\n break;\n }\n case \"event.emit\": {\n const payload = envelope.payload as EventEmitPayload;\n const meta: EventMeta = { ts: envelope.ts };\n if (envelope.source) {\n meta.source = envelope.source;\n }\n handleEvent(payload.name, payload.data, meta);\n break;\n }\n case \"ping\":\n sendRaw(stringifyEnvelope(makeEnvelope(\"pong\", {})));\n break;\n default:\n break;\n }\n } catch (error) {\n logger.warn(\"Failed to parse consumer message.\", { error: String(error) });\n }\n });\n\n socket.on(\"close\", () => {\n const willReconnect = !isClosed && reconnectEnabled;\n rejectConnect(\"Shardwire connection closed.\");\n isAuthed = false;\n currentConnectionId = null;\n rejectAllPending(\"DISCONNECTED\", \"Shardwire connection closed before command completed.\");\n for (const handler of disconnectedHandlers) {\n try {\n handler({\n reason: \"Shardwire connection closed.\",\n at: Date.now(),\n willReconnect,\n });\n } catch (error) {\n logger.warn(\"Disconnected handler threw an error.\", { error: String(error) });\n }\n }\n if (!isClosed) {\n scheduleReconnect();\n }\n });\n\n socket.on(\"error\", (error) => {\n logger.warn(\"Consumer socket error.\", { error: String(error) });\n });\n\n return connectPromise;\n }\n\n void connect().catch((error) => {\n logger.warn(\"Initial connection attempt failed.\", { error: String(error) });\n });\n\n return {\n mode: \"consumer\",\n async send<K extends keyof C & string>(\n name: K,\n payload: CommandRequestOf<C[K]>,\n sendOptions?: { timeoutMs?: number; requestId?: string },\n ): Promise<CommandResult<CommandResponseOf<C[K]>>> {\n assertMessageName(\"command\", name);\n assertJsonPayload(\"command\", name, payload);\n if (!isAuthed) {\n try {\n await connect();\n } catch (error) {\n return {\n ok: false,\n requestId: sendOptions?.requestId ?? \"unknown\",\n ts: Date.now(),\n error: {\n code: \"UNAUTHORIZED\",\n message: error instanceof Error ? error.message : \"Failed to authenticate.\",\n },\n } satisfies CommandFailure;\n }\n }\n if (!socket || socket.readyState !== 1) {\n return {\n ok: false,\n requestId: sendOptions?.requestId ?? \"unknown\",\n ts: Date.now(),\n error: {\n code: \"DISCONNECTED\",\n message: \"Not connected to Shardwire host.\",\n },\n } satisfies CommandFailure;\n }\n\n const requestId = sendOptions?.requestId ?? createRequestId();\n const timeoutMs = sendOptions?.timeoutMs ?? requestTimeoutMs;\n\n const promise = new Promise<CommandResult>((resolve, reject) => {\n const timer = setTimeout(() => {\n pendingRequests.delete(requestId);\n reject(new CommandRequestError(\"TIMEOUT\", `Command \"${name}\" timed out after ${timeoutMs}ms.`));\n }, timeoutMs);\n\n pendingRequests.set(requestId, {\n resolve,\n reject: (error) => reject(error),\n timer,\n });\n });\n\n sendRaw(\n stringifyEnvelope(\n makeEnvelope(\n \"command.request\",\n {\n name,\n data: payload,\n },\n { requestId },\n ),\n ),\n );\n\n try {\n return (await promise) as CommandResult<CommandResponseOf<C[K]>>;\n } catch (error) {\n const failureCode =\n error instanceof CommandRequestError\n ? error.code\n : !socket || socket.readyState !== 1\n ? \"DISCONNECTED\"\n : \"TIMEOUT\";\n return {\n ok: false,\n requestId,\n ts: Date.now(),\n error: {\n code: failureCode,\n message: error instanceof Error ? error.message : \"Command request failed.\",\n },\n } satisfies CommandFailure;\n }\n },\n on(name, handler) {\n assertMessageName(\"event\", name);\n const casted = handler as EventHandler;\n const existing = eventHandlers.get(name);\n if (existing) {\n existing.add(casted);\n } else {\n eventHandlers.set(name, new Set<EventHandler>([casted]));\n }\n return () => {\n const handlers = eventHandlers.get(name);\n if (!handlers) {\n return;\n }\n handlers.delete(casted);\n if (handlers.size === 0) {\n eventHandlers.delete(name);\n }\n };\n },\n off(name, handler) {\n assertMessageName(\"event\", name);\n const handlers = eventHandlers.get(name);\n if (!handlers) {\n return;\n }\n handlers.delete(handler as EventHandler);\n if (handlers.size === 0) {\n eventHandlers.delete(name);\n }\n },\n onConnected(handler) {\n connectedHandlers.add(handler);\n return () => {\n connectedHandlers.delete(handler);\n };\n },\n onDisconnected(handler) {\n disconnectedHandlers.add(handler);\n return () => {\n disconnectedHandlers.delete(handler);\n };\n },\n onReconnecting(handler) {\n reconnectingHandlers.add(handler);\n return () => {\n reconnectingHandlers.delete(handler);\n };\n },\n ready() {\n return connect();\n },\n connected() {\n return Boolean(socket && socket.readyState === 1 && isAuthed);\n },\n connectionId() {\n return currentConnectionId;\n },\n async close() {\n isClosed = true;\n isAuthed = false;\n currentConnectionId = null;\n rejectConnect(\"Shardwire consumer has been closed.\");\n if (reconnectTimer) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n }\n rejectAllPending(\"DISCONNECTED\", \"Shardwire consumer has been closed.\");\n if (!socket) {\n return;\n }\n await new Promise<void>((resolve) => {\n const current = socket;\n if (!current) {\n resolve();\n return;\n }\n current.once(\"close\", () => resolve());\n current.close();\n });\n socket = null;\n },\n };\n}\n","import type { DiscordClientLike, HostOptions } from \"../core/types\";\n\ninterface OwnedClientState {\n client?: DiscordClientLike;\n owned: boolean;\n}\n\nexport async function resolveDiscordClient<C extends Record<string, unknown>, E extends Record<string, unknown>>(\n options: HostOptions<C, E>,\n): Promise<OwnedClientState> {\n if (options.client) {\n return { client: options.client, owned: false };\n }\n\n if (!options.token) {\n return { owned: false };\n }\n\n const discordModule = await import(\"discord.js\");\n const created = new discordModule.Client({\n intents: [],\n });\n await created.login(options.token);\n return { client: created as unknown as DiscordClientLike, owned: true };\n}\n","export async function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n timeoutMessage = \"Operation timed out.\",\n): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(timeoutMessage));\n }, timeoutMs);\n\n promise\n .then((value) => {\n clearTimeout(timeout);\n resolve(value);\n })\n .catch((error) => {\n clearTimeout(timeout);\n reject(error);\n });\n });\n}\n\nexport class DedupeCache<T> {\n private readonly cache = new Map<string, { value: T; expiresAt: number }>();\n\n constructor(private readonly ttlMs: number) {}\n\n get(key: string): T | undefined {\n const entry = this.cache.get(key);\n if (!entry) {\n return undefined;\n }\n if (entry.expiresAt <= Date.now()) {\n this.cache.delete(key);\n return undefined;\n }\n return entry.value;\n }\n\n set(key: string, value: T): void {\n this.cache.set(key, { value, expiresAt: Date.now() + this.ttlMs });\n }\n}\n","import { WebSocketServer, type WebSocket } from \"ws\";\nimport type { IncomingMessage } from \"node:http\";\nimport {\n makeEnvelope,\n parseEnvelope,\n stringifyEnvelope,\n type AuthHelloPayload,\n type CommandRequestPayload,\n type EventEmitPayload,\n type WireEnvelope,\n} from \"../../core/protocol\";\nimport type { CommandFailure, CommandSuccess, HostOptions, ShardwireLogger } from \"../../core/types\";\nimport { withLogger } from \"../../utils/logger\";\nimport { createConnectionId } from \"../../utils/id\";\nimport type { HostConnectionState } from \"../../runtime/state\";\nimport { getSecretId, isSecretValid } from \"../../runtime/security\";\n\nconst CLOSE_AUTH_REQUIRED = 4001;\nconst CLOSE_AUTH_FAILED = 4003;\nconst CLOSE_INVALID_PAYLOAD = 4004;\n\ninterface HostServerConfig {\n options: HostOptions<any, any>;\n onCommandRequest: (\n connection: HostConnectionState,\n payload: CommandRequestPayload,\n requestId: string,\n source?: string,\n ) => Promise<CommandSuccess | CommandFailure>;\n}\n\nexport class HostWebSocketServer {\n private readonly wss: WebSocketServer;\n private readonly connections = new Map<WebSocket, HostConnectionState>();\n private readonly logger: Required<ShardwireLogger>;\n private readonly heartbeatMs: number;\n private readonly authTimeoutMs = 5000;\n private readonly interval: NodeJS.Timeout;\n\n constructor(private readonly config: HostServerConfig) {\n const serverConfig = config.options.server;\n this.heartbeatMs = serverConfig.heartbeatMs ?? 30000;\n this.logger = withLogger(config.options.logger);\n\n this.wss = new WebSocketServer({\n host: serverConfig.host,\n port: serverConfig.port,\n path: serverConfig.path ?? \"/shardwire\",\n maxPayload: serverConfig.maxPayloadBytes ?? 65536,\n });\n\n this.wss.on(\"connection\", (socket, request) => this.handleConnection(socket, request));\n this.wss.on(\"error\", (error) =>\n this.logger.error(\"Shardwire host server error.\", { error: String(error) }),\n );\n\n this.interval = setInterval(() => {\n this.checkHeartbeats();\n }, this.heartbeatMs);\n }\n\n emitEvent(name: string, data: unknown, source?: string): void {\n const envelope = makeEnvelope(\n \"event.emit\",\n { name, data } satisfies EventEmitPayload,\n source ? { source } : undefined,\n );\n const raw = stringifyEnvelope(envelope);\n\n for (const state of this.connections.values()) {\n if (!state.authenticated) {\n continue;\n }\n this.safeSend(state.socket, raw);\n }\n }\n\n async close(): Promise<void> {\n clearInterval(this.interval);\n for (const connection of this.connections.values()) {\n connection.socket.close();\n }\n this.connections.clear();\n await new Promise<void>((resolve, reject) => {\n this.wss.close((error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n }\n\n private handleConnection(socket: WebSocket, request: IncomingMessage): void {\n const allowlist = this.config.options.server.corsOrigins;\n if (allowlist && allowlist.length > 0) {\n const origin = request.headers.origin;\n if (!origin || !allowlist.includes(origin)) {\n socket.close(CLOSE_AUTH_FAILED, \"Origin not allowed.\");\n return;\n }\n }\n\n const state: HostConnectionState = {\n id: createConnectionId(),\n socket,\n authenticated: false,\n lastHeartbeatAt: Date.now(),\n };\n this.connections.set(socket, state);\n\n const authTimer = setTimeout(() => {\n if (!state.authenticated) {\n socket.close(CLOSE_AUTH_REQUIRED, \"Authentication required.\");\n }\n }, this.authTimeoutMs);\n\n socket.on(\"message\", async (raw) => {\n try {\n const parsed = parseEnvelope(raw.toString());\n await this.handleMessage(state, parsed);\n } catch (error) {\n this.logger.warn(\"Invalid message payload from client.\", { error: String(error) });\n socket.close(CLOSE_INVALID_PAYLOAD, \"Invalid payload.\");\n }\n });\n\n socket.on(\"close\", () => {\n clearTimeout(authTimer);\n this.connections.delete(socket);\n });\n\n socket.on(\"error\", (error) =>\n this.logger.warn(\"Socket error.\", { connectionId: state.id, error: String(error) }),\n );\n }\n\n private async handleMessage(state: HostConnectionState, envelope: WireEnvelope): Promise<void> {\n if (envelope.type === \"ping\") {\n state.lastHeartbeatAt = Date.now();\n this.safeSend(state.socket, stringifyEnvelope(makeEnvelope(\"pong\", {})));\n return;\n }\n if (envelope.type === \"pong\") {\n state.lastHeartbeatAt = Date.now();\n return;\n }\n\n if (!state.authenticated) {\n if (envelope.type !== \"auth.hello\") {\n state.socket.close(CLOSE_AUTH_REQUIRED, \"Authentication required.\");\n return;\n }\n\n const payload = envelope.payload as AuthHelloPayload;\n const providedSecret = payload?.secret;\n const knownSecrets = this.config.options.server.secrets;\n const secretId = payload?.secretId;\n let authReason: \"unknown_secret_id\" | \"invalid_secret\" | null = null;\n\n if (!providedSecret) {\n authReason = \"invalid_secret\";\n } else if (secretId) {\n const secretIndex = knownSecrets.findIndex((_, index) => getSecretId(index) === secretId);\n if (secretIndex < 0) {\n authReason = \"unknown_secret_id\";\n } else {\n const expectedSecret = knownSecrets[secretIndex];\n if (!expectedSecret || !isSecretValid(providedSecret, expectedSecret)) {\n authReason = \"invalid_secret\";\n }\n }\n } else if (!knownSecrets.some((secret) => isSecretValid(providedSecret, secret))) {\n authReason = \"invalid_secret\";\n }\n\n if (authReason) {\n this.safeSend(\n state.socket,\n stringifyEnvelope(\n makeEnvelope(\"auth.error\", {\n code: \"UNAUTHORIZED\",\n reason: authReason,\n message: \"Authentication failed.\",\n }),\n ),\n );\n state.socket.close(CLOSE_AUTH_FAILED, \"Invalid secret.\");\n return;\n }\n\n state.authenticated = true;\n state.lastHeartbeatAt = Date.now();\n if (payload.clientName) {\n state.clientName = payload.clientName;\n }\n this.safeSend(\n state.socket,\n stringifyEnvelope(makeEnvelope(\"auth.ok\", { connectionId: state.id })),\n );\n return;\n }\n\n if (envelope.type === \"command.request\") {\n const payload = envelope.payload as CommandRequestPayload;\n if (!envelope.requestId || !payload?.name) {\n const invalid: CommandFailure = {\n ok: false,\n requestId: envelope.requestId ?? \"unknown\",\n ts: Date.now(),\n error: {\n code: \"VALIDATION_ERROR\",\n message: \"Invalid command request envelope.\",\n },\n };\n this.safeSend(\n state.socket,\n stringifyEnvelope(makeEnvelope(\"command.error\", invalid, { requestId: invalid.requestId })),\n );\n return;\n }\n\n const response = await this.config.onCommandRequest(\n state,\n payload,\n envelope.requestId,\n envelope.source,\n );\n const responseType = response.ok ? \"command.result\" : \"command.error\";\n this.safeSend(\n state.socket,\n stringifyEnvelope(makeEnvelope(responseType, response, { requestId: response.requestId })),\n );\n return;\n }\n }\n\n private checkHeartbeats(): void {\n const now = Date.now();\n const threshold = this.heartbeatMs * 2;\n\n for (const state of this.connections.values()) {\n if (!state.authenticated) {\n continue;\n }\n\n if (now - state.lastHeartbeatAt > threshold) {\n state.socket.terminate();\n this.connections.delete(state.socket);\n continue;\n }\n\n this.safeSend(state.socket, stringifyEnvelope(makeEnvelope(\"ping\", {})));\n }\n }\n\n private safeSend(socket: WebSocket, payload: string): void {\n if (socket.readyState === 1) {\n socket.send(payload);\n }\n }\n}\n","import { timingSafeEqual } from \"node:crypto\";\n\nexport function isSecretValid(provided: string, expected: string): boolean {\n const providedBuffer = Buffer.from(provided);\n const expectedBuffer = Buffer.from(expected);\n\n if (providedBuffer.length !== expectedBuffer.length) {\n return false;\n }\n\n return timingSafeEqual(providedBuffer, expectedBuffer);\n}\n\nexport function getSecretId(secretIndex: number): string {\n return `s${secretIndex}`;\n}\n","import type {\n CommandContext,\n CommandFailure,\n CommandMap,\n CommandSuccess,\n EventMap,\n HostOptions,\n HostShardwire,\n} from \"../core/types\";\nimport { withTimeout, DedupeCache } from \"../runtime/reliability\";\nimport type { CommandHandler } from \"../runtime/state\";\nimport { HostWebSocketServer } from \"../transport/ws/host-server\";\nimport {\n assertJsonPayload,\n assertMessageName,\n parsePayloadWithSchema,\n PayloadValidationError,\n} from \"../runtime/validation\";\n\nconst DEFAULT_COMMAND_TIMEOUT_MS = 10000;\n\nexport function createHostShardwire<C extends CommandMap, E extends EventMap>(\n options: HostOptions<C, E>,\n runtimeHooks?: {\n onClose?: () => Promise<void> | void;\n },\n): HostShardwire<C, E> {\n const commandHandlers = new Map<string, CommandHandler>();\n const commandTimeoutMs = options.server.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n const dedupeCache = new DedupeCache<CommandSuccess | CommandFailure>(commandTimeoutMs * 2);\n\n const hostServer = new HostWebSocketServer({\n options,\n onCommandRequest: async (connection, payload, requestId, source) => {\n const cacheKey = `${requestId}:${payload.name}`;\n const cached = dedupeCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n const handler = commandHandlers.get(payload.name);\n if (!handler) {\n const failure: CommandFailure = {\n ok: false,\n requestId,\n ts: Date.now(),\n error: {\n code: \"COMMAND_NOT_FOUND\",\n message: `No command handler registered for \"${payload.name}\".`,\n },\n };\n dedupeCache.set(cacheKey, failure);\n return failure;\n }\n\n const context: CommandContext = {\n requestId,\n connectionId: connection.id,\n receivedAt: Date.now(),\n };\n if (source) {\n context.source = source;\n }\n\n try {\n const commandValidation = options.validation?.commands?.[payload.name];\n const validatedRequest = parsePayloadWithSchema(commandValidation?.request, payload.data, {\n name: payload.name,\n stage: \"command.request\",\n });\n\n const maybePromise = Promise.resolve(handler(validatedRequest, context));\n const value = await withTimeout(\n maybePromise,\n commandTimeoutMs,\n `Command \"${payload.name}\" timed out after ${commandTimeoutMs}ms.`,\n );\n const validatedResponse = parsePayloadWithSchema(commandValidation?.response, value, {\n name: payload.name,\n stage: \"command.response\",\n });\n const success: CommandSuccess = {\n ok: true,\n requestId,\n ts: Date.now(),\n data: validatedResponse,\n };\n dedupeCache.set(cacheKey, success);\n return success;\n } catch (error) {\n if (error instanceof PayloadValidationError) {\n const failure: CommandFailure = {\n ok: false,\n requestId,\n ts: Date.now(),\n error: {\n code: \"VALIDATION_ERROR\",\n message: error.message,\n details: error.details,\n },\n };\n dedupeCache.set(cacheKey, failure);\n return failure;\n }\n const isTimeout = error instanceof Error && /timed out/i.test(error.message);\n const failure: CommandFailure = {\n ok: false,\n requestId,\n ts: Date.now(),\n error: {\n code: isTimeout ? \"TIMEOUT\" : \"INTERNAL_ERROR\",\n message: error instanceof Error ? error.message : \"Unknown command execution error.\",\n },\n };\n dedupeCache.set(cacheKey, failure);\n return failure;\n }\n },\n });\n\n return {\n mode: \"host\",\n onCommand(name, handler) {\n assertMessageName(\"command\", name);\n commandHandlers.set(name, handler as CommandHandler);\n return () => {\n commandHandlers.delete(name);\n };\n },\n emitEvent(name, payload) {\n assertMessageName(\"event\", name);\n const validatedPayload = parsePayloadWithSchema(options.validation?.events?.[name], payload, {\n name,\n stage: \"event.emit\",\n });\n assertJsonPayload(\"event\", name, validatedPayload);\n hostServer.emitEvent(name, validatedPayload, options.name);\n },\n broadcast(name, payload) {\n assertMessageName(\"event\", name);\n const validatedPayload = parsePayloadWithSchema(options.validation?.events?.[name], payload, {\n name,\n stage: \"event.emit\",\n });\n assertJsonPayload(\"event\", name, validatedPayload);\n hostServer.emitEvent(name, validatedPayload, options.name);\n },\n close() {\n return hostServer.close().then(async () => {\n await runtimeHooks?.onClose?.();\n });\n },\n };\n}\n","import type { RuntimeSchema, SchemaValidationIssue } from \"../core/types\";\n\nexport interface SafeParseResultSuccess<T> {\n success: true;\n data: T;\n}\n\nexport interface SafeParseResultFailure {\n success: false;\n error: {\n message: string;\n issues?: SchemaValidationIssue[];\n };\n}\n\nexport type SafeParseResult<T> = SafeParseResultSuccess<T> | SafeParseResultFailure;\n\nexport interface SafeParseSchema<T> {\n safeParse: (value: unknown) => SafeParseResult<T>;\n}\n\nexport function fromSafeParseSchema<T>(schema: SafeParseSchema<T>): RuntimeSchema<T> {\n return {\n parse(value) {\n const result = schema.safeParse(value);\n if (result.success) {\n return result.data;\n }\n const error = new Error(result.error.message) as Error & { issues?: SchemaValidationIssue[] };\n if (result.error.issues) {\n error.issues = result.error.issues;\n }\n throw error;\n },\n };\n}\n","import type { RuntimeSchema, SchemaValidationIssue } from \"../core/types\";\nimport { fromSafeParseSchema } from \"./index\";\nimport type { ZodType } from \"zod\";\n\nfunction normalizeZodPath(path: ReadonlyArray<PropertyKey>): string {\n if (path.length === 0) {\n return \"\";\n }\n return path\n .filter((segment): segment is string | number => typeof segment === \"string\" || typeof segment === \"number\")\n .map((segment) => String(segment))\n .join(\".\");\n}\n\nexport function fromZodSchema<T>(schema: ZodType<T>): RuntimeSchema<T> {\n return fromSafeParseSchema<T>({\n safeParse(value) {\n const result = schema.safeParse(value);\n if (result.success) {\n return { success: true, data: result.data };\n }\n const issues: SchemaValidationIssue[] = result.error.issues.map((issue) => ({\n path: normalizeZodPath(issue.path),\n message: issue.message,\n }));\n return {\n success: false,\n error: {\n message: \"Schema validation failed.\",\n issues,\n },\n };\n },\n });\n}\n","import { createConsumerShardwire } from \"./consumer\";\nimport { resolveDiscordClient } from \"./discord/client\";\nimport { createHostShardwire } from \"./host\";\nimport { assertConsumerOptions, assertHostOptions } from \"./runtime/validation\";\nimport type {\n CommandMap,\n ConsumerOptions,\n ConsumerShardwire,\n EventMap,\n HostOptions,\n HostShardwire,\n} from \"./core/types\";\n\nfunction isHostOptions<C extends CommandMap, E extends EventMap>(\n options: HostOptions<C, E> | ConsumerOptions<C, E>,\n): options is HostOptions<C, E> {\n return \"server\" in options;\n}\n\nexport function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(\n options: HostOptions<C, E>,\n): HostShardwire<C, E>;\nexport function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(\n options: ConsumerOptions<C, E>,\n): ConsumerShardwire<C, E>;\nexport function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(\n options: HostOptions<C, E> | ConsumerOptions<C, E>,\n): HostShardwire<C, E> | ConsumerShardwire<C, E> {\n if (!isHostOptions(options)) {\n assertConsumerOptions(options);\n return createConsumerShardwire<C, E>(options);\n }\n assertHostOptions(options);\n\n let ownedClientPromise: Promise<{ destroy: () => void } | undefined> | undefined;\n\n if (!options.client && options.token) {\n ownedClientPromise = resolveDiscordClient(options)\n .then((state) => {\n if (!state.owned || !state.client) {\n return undefined;\n }\n return {\n destroy: () => state.client?.destroy(),\n };\n })\n .catch((error) => {\n options.logger?.error?.(\"Failed to initialize discord.js client from token.\", {\n error: String(error),\n });\n return undefined;\n });\n }\n\n return createHostShardwire<C, E>(options, {\n onClose: async () => {\n const owned = await ownedClientPromise;\n owned?.destroy();\n },\n });\n}\n\nexport { fromSafeParseSchema } from \"./schema\";\nexport { fromZodSchema } from \"./schema/zod\";\n\nexport type {\n CommandContext,\n CommandFailure,\n CommandMap,\n CommandRequestOf,\n CommandResult,\n CommandResponseOf,\n CommandSchema,\n CommandSuccess,\n ConsumerOptions,\n ConsumerShardwire,\n CreateShardwire,\n DiscordClientLike,\n EventMap,\n EventMeta,\n HostOptions,\n HostShardwire,\n RuntimeSchema,\n SchemaValidationIssue,\n ShardwireLogger,\n Unsubscribe,\n} from \"./core/types\";\n"],"mappings":"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","names":["failure"]}
|
|
1
|
+
{"version":3,"sources":["../src/transport/ws/consumer-socket.ts","../src/utils/id.ts","../src/utils/backoff.ts","../src/utils/logger.ts","../src/core/protocol.ts","../src/runtime/validation.ts","../src/consumer/index.ts","../src/discord/client.ts","../src/runtime/reliability.ts","../src/transport/ws/host-server.ts","../src/runtime/security.ts","../src/host/index.ts","../src/schema/index.ts","../src/schema/zod.ts","../src/index.ts"],"sourcesContent":["import { WebSocket } from \"ws\";\n\nexport interface WebSocketLike {\n readyState: number;\n send(data: string): void;\n close(code?: number, reason?: string): void;\n on(event: \"open\", listener: () => void): void;\n on(event: \"message\", listener: (data: unknown) => void): void;\n on(event: \"close\", listener: () => void): void;\n on(event: \"error\", listener: (error: unknown) => void): void;\n once(event: \"close\", listener: () => void): void;\n}\n\nexport function createNodeWebSocket(url: string): WebSocketLike {\n return new WebSocket(url) as unknown as WebSocketLike;\n}\n","import { randomUUID } from \"node:crypto\";\n\nexport function createRequestId(): string {\n return randomUUID();\n}\n\nexport function createConnectionId(): string {\n return randomUUID();\n}\n","export interface BackoffConfig {\n initialDelayMs: number;\n maxDelayMs: number;\n jitter: boolean;\n}\n\nexport function getBackoffDelay(attempt: number, config: BackoffConfig): number {\n const base = Math.min(config.maxDelayMs, config.initialDelayMs * 2 ** attempt);\n if (!config.jitter) {\n return base;\n }\n const spread = Math.floor(base * 0.2);\n const min = Math.max(0, base - spread);\n const max = base + spread;\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n","import type { ShardwireLogger } from \"../core/types\";\n\nexport function withLogger(logger?: ShardwireLogger): Required<ShardwireLogger> {\n return {\n debug: logger?.debug ?? (() => undefined),\n info: logger?.info ?? (() => undefined),\n warn: logger?.warn ?? (() => undefined),\n error: logger?.error ?? (() => undefined),\n };\n}\n","import type { CommandResult } from \"./types\";\n\nexport const PROTOCOL_VERSION = 1 as const;\n\nexport type WireType =\n | \"auth.hello\"\n | \"auth.ok\"\n | \"auth.error\"\n | \"command.request\"\n | \"command.result\"\n | \"command.error\"\n | \"event.emit\"\n | \"ping\"\n | \"pong\";\n\nexport type WireEnvelope<TType extends WireType = WireType, TPayload = unknown> = {\n v: typeof PROTOCOL_VERSION;\n type: TType;\n ts: number;\n requestId?: string;\n source?: string;\n payload: TPayload;\n};\n\nexport interface AuthHelloPayload {\n secret: string;\n secretId?: string;\n clientName?: string;\n}\n\nexport interface AuthOkPayload {\n connectionId: string;\n}\n\nexport interface AuthErrorPayload {\n code: \"UNAUTHORIZED\";\n reason: \"unknown_secret_id\" | \"invalid_secret\";\n message: string;\n}\n\nexport interface CommandRequestPayload {\n name: string;\n data: unknown;\n}\n\nexport interface EventEmitPayload {\n name: string;\n data: unknown;\n}\n\nexport type CommandResultPayload = CommandResult;\n\nexport function makeEnvelope<TType extends WireType, TPayload>(\n type: TType,\n payload: TPayload,\n extras?: { requestId?: string; source?: string },\n): WireEnvelope<TType, TPayload> {\n const envelope: WireEnvelope<TType, TPayload> = {\n v: PROTOCOL_VERSION,\n type,\n ts: Date.now(),\n payload,\n };\n if (extras?.requestId) {\n envelope.requestId = extras.requestId;\n }\n if (extras?.source) {\n envelope.source = extras.source;\n }\n return envelope;\n}\n\nexport function parseEnvelope(raw: string): WireEnvelope {\n const parsed = JSON.parse(raw) as WireEnvelope;\n if (!parsed || parsed.v !== PROTOCOL_VERSION || typeof parsed.type !== \"string\") {\n throw new Error(\"Invalid wire envelope.\");\n }\n return parsed;\n}\n\nexport function stringifyEnvelope(envelope: WireEnvelope): string {\n return JSON.stringify(envelope);\n}\n","import type { ConsumerOptions, HostOptions, RuntimeSchema, SchemaValidationIssue } from \"../core/types\";\n\nexport class PayloadValidationError extends Error {\n constructor(\n message: string,\n public readonly details: {\n name: string;\n stage: \"command.request\" | \"command.response\" | \"event.emit\";\n issues?: SchemaValidationIssue[];\n },\n ) {\n super(message);\n this.name = \"PayloadValidationError\";\n }\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n\nfunction assertPositiveNumber(name: string, value: unknown): void {\n if (typeof value !== \"number\" || Number.isNaN(value) || value <= 0) {\n throw new Error(`${name} must be a positive number.`);\n }\n}\n\nexport function assertHostOptions(options: HostOptions<Record<string, unknown>, Record<string, unknown>>): void {\n if (!options.server) {\n throw new Error(\"Host mode requires a server configuration.\");\n }\n assertPositiveNumber(\"server.port\", options.server.port);\n if (!Array.isArray(options.server.secrets) || options.server.secrets.length === 0) {\n throw new Error(\"server.secrets must contain at least one secret.\");\n }\n for (const [index, secret] of options.server.secrets.entries()) {\n if (!isNonEmptyString(secret)) {\n throw new Error(`server.secrets[${index}] must be a non-empty string.`);\n }\n }\n if (\n options.server.primarySecretId !== undefined &&\n !options.server.secrets.some((_, index) => options.server.primarySecretId === `s${index}`)\n ) {\n throw new Error(\"server.primarySecretId must reference an existing secret id.\");\n }\n if (options.server.heartbeatMs !== undefined) {\n assertPositiveNumber(\"server.heartbeatMs\", options.server.heartbeatMs);\n }\n if (options.server.commandTimeoutMs !== undefined) {\n assertPositiveNumber(\"server.commandTimeoutMs\", options.server.commandTimeoutMs);\n }\n if (options.server.maxPayloadBytes !== undefined) {\n assertPositiveNumber(\"server.maxPayloadBytes\", options.server.maxPayloadBytes);\n }\n}\n\nexport function assertConsumerOptions(options: ConsumerOptions): void {\n if (!isNonEmptyString(options.url)) {\n throw new Error(\"Consumer mode requires `url`.\");\n }\n let parsedUrl: URL;\n try {\n parsedUrl = new URL(options.url);\n } catch {\n throw new Error(\"Consumer option `url` must be a valid URL.\");\n }\n if (parsedUrl.protocol !== \"ws:\" && parsedUrl.protocol !== \"wss:\") {\n throw new Error(\"Consumer option `url` must use `ws://` or `wss://`.\");\n }\n const isLoopbackHost =\n parsedUrl.hostname === \"localhost\" || parsedUrl.hostname === \"127.0.0.1\" || parsedUrl.hostname === \"::1\";\n if (parsedUrl.protocol === \"ws:\" && !isLoopbackHost && !options.allowInsecureWs) {\n throw new Error(\n \"Insecure `ws://` is only allowed for loopback hosts by default. Use `wss://` or set `allowInsecureWs` to true.\",\n );\n }\n if (!isNonEmptyString(options.secret)) {\n throw new Error(\"Consumer mode requires `secret`.\");\n }\n if (options.secretId !== undefined && !isNonEmptyString(options.secretId)) {\n throw new Error(\"Consumer option `secretId` must be a non-empty string.\");\n }\n if (options.clientName !== undefined && !isNonEmptyString(options.clientName)) {\n throw new Error(\"Consumer option `clientName` must be a non-empty string.\");\n }\n if (options.requestTimeoutMs !== undefined) {\n assertPositiveNumber(\"requestTimeoutMs\", options.requestTimeoutMs);\n }\n if (options.reconnect?.initialDelayMs !== undefined) {\n assertPositiveNumber(\"reconnect.initialDelayMs\", options.reconnect.initialDelayMs);\n }\n if (options.reconnect?.maxDelayMs !== undefined) {\n assertPositiveNumber(\"reconnect.maxDelayMs\", options.reconnect.maxDelayMs);\n }\n}\n\nexport function assertMessageName(kind: \"command\" | \"event\", name: string): void {\n if (!isNonEmptyString(name)) {\n throw new Error(`${kind} name must be a non-empty string.`);\n }\n}\n\nexport function assertJsonPayload(kind: \"command\" | \"event\", name: string, payload: unknown): void {\n try {\n JSON.stringify(payload);\n } catch {\n throw new Error(`${kind} \"${name}\" payload must be JSON-serializable.`);\n }\n}\n\nfunction normalizeSchemaIssues(error: unknown): SchemaValidationIssue[] | undefined {\n if (!error || typeof error !== \"object\") {\n return undefined;\n }\n const issues = (error as { issues?: unknown }).issues;\n if (!Array.isArray(issues)) {\n return undefined;\n }\n const normalized = issues\n .map((issue) => {\n if (!issue || typeof issue !== \"object\") {\n return null;\n }\n const message = (issue as { message?: unknown }).message;\n const rawPath = (issue as { path?: unknown }).path;\n if (typeof message !== \"string\") {\n return null;\n }\n const path =\n Array.isArray(rawPath) && rawPath.length > 0\n ? rawPath\n .map((segment) => (typeof segment === \"string\" || typeof segment === \"number\" ? String(segment) : \"\"))\n .filter(Boolean)\n .join(\".\")\n : \"\";\n return { path, message } satisfies SchemaValidationIssue;\n })\n .filter((issue): issue is SchemaValidationIssue => Boolean(issue));\n return normalized.length > 0 ? normalized : undefined;\n}\n\nexport function parsePayloadWithSchema<T>(\n schema: RuntimeSchema<T> | undefined,\n payload: unknown,\n context: {\n name: string;\n stage: \"command.request\" | \"command.response\" | \"event.emit\";\n },\n): T | unknown {\n if (!schema) {\n return payload;\n }\n try {\n return schema.parse(payload);\n } catch (error) {\n const message =\n error instanceof Error && error.message.trim().length > 0\n ? error.message\n : `Payload validation failed for ${context.stage} \"${context.name}\".`;\n const issues = normalizeSchemaIssues(error);\n throw new PayloadValidationError(message, {\n ...context,\n ...(issues ? { issues } : {}),\n });\n }\n}\n","import type {\n CommandFailure,\n CommandMap,\n CommandRequestOf,\n CommandResponseOf,\n CommandResult,\n ConsumerOptions,\n ConsumerShardwire,\n EventMap,\n EventMeta,\n} from \"../core/types\";\nimport { createNodeWebSocket, type WebSocketLike } from \"../transport/ws/consumer-socket\";\nimport { createRequestId } from \"../utils/id\";\nimport { getBackoffDelay } from \"../utils/backoff\";\nimport { withLogger } from \"../utils/logger\";\nimport {\n makeEnvelope,\n parseEnvelope,\n stringifyEnvelope,\n type AuthErrorPayload,\n type CommandResultPayload,\n type EventEmitPayload,\n} from \"../core/protocol\";\nimport { assertJsonPayload, assertMessageName } from \"../runtime/validation\";\n\ntype EventHandler = (payload: unknown, meta: EventMeta) => void;\n\ninterface PendingRequest {\n resolve: (value: CommandResult) => void;\n reject: (error: CommandRequestError) => void;\n timer: NodeJS.Timeout;\n}\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 10000;\n\nclass CommandRequestError extends Error {\n constructor(\n public readonly code: \"TIMEOUT\" | \"DISCONNECTED\" | \"UNAUTHORIZED\",\n message: string,\n ) {\n super(message);\n this.name = \"CommandRequestError\";\n }\n}\n\nexport function createConsumerShardwire<C extends CommandMap, E extends EventMap>(\n options: ConsumerOptions,\n): ConsumerShardwire<C, E> {\n const logger = withLogger(options.logger);\n const reconnectEnabled = options.reconnect?.enabled ?? true;\n const initialDelayMs = options.reconnect?.initialDelayMs ?? 500;\n const maxDelayMs = options.reconnect?.maxDelayMs ?? 10000;\n const jitter = options.reconnect?.jitter ?? true;\n const requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n\n let socket: WebSocketLike | null = null;\n let isClosed = false;\n let isAuthed = false;\n let reconnectAttempts = 0;\n let reconnectTimer: NodeJS.Timeout | null = null;\n let connectPromise: Promise<void> | null = null;\n let connectResolve: (() => void) | null = null;\n let connectReject: ((error: Error) => void) | null = null;\n let authTimeoutTimer: NodeJS.Timeout | null = null;\n let currentConnectionId: string | null = null;\n\n const pendingRequests = new Map<string, PendingRequest>();\n const eventHandlers = new Map<string, Set<EventHandler>>();\n const connectedHandlers = new Set<(info: { connectionId: string; connectedAt: number }) => void>();\n const disconnectedHandlers = new Set<\n (info: { reason: string; at: number; willReconnect: boolean }) => void\n >();\n const reconnectingHandlers = new Set<(info: { attempt: number; delayMs: number; at: number }) => void>();\n\n function clearAuthTimeout(): void {\n if (authTimeoutTimer) {\n clearTimeout(authTimeoutTimer);\n authTimeoutTimer = null;\n }\n }\n\n function resolveConnect(): void {\n clearAuthTimeout();\n connectResolve?.();\n connectResolve = null;\n connectReject = null;\n connectPromise = null;\n }\n\n function rejectConnect(message: string): void {\n clearAuthTimeout();\n if (connectReject) {\n connectReject(new Error(message));\n }\n connectResolve = null;\n connectReject = null;\n connectPromise = null;\n }\n\n function sendRaw(data: string): void {\n if (!socket || socket.readyState !== 1) {\n throw new Error(\"Shardwire consumer is not connected.\");\n }\n socket.send(data);\n }\n\n function rejectAllPending(\n code: \"TIMEOUT\" | \"DISCONNECTED\" | \"UNAUTHORIZED\",\n reason: string,\n ): void {\n for (const [requestId, pending] of pendingRequests.entries()) {\n clearTimeout(pending.timer);\n pending.reject(new CommandRequestError(code, reason));\n pendingRequests.delete(requestId);\n }\n }\n\n function scheduleReconnect(): void {\n if (isClosed || !reconnectEnabled || reconnectTimer) {\n return;\n }\n const delay = getBackoffDelay(reconnectAttempts, { initialDelayMs, maxDelayMs, jitter });\n reconnectAttempts += 1;\n for (const handler of reconnectingHandlers) {\n try {\n handler({ attempt: reconnectAttempts, delayMs: delay, at: Date.now() });\n } catch (error) {\n logger.warn(\"Reconnect handler threw an error.\", { error: String(error) });\n }\n }\n reconnectTimer = setTimeout(() => {\n reconnectTimer = null;\n void connect().catch((error) => {\n logger.warn(\"Reconnect attempt failed.\", { error: String(error) });\n });\n }, delay);\n }\n\n function handleEvent(name: string, payload: unknown, meta: EventMeta): void {\n const handlers = eventHandlers.get(name);\n if (!handlers || handlers.size === 0) {\n return;\n }\n for (const handler of handlers) {\n try {\n handler(payload, meta);\n } catch (error) {\n logger.warn(\"Event handler threw an error.\", { name, error: String(error) });\n }\n }\n }\n\n async function connect(): Promise<void> {\n if (isClosed) {\n return;\n }\n if (socket && socket.readyState === 1 && isAuthed) {\n return;\n }\n if (connectPromise) {\n return connectPromise;\n }\n\n connectPromise = new Promise<void>((resolve, reject) => {\n connectResolve = resolve;\n connectReject = reject;\n });\n\n socket = options.webSocketFactory\n ? (options.webSocketFactory(options.url) as WebSocketLike)\n : createNodeWebSocket(options.url);\n\n socket.on(\"open\", () => {\n reconnectAttempts = 0;\n isAuthed = false;\n currentConnectionId = null;\n const hello = makeEnvelope(\"auth.hello\", {\n secret: options.secret,\n secretId: options.secretId,\n clientName: options.clientName,\n });\n socket?.send(stringifyEnvelope(hello));\n authTimeoutTimer = setTimeout(() => {\n if (!isAuthed) {\n rejectConnect(\"Shardwire auth timed out.\");\n socket?.close();\n }\n }, requestTimeoutMs);\n });\n\n socket.on(\"message\", (raw) => {\n try {\n const serialized = typeof raw === \"string\" ? raw : String(raw);\n const envelope = parseEnvelope(serialized);\n switch (envelope.type) {\n case \"auth.ok\":\n isAuthed = true;\n if (\n envelope.payload &&\n typeof envelope.payload === \"object\" &&\n \"connectionId\" in envelope.payload &&\n typeof (envelope.payload as { connectionId?: unknown }).connectionId === \"string\"\n ) {\n currentConnectionId = (envelope.payload as { connectionId: string }).connectionId;\n }\n if (currentConnectionId) {\n for (const handler of connectedHandlers) {\n try {\n handler({ connectionId: currentConnectionId, connectedAt: Date.now() });\n } catch (error) {\n logger.warn(\"Connected handler threw an error.\", { error: String(error) });\n }\n }\n }\n resolveConnect();\n break;\n case \"auth.error\": {\n const payload = envelope.payload as AuthErrorPayload;\n logger.error(\"Authentication failed for consumer.\", {\n code: payload.code,\n message: payload.message,\n });\n rejectConnect(payload.message);\n rejectAllPending(\"UNAUTHORIZED\", \"Shardwire authentication failed.\");\n socket?.close();\n break;\n }\n case \"command.result\":\n case \"command.error\": {\n const requestId = envelope.requestId;\n if (!requestId) {\n return;\n }\n const pending = pendingRequests.get(requestId);\n if (!pending) {\n return;\n }\n clearTimeout(pending.timer);\n pending.resolve(envelope.payload as CommandResultPayload);\n pendingRequests.delete(requestId);\n break;\n }\n case \"event.emit\": {\n const payload = envelope.payload as EventEmitPayload;\n const meta: EventMeta = { ts: envelope.ts };\n if (envelope.source) {\n meta.source = envelope.source;\n }\n handleEvent(payload.name, payload.data, meta);\n break;\n }\n case \"ping\":\n sendRaw(stringifyEnvelope(makeEnvelope(\"pong\", {})));\n break;\n default:\n break;\n }\n } catch (error) {\n logger.warn(\"Failed to parse consumer message.\", { error: String(error) });\n }\n });\n\n socket.on(\"close\", () => {\n const willReconnect = !isClosed && reconnectEnabled;\n rejectConnect(\"Shardwire connection closed.\");\n isAuthed = false;\n currentConnectionId = null;\n rejectAllPending(\"DISCONNECTED\", \"Shardwire connection closed before command completed.\");\n for (const handler of disconnectedHandlers) {\n try {\n handler({\n reason: \"Shardwire connection closed.\",\n at: Date.now(),\n willReconnect,\n });\n } catch (error) {\n logger.warn(\"Disconnected handler threw an error.\", { error: String(error) });\n }\n }\n if (!isClosed) {\n scheduleReconnect();\n }\n });\n\n socket.on(\"error\", (error) => {\n logger.warn(\"Consumer socket error.\", { error: String(error) });\n });\n\n return connectPromise;\n }\n\n void connect().catch((error) => {\n logger.warn(\"Initial connection attempt failed.\", { error: String(error) });\n });\n\n return {\n mode: \"consumer\",\n async send<K extends keyof C & string>(\n name: K,\n payload: CommandRequestOf<C[K]>,\n sendOptions?: { timeoutMs?: number; requestId?: string },\n ): Promise<CommandResult<CommandResponseOf<C[K]>>> {\n assertMessageName(\"command\", name);\n assertJsonPayload(\"command\", name, payload);\n if (!isAuthed) {\n try {\n await connect();\n } catch (error) {\n return {\n ok: false,\n requestId: sendOptions?.requestId ?? \"unknown\",\n ts: Date.now(),\n error: {\n code: \"UNAUTHORIZED\",\n message: error instanceof Error ? error.message : \"Failed to authenticate.\",\n },\n } satisfies CommandFailure;\n }\n }\n if (!socket || socket.readyState !== 1) {\n return {\n ok: false,\n requestId: sendOptions?.requestId ?? \"unknown\",\n ts: Date.now(),\n error: {\n code: \"DISCONNECTED\",\n message: \"Not connected to Shardwire host.\",\n },\n } satisfies CommandFailure;\n }\n\n const requestId = sendOptions?.requestId ?? createRequestId();\n const timeoutMs = sendOptions?.timeoutMs ?? requestTimeoutMs;\n\n const promise = new Promise<CommandResult>((resolve, reject) => {\n const timer = setTimeout(() => {\n pendingRequests.delete(requestId);\n reject(new CommandRequestError(\"TIMEOUT\", `Command \"${name}\" timed out after ${timeoutMs}ms.`));\n }, timeoutMs);\n\n pendingRequests.set(requestId, {\n resolve,\n reject: (error) => reject(error),\n timer,\n });\n });\n\n sendRaw(\n stringifyEnvelope(\n makeEnvelope(\n \"command.request\",\n {\n name,\n data: payload,\n },\n { requestId },\n ),\n ),\n );\n\n try {\n return (await promise) as CommandResult<CommandResponseOf<C[K]>>;\n } catch (error) {\n const failureCode =\n error instanceof CommandRequestError\n ? error.code\n : !socket || socket.readyState !== 1\n ? \"DISCONNECTED\"\n : \"TIMEOUT\";\n return {\n ok: false,\n requestId,\n ts: Date.now(),\n error: {\n code: failureCode,\n message: error instanceof Error ? error.message : \"Command request failed.\",\n },\n } satisfies CommandFailure;\n }\n },\n on(name, handler) {\n assertMessageName(\"event\", name);\n const casted = handler as EventHandler;\n const existing = eventHandlers.get(name);\n if (existing) {\n existing.add(casted);\n } else {\n eventHandlers.set(name, new Set<EventHandler>([casted]));\n }\n return () => {\n const handlers = eventHandlers.get(name);\n if (!handlers) {\n return;\n }\n handlers.delete(casted);\n if (handlers.size === 0) {\n eventHandlers.delete(name);\n }\n };\n },\n off(name, handler) {\n assertMessageName(\"event\", name);\n const handlers = eventHandlers.get(name);\n if (!handlers) {\n return;\n }\n handlers.delete(handler as EventHandler);\n if (handlers.size === 0) {\n eventHandlers.delete(name);\n }\n },\n onConnected(handler) {\n connectedHandlers.add(handler);\n return () => {\n connectedHandlers.delete(handler);\n };\n },\n onDisconnected(handler) {\n disconnectedHandlers.add(handler);\n return () => {\n disconnectedHandlers.delete(handler);\n };\n },\n onReconnecting(handler) {\n reconnectingHandlers.add(handler);\n return () => {\n reconnectingHandlers.delete(handler);\n };\n },\n ready() {\n return connect();\n },\n connected() {\n return Boolean(socket && socket.readyState === 1 && isAuthed);\n },\n connectionId() {\n return currentConnectionId;\n },\n async close() {\n isClosed = true;\n isAuthed = false;\n currentConnectionId = null;\n rejectConnect(\"Shardwire consumer has been closed.\");\n if (reconnectTimer) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n }\n rejectAllPending(\"DISCONNECTED\", \"Shardwire consumer has been closed.\");\n if (!socket) {\n return;\n }\n await new Promise<void>((resolve) => {\n const current = socket;\n if (!current) {\n resolve();\n return;\n }\n current.once(\"close\", () => resolve());\n current.close();\n });\n socket = null;\n },\n };\n}\n","import type { DiscordClientLike, HostOptions } from \"../core/types\";\n\ninterface OwnedClientState {\n client?: DiscordClientLike;\n owned: boolean;\n}\n\nexport async function resolveDiscordClient<C extends Record<string, unknown>, E extends Record<string, unknown>>(\n options: HostOptions<C, E>,\n): Promise<OwnedClientState> {\n if (options.client) {\n return { client: options.client, owned: false };\n }\n\n if (!options.token) {\n return { owned: false };\n }\n\n const discordModule = await import(\"discord.js\");\n const created = new discordModule.Client({\n intents: [],\n });\n await created.login(options.token);\n return { client: created as unknown as DiscordClientLike, owned: true };\n}\n","export async function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n timeoutMessage = \"Operation timed out.\",\n): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(timeoutMessage));\n }, timeoutMs);\n\n promise\n .then((value) => {\n clearTimeout(timeout);\n resolve(value);\n })\n .catch((error) => {\n clearTimeout(timeout);\n reject(error instanceof Error ? error : new Error(String(error)));\n });\n });\n}\n\nexport class DedupeCache<T> {\n private readonly cache = new Map<string, { value: T; expiresAt: number }>();\n\n constructor(private readonly ttlMs: number) {}\n\n get(key: string): T | undefined {\n const entry = this.cache.get(key);\n if (!entry) {\n return undefined;\n }\n if (entry.expiresAt <= Date.now()) {\n this.cache.delete(key);\n return undefined;\n }\n return entry.value;\n }\n\n set(key: string, value: T): void {\n this.cache.set(key, { value, expiresAt: Date.now() + this.ttlMs });\n }\n}\n","import { WebSocketServer, type WebSocket } from \"ws\";\nimport type { IncomingMessage } from \"node:http\";\nimport {\n makeEnvelope,\n parseEnvelope,\n stringifyEnvelope,\n type AuthHelloPayload,\n type CommandRequestPayload,\n type EventEmitPayload,\n type WireEnvelope,\n} from \"../../core/protocol\";\nimport type { CommandFailure, CommandSuccess, HostOptions, ShardwireLogger } from \"../../core/types\";\nimport { withLogger } from \"../../utils/logger\";\nimport { createConnectionId } from \"../../utils/id\";\nimport type { HostConnectionState } from \"../../runtime/state\";\nimport { getSecretId, isSecretValid } from \"../../runtime/security\";\n\nconst CLOSE_AUTH_REQUIRED = 4001;\nconst CLOSE_AUTH_FAILED = 4003;\nconst CLOSE_INVALID_PAYLOAD = 4004;\n\ninterface HostServerConfig {\n options: HostOptions<Record<string, unknown>, Record<string, unknown>>;\n onCommandRequest: (\n connection: HostConnectionState,\n payload: CommandRequestPayload,\n requestId: string,\n source?: string,\n ) => Promise<CommandSuccess | CommandFailure>;\n}\n\nexport class HostWebSocketServer {\n private readonly wss: WebSocketServer;\n private readonly connections = new Map<WebSocket, HostConnectionState>();\n private readonly logger: Required<ShardwireLogger>;\n private readonly heartbeatMs: number;\n private readonly authTimeoutMs = 5000;\n private readonly interval: NodeJS.Timeout;\n\n constructor(private readonly config: HostServerConfig) {\n const serverConfig = config.options.server;\n this.heartbeatMs = serverConfig.heartbeatMs ?? 30000;\n this.logger = withLogger(config.options.logger);\n\n this.wss = new WebSocketServer({\n host: serverConfig.host,\n port: serverConfig.port,\n path: serverConfig.path ?? \"/shardwire\",\n maxPayload: serverConfig.maxPayloadBytes ?? 65536,\n });\n\n this.wss.on(\"connection\", (socket, request) => this.handleConnection(socket, request));\n this.wss.on(\"error\", (error) =>\n this.logger.error(\"Shardwire host server error.\", { error: String(error) }),\n );\n\n this.interval = setInterval(() => {\n this.checkHeartbeats();\n }, this.heartbeatMs);\n }\n\n emitEvent(name: string, data: unknown, source?: string): void {\n const envelope = makeEnvelope(\n \"event.emit\",\n { name, data } satisfies EventEmitPayload,\n source ? { source } : undefined,\n );\n const raw = stringifyEnvelope(envelope);\n\n for (const state of this.connections.values()) {\n if (!state.authenticated) {\n continue;\n }\n this.safeSend(state.socket, raw);\n }\n }\n\n async close(): Promise<void> {\n clearInterval(this.interval);\n for (const connection of this.connections.values()) {\n connection.socket.close();\n }\n this.connections.clear();\n await new Promise<void>((resolve, reject) => {\n this.wss.close((error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n }\n\n private handleConnection(socket: WebSocket, request: IncomingMessage): void {\n const allowlist = this.config.options.server.corsOrigins;\n if (allowlist && allowlist.length > 0) {\n const origin = request.headers.origin;\n if (!origin || !allowlist.includes(origin)) {\n socket.close(CLOSE_AUTH_FAILED, \"Origin not allowed.\");\n return;\n }\n }\n\n const state: HostConnectionState = {\n id: createConnectionId(),\n socket,\n authenticated: false,\n lastHeartbeatAt: Date.now(),\n };\n this.connections.set(socket, state);\n\n const authTimer = setTimeout(() => {\n if (!state.authenticated) {\n socket.close(CLOSE_AUTH_REQUIRED, \"Authentication required.\");\n }\n }, this.authTimeoutMs);\n\n socket.on(\"message\", (raw) => {\n const serialized =\n typeof raw === \"string\" ? raw : Buffer.isBuffer(raw) ? raw.toString(\"utf8\") : undefined;\n if (!serialized) {\n this.logger.warn(\"Invalid message payload from client.\", { error: \"Unsupported payload type.\" });\n socket.close(CLOSE_INVALID_PAYLOAD, \"Invalid payload.\");\n return;\n }\n let parsed: WireEnvelope;\n try {\n parsed = parseEnvelope(serialized);\n } catch (error) {\n this.logger.warn(\"Invalid message payload from client.\", { error: String(error) });\n socket.close(CLOSE_INVALID_PAYLOAD, \"Invalid payload.\");\n return;\n }\n void this.handleMessage(state, parsed).catch((error: unknown) => {\n this.logger.warn(\"Invalid message payload from client.\", { error: String(error) });\n socket.close(CLOSE_INVALID_PAYLOAD, \"Invalid payload.\");\n });\n });\n\n socket.on(\"close\", () => {\n clearTimeout(authTimer);\n this.connections.delete(socket);\n });\n\n socket.on(\"error\", (error) =>\n this.logger.warn(\"Socket error.\", { connectionId: state.id, error: String(error) }),\n );\n }\n\n private async handleMessage(state: HostConnectionState, envelope: WireEnvelope): Promise<void> {\n if (envelope.type === \"ping\") {\n state.lastHeartbeatAt = Date.now();\n this.safeSend(state.socket, stringifyEnvelope(makeEnvelope(\"pong\", {})));\n return;\n }\n if (envelope.type === \"pong\") {\n state.lastHeartbeatAt = Date.now();\n return;\n }\n\n if (!state.authenticated) {\n if (envelope.type !== \"auth.hello\") {\n state.socket.close(CLOSE_AUTH_REQUIRED, \"Authentication required.\");\n return;\n }\n\n const payload = envelope.payload as AuthHelloPayload;\n const providedSecret = payload?.secret;\n const knownSecrets = this.config.options.server.secrets;\n const secretId = payload?.secretId;\n let authReason: \"unknown_secret_id\" | \"invalid_secret\" | null = null;\n\n if (!providedSecret) {\n authReason = \"invalid_secret\";\n } else if (secretId) {\n const secretIndex = knownSecrets.findIndex((_, index) => getSecretId(index) === secretId);\n if (secretIndex < 0) {\n authReason = \"unknown_secret_id\";\n } else {\n const expectedSecret = knownSecrets[secretIndex];\n if (!expectedSecret || !isSecretValid(providedSecret, expectedSecret)) {\n authReason = \"invalid_secret\";\n }\n }\n } else if (!knownSecrets.some((secret) => isSecretValid(providedSecret, secret))) {\n authReason = \"invalid_secret\";\n }\n\n if (authReason) {\n this.safeSend(\n state.socket,\n stringifyEnvelope(\n makeEnvelope(\"auth.error\", {\n code: \"UNAUTHORIZED\",\n reason: authReason,\n message: \"Authentication failed.\",\n }),\n ),\n );\n state.socket.close(CLOSE_AUTH_FAILED, \"Invalid secret.\");\n return;\n }\n\n state.authenticated = true;\n state.lastHeartbeatAt = Date.now();\n if (payload.clientName) {\n state.clientName = payload.clientName;\n }\n this.safeSend(\n state.socket,\n stringifyEnvelope(makeEnvelope(\"auth.ok\", { connectionId: state.id })),\n );\n return;\n }\n\n if (envelope.type === \"command.request\") {\n const payload = envelope.payload as CommandRequestPayload;\n if (!envelope.requestId || !payload?.name) {\n const invalid: CommandFailure = {\n ok: false,\n requestId: envelope.requestId ?? \"unknown\",\n ts: Date.now(),\n error: {\n code: \"VALIDATION_ERROR\",\n message: \"Invalid command request envelope.\",\n },\n };\n this.safeSend(\n state.socket,\n stringifyEnvelope(makeEnvelope(\"command.error\", invalid, { requestId: invalid.requestId })),\n );\n return;\n }\n\n const response = await this.config.onCommandRequest(\n state,\n payload,\n envelope.requestId,\n envelope.source,\n );\n const responseType = response.ok ? \"command.result\" : \"command.error\";\n this.safeSend(\n state.socket,\n stringifyEnvelope(makeEnvelope(responseType, response, { requestId: response.requestId })),\n );\n return;\n }\n }\n\n private checkHeartbeats(): void {\n const now = Date.now();\n const threshold = this.heartbeatMs * 2;\n\n for (const state of this.connections.values()) {\n if (!state.authenticated) {\n continue;\n }\n\n if (now - state.lastHeartbeatAt > threshold) {\n state.socket.terminate();\n this.connections.delete(state.socket);\n continue;\n }\n\n this.safeSend(state.socket, stringifyEnvelope(makeEnvelope(\"ping\", {})));\n }\n }\n\n private safeSend(socket: WebSocket, payload: string): void {\n if (socket.readyState === 1) {\n socket.send(payload);\n }\n }\n}\n","import { timingSafeEqual } from \"node:crypto\";\n\nexport function isSecretValid(provided: string, expected: string): boolean {\n const providedBuffer = Buffer.from(provided);\n const expectedBuffer = Buffer.from(expected);\n\n if (providedBuffer.length !== expectedBuffer.length) {\n return false;\n }\n\n return timingSafeEqual(providedBuffer, expectedBuffer);\n}\n\nexport function getSecretId(secretIndex: number): string {\n return `s${secretIndex}`;\n}\n","import type {\n CommandContext,\n CommandFailure,\n CommandMap,\n CommandSuccess,\n EventMap,\n HostOptions,\n HostShardwire,\n} from \"../core/types\";\nimport { withTimeout, DedupeCache } from \"../runtime/reliability\";\nimport type { CommandHandler } from \"../runtime/state\";\nimport { HostWebSocketServer } from \"../transport/ws/host-server\";\nimport {\n assertJsonPayload,\n assertMessageName,\n parsePayloadWithSchema,\n PayloadValidationError,\n} from \"../runtime/validation\";\n\nconst DEFAULT_COMMAND_TIMEOUT_MS = 10000;\n\nexport function createHostShardwire<C extends CommandMap, E extends EventMap>(\n options: HostOptions<C, E>,\n runtimeHooks?: {\n onClose?: () => Promise<void> | void;\n },\n): HostShardwire<C, E> {\n const commandHandlers = new Map<string, CommandHandler>();\n const commandTimeoutMs = options.server.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n const dedupeCache = new DedupeCache<CommandSuccess | CommandFailure>(commandTimeoutMs * 2);\n\n const hostServer = new HostWebSocketServer({\n options,\n onCommandRequest: async (connection, payload, requestId, source) => {\n const cacheKey = `${connection.id}:${requestId}:${payload.name}`;\n const cached = dedupeCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n const handler = commandHandlers.get(payload.name);\n if (!handler) {\n const failure: CommandFailure = {\n ok: false,\n requestId,\n ts: Date.now(),\n error: {\n code: \"COMMAND_NOT_FOUND\",\n message: `No command handler registered for \"${payload.name}\".`,\n },\n };\n dedupeCache.set(cacheKey, failure);\n return failure;\n }\n\n const context: CommandContext = {\n requestId,\n connectionId: connection.id,\n receivedAt: Date.now(),\n };\n if (source) {\n context.source = source;\n }\n\n try {\n const commandValidation = options.validation?.commands?.[payload.name];\n const validatedRequest = parsePayloadWithSchema(commandValidation?.request, payload.data, {\n name: payload.name,\n stage: \"command.request\",\n });\n\n const maybePromise = Promise.resolve(handler(validatedRequest, context));\n const value = await withTimeout(\n maybePromise,\n commandTimeoutMs,\n `Command \"${payload.name}\" timed out after ${commandTimeoutMs}ms.`,\n );\n const validatedResponse = parsePayloadWithSchema(commandValidation?.response, value, {\n name: payload.name,\n stage: \"command.response\",\n });\n const success: CommandSuccess = {\n ok: true,\n requestId,\n ts: Date.now(),\n data: validatedResponse,\n };\n dedupeCache.set(cacheKey, success);\n return success;\n } catch (error) {\n if (error instanceof PayloadValidationError) {\n const failure: CommandFailure = {\n ok: false,\n requestId,\n ts: Date.now(),\n error: {\n code: \"VALIDATION_ERROR\",\n message: error.message,\n details: error.details,\n },\n };\n dedupeCache.set(cacheKey, failure);\n return failure;\n }\n const isTimeout = error instanceof Error && /timed out/i.test(error.message);\n const failure: CommandFailure = {\n ok: false,\n requestId,\n ts: Date.now(),\n error: {\n code: isTimeout ? \"TIMEOUT\" : \"INTERNAL_ERROR\",\n message: error instanceof Error ? error.message : \"Unknown command execution error.\",\n },\n };\n dedupeCache.set(cacheKey, failure);\n return failure;\n }\n },\n });\n\n return {\n mode: \"host\",\n onCommand(name, handler) {\n assertMessageName(\"command\", name);\n commandHandlers.set(name, handler as CommandHandler);\n return () => {\n commandHandlers.delete(name);\n };\n },\n emitEvent(name, payload) {\n assertMessageName(\"event\", name);\n const validatedPayload = parsePayloadWithSchema(options.validation?.events?.[name], payload, {\n name,\n stage: \"event.emit\",\n });\n assertJsonPayload(\"event\", name, validatedPayload);\n hostServer.emitEvent(name, validatedPayload, options.name);\n },\n broadcast(name, payload) {\n assertMessageName(\"event\", name);\n const validatedPayload = parsePayloadWithSchema(options.validation?.events?.[name], payload, {\n name,\n stage: \"event.emit\",\n });\n assertJsonPayload(\"event\", name, validatedPayload);\n hostServer.emitEvent(name, validatedPayload, options.name);\n },\n close() {\n return hostServer.close().then(async () => {\n await runtimeHooks?.onClose?.();\n });\n },\n };\n}\n","import type { RuntimeSchema, SchemaValidationIssue } from \"../core/types\";\n\nexport interface SafeParseResultSuccess<T> {\n success: true;\n data: T;\n}\n\nexport interface SafeParseResultFailure {\n success: false;\n error: {\n message: string;\n issues?: SchemaValidationIssue[];\n };\n}\n\nexport type SafeParseResult<T> = SafeParseResultSuccess<T> | SafeParseResultFailure;\n\nexport interface SafeParseSchema<T> {\n safeParse: (value: unknown) => SafeParseResult<T>;\n}\n\nexport function fromSafeParseSchema<T>(schema: SafeParseSchema<T>): RuntimeSchema<T> {\n return {\n parse(value) {\n const result = schema.safeParse(value);\n if (result.success) {\n return result.data;\n }\n const error = new Error(result.error.message) as Error & { issues?: SchemaValidationIssue[] };\n if (result.error.issues) {\n error.issues = result.error.issues;\n }\n throw error;\n },\n };\n}\n","import type { RuntimeSchema, SchemaValidationIssue } from \"../core/types\";\nimport { fromSafeParseSchema } from \"./index\";\nimport type { ZodType } from \"zod\";\n\nfunction normalizeZodPath(path: ReadonlyArray<PropertyKey>): string {\n if (path.length === 0) {\n return \"\";\n }\n return path\n .filter((segment): segment is string | number => typeof segment === \"string\" || typeof segment === \"number\")\n .map((segment) => String(segment))\n .join(\".\");\n}\n\nexport function fromZodSchema<T>(schema: ZodType<T>): RuntimeSchema<T> {\n return fromSafeParseSchema<T>({\n safeParse(value) {\n const result = schema.safeParse(value);\n if (result.success) {\n return { success: true, data: result.data };\n }\n const issues: SchemaValidationIssue[] = result.error.issues.map((issue) => ({\n path: normalizeZodPath(issue.path),\n message: issue.message,\n }));\n return {\n success: false,\n error: {\n message: \"Schema validation failed.\",\n issues,\n },\n };\n },\n });\n}\n","import { createConsumerShardwire } from \"./consumer\";\nimport { resolveDiscordClient } from \"./discord/client\";\nimport { createHostShardwire } from \"./host\";\nimport { assertConsumerOptions, assertHostOptions } from \"./runtime/validation\";\nimport type {\n CommandMap,\n ConsumerOptions,\n ConsumerShardwire,\n EventMap,\n HostOptions,\n HostShardwire,\n} from \"./core/types\";\n\nfunction isHostOptions<C extends CommandMap, E extends EventMap>(\n options: HostOptions<C, E> | ConsumerOptions,\n): options is HostOptions<C, E> {\n return \"server\" in options;\n}\n\nexport function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(\n options: HostOptions<C, E>,\n): HostShardwire<C, E>;\nexport function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(\n options: ConsumerOptions,\n): ConsumerShardwire<C, E>;\nexport function createShardwire<C extends CommandMap = {}, E extends EventMap = {}>(\n options: HostOptions<C, E> | ConsumerOptions,\n): HostShardwire<C, E> | ConsumerShardwire<C, E> {\n if (!isHostOptions(options)) {\n assertConsumerOptions(options);\n return createConsumerShardwire<C, E>(options);\n }\n assertHostOptions(options);\n\n let ownedClientPromise: Promise<{ destroy: () => void } | undefined> | undefined;\n\n if (!options.client && options.token) {\n ownedClientPromise = resolveDiscordClient(options)\n .then((state) => {\n if (!state.owned || !state.client) {\n return undefined;\n }\n return {\n destroy: () => state.client?.destroy(),\n };\n })\n .catch((error) => {\n options.logger?.error?.(\"Failed to initialize discord.js client from token.\", {\n error: String(error),\n });\n return undefined;\n });\n }\n\n return createHostShardwire<C, E>(options, {\n onClose: async () => {\n const owned = await ownedClientPromise;\n owned?.destroy();\n },\n });\n}\n\nexport { fromSafeParseSchema } from \"./schema\";\nexport { fromZodSchema } from \"./schema/zod\";\n\nexport type {\n CommandContext,\n CommandFailure,\n CommandMap,\n CommandRequestOf,\n CommandResult,\n CommandResponseOf,\n CommandSchema,\n CommandSuccess,\n ConsumerOptions,\n ConsumerShardwire,\n CreateShardwire,\n DiscordClientLike,\n EventMap,\n EventMeta,\n HostOptions,\n HostShardwire,\n RuntimeSchema,\n SchemaValidationIssue,\n ShardwireLogger,\n Unsubscribe,\n} from \"./core/types\";\n"],"mappings":";AAAA,SAAS,iBAAiB;AAanB,SAAS,oBAAoB,KAA4B;AAC9D,SAAO,IAAI,UAAU,GAAG;AAC1B;;;ACfA,SAAS,kBAAkB;AAEpB,SAAS,kBAA0B;AACxC,SAAO,WAAW;AACpB;AAEO,SAAS,qBAA6B;AAC3C,SAAO,WAAW;AACpB;;;ACFO,SAAS,gBAAgB,SAAiB,QAA+B;AAC9E,QAAM,OAAO,KAAK,IAAI,OAAO,YAAY,OAAO,iBAAiB,KAAK,OAAO;AAC7E,MAAI,CAAC,OAAO,QAAQ;AAClB,WAAO;AAAA,EACT;AACA,QAAM,SAAS,KAAK,MAAM,OAAO,GAAG;AACpC,QAAM,MAAM,KAAK,IAAI,GAAG,OAAO,MAAM;AACrC,QAAM,MAAM,OAAO;AACnB,SAAO,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,MAAM,EAAE,IAAI;AACvD;;;ACbO,SAAS,WAAW,QAAqD;AAC9E,SAAO;AAAA,IACL,OAAO,QAAQ,UAAU,MAAM;AAAA,IAC/B,MAAM,QAAQ,SAAS,MAAM;AAAA,IAC7B,MAAM,QAAQ,SAAS,MAAM;AAAA,IAC7B,OAAO,QAAQ,UAAU,MAAM;AAAA,EACjC;AACF;;;ACPO,IAAM,mBAAmB;AAkDzB,SAAS,aACd,MACA,SACA,QAC+B;AAC/B,QAAM,WAA0C;AAAA,IAC9C,GAAG;AAAA,IACH;AAAA,IACA,IAAI,KAAK,IAAI;AAAA,IACb;AAAA,EACF;AACA,MAAI,QAAQ,WAAW;AACrB,aAAS,YAAY,OAAO;AAAA,EAC9B;AACA,MAAI,QAAQ,QAAQ;AAClB,aAAS,SAAS,OAAO;AAAA,EAC3B;AACA,SAAO;AACT;AAEO,SAAS,cAAc,KAA2B;AACvD,QAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,MAAI,CAAC,UAAU,OAAO,MAAM,oBAAoB,OAAO,OAAO,SAAS,UAAU;AAC/E,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C;AACA,SAAO;AACT;AAEO,SAAS,kBAAkB,UAAgC;AAChE,SAAO,KAAK,UAAU,QAAQ;AAChC;;;AChFO,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAChD,YACE,SACgB,SAKhB;AACA,UAAM,OAAO;AANG;AAOhB,SAAK,OAAO;AAAA,EACd;AAAA,EARkB;AASpB;AAEA,SAAS,iBAAiB,OAAiC;AACzD,SAAO,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS;AAC5D;AAEA,SAAS,qBAAqB,MAAc,OAAsB;AAChE,MAAI,OAAO,UAAU,YAAY,OAAO,MAAM,KAAK,KAAK,SAAS,GAAG;AAClE,UAAM,IAAI,MAAM,GAAG,IAAI,6BAA6B;AAAA,EACtD;AACF;AAEO,SAAS,kBAAkB,SAA8E;AAC9G,MAAI,CAAC,QAAQ,QAAQ;AACnB,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AACA,uBAAqB,eAAe,QAAQ,OAAO,IAAI;AACvD,MAAI,CAAC,MAAM,QAAQ,QAAQ,OAAO,OAAO,KAAK,QAAQ,OAAO,QAAQ,WAAW,GAAG;AACjF,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACpE;AACA,aAAW,CAAC,OAAO,MAAM,KAAK,QAAQ,OAAO,QAAQ,QAAQ,GAAG;AAC9D,QAAI,CAAC,iBAAiB,MAAM,GAAG;AAC7B,YAAM,IAAI,MAAM,kBAAkB,KAAK,+BAA+B;AAAA,IACxE;AAAA,EACF;AACA,MACE,QAAQ,OAAO,oBAAoB,UACnC,CAAC,QAAQ,OAAO,QAAQ,KAAK,CAAC,GAAG,UAAU,QAAQ,OAAO,oBAAoB,IAAI,KAAK,EAAE,GACzF;AACA,UAAM,IAAI,MAAM,8DAA8D;AAAA,EAChF;AACA,MAAI,QAAQ,OAAO,gBAAgB,QAAW;AAC5C,yBAAqB,sBAAsB,QAAQ,OAAO,WAAW;AAAA,EACvE;AACA,MAAI,QAAQ,OAAO,qBAAqB,QAAW;AACjD,yBAAqB,2BAA2B,QAAQ,OAAO,gBAAgB;AAAA,EACjF;AACA,MAAI,QAAQ,OAAO,oBAAoB,QAAW;AAChD,yBAAqB,0BAA0B,QAAQ,OAAO,eAAe;AAAA,EAC/E;AACF;AAEO,SAAS,sBAAsB,SAAgC;AACpE,MAAI,CAAC,iBAAiB,QAAQ,GAAG,GAAG;AAClC,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AACA,MAAI;AACJ,MAAI;AACF,gBAAY,IAAI,IAAI,QAAQ,GAAG;AAAA,EACjC,QAAQ;AACN,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AACA,MAAI,UAAU,aAAa,SAAS,UAAU,aAAa,QAAQ;AACjE,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AACA,QAAM,iBACJ,UAAU,aAAa,eAAe,UAAU,aAAa,eAAe,UAAU,aAAa;AACrG,MAAI,UAAU,aAAa,SAAS,CAAC,kBAAkB,CAAC,QAAQ,iBAAiB;AAC/E,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,MAAI,CAAC,iBAAiB,QAAQ,MAAM,GAAG;AACrC,UAAM,IAAI,MAAM,kCAAkC;AAAA,EACpD;AACA,MAAI,QAAQ,aAAa,UAAa,CAAC,iBAAiB,QAAQ,QAAQ,GAAG;AACzE,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACA,MAAI,QAAQ,eAAe,UAAa,CAAC,iBAAiB,QAAQ,UAAU,GAAG;AAC7E,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AACA,MAAI,QAAQ,qBAAqB,QAAW;AAC1C,yBAAqB,oBAAoB,QAAQ,gBAAgB;AAAA,EACnE;AACA,MAAI,QAAQ,WAAW,mBAAmB,QAAW;AACnD,yBAAqB,4BAA4B,QAAQ,UAAU,cAAc;AAAA,EACnF;AACA,MAAI,QAAQ,WAAW,eAAe,QAAW;AAC/C,yBAAqB,wBAAwB,QAAQ,UAAU,UAAU;AAAA,EAC3E;AACF;AAEO,SAAS,kBAAkB,MAA2B,MAAoB;AAC/E,MAAI,CAAC,iBAAiB,IAAI,GAAG;AAC3B,UAAM,IAAI,MAAM,GAAG,IAAI,mCAAmC;AAAA,EAC5D;AACF;AAEO,SAAS,kBAAkB,MAA2B,MAAc,SAAwB;AACjG,MAAI;AACF,SAAK,UAAU,OAAO;AAAA,EACxB,QAAQ;AACN,UAAM,IAAI,MAAM,GAAG,IAAI,KAAK,IAAI,sCAAsC;AAAA,EACxE;AACF;AAEA,SAAS,sBAAsB,OAAqD;AAClF,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,QAAM,SAAU,MAA+B;AAC/C,MAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,WAAO;AAAA,EACT;AACA,QAAM,aAAa,OAChB,IAAI,CAAC,UAAU;AACd,QAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,aAAO;AAAA,IACT;AACA,UAAM,UAAW,MAAgC;AACjD,UAAM,UAAW,MAA6B;AAC9C,QAAI,OAAO,YAAY,UAAU;AAC/B,aAAO;AAAA,IACT;AACA,UAAM,OACJ,MAAM,QAAQ,OAAO,KAAK,QAAQ,SAAS,IACvC,QACG,IAAI,CAAC,YAAa,OAAO,YAAY,YAAY,OAAO,YAAY,WAAW,OAAO,OAAO,IAAI,EAAG,EACpG,OAAO,OAAO,EACd,KAAK,GAAG,IACX;AACN,WAAO,EAAE,MAAM,QAAQ;AAAA,EACzB,CAAC,EACA,OAAO,CAAC,UAA0C,QAAQ,KAAK,CAAC;AACnE,SAAO,WAAW,SAAS,IAAI,aAAa;AAC9C;AAEO,SAAS,uBACd,QACA,SACA,SAIa;AACb,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,MAAI;AACF,WAAO,OAAO,MAAM,OAAO;AAAA,EAC7B,SAAS,OAAO;AACd,UAAM,UACJ,iBAAiB,SAAS,MAAM,QAAQ,KAAK,EAAE,SAAS,IACpD,MAAM,UACN,iCAAiC,QAAQ,KAAK,KAAK,QAAQ,IAAI;AACrE,UAAM,SAAS,sBAAsB,KAAK;AAC1C,UAAM,IAAI,uBAAuB,SAAS;AAAA,MACxC,GAAG;AAAA,MACH,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IAC7B,CAAC;AAAA,EACH;AACF;;;ACpIA,IAAM,6BAA6B;AAEnC,IAAM,sBAAN,cAAkC,MAAM;AAAA,EACtC,YACkB,MAChB,SACA;AACA,UAAM,OAAO;AAHG;AAIhB,SAAK,OAAO;AAAA,EACd;AAAA,EALkB;AAMpB;AAEO,SAAS,wBACd,SACyB;AACzB,QAAM,SAAS,WAAW,QAAQ,MAAM;AACxC,QAAM,mBAAmB,QAAQ,WAAW,WAAW;AACvD,QAAM,iBAAiB,QAAQ,WAAW,kBAAkB;AAC5D,QAAM,aAAa,QAAQ,WAAW,cAAc;AACpD,QAAM,SAAS,QAAQ,WAAW,UAAU;AAC5C,QAAM,mBAAmB,QAAQ,oBAAoB;AAErD,MAAI,SAA+B;AACnC,MAAI,WAAW;AACf,MAAI,WAAW;AACf,MAAI,oBAAoB;AACxB,MAAI,iBAAwC;AAC5C,MAAI,iBAAuC;AAC3C,MAAI,iBAAsC;AAC1C,MAAI,gBAAiD;AACrD,MAAI,mBAA0C;AAC9C,MAAI,sBAAqC;AAEzC,QAAM,kBAAkB,oBAAI,IAA4B;AACxD,QAAM,gBAAgB,oBAAI,IAA+B;AACzD,QAAM,oBAAoB,oBAAI,IAAmE;AACjG,QAAM,uBAAuB,oBAAI,IAE/B;AACF,QAAM,uBAAuB,oBAAI,IAAsE;AAEvG,WAAS,mBAAyB;AAChC,QAAI,kBAAkB;AACpB,mBAAa,gBAAgB;AAC7B,yBAAmB;AAAA,IACrB;AAAA,EACF;AAEA,WAAS,iBAAuB;AAC9B,qBAAiB;AACjB,qBAAiB;AACjB,qBAAiB;AACjB,oBAAgB;AAChB,qBAAiB;AAAA,EACnB;AAEA,WAAS,cAAc,SAAuB;AAC5C,qBAAiB;AACjB,QAAI,eAAe;AACjB,oBAAc,IAAI,MAAM,OAAO,CAAC;AAAA,IAClC;AACA,qBAAiB;AACjB,oBAAgB;AAChB,qBAAiB;AAAA,EACnB;AAEA,WAAS,QAAQ,MAAoB;AACnC,QAAI,CAAC,UAAU,OAAO,eAAe,GAAG;AACtC,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AACA,WAAO,KAAK,IAAI;AAAA,EAClB;AAEA,WAAS,iBACP,MACA,QACM;AACN,eAAW,CAAC,WAAW,OAAO,KAAK,gBAAgB,QAAQ,GAAG;AAC5D,mBAAa,QAAQ,KAAK;AAC1B,cAAQ,OAAO,IAAI,oBAAoB,MAAM,MAAM,CAAC;AACpD,sBAAgB,OAAO,SAAS;AAAA,IAClC;AAAA,EACF;AAEA,WAAS,oBAA0B;AACjC,QAAI,YAAY,CAAC,oBAAoB,gBAAgB;AACnD;AAAA,IACF;AACA,UAAM,QAAQ,gBAAgB,mBAAmB,EAAE,gBAAgB,YAAY,OAAO,CAAC;AACvF,yBAAqB;AACrB,eAAW,WAAW,sBAAsB;AAC1C,UAAI;AACF,gBAAQ,EAAE,SAAS,mBAAmB,SAAS,OAAO,IAAI,KAAK,IAAI,EAAE,CAAC;AAAA,MACxE,SAAS,OAAO;AACd,eAAO,KAAK,qCAAqC,EAAE,OAAO,OAAO,KAAK,EAAE,CAAC;AAAA,MAC3E;AAAA,IACF;AACA,qBAAiB,WAAW,MAAM;AAChC,uBAAiB;AACjB,WAAK,QAAQ,EAAE,MAAM,CAAC,UAAU;AAC9B,eAAO,KAAK,6BAA6B,EAAE,OAAO,OAAO,KAAK,EAAE,CAAC;AAAA,MACnE,CAAC;AAAA,IACH,GAAG,KAAK;AAAA,EACV;AAEA,WAAS,YAAY,MAAc,SAAkB,MAAuB;AAC1E,UAAM,WAAW,cAAc,IAAI,IAAI;AACvC,QAAI,CAAC,YAAY,SAAS,SAAS,GAAG;AACpC;AAAA,IACF;AACA,eAAW,WAAW,UAAU;AAC9B,UAAI;AACF,gBAAQ,SAAS,IAAI;AAAA,MACvB,SAAS,OAAO;AACd,eAAO,KAAK,iCAAiC,EAAE,MAAM,OAAO,OAAO,KAAK,EAAE,CAAC;AAAA,MAC7E;AAAA,IACF;AAAA,EACF;AAEA,iBAAe,UAAyB;AACtC,QAAI,UAAU;AACZ;AAAA,IACF;AACA,QAAI,UAAU,OAAO,eAAe,KAAK,UAAU;AACjD;AAAA,IACF;AACA,QAAI,gBAAgB;AAClB,aAAO;AAAA,IACT;AAEA,qBAAiB,IAAI,QAAc,CAAC,SAAS,WAAW;AACtD,uBAAiB;AACjB,sBAAgB;AAAA,IAClB,CAAC;AAED,aAAS,QAAQ,mBACZ,QAAQ,iBAAiB,QAAQ,GAAG,IACrC,oBAAoB,QAAQ,GAAG;AAEnC,WAAO,GAAG,QAAQ,MAAM;AACtB,0BAAoB;AACpB,iBAAW;AACX,4BAAsB;AACtB,YAAM,QAAQ,aAAa,cAAc;AAAA,QACvC,QAAQ,QAAQ;AAAA,QAChB,UAAU,QAAQ;AAAA,QAClB,YAAY,QAAQ;AAAA,MACtB,CAAC;AACD,cAAQ,KAAK,kBAAkB,KAAK,CAAC;AACrC,yBAAmB,WAAW,MAAM;AAClC,YAAI,CAAC,UAAU;AACb,wBAAc,2BAA2B;AACzC,kBAAQ,MAAM;AAAA,QAChB;AAAA,MACF,GAAG,gBAAgB;AAAA,IACrB,CAAC;AAED,WAAO,GAAG,WAAW,CAAC,QAAQ;AAC5B,UAAI;AACF,cAAM,aAAa,OAAO,QAAQ,WAAW,MAAM,OAAO,GAAG;AAC7D,cAAM,WAAW,cAAc,UAAU;AACzC,gBAAQ,SAAS,MAAM;AAAA,UACrB,KAAK;AACH,uBAAW;AACX,gBACE,SAAS,WACT,OAAO,SAAS,YAAY,YAC5B,kBAAkB,SAAS,WAC3B,OAAQ,SAAS,QAAuC,iBAAiB,UACzE;AACA,oCAAuB,SAAS,QAAqC;AAAA,YACvE;AACA,gBAAI,qBAAqB;AACvB,yBAAW,WAAW,mBAAmB;AACvC,oBAAI;AACF,0BAAQ,EAAE,cAAc,qBAAqB,aAAa,KAAK,IAAI,EAAE,CAAC;AAAA,gBACxE,SAAS,OAAO;AACd,yBAAO,KAAK,qCAAqC,EAAE,OAAO,OAAO,KAAK,EAAE,CAAC;AAAA,gBAC3E;AAAA,cACF;AAAA,YACF;AACA,2BAAe;AACf;AAAA,UACF,KAAK,cAAc;AACjB,kBAAM,UAAU,SAAS;AACzB,mBAAO,MAAM,uCAAuC;AAAA,cAClD,MAAM,QAAQ;AAAA,cACd,SAAS,QAAQ;AAAA,YACnB,CAAC;AACD,0BAAc,QAAQ,OAAO;AAC7B,6BAAiB,gBAAgB,kCAAkC;AACnE,oBAAQ,MAAM;AACd;AAAA,UACF;AAAA,UACA,KAAK;AAAA,UACL,KAAK,iBAAiB;AACpB,kBAAM,YAAY,SAAS;AAC3B,gBAAI,CAAC,WAAW;AACd;AAAA,YACF;AACA,kBAAM,UAAU,gBAAgB,IAAI,SAAS;AAC7C,gBAAI,CAAC,SAAS;AACZ;AAAA,YACF;AACA,yBAAa,QAAQ,KAAK;AAC1B,oBAAQ,QAAQ,SAAS,OAA+B;AACxD,4BAAgB,OAAO,SAAS;AAChC;AAAA,UACF;AAAA,UACA,KAAK,cAAc;AACjB,kBAAM,UAAU,SAAS;AACzB,kBAAM,OAAkB,EAAE,IAAI,SAAS,GAAG;AAC1C,gBAAI,SAAS,QAAQ;AACnB,mBAAK,SAAS,SAAS;AAAA,YACzB;AACA,wBAAY,QAAQ,MAAM,QAAQ,MAAM,IAAI;AAC5C;AAAA,UACF;AAAA,UACA,KAAK;AACH,oBAAQ,kBAAkB,aAAa,QAAQ,CAAC,CAAC,CAAC,CAAC;AACnD;AAAA,UACF;AACE;AAAA,QACJ;AAAA,MACF,SAAS,OAAO;AACd,eAAO,KAAK,qCAAqC,EAAE,OAAO,OAAO,KAAK,EAAE,CAAC;AAAA,MAC3E;AAAA,IACF,CAAC;AAED,WAAO,GAAG,SAAS,MAAM;AACvB,YAAM,gBAAgB,CAAC,YAAY;AACnC,oBAAc,8BAA8B;AAC5C,iBAAW;AACX,4BAAsB;AACtB,uBAAiB,gBAAgB,uDAAuD;AACxF,iBAAW,WAAW,sBAAsB;AAC1C,YAAI;AACF,kBAAQ;AAAA,YACN,QAAQ;AAAA,YACR,IAAI,KAAK,IAAI;AAAA,YACb;AAAA,UACF,CAAC;AAAA,QACH,SAAS,OAAO;AACd,iBAAO,KAAK,wCAAwC,EAAE,OAAO,OAAO,KAAK,EAAE,CAAC;AAAA,QAC9E;AAAA,MACF;AACA,UAAI,CAAC,UAAU;AACb,0BAAkB;AAAA,MACpB;AAAA,IACF,CAAC;AAED,WAAO,GAAG,SAAS,CAAC,UAAU;AAC5B,aAAO,KAAK,0BAA0B,EAAE,OAAO,OAAO,KAAK,EAAE,CAAC;AAAA,IAChE,CAAC;AAED,WAAO;AAAA,EACT;AAEA,OAAK,QAAQ,EAAE,MAAM,CAAC,UAAU;AAC9B,WAAO,KAAK,sCAAsC,EAAE,OAAO,OAAO,KAAK,EAAE,CAAC;AAAA,EAC5E,CAAC;AAED,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM,KACJ,MACA,SACA,aACiD;AACjD,wBAAkB,WAAW,IAAI;AACjC,wBAAkB,WAAW,MAAM,OAAO;AAC1C,UAAI,CAAC,UAAU;AACb,YAAI;AACF,gBAAM,QAAQ;AAAA,QAChB,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,IAAI;AAAA,YACJ,WAAW,aAAa,aAAa;AAAA,YACrC,IAAI,KAAK,IAAI;AAAA,YACb,OAAO;AAAA,cACL,MAAM;AAAA,cACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU;AAAA,YACpD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,UAAI,CAAC,UAAU,OAAO,eAAe,GAAG;AACtC,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,WAAW,aAAa,aAAa;AAAA,UACrC,IAAI,KAAK,IAAI;AAAA,UACb,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS;AAAA,UACX;AAAA,QACF;AAAA,MACF;AAEA,YAAM,YAAY,aAAa,aAAa,gBAAgB;AAC5D,YAAM,YAAY,aAAa,aAAa;AAE5C,YAAM,UAAU,IAAI,QAAuB,CAAC,SAAS,WAAW;AAC9D,cAAM,QAAQ,WAAW,MAAM;AAC7B,0BAAgB,OAAO,SAAS;AAChC,iBAAO,IAAI,oBAAoB,WAAW,YAAY,IAAI,qBAAqB,SAAS,KAAK,CAAC;AAAA,QAChG,GAAG,SAAS;AAEZ,wBAAgB,IAAI,WAAW;AAAA,UAC7B;AAAA,UACA,QAAQ,CAAC,UAAU,OAAO,KAAK;AAAA,UAC/B;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAED;AAAA,QACE;AAAA,UACE;AAAA,YACE;AAAA,YACA;AAAA,cACE;AAAA,cACA,MAAM;AAAA,YACR;AAAA,YACA,EAAE,UAAU;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAEA,UAAI;AACF,eAAQ,MAAM;AAAA,MAChB,SAAS,OAAO;AACd,cAAM,cACJ,iBAAiB,sBACb,MAAM,OACN,CAAC,UAAU,OAAO,eAAe,IAC/B,iBACA;AACR,eAAO;AAAA,UACL,IAAI;AAAA,UACJ;AAAA,UACA,IAAI,KAAK,IAAI;AAAA,UACb,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU;AAAA,UACpD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,GAAG,MAAM,SAAS;AAChB,wBAAkB,SAAS,IAAI;AAC/B,YAAM,SAAS;AACf,YAAM,WAAW,cAAc,IAAI,IAAI;AACvC,UAAI,UAAU;AACZ,iBAAS,IAAI,MAAM;AAAA,MACrB,OAAO;AACL,sBAAc,IAAI,MAAM,oBAAI,IAAkB,CAAC,MAAM,CAAC,CAAC;AAAA,MACzD;AACA,aAAO,MAAM;AACX,cAAM,WAAW,cAAc,IAAI,IAAI;AACvC,YAAI,CAAC,UAAU;AACb;AAAA,QACF;AACA,iBAAS,OAAO,MAAM;AACtB,YAAI,SAAS,SAAS,GAAG;AACvB,wBAAc,OAAO,IAAI;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AAAA,IACA,IAAI,MAAM,SAAS;AACjB,wBAAkB,SAAS,IAAI;AAC/B,YAAM,WAAW,cAAc,IAAI,IAAI;AACvC,UAAI,CAAC,UAAU;AACb;AAAA,MACF;AACA,eAAS,OAAO,OAAuB;AACvC,UAAI,SAAS,SAAS,GAAG;AACvB,sBAAc,OAAO,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA,IACA,YAAY,SAAS;AACnB,wBAAkB,IAAI,OAAO;AAC7B,aAAO,MAAM;AACX,0BAAkB,OAAO,OAAO;AAAA,MAClC;AAAA,IACF;AAAA,IACA,eAAe,SAAS;AACtB,2BAAqB,IAAI,OAAO;AAChC,aAAO,MAAM;AACX,6BAAqB,OAAO,OAAO;AAAA,MACrC;AAAA,IACF;AAAA,IACA,eAAe,SAAS;AACtB,2BAAqB,IAAI,OAAO;AAChC,aAAO,MAAM;AACX,6BAAqB,OAAO,OAAO;AAAA,MACrC;AAAA,IACF;AAAA,IACA,QAAQ;AACN,aAAO,QAAQ;AAAA,IACjB;AAAA,IACA,YAAY;AACV,aAAO,QAAQ,UAAU,OAAO,eAAe,KAAK,QAAQ;AAAA,IAC9D;AAAA,IACA,eAAe;AACb,aAAO;AAAA,IACT;AAAA,IACA,MAAM,QAAQ;AACZ,iBAAW;AACX,iBAAW;AACX,4BAAsB;AACtB,oBAAc,qCAAqC;AACnD,UAAI,gBAAgB;AAClB,qBAAa,cAAc;AAC3B,yBAAiB;AAAA,MACnB;AACA,uBAAiB,gBAAgB,qCAAqC;AACtE,UAAI,CAAC,QAAQ;AACX;AAAA,MACF;AACA,YAAM,IAAI,QAAc,CAAC,YAAY;AACnC,cAAM,UAAU;AAChB,YAAI,CAAC,SAAS;AACZ,kBAAQ;AACR;AAAA,QACF;AACA,gBAAQ,KAAK,SAAS,MAAM,QAAQ,CAAC;AACrC,gBAAQ,MAAM;AAAA,MAChB,CAAC;AACD,eAAS;AAAA,IACX;AAAA,EACF;AACF;;;ACxcA,eAAsB,qBACpB,SAC2B;AAC3B,MAAI,QAAQ,QAAQ;AAClB,WAAO,EAAE,QAAQ,QAAQ,QAAQ,OAAO,MAAM;AAAA,EAChD;AAEA,MAAI,CAAC,QAAQ,OAAO;AAClB,WAAO,EAAE,OAAO,MAAM;AAAA,EACxB;AAEA,QAAM,gBAAgB,MAAM,OAAO,YAAY;AAC/C,QAAM,UAAU,IAAI,cAAc,OAAO;AAAA,IACvC,SAAS,CAAC;AAAA,EACZ,CAAC;AACD,QAAM,QAAQ,MAAM,QAAQ,KAAK;AACjC,SAAO,EAAE,QAAQ,SAAyC,OAAO,KAAK;AACxE;;;ACxBA,eAAsB,YACpB,SACA,WACA,iBAAiB,wBACL;AACZ,SAAO,IAAI,QAAW,CAAC,SAAS,WAAW;AACzC,UAAM,UAAU,WAAW,MAAM;AAC/B,aAAO,IAAI,MAAM,cAAc,CAAC;AAAA,IAClC,GAAG,SAAS;AAEZ,YACG,KAAK,CAAC,UAAU;AACf,mBAAa,OAAO;AACpB,cAAQ,KAAK;AAAA,IACf,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,mBAAa,OAAO;AACpB,aAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,IAClE,CAAC;AAAA,EACL,CAAC;AACH;AAEO,IAAM,cAAN,MAAqB;AAAA,EAG1B,YAA6B,OAAe;AAAf;AAAA,EAAgB;AAAA,EAAhB;AAAA,EAFZ,QAAQ,oBAAI,IAA6C;AAAA,EAI1E,IAAI,KAA4B;AAC9B,UAAM,QAAQ,KAAK,MAAM,IAAI,GAAG;AAChC,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,IACT;AACA,QAAI,MAAM,aAAa,KAAK,IAAI,GAAG;AACjC,WAAK,MAAM,OAAO,GAAG;AACrB,aAAO;AAAA,IACT;AACA,WAAO,MAAM;AAAA,EACf;AAAA,EAEA,IAAI,KAAa,OAAgB;AAC/B,SAAK,MAAM,IAAI,KAAK,EAAE,OAAO,WAAW,KAAK,IAAI,IAAI,KAAK,MAAM,CAAC;AAAA,EACnE;AACF;;;AC1CA,SAAS,uBAAuC;;;ACAhD,SAAS,uBAAuB;AAEzB,SAAS,cAAc,UAAkB,UAA2B;AACzE,QAAM,iBAAiB,OAAO,KAAK,QAAQ;AAC3C,QAAM,iBAAiB,OAAO,KAAK,QAAQ;AAE3C,MAAI,eAAe,WAAW,eAAe,QAAQ;AACnD,WAAO;AAAA,EACT;AAEA,SAAO,gBAAgB,gBAAgB,cAAc;AACvD;AAEO,SAAS,YAAY,aAA6B;AACvD,SAAO,IAAI,WAAW;AACxB;;;ADEA,IAAM,sBAAsB;AAC5B,IAAM,oBAAoB;AAC1B,IAAM,wBAAwB;AAYvB,IAAM,sBAAN,MAA0B;AAAA,EAQ/B,YAA6B,QAA0B;AAA1B;AAC3B,UAAM,eAAe,OAAO,QAAQ;AACpC,SAAK,cAAc,aAAa,eAAe;AAC/C,SAAK,SAAS,WAAW,OAAO,QAAQ,MAAM;AAE9C,SAAK,MAAM,IAAI,gBAAgB;AAAA,MAC7B,MAAM,aAAa;AAAA,MACnB,MAAM,aAAa;AAAA,MACnB,MAAM,aAAa,QAAQ;AAAA,MAC3B,YAAY,aAAa,mBAAmB;AAAA,IAC9C,CAAC;AAED,SAAK,IAAI,GAAG,cAAc,CAAC,QAAQ,YAAY,KAAK,iBAAiB,QAAQ,OAAO,CAAC;AACrF,SAAK,IAAI;AAAA,MAAG;AAAA,MAAS,CAAC,UACpB,KAAK,OAAO,MAAM,gCAAgC,EAAE,OAAO,OAAO,KAAK,EAAE,CAAC;AAAA,IAC5E;AAEA,SAAK,WAAW,YAAY,MAAM;AAChC,WAAK,gBAAgB;AAAA,IACvB,GAAG,KAAK,WAAW;AAAA,EACrB;AAAA,EApB6B;AAAA,EAPZ;AAAA,EACA,cAAc,oBAAI,IAAoC;AAAA,EACtD;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,EAChB;AAAA,EAwBjB,UAAU,MAAc,MAAe,QAAuB;AAC5D,UAAM,WAAW;AAAA,MACf;AAAA,MACA,EAAE,MAAM,KAAK;AAAA,MACb,SAAS,EAAE,OAAO,IAAI;AAAA,IACxB;AACA,UAAM,MAAM,kBAAkB,QAAQ;AAEtC,eAAW,SAAS,KAAK,YAAY,OAAO,GAAG;AAC7C,UAAI,CAAC,MAAM,eAAe;AACxB;AAAA,MACF;AACA,WAAK,SAAS,MAAM,QAAQ,GAAG;AAAA,IACjC;AAAA,EACF;AAAA,EAEA,MAAM,QAAuB;AAC3B,kBAAc,KAAK,QAAQ;AAC3B,eAAW,cAAc,KAAK,YAAY,OAAO,GAAG;AAClD,iBAAW,OAAO,MAAM;AAAA,IAC1B;AACA,SAAK,YAAY,MAAM;AACvB,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,WAAK,IAAI,MAAM,CAAC,UAAU;AACxB,YAAI,OAAO;AACT,iBAAO,KAAK;AACZ;AAAA,QACF;AACA,gBAAQ;AAAA,MACV,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEQ,iBAAiB,QAAmB,SAAgC;AAC1E,UAAM,YAAY,KAAK,OAAO,QAAQ,OAAO;AAC7C,QAAI,aAAa,UAAU,SAAS,GAAG;AACrC,YAAM,SAAS,QAAQ,QAAQ;AAC/B,UAAI,CAAC,UAAU,CAAC,UAAU,SAAS,MAAM,GAAG;AAC1C,eAAO,MAAM,mBAAmB,qBAAqB;AACrD;AAAA,MACF;AAAA,IACF;AAEA,UAAM,QAA6B;AAAA,MACjC,IAAI,mBAAmB;AAAA,MACvB;AAAA,MACA,eAAe;AAAA,MACf,iBAAiB,KAAK,IAAI;AAAA,IAC5B;AACA,SAAK,YAAY,IAAI,QAAQ,KAAK;AAElC,UAAM,YAAY,WAAW,MAAM;AACjC,UAAI,CAAC,MAAM,eAAe;AACxB,eAAO,MAAM,qBAAqB,0BAA0B;AAAA,MAC9D;AAAA,IACF,GAAG,KAAK,aAAa;AAErB,WAAO,GAAG,WAAW,CAAC,QAAQ;AAC5B,YAAM,aACJ,OAAO,QAAQ,WAAW,MAAM,OAAO,SAAS,GAAG,IAAI,IAAI,SAAS,MAAM,IAAI;AAChF,UAAI,CAAC,YAAY;AACf,aAAK,OAAO,KAAK,wCAAwC,EAAE,OAAO,4BAA4B,CAAC;AAC/F,eAAO,MAAM,uBAAuB,kBAAkB;AACtD;AAAA,MACF;AACA,UAAI;AACJ,UAAI;AACF,iBAAS,cAAc,UAAU;AAAA,MACnC,SAAS,OAAO;AACd,aAAK,OAAO,KAAK,wCAAwC,EAAE,OAAO,OAAO,KAAK,EAAE,CAAC;AACjF,eAAO,MAAM,uBAAuB,kBAAkB;AACtD;AAAA,MACF;AACA,WAAK,KAAK,cAAc,OAAO,MAAM,EAAE,MAAM,CAAC,UAAmB;AAC/D,aAAK,OAAO,KAAK,wCAAwC,EAAE,OAAO,OAAO,KAAK,EAAE,CAAC;AACjF,eAAO,MAAM,uBAAuB,kBAAkB;AAAA,MACxD,CAAC;AAAA,IACH,CAAC;AAED,WAAO,GAAG,SAAS,MAAM;AACvB,mBAAa,SAAS;AACtB,WAAK,YAAY,OAAO,MAAM;AAAA,IAChC,CAAC;AAED,WAAO;AAAA,MAAG;AAAA,MAAS,CAAC,UAClB,KAAK,OAAO,KAAK,iBAAiB,EAAE,cAAc,MAAM,IAAI,OAAO,OAAO,KAAK,EAAE,CAAC;AAAA,IACpF;AAAA,EACF;AAAA,EAEA,MAAc,cAAc,OAA4B,UAAuC;AAC7F,QAAI,SAAS,SAAS,QAAQ;AAC5B,YAAM,kBAAkB,KAAK,IAAI;AACjC,WAAK,SAAS,MAAM,QAAQ,kBAAkB,aAAa,QAAQ,CAAC,CAAC,CAAC,CAAC;AACvE;AAAA,IACF;AACA,QAAI,SAAS,SAAS,QAAQ;AAC5B,YAAM,kBAAkB,KAAK,IAAI;AACjC;AAAA,IACF;AAEA,QAAI,CAAC,MAAM,eAAe;AACxB,UAAI,SAAS,SAAS,cAAc;AAClC,cAAM,OAAO,MAAM,qBAAqB,0BAA0B;AAClE;AAAA,MACF;AAEA,YAAM,UAAU,SAAS;AACzB,YAAM,iBAAiB,SAAS;AAChC,YAAM,eAAe,KAAK,OAAO,QAAQ,OAAO;AAChD,YAAM,WAAW,SAAS;AAC1B,UAAI,aAA4D;AAEhE,UAAI,CAAC,gBAAgB;AACnB,qBAAa;AAAA,MACf,WAAW,UAAU;AACnB,cAAM,cAAc,aAAa,UAAU,CAAC,GAAG,UAAU,YAAY,KAAK,MAAM,QAAQ;AACxF,YAAI,cAAc,GAAG;AACnB,uBAAa;AAAA,QACf,OAAO;AACL,gBAAM,iBAAiB,aAAa,WAAW;AAC/C,cAAI,CAAC,kBAAkB,CAAC,cAAc,gBAAgB,cAAc,GAAG;AACrE,yBAAa;AAAA,UACf;AAAA,QACF;AAAA,MACF,WAAW,CAAC,aAAa,KAAK,CAAC,WAAW,cAAc,gBAAgB,MAAM,CAAC,GAAG;AAChF,qBAAa;AAAA,MACf;AAEA,UAAI,YAAY;AACd,aAAK;AAAA,UACH,MAAM;AAAA,UACN;AAAA,YACE,aAAa,cAAc;AAAA,cACzB,MAAM;AAAA,cACN,QAAQ;AAAA,cACR,SAAS;AAAA,YACX,CAAC;AAAA,UACH;AAAA,QACF;AACA,cAAM,OAAO,MAAM,mBAAmB,iBAAiB;AACvD;AAAA,MACF;AAEA,YAAM,gBAAgB;AACtB,YAAM,kBAAkB,KAAK,IAAI;AACjC,UAAI,QAAQ,YAAY;AACtB,cAAM,aAAa,QAAQ;AAAA,MAC7B;AACA,WAAK;AAAA,QACH,MAAM;AAAA,QACN,kBAAkB,aAAa,WAAW,EAAE,cAAc,MAAM,GAAG,CAAC,CAAC;AAAA,MACvE;AACA;AAAA,IACF;AAEA,QAAI,SAAS,SAAS,mBAAmB;AACvC,YAAM,UAAU,SAAS;AACzB,UAAI,CAAC,SAAS,aAAa,CAAC,SAAS,MAAM;AACzC,cAAM,UAA0B;AAAA,UAC9B,IAAI;AAAA,UACJ,WAAW,SAAS,aAAa;AAAA,UACjC,IAAI,KAAK,IAAI;AAAA,UACb,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS;AAAA,UACX;AAAA,QACF;AACA,aAAK;AAAA,UACH,MAAM;AAAA,UACN,kBAAkB,aAAa,iBAAiB,SAAS,EAAE,WAAW,QAAQ,UAAU,CAAC,CAAC;AAAA,QAC5F;AACA;AAAA,MACF;AAEA,YAAM,WAAW,MAAM,KAAK,OAAO;AAAA,QACjC;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AACA,YAAM,eAAe,SAAS,KAAK,mBAAmB;AACtD,WAAK;AAAA,QACH,MAAM;AAAA,QACN,kBAAkB,aAAa,cAAc,UAAU,EAAE,WAAW,SAAS,UAAU,CAAC,CAAC;AAAA,MAC3F;AACA;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,kBAAwB;AAC9B,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,YAAY,KAAK,cAAc;AAErC,eAAW,SAAS,KAAK,YAAY,OAAO,GAAG;AAC7C,UAAI,CAAC,MAAM,eAAe;AACxB;AAAA,MACF;AAEA,UAAI,MAAM,MAAM,kBAAkB,WAAW;AAC3C,cAAM,OAAO,UAAU;AACvB,aAAK,YAAY,OAAO,MAAM,MAAM;AACpC;AAAA,MACF;AAEA,WAAK,SAAS,MAAM,QAAQ,kBAAkB,aAAa,QAAQ,CAAC,CAAC,CAAC,CAAC;AAAA,IACzE;AAAA,EACF;AAAA,EAEQ,SAAS,QAAmB,SAAuB;AACzD,QAAI,OAAO,eAAe,GAAG;AAC3B,aAAO,KAAK,OAAO;AAAA,IACrB;AAAA,EACF;AACF;;;AE/PA,IAAM,6BAA6B;AAE5B,SAAS,oBACd,SACA,cAGqB;AACrB,QAAM,kBAAkB,oBAAI,IAA4B;AACxD,QAAM,mBAAmB,QAAQ,OAAO,oBAAoB;AAC5D,QAAM,cAAc,IAAI,YAA6C,mBAAmB,CAAC;AAEzF,QAAM,aAAa,IAAI,oBAAoB;AAAA,IACzC;AAAA,IACA,kBAAkB,OAAO,YAAY,SAAS,WAAW,WAAW;AAClE,YAAM,WAAW,GAAG,WAAW,EAAE,IAAI,SAAS,IAAI,QAAQ,IAAI;AAC9D,YAAM,SAAS,YAAY,IAAI,QAAQ;AACvC,UAAI,QAAQ;AACV,eAAO;AAAA,MACT;AAEA,YAAM,UAAU,gBAAgB,IAAI,QAAQ,IAAI;AAChD,UAAI,CAAC,SAAS;AACZ,cAAM,UAA0B;AAAA,UAC9B,IAAI;AAAA,UACJ;AAAA,UACA,IAAI,KAAK,IAAI;AAAA,UACb,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS,sCAAsC,QAAQ,IAAI;AAAA,UAC7D;AAAA,QACF;AACA,oBAAY,IAAI,UAAU,OAAO;AACjC,eAAO;AAAA,MACT;AAEA,YAAM,UAA0B;AAAA,QAC9B;AAAA,QACA,cAAc,WAAW;AAAA,QACzB,YAAY,KAAK,IAAI;AAAA,MACvB;AACA,UAAI,QAAQ;AACV,gBAAQ,SAAS;AAAA,MACnB;AAEA,UAAI;AACF,cAAM,oBAAoB,QAAQ,YAAY,WAAW,QAAQ,IAAI;AACrE,cAAM,mBAAmB,uBAAuB,mBAAmB,SAAS,QAAQ,MAAM;AAAA,UACxF,MAAM,QAAQ;AAAA,UACd,OAAO;AAAA,QACT,CAAC;AAED,cAAM,eAAe,QAAQ,QAAQ,QAAQ,kBAAkB,OAAO,CAAC;AACvE,cAAM,QAAQ,MAAM;AAAA,UAClB;AAAA,UACA;AAAA,UACA,YAAY,QAAQ,IAAI,qBAAqB,gBAAgB;AAAA,QAC/D;AACA,cAAM,oBAAoB,uBAAuB,mBAAmB,UAAU,OAAO;AAAA,UACnF,MAAM,QAAQ;AAAA,UACd,OAAO;AAAA,QACT,CAAC;AACD,cAAM,UAA0B;AAAA,UAC9B,IAAI;AAAA,UACJ;AAAA,UACA,IAAI,KAAK,IAAI;AAAA,UACb,MAAM;AAAA,QACR;AACA,oBAAY,IAAI,UAAU,OAAO;AACjC,eAAO;AAAA,MACT,SAAS,OAAO;AACd,YAAI,iBAAiB,wBAAwB;AAC3C,gBAAMA,WAA0B;AAAA,YAC9B,IAAI;AAAA,YACJ;AAAA,YACA,IAAI,KAAK,IAAI;AAAA,YACb,OAAO;AAAA,cACL,MAAM;AAAA,cACN,SAAS,MAAM;AAAA,cACf,SAAS,MAAM;AAAA,YACjB;AAAA,UACF;AACA,sBAAY,IAAI,UAAUA,QAAO;AACjC,iBAAOA;AAAA,QACT;AACA,cAAM,YAAY,iBAAiB,SAAS,aAAa,KAAK,MAAM,OAAO;AAC3E,cAAM,UAA0B;AAAA,UAC9B,IAAI;AAAA,UACJ;AAAA,UACA,IAAI,KAAK,IAAI;AAAA,UACb,OAAO;AAAA,YACL,MAAM,YAAY,YAAY;AAAA,YAC9B,SAAS,iBAAiB,QAAQ,MAAM,UAAU;AAAA,UACpD;AAAA,QACF;AACA,oBAAY,IAAI,UAAU,OAAO;AACjC,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU,MAAM,SAAS;AACvB,wBAAkB,WAAW,IAAI;AACjC,sBAAgB,IAAI,MAAM,OAAyB;AACnD,aAAO,MAAM;AACX,wBAAgB,OAAO,IAAI;AAAA,MAC7B;AAAA,IACF;AAAA,IACA,UAAU,MAAM,SAAS;AACvB,wBAAkB,SAAS,IAAI;AAC/B,YAAM,mBAAmB,uBAAuB,QAAQ,YAAY,SAAS,IAAI,GAAG,SAAS;AAAA,QAC3F;AAAA,QACA,OAAO;AAAA,MACT,CAAC;AACD,wBAAkB,SAAS,MAAM,gBAAgB;AACjD,iBAAW,UAAU,MAAM,kBAAkB,QAAQ,IAAI;AAAA,IAC3D;AAAA,IACA,UAAU,MAAM,SAAS;AACvB,wBAAkB,SAAS,IAAI;AAC/B,YAAM,mBAAmB,uBAAuB,QAAQ,YAAY,SAAS,IAAI,GAAG,SAAS;AAAA,QAC3F;AAAA,QACA,OAAO;AAAA,MACT,CAAC;AACD,wBAAkB,SAAS,MAAM,gBAAgB;AACjD,iBAAW,UAAU,MAAM,kBAAkB,QAAQ,IAAI;AAAA,IAC3D;AAAA,IACA,QAAQ;AACN,aAAO,WAAW,MAAM,EAAE,KAAK,YAAY;AACzC,cAAM,cAAc,UAAU;AAAA,MAChC,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;ACpIO,SAAS,oBAAuB,QAA8C;AACnF,SAAO;AAAA,IACL,MAAM,OAAO;AACX,YAAM,SAAS,OAAO,UAAU,KAAK;AACrC,UAAI,OAAO,SAAS;AAClB,eAAO,OAAO;AAAA,MAChB;AACA,YAAM,QAAQ,IAAI,MAAM,OAAO,MAAM,OAAO;AAC5C,UAAI,OAAO,MAAM,QAAQ;AACvB,cAAM,SAAS,OAAO,MAAM;AAAA,MAC9B;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;AC/BA,SAAS,iBAAiB,MAA0C;AAClE,MAAI,KAAK,WAAW,GAAG;AACrB,WAAO;AAAA,EACT;AACA,SAAO,KACJ,OAAO,CAAC,YAAwC,OAAO,YAAY,YAAY,OAAO,YAAY,QAAQ,EAC1G,IAAI,CAAC,YAAY,OAAO,OAAO,CAAC,EAChC,KAAK,GAAG;AACb;AAEO,SAAS,cAAiB,QAAsC;AACrE,SAAO,oBAAuB;AAAA,IAC5B,UAAU,OAAO;AACf,YAAM,SAAS,OAAO,UAAU,KAAK;AACrC,UAAI,OAAO,SAAS;AAClB,eAAO,EAAE,SAAS,MAAM,MAAM,OAAO,KAAK;AAAA,MAC5C;AACA,YAAM,SAAkC,OAAO,MAAM,OAAO,IAAI,CAAC,WAAW;AAAA,QAC1E,MAAM,iBAAiB,MAAM,IAAI;AAAA,QACjC,SAAS,MAAM;AAAA,MACjB,EAAE;AACF,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,UACL,SAAS;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ACrBA,SAAS,cACP,SAC8B;AAC9B,SAAO,YAAY;AACrB;AAQO,SAAS,gBACd,SAC+C;AAC/C,MAAI,CAAC,cAAc,OAAO,GAAG;AAC3B,0BAAsB,OAAO;AAC7B,WAAO,wBAA8B,OAAO;AAAA,EAC9C;AACA,oBAAkB,OAAO;AAEzB,MAAI;AAEJ,MAAI,CAAC,QAAQ,UAAU,QAAQ,OAAO;AACpC,yBAAqB,qBAAqB,OAAO,EAC9C,KAAK,CAAC,UAAU;AACf,UAAI,CAAC,MAAM,SAAS,CAAC,MAAM,QAAQ;AACjC,eAAO;AAAA,MACT;AACA,aAAO;AAAA,QACL,SAAS,MAAM,MAAM,QAAQ,QAAQ;AAAA,MACvC;AAAA,IACF,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,cAAQ,QAAQ,QAAQ,sDAAsD;AAAA,QAC5E,OAAO,OAAO,KAAK;AAAA,MACrB,CAAC;AACD,aAAO;AAAA,IACT,CAAC;AAAA,EACL;AAEA,SAAO,oBAA0B,SAAS;AAAA,IACxC,SAAS,YAAY;AACnB,YAAM,QAAQ,MAAM;AACpB,aAAO,QAAQ;AAAA,IACjB;AAAA,EACF,CAAC;AACH;","names":["failure"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shardwire",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Lightweight Discord-hosted WebSocket bridge for commands and events.",
|
|
5
5
|
"homepage": "https://www.npmjs.com/package/shardwire",
|
|
6
6
|
"repository": {
|
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
"clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
|
|
26
26
|
"build": "tsup src/index.ts --format esm,cjs --dts --sourcemap",
|
|
27
27
|
"typecheck": "tsc --noEmit",
|
|
28
|
+
"lint": "eslint . --max-warnings=0",
|
|
29
|
+
"lint:fix": "eslint . --fix",
|
|
28
30
|
"test": "vitest run",
|
|
29
31
|
"example:host": "tsx examples/host-basic.ts",
|
|
30
32
|
"example:consumer": "tsx examples/consumer-basic.ts",
|
|
@@ -67,10 +69,14 @@
|
|
|
67
69
|
"zod": "^4.3.6"
|
|
68
70
|
},
|
|
69
71
|
"devDependencies": {
|
|
72
|
+
"@eslint/js": "^9.38.0",
|
|
70
73
|
"@types/node": "^24.5.2",
|
|
71
74
|
"@types/ws": "^8.18.1",
|
|
75
|
+
"eslint": "^9.38.0",
|
|
76
|
+
"globals": "^16.4.0",
|
|
72
77
|
"tsup": "^8.5.0",
|
|
73
78
|
"tsx": "^4.20.6",
|
|
79
|
+
"typescript-eslint": "^8.46.1",
|
|
74
80
|
"typescript": "^5.9.2",
|
|
75
81
|
"vitest": "^3.2.4"
|
|
76
82
|
},
|