silgi 0.0.14 → 0.1.0-beta.2
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 +102 -1
- package/dist/_virtual/_rolldown/runtime.mjs +5 -0
- package/dist/adapters/astro.d.mts +17 -0
- package/dist/adapters/astro.mjs +24 -0
- package/dist/adapters/aws-lambda.d.mts +31 -0
- package/dist/adapters/aws-lambda.mjs +85 -0
- package/dist/adapters/elysia.d.mts +17 -0
- package/dist/adapters/elysia.mjs +76 -0
- package/dist/adapters/express.d.mts +16 -0
- package/dist/adapters/express.mjs +78 -0
- package/dist/adapters/fastify.d.mts +15 -0
- package/dist/adapters/fastify.mjs +78 -0
- package/dist/adapters/message-port.d.mts +37 -0
- package/dist/adapters/message-port.mjs +129 -0
- package/dist/adapters/nestjs.d.mts +25 -0
- package/dist/adapters/nestjs.mjs +91 -0
- package/dist/adapters/nextjs.d.mts +21 -0
- package/dist/adapters/nextjs.mjs +30 -0
- package/dist/adapters/peer.d.mts +27 -0
- package/dist/adapters/peer.mjs +36 -0
- package/dist/adapters/remix.d.mts +17 -0
- package/dist/adapters/remix.mjs +24 -0
- package/dist/adapters/solidstart.d.mts +14 -0
- package/dist/adapters/solidstart.mjs +30 -0
- package/dist/adapters/sveltekit.d.mts +18 -0
- package/dist/adapters/sveltekit.mjs +33 -0
- package/dist/analyze.mjs +26 -0
- package/dist/broker/index.d.mts +62 -0
- package/dist/broker/index.mjs +153 -0
- package/dist/broker/nats.d.mts +33 -0
- package/dist/broker/nats.mjs +31 -0
- package/dist/broker/redis.d.mts +51 -0
- package/dist/broker/redis.mjs +92 -0
- package/dist/builder.d.mts +36 -0
- package/dist/builder.mjs +51 -0
- package/dist/callable.d.mts +17 -0
- package/dist/callable.mjs +42 -0
- package/dist/client/adapters/fetch/index.d.mts +17 -0
- package/dist/client/adapters/fetch/index.mjs +61 -0
- package/dist/client/adapters/ofetch/index.d.mts +41 -0
- package/dist/client/adapters/ofetch/index.mjs +92 -0
- package/dist/client/client.d.mts +29 -0
- package/dist/client/client.mjs +54 -0
- package/dist/client/dynamic-link.d.mts +15 -0
- package/dist/client/dynamic-link.mjs +16 -0
- package/dist/client/index.d.mts +7 -0
- package/dist/client/index.mjs +6 -0
- package/dist/client/interceptor.d.mts +31 -0
- package/dist/client/interceptor.mjs +34 -0
- package/dist/client/merge.d.mts +28 -0
- package/dist/client/merge.mjs +30 -0
- package/dist/client/openapi.d.mts +29 -0
- package/dist/client/openapi.mjs +89 -0
- package/dist/client/plugins/batch.d.mts +20 -0
- package/dist/client/plugins/batch.mjs +64 -0
- package/dist/client/plugins/csrf.d.mts +13 -0
- package/dist/client/plugins/csrf.mjs +20 -0
- package/dist/client/plugins/dedupe.d.mts +10 -0
- package/dist/client/plugins/dedupe.mjs +28 -0
- package/dist/client/plugins/index.d.mts +5 -0
- package/dist/client/plugins/index.mjs +5 -0
- package/dist/client/plugins/retry.d.mts +11 -0
- package/dist/client/plugins/retry.mjs +21 -0
- package/dist/client/server.d.mts +16 -0
- package/dist/client/server.mjs +60 -0
- package/dist/client/types.d.mts +29 -0
- package/dist/codec/devalue.d.mts +21 -0
- package/dist/codec/devalue.mjs +32 -0
- package/dist/codec/msgpack.d.mts +21 -0
- package/dist/codec/msgpack.mjs +59 -0
- package/dist/compile.d.mts +54 -0
- package/dist/compile.mjs +305 -0
- package/dist/contract.d.mts +36 -0
- package/dist/contract.mjs +40 -0
- package/dist/core/error.d.mts +104 -0
- package/dist/core/error.mjs +139 -0
- package/dist/core/handler.mjs +546 -0
- package/dist/core/iterator.d.mts +17 -0
- package/dist/core/iterator.mjs +79 -0
- package/dist/core/router-utils.mjs +16 -0
- package/dist/core/schema.d.mts +19 -0
- package/dist/core/schema.mjs +26 -0
- package/dist/core/serve.mjs +38 -0
- package/dist/core/sse.d.mts +16 -0
- package/dist/core/sse.mjs +95 -0
- package/dist/core/storage.d.mts +21 -0
- package/dist/core/storage.mjs +63 -0
- package/dist/core/utils.mjs +21 -0
- package/dist/fast-stringify.mjs +125 -0
- package/dist/index.d.mts +15 -37
- package/dist/index.mjs +13 -7
- package/dist/integrations/ai/index.d.mts +25 -0
- package/dist/integrations/ai/index.mjs +116 -0
- package/dist/integrations/react/index.d.mts +83 -0
- package/dist/integrations/react/index.mjs +197 -0
- package/dist/integrations/tanstack-query/index.d.mts +120 -0
- package/dist/integrations/tanstack-query/index.mjs +100 -0
- package/dist/integrations/tanstack-query/ssr.d.mts +51 -0
- package/dist/integrations/tanstack-query/ssr.mjs +89 -0
- package/dist/integrations/zod/converter.d.mts +75 -0
- package/dist/integrations/zod/converter.mjs +345 -0
- package/dist/integrations/zod/index.d.mts +2 -0
- package/dist/integrations/zod/index.mjs +2 -0
- package/dist/lazy.d.mts +24 -0
- package/dist/lazy.mjs +27 -0
- package/dist/lifecycle.d.mts +36 -0
- package/dist/lifecycle.mjs +46 -0
- package/dist/map-input.d.mts +17 -0
- package/dist/map-input.mjs +24 -0
- package/dist/plugins/analytics.d.mts +168 -0
- package/dist/plugins/analytics.mjs +459 -0
- package/dist/plugins/batch-server.d.mts +20 -0
- package/dist/plugins/batch-server.mjs +86 -0
- package/dist/plugins/body-limit.d.mts +16 -0
- package/dist/plugins/body-limit.mjs +44 -0
- package/dist/plugins/cache.d.mts +170 -0
- package/dist/plugins/cache.mjs +200 -0
- package/dist/plugins/coerce.d.mts +21 -0
- package/dist/plugins/coerce.mjs +46 -0
- package/dist/plugins/compression.d.mts +19 -0
- package/dist/plugins/compression.mjs +23 -0
- package/dist/plugins/cookies.d.mts +44 -0
- package/dist/plugins/cookies.mjs +67 -0
- package/dist/plugins/cors.d.mts +39 -0
- package/dist/plugins/cors.mjs +56 -0
- package/dist/plugins/custom-serializer.d.mts +57 -0
- package/dist/plugins/custom-serializer.mjs +40 -0
- package/dist/plugins/file-upload.d.mts +38 -0
- package/dist/plugins/file-upload.mjs +100 -0
- package/dist/plugins/index.d.mts +16 -0
- package/dist/plugins/index.mjs +16 -0
- package/dist/plugins/otel.d.mts +35 -0
- package/dist/plugins/otel.mjs +40 -0
- package/dist/plugins/pino.d.mts +60 -0
- package/dist/plugins/pino.mjs +42 -0
- package/dist/plugins/pubsub.d.mts +50 -0
- package/dist/plugins/pubsub.mjs +53 -0
- package/dist/plugins/ratelimit.d.mts +51 -0
- package/dist/plugins/ratelimit.mjs +81 -0
- package/dist/plugins/signing.d.mts +41 -0
- package/dist/plugins/signing.mjs +115 -0
- package/dist/plugins/strict-get.d.mts +10 -0
- package/dist/plugins/strict-get.mjs +33 -0
- package/dist/route/add.mjs +240 -0
- package/dist/route/compiler.mjs +373 -0
- package/dist/route/context.mjs +12 -0
- package/dist/route/types.d.mts +11 -0
- package/dist/route/utils.mjs +17 -0
- package/dist/scalar.d.mts +53 -0
- package/dist/scalar.mjs +330 -0
- package/dist/silgi.d.mts +139 -0
- package/dist/silgi.mjs +113 -0
- package/dist/trpc-interop.d.mts +22 -0
- package/dist/trpc-interop.mjs +68 -0
- package/dist/types.d.mts +82 -0
- package/dist/ws.d.mts +42 -0
- package/dist/ws.mjs +137 -0
- package/lib/dashboard/index.html +123 -0
- package/lib/ocache.d.mts +1 -0
- package/lib/ocache.mjs +1 -0
- package/lib/ofetch.d.mts +1 -0
- package/lib/ofetch.mjs +1 -0
- package/lib/srvx.d.mts +1 -0
- package/lib/srvx.mjs +1 -0
- package/lib/unstorage.d.mts +1 -0
- package/lib/unstorage.mjs +1 -0
- package/package.json +291 -65
- package/bin/silgi.mjs +0 -3
- package/dist/chunks/generate.mjs +0 -933
- package/dist/chunks/init.mjs +0 -21
- package/dist/cli/config.d.mts +0 -19
- package/dist/cli/config.d.ts +0 -19
- package/dist/cli/config.mjs +0 -5
- package/dist/cli/index.d.mts +0 -2
- package/dist/cli/index.d.ts +0 -2
- package/dist/cli/index.mjs +0 -119
- package/dist/index.d.ts +0 -37
- package/dist/plugins/openapi.d.mts +0 -138
- package/dist/plugins/openapi.d.ts +0 -138
- package/dist/plugins/openapi.mjs +0 -204
- package/dist/plugins/scalar.d.mts +0 -14
- package/dist/plugins/scalar.d.ts +0 -14
- package/dist/plugins/scalar.mjs +0 -66
- package/dist/shared/silgi.BMCYk2cR.mjs +0 -841
- package/dist/shared/silgi.D5qK9QOm.d.mts +0 -301
- package/dist/shared/silgi.D5qK9QOm.d.ts +0 -301
package/dist/types.d.mts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { AnySchema, InferSchemaInput } from "./core/schema.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/types.d.ts
|
|
4
|
+
/** HTTP route metadata */
|
|
5
|
+
interface Route {
|
|
6
|
+
method?: string;
|
|
7
|
+
path?: string;
|
|
8
|
+
summary?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
tags?: string[];
|
|
11
|
+
deprecated?: boolean;
|
|
12
|
+
successStatus?: number;
|
|
13
|
+
successDescription?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Cache-Control header for query responses.
|
|
16
|
+
*
|
|
17
|
+
* - `number` — shorthand for `max-age=N` (seconds)
|
|
18
|
+
* - `string` — full Cache-Control value (e.g. `'public, max-age=60, stale-while-revalidate=30'`)
|
|
19
|
+
* - Only applies to query procedures (mutations and subscriptions are never cached)
|
|
20
|
+
*/
|
|
21
|
+
cache?: number | string;
|
|
22
|
+
/** Enable WebSocket RPC for this procedure */
|
|
23
|
+
ws?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/** Procedure metadata */
|
|
26
|
+
type Meta = Record<string, unknown>;
|
|
27
|
+
type ProcedureType = 'query' | 'mutation' | 'subscription';
|
|
28
|
+
/** Internal procedure representation — fixed shape for V8 optimization */
|
|
29
|
+
interface ProcedureDef<TType extends ProcedureType = ProcedureType, _TInput = unknown, _TOutput = unknown, TErrors extends ErrorDef = ErrorDef> {
|
|
30
|
+
readonly type: TType;
|
|
31
|
+
readonly input: AnySchema | null;
|
|
32
|
+
readonly output: AnySchema | null;
|
|
33
|
+
readonly errors: TErrors | null;
|
|
34
|
+
readonly use: readonly MiddlewareDef[] | null;
|
|
35
|
+
readonly resolve: Function;
|
|
36
|
+
readonly route: Route | null;
|
|
37
|
+
readonly meta: Meta | null;
|
|
38
|
+
}
|
|
39
|
+
/** Error definition: number shorthand or full config */
|
|
40
|
+
type ErrorDefItem = number | {
|
|
41
|
+
status: number;
|
|
42
|
+
message?: string;
|
|
43
|
+
data?: AnySchema;
|
|
44
|
+
};
|
|
45
|
+
type ErrorDef = Record<string, ErrorDefItem>;
|
|
46
|
+
/** Extract data schema from error def item */
|
|
47
|
+
type ErrorData<T extends ErrorDefItem> = T extends {
|
|
48
|
+
data: infer S extends AnySchema;
|
|
49
|
+
} ? InferSchemaInput<S> : undefined;
|
|
50
|
+
/** Typed fail() function — inferred from errors definition */
|
|
51
|
+
type FailFn<TErrors extends ErrorDef> = <K extends keyof TErrors & string>(code: K, ...args: ErrorData<TErrors[K]> extends undefined ? [data?: unknown] : [data: ErrorData<TErrors[K]>]) => never;
|
|
52
|
+
type GuardFn<TCtxIn, TReturn> = (ctx: TCtxIn) => TReturn | Promise<TReturn> | void | Promise<void>;
|
|
53
|
+
type WrapFn<TCtx> = (ctx: TCtx, next: () => Promise<unknown>) => Promise<unknown>;
|
|
54
|
+
interface GuardDef<TCtxIn = unknown, TReturn = unknown, TErrors extends ErrorDef = {}> {
|
|
55
|
+
readonly kind: 'guard';
|
|
56
|
+
readonly fn: GuardFn<TCtxIn, TReturn>;
|
|
57
|
+
readonly errors?: TErrors;
|
|
58
|
+
}
|
|
59
|
+
interface WrapDef<TCtx = unknown> {
|
|
60
|
+
readonly kind: 'wrap';
|
|
61
|
+
readonly fn: WrapFn<TCtx>;
|
|
62
|
+
}
|
|
63
|
+
type MiddlewareDef = GuardDef<any, any> | WrapDef<any>;
|
|
64
|
+
/** Extract the context additions from a single guard */
|
|
65
|
+
type InferGuardOutput<T> = T extends GuardDef<any, infer O> ? (O extends void | undefined ? {} : O extends Record<string, unknown> ? O : {}) : {};
|
|
66
|
+
/** Walk a middleware tuple, accumulate guard outputs into context */
|
|
67
|
+
type InferContextFromUse<T extends readonly MiddlewareDef[], TBase> = T extends readonly [infer Head, ...infer Tail extends readonly MiddlewareDef[]] ? InferContextFromUse<Tail, TBase & InferGuardOutput<Head>> : TBase;
|
|
68
|
+
interface ResolveContext<TCtx, TInput, TErrors extends ErrorDef> {
|
|
69
|
+
ctx: TCtx;
|
|
70
|
+
input: TInput;
|
|
71
|
+
fail: FailFn<TErrors>;
|
|
72
|
+
signal: AbortSignal;
|
|
73
|
+
/** URL params extracted from the route pattern (e.g. `/users/:id` → `{ id: '123' }`) */
|
|
74
|
+
params: Record<string, string>;
|
|
75
|
+
}
|
|
76
|
+
type RouterDef = {
|
|
77
|
+
[key: string]: ProcedureDef<any, any, any, any> | RouterDef;
|
|
78
|
+
};
|
|
79
|
+
/** Infer client type from router */
|
|
80
|
+
type InferClient<T> = T extends ProcedureDef<infer TType, infer TInput, infer TOutput> ? TType extends 'subscription' ? undefined extends TInput ? () => AsyncIterableIterator<TOutput> : (input: TInput) => AsyncIterableIterator<TOutput> : undefined extends TInput ? () => Promise<TOutput> : (input: TInput) => Promise<TOutput> : T extends Record<string, unknown> ? { [K in keyof T]: InferClient<T[K]> } : never;
|
|
81
|
+
//#endregion
|
|
82
|
+
export { ErrorDef, ErrorDefItem, FailFn, GuardDef, GuardFn, InferClient, InferContextFromUse, InferGuardOutput, Meta, MiddlewareDef, ProcedureDef, ProcedureType, ResolveContext, Route, RouterDef, WrapDef, WrapFn };
|
package/dist/ws.d.mts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { RouterDef } from "./types.mjs";
|
|
2
|
+
import { Hooks } from "crossws";
|
|
3
|
+
import { Server } from "node:http";
|
|
4
|
+
|
|
5
|
+
//#region src/ws.d.ts
|
|
6
|
+
interface WSAdapterOptions {
|
|
7
|
+
/** Use MessagePack binary protocol instead of JSON */
|
|
8
|
+
binary?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Create crossws-compatible hooks for Silgi RPC over WebSocket.
|
|
12
|
+
*
|
|
13
|
+
* Works with any crossws integration — Nitro, Deno, Bun, Cloudflare, etc.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* // Nitro / Nuxt
|
|
18
|
+
* import { createWSHooks } from "silgi/ws";
|
|
19
|
+
* export default defineWebSocketHandler(createWSHooks(appRouter));
|
|
20
|
+
*
|
|
21
|
+
* // Deno
|
|
22
|
+
* import { createWSHooks } from "silgi/ws";
|
|
23
|
+
* Deno.serve({ handler, websocket: createWSHooks(appRouter) });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
declare function createWSHooks(routerDef: RouterDef, options?: WSAdapterOptions): Partial<Hooks>;
|
|
27
|
+
/**
|
|
28
|
+
* Attach WebSocket RPC handler to an existing Node.js HTTP server.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { createServer } from "node:http";
|
|
33
|
+
* import { attachWebSocket } from "silgi/ws";
|
|
34
|
+
*
|
|
35
|
+
* const server = createServer(httpHandler);
|
|
36
|
+
* attachWebSocket(server, appRouter);
|
|
37
|
+
* server.listen(3000);
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
declare function attachWebSocket(server: Server, routerDef: RouterDef, options?: WSAdapterOptions): Promise<void>;
|
|
41
|
+
//#endregion
|
|
42
|
+
export { WSAdapterOptions, attachWebSocket, createWSHooks };
|
package/dist/ws.mjs
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { SilgiError, toSilgiError } from "./core/error.mjs";
|
|
2
|
+
import { compileRouter } from "./compile.mjs";
|
|
3
|
+
import { stringifyJSON } from "./core/utils.mjs";
|
|
4
|
+
import { decode, encode } from "./codec/msgpack.mjs";
|
|
5
|
+
//#region src/ws.ts
|
|
6
|
+
/**
|
|
7
|
+
* WebSocket RPC adapter — powered by crossws.
|
|
8
|
+
*
|
|
9
|
+
* Bidirectional type-safe RPC over WebSocket.
|
|
10
|
+
* Supports subscriptions (server → client streaming) natively.
|
|
11
|
+
*
|
|
12
|
+
* Protocol:
|
|
13
|
+
* Client → Server: { id: string, path: string, input?: unknown }
|
|
14
|
+
* Server → Client: { id: string, result?: unknown, error?: unknown }
|
|
15
|
+
* Server → Client (stream): { id: string, data: unknown, done?: boolean }
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Create crossws-compatible hooks for Silgi RPC over WebSocket.
|
|
19
|
+
*
|
|
20
|
+
* Works with any crossws integration — Nitro, Deno, Bun, Cloudflare, etc.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* // Nitro / Nuxt
|
|
25
|
+
* import { createWSHooks } from "silgi/ws";
|
|
26
|
+
* export default defineWebSocketHandler(createWSHooks(appRouter));
|
|
27
|
+
*
|
|
28
|
+
* // Deno
|
|
29
|
+
* import { createWSHooks } from "silgi/ws";
|
|
30
|
+
* Deno.serve({ handler, websocket: createWSHooks(appRouter) });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
function createWSHooks(routerDef, options = {}) {
|
|
34
|
+
const flat = compileRouter(routerDef);
|
|
35
|
+
const binary = options.binary ?? false;
|
|
36
|
+
function send(peer, data) {
|
|
37
|
+
if (binary) peer.send(encode(data));
|
|
38
|
+
else peer.send(stringifyJSON(data));
|
|
39
|
+
}
|
|
40
|
+
function parseMessage(message) {
|
|
41
|
+
if (binary) return decode(message.uint8Array());
|
|
42
|
+
return message.json();
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
open(_peer) {},
|
|
46
|
+
async message(peer, message) {
|
|
47
|
+
let req;
|
|
48
|
+
try {
|
|
49
|
+
req = parseMessage(message);
|
|
50
|
+
} catch {
|
|
51
|
+
send(peer, {
|
|
52
|
+
id: "0",
|
|
53
|
+
error: {
|
|
54
|
+
code: "BAD_REQUEST",
|
|
55
|
+
status: 400,
|
|
56
|
+
message: "Invalid message format"
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const { id, path, input } = req;
|
|
62
|
+
const route = flat("POST", "/" + path)?.data;
|
|
63
|
+
if (!route || !route.ws) {
|
|
64
|
+
send(peer, {
|
|
65
|
+
id,
|
|
66
|
+
error: {
|
|
67
|
+
code: "NOT_FOUND",
|
|
68
|
+
status: 404,
|
|
69
|
+
message: `Procedure "${path}" not found`
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const ctx = Object.create(null);
|
|
75
|
+
const ac = new AbortController();
|
|
76
|
+
try {
|
|
77
|
+
const result = route.handler(ctx, input ?? {}, ac.signal);
|
|
78
|
+
const output = result instanceof Promise ? await result : result;
|
|
79
|
+
if (output && typeof output === "object" && Symbol.asyncIterator in output) {
|
|
80
|
+
const iter = output;
|
|
81
|
+
try {
|
|
82
|
+
for await (const data of iter) send(peer, {
|
|
83
|
+
id,
|
|
84
|
+
data
|
|
85
|
+
});
|
|
86
|
+
send(peer, {
|
|
87
|
+
id,
|
|
88
|
+
data: null,
|
|
89
|
+
done: true
|
|
90
|
+
});
|
|
91
|
+
} catch (err) {
|
|
92
|
+
send(peer, {
|
|
93
|
+
id,
|
|
94
|
+
error: (err instanceof SilgiError ? err : toSilgiError(err)).toJSON()
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
send(peer, {
|
|
100
|
+
id,
|
|
101
|
+
result: output
|
|
102
|
+
});
|
|
103
|
+
} catch (err) {
|
|
104
|
+
send(peer, {
|
|
105
|
+
id,
|
|
106
|
+
error: (err instanceof SilgiError ? err : toSilgiError(err)).toJSON()
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
close(_peer, _details) {},
|
|
111
|
+
error(_peer, error) {
|
|
112
|
+
console.error("[silgi:ws] error:", error);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Attach WebSocket RPC handler to an existing Node.js HTTP server.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* import { createServer } from "node:http";
|
|
122
|
+
* import { attachWebSocket } from "silgi/ws";
|
|
123
|
+
*
|
|
124
|
+
* const server = createServer(httpHandler);
|
|
125
|
+
* attachWebSocket(server, appRouter);
|
|
126
|
+
* server.listen(3000);
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
async function attachWebSocket(server, routerDef, options = {}) {
|
|
130
|
+
const nodeAdapter = (await import("crossws/adapters/node")).default;
|
|
131
|
+
const ws = nodeAdapter({ hooks: createWSHooks(routerDef, options) });
|
|
132
|
+
server.on("upgrade", (req, socket, head) => {
|
|
133
|
+
ws.handleUpgrade(req, socket, head);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
//#endregion
|
|
137
|
+
export { attachWebSocket, createWSHooks };
|