@spikard/node 0.12.0 → 0.13.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 CHANGED
@@ -1,18 +1,37 @@
1
- # Spikard for Node.js
1
+ <!-- GENERATED FILE — DO NOT EDIT DIRECTLY. Run: task readme:generate -->
2
2
 
3
- [![Documentation](https://img.shields.io/badge/docs-spikard.dev-blue)](https://spikard.dev)
4
- [![Crates.io](https://img.shields.io/crates/v/spikard.svg?color=blue)](https://crates.io/crates/spikard)
5
- [![PyPI](https://img.shields.io/pypi/v/spikard.svg?color=blue)](https://pypi.org/project/spikard/)
6
- [![npm](https://img.shields.io/npm/v/@spikard/node.svg?color=blue)](https://www.npmjs.com/package/@spikard/node)
7
- [![Gem](https://img.shields.io/gem/v/spikard.svg?color=blue)](https://rubygems.org/gems/spikard)
8
- [![Packagist](https://img.shields.io/packagist/v/spikard/spikard.svg?color=blue)](https://packagist.org/packages/spikard/spikard)
9
- [![Hex.pm](https://img.shields.io/hexpm/v/spikard.svg?color=blue)](https://hex.pm/packages/spikard)
10
- [![License](https://img.shields.io/badge/license-MIT-blue.svg)](../../LICENSE)
3
+ # Spikard for Node.js
11
4
 
12
- High-performance HTTP framework for Node.js powered by a Rust core. Provides type-safe routing, validation, middleware, and testing via **napi-rs** bindings with zero-copy JSON conversion.
5
+ <div align="center" style="display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin: 20px 0;">
6
+ <a href="https://spikard.dev">
7
+ <img src="https://img.shields.io/badge/docs-spikard.dev-007ec6" alt="Documentation">
8
+ </a>
9
+ <a href="https://crates.io/crates/spikard">
10
+ <img src="https://img.shields.io/crates/v/spikard.svg?color=007ec6" alt="Crates.io">
11
+ </a>
12
+ <a href="https://pypi.org/project/spikard/">
13
+ <img src="https://img.shields.io/pypi/v/spikard.svg?color=007ec6" alt="PyPI">
14
+ </a>
15
+ <a href="https://www.npmjs.com/package/@spikard/node">
16
+ <img src="https://img.shields.io/npm/v/@spikard/node.svg?color=007ec6" alt="npm">
17
+ </a>
18
+ <a href="https://rubygems.org/gems/spikard">
19
+ <img src="https://img.shields.io/gem/v/spikard.svg?color=007ec6" alt="RubyGems">
20
+ </a>
21
+ <a href="https://packagist.org/packages/spikard/spikard">
22
+ <img src="https://img.shields.io/packagist/v/spikard/spikard.svg?color=007ec6" alt="Packagist">
23
+ </a>
24
+ <a href="https://hex.pm/packages/spikard">
25
+ <img src="https://img.shields.io/hexpm/v/spikard.svg?color=007ec6" alt="Hex.pm">
26
+ </a>
27
+ <a href="https://github.com/Goldziher/spikard/blob/main/LICENSE">
28
+ <img src="https://img.shields.io/badge/license-MIT-007ec6" alt="License">
29
+ </a>
30
+ </div>
31
+
32
+ High-performance HTTP framework for Node.js powered by a Rust core. Provides type-safe routing, validation, middleware, and testing via napi-rs bindings with zero-copy JSON conversion.
13
33
 
14
34
  ## Features
15
-
16
35
  - **Rust-Powered Performance**: Native speed via Tokio with dedicated thread pool
17
36
  - **Full TypeScript Support**: Auto-generated types from napi-rs FFI bindings
18
37
  - **Zero-Copy JSON**: Direct conversion without serialization overhead
@@ -77,7 +96,6 @@ app.addRoute(
77
96
 
78
97
  app.run({ port: 8000 });
79
98
  ```
80
-
81
99
  ## Routing & Schemas
82
100
 
83
101
  Routes support Zod validation (recommended) or raw JSON Schema:
@@ -215,6 +233,28 @@ app.onResponse(async (response) => {
215
233
  });
216
234
  ```
217
235
 
236
+ ## Performance
237
+
238
+ Benchmarked across 34 workloads at 100 concurrency ([methodology](../../docs/benchmarks/methodology.md)):
239
+
240
+ | Framework | Avg RPS | P50 (ms) | P99 (ms) |
241
+ |-----------|--------:|----------:|----------:|
242
+ | **spikard (Bun)** | 49,460 | 2.18 | 4.21 |
243
+ | **spikard (Node)** | 46,160 | 2.18 | 3.35 |
244
+ | elysia | 44,326 | 2.41 | 4.68 |
245
+ | kito | 36,958 | 4.94 | 12.86 |
246
+ | fastify | 19,167 | 6.74 | 14.76 |
247
+ | morojs | 14,196 | 6.44 | 12.61 |
248
+ | hono | 10,928 | 10.91 | 18.62 |
249
+
250
+ Spikard is **1.2x faster than Kito and 2.4x faster than Fastify**.
251
+
252
+ Key optimizations:
253
+ - **napi-rs** zero-copy FFI bindings
254
+ - **Dedicated Tokio runtime** without blocking Node event loop
255
+ - **Zero-copy JSON** conversion (30-40% faster than JSON.parse)
256
+ - **ThreadsafeFunction** for async JavaScript callbacks
257
+
218
258
  ## Testing
219
259
 
220
260
  Use TestClient for HTTP, WebSocket, and SSE testing:
@@ -237,48 +277,22 @@ await ws.sendJson({ message: "hello" });
237
277
  const sse = await client.get("/events");
238
278
  ```
239
279
 
240
- ## Performance
241
-
242
- Benchmarked across 34 workloads at 100 concurrency ([methodology](../../docs/benchmarks/methodology.md)):
243
-
244
- | Framework | Avg RPS | P50 (ms) | P99 (ms) |
245
- |-----------|--------:|----------:|----------:|
246
- | **spikard (Bun)** | 49,460 | 2.18 | 4.21 |
247
- | **spikard (Node)** | 46,160 | 2.18 | 3.35 |
248
- | elysia | 44,326 | 2.41 | 4.68 |
249
- | kito | 36,958 | 4.94 | 12.86 |
250
- | fastify | 19,167 | 6.74 | 14.76 |
251
- | morojs | 14,196 | 6.44 | 12.61 |
252
- | hono | 10,928 | 10.91 | 18.62 |
253
-
254
- Spikard Node is **1.2x faster** than Kito and **2.4x faster** than Fastify.
255
-
256
- Key optimizations:
257
- - **napi-rs** zero-copy FFI bindings
258
- - **Dedicated Tokio runtime** without blocking Node event loop
259
- - **Zero-copy JSON** conversion (30-40% faster than JSON.parse)
260
- - **ThreadsafeFunction** for async JavaScript callbacks
261
-
262
280
  ## Examples
263
281
 
264
- See [examples/](../../examples/) for runnable projects. Code generation is supported for OpenAPI, GraphQL, AsyncAPI, and JSON-RPC specifications.
282
+ See [examples/](../../examples/) for runnable projects. Code generation is supported for OpenAPI, GraphQL, AsyncAPI, OpenRPC/JSON-RPC, and Protobuf/gRPC specifications.
265
283
 
266
284
  ## Documentation
267
285
 
268
286
  Full documentation at [spikard.dev](https://spikard.dev). See also [CONTRIBUTING.md](../../CONTRIBUTING.md).
269
287
 
270
- ## Ecosystem
271
-
272
- Spikard is available across multiple languages:
288
+ ## Other Languages
273
289
 
274
- | Platform | Package | Status |
275
- |----------|---------|--------|
276
- | **Node.js** | [@spikard/node](https://www.npmjs.com/package/@spikard/node) | Stable |
277
- | **Python** | [spikard](https://pypi.org/project/spikard/) | Stable |
278
- | **Rust** | [spikard](https://crates.io/crates/spikard) | Stable |
279
- | **Ruby** | [spikard](https://rubygems.org/gems/spikard) | Stable |
280
- | **PHP** | [spikard/spikard](https://packagist.org/packages/spikard/spikard) | Stable |
281
- | **Elixir** | [spikard](https://hex.pm/packages/spikard) | Stable |
290
+ - **Rust:** [Crates.io](https://crates.io/crates/spikard)
291
+ - **Python:** [PyPI](https://pypi.org/project/spikard/)
292
+ - **TypeScript:** [npm (@spikard/node)](https://www.npmjs.com/package/@spikard/node)
293
+ - **Ruby:** [RubyGems](https://rubygems.org/gems/spikard)
294
+ - **PHP:** [Packagist](https://packagist.org/packages/spikard/spikard)
295
+ - **Elixir:** [Hex.pm](https://hex.pm/packages/spikard)
282
296
 
283
297
  ## License
284
298
 
package/dist/index.d.mts CHANGED
@@ -1,67 +1,3 @@
1
- interface StreamingResponseInit {
2
- statusCode?: number;
3
- headers?: Record<string, string>;
4
- }
5
- declare const STREAM_HANDLE_PROP: "__spikard_stream_handle";
6
- type StreamChunk = JsonValue | string | Buffer | Uint8Array | ArrayBuffer | ArrayBufferView | null | undefined;
7
- type ChunkIterator = AsyncIterator<StreamChunk> & AsyncIterable<StreamChunk>;
8
- type StreamingHandle = {
9
- kind: "native";
10
- handle: number;
11
- init: StreamingResponseInit;
12
- } | {
13
- kind: "js";
14
- iterator: ChunkIterator;
15
- init: StreamingResponseInit;
16
- };
17
- declare class StreamingResponse {
18
- readonly [STREAM_HANDLE_PROP]: StreamingHandle;
19
- constructor(stream: AsyncIterable<StreamChunk> | AsyncIterator<StreamChunk>, init?: StreamingResponseInit);
20
- }
21
-
22
- type JsonPrimitive = string | number | boolean | null;
23
- type JsonValue = JsonPrimitive | JsonValue[] | {
24
- [Key in string]: JsonValue;
25
- };
26
- type JsonRecord = Record<string, JsonValue>;
27
- type MaybePromise<T> = T | Promise<T>;
28
- interface Base64EncodedBody {
29
- __spikard_base64__: string;
30
- }
31
- type HandlerBody = JsonValue | Base64EncodedBody | null;
32
- interface StructuredHandlerResponse {
33
- status?: number;
34
- statusCode?: number;
35
- headers?: Record<string, string>;
36
- body?: HandlerBody;
37
- }
38
- type HandlerResult = StructuredHandlerResponse | JsonValue | StreamingResponse | undefined;
39
- type HandlerFunction<TReturn extends HandlerResult = HandlerResult> = (request: Request) => MaybePromise<TReturn>;
40
- type NativeHandlerFunction<TReturn extends HandlerResult = HandlerResult> = (requestJson: string) => MaybePromise<TReturn | string>;
41
- type WebSocketHandler = (message: unknown) => MaybePromise<unknown>;
42
- interface WebSocketOptions {
43
- onConnect?: () => MaybePromise<void>;
44
- onDisconnect?: () => MaybePromise<void>;
45
- messageSchema?: unknown;
46
- responseSchema?: unknown;
47
- handlerName?: string;
48
- }
49
-
50
- interface Request {
51
- method: string;
52
- path: string;
53
- params: Record<string, string>;
54
- pathParams: Record<string, string>;
55
- query: Record<string, string>;
56
- queryParams: Record<string, string>;
57
- headers: Record<string, string>;
58
- cookies: Record<string, string>;
59
- body: Buffer | null;
60
- dependencies: Record<string, unknown> | undefined;
61
- json<T = JsonValue>(): T;
62
- form(): Record<string, string>;
63
- }
64
-
65
1
  interface CompressionConfig {
66
2
  gzip?: boolean;
67
3
  brotli?: boolean;
@@ -147,62 +83,6 @@ interface ServerConfig {
147
83
  jsonrpc?: JsonRpcConfig | null;
148
84
  }
149
85
 
150
- interface ServerOptions {
151
- host?: string;
152
- port?: number;
153
- }
154
- declare function runServer(app: SpikardApp, config?: ServerConfig | ServerOptions): void;
155
-
156
- type DependencyValue = unknown;
157
- type DependencyFactory = (dependencies: Record<string, DependencyValue>) => MaybePromise<DependencyValue>;
158
- interface DependencyOptions {
159
- dependsOn?: string[];
160
- singleton?: boolean;
161
- cacheable?: boolean;
162
- }
163
- interface DependencyDescriptor {
164
- isFactory: boolean;
165
- value?: DependencyValue | undefined;
166
- factory?: DependencyFactory | undefined;
167
- dependsOn: string[];
168
- singleton: boolean;
169
- cacheable: boolean;
170
- }
171
- type LifecycleHookPayload = Request | StructuredHandlerResponse;
172
- type LifecycleHookFunction = (payload: LifecycleHookPayload) => MaybePromise<LifecycleHookPayload>;
173
- interface LifecycleHooks {
174
- onRequest: LifecycleHookFunction[];
175
- preValidation: LifecycleHookFunction[];
176
- preHandler: LifecycleHookFunction[];
177
- onResponse: LifecycleHookFunction[];
178
- onError: LifecycleHookFunction[];
179
- }
180
- declare class Spikard implements SpikardApp {
181
- routes: RouteMetadata[];
182
- handlers: Record<string, HandlerFunction | NativeHandlerFunction>;
183
- websocketRoutes: RouteMetadata[];
184
- websocketHandlers: Record<string, Record<string, unknown>>;
185
- lifecycleHooks: LifecycleHooks;
186
- dependencies: Record<string, DependencyDescriptor>;
187
- addRoute(metadata: RouteMetadata, handler: HandlerFunction | NativeHandlerFunction): void;
188
- websocket(path: string, handler: WebSocketHandler, options?: WebSocketOptions): void;
189
- run(options?: ServerOptions): void;
190
- onRequest(hook: LifecycleHookFunction): LifecycleHookFunction;
191
- preValidation(hook: LifecycleHookFunction): LifecycleHookFunction;
192
- preHandler(hook: LifecycleHookFunction): LifecycleHookFunction;
193
- onResponse(hook: LifecycleHookFunction): LifecycleHookFunction;
194
- onError(hook: LifecycleHookFunction): LifecycleHookFunction;
195
- provide(key: string, valueOrFactory: DependencyValue | DependencyFactory, options?: DependencyOptions): this;
196
- getLifecycleHooks(): LifecycleHooks;
197
- }
198
-
199
- declare function run(work: () => void | Promise<void>): void;
200
-
201
- declare const background_run: typeof run;
202
- declare namespace background {
203
- export { background_run as run };
204
- }
205
-
206
86
  type GrpcMetadata = Record<string, string>;
207
87
  interface GrpcRequest {
208
88
  serviceName: string;
@@ -214,9 +94,37 @@ interface GrpcResponse {
214
94
  payload: Buffer;
215
95
  metadata?: GrpcMetadata;
216
96
  }
97
+ interface GrpcClientStreamRequest {
98
+ serviceName: string;
99
+ methodName: string;
100
+ metadata: GrpcMetadata;
101
+ messages: Buffer[];
102
+ }
103
+ interface GrpcServerStreamResponse {
104
+ messages: Buffer[];
105
+ }
106
+ interface GrpcBidiStreamRequest {
107
+ serviceName: string;
108
+ methodName: string;
109
+ metadata: GrpcMetadata;
110
+ messages: Buffer[];
111
+ }
112
+ interface GrpcBidiStreamResponse {
113
+ messages: Buffer[];
114
+ metadata?: GrpcMetadata;
115
+ }
217
116
  interface GrpcHandler {
218
117
  handleRequest(request: GrpcRequest): Promise<GrpcResponse>;
219
118
  }
119
+ interface GrpcServerStreamingHandler {
120
+ handleServerStream(request: GrpcRequest): Promise<GrpcServerStreamResponse>;
121
+ }
122
+ interface GrpcClientStreamingHandler {
123
+ handleClientStream(request: GrpcClientStreamRequest): Promise<GrpcResponse>;
124
+ }
125
+ interface GrpcBidirectionalStreamingHandler {
126
+ handleBidiStream(request: GrpcBidiStreamRequest): Promise<GrpcBidiStreamResponse>;
127
+ }
220
128
  declare enum GrpcStatusCode {
221
129
  OK = 0,
222
130
  CANCELLED = 1,
@@ -240,9 +148,29 @@ declare class GrpcError extends Error {
240
148
  readonly code: GrpcStatusCode;
241
149
  constructor(code: GrpcStatusCode, message: string);
242
150
  }
243
- interface GrpcServiceConfig {
151
+ type GrpcRpcMode = "unary" | "serverStreaming" | "clientStreaming" | "bidirectionalStreaming";
152
+ type GrpcMethodHandler = GrpcHandler | GrpcServerStreamingHandler | GrpcClientStreamingHandler | GrpcBidirectionalStreamingHandler;
153
+ interface GrpcMethodConfig {
244
154
  serviceName: string;
245
- handler: GrpcHandler;
155
+ methodName: string;
156
+ rpcMode: GrpcRpcMode;
157
+ handler: GrpcMethodHandler;
158
+ }
159
+ declare class GrpcService {
160
+ private readonly methods;
161
+ private methodKey;
162
+ private registerMethod;
163
+ registerUnary(serviceName: string, methodName: string, handler: GrpcHandler): this;
164
+ registerServerStreaming(serviceName: string, methodName: string, handler: GrpcServerStreamingHandler): this;
165
+ registerClientStreaming(serviceName: string, methodName: string, handler: GrpcClientStreamingHandler): this;
166
+ registerBidirectionalStreaming(serviceName: string, methodName: string, handler: GrpcBidirectionalStreamingHandler): this;
167
+ unregister(serviceName: string, methodName: string): void;
168
+ getMethod(serviceName: string, methodName: string): GrpcMethodConfig | undefined;
169
+ serviceNames(): string[];
170
+ methodNames(serviceName: string): string[];
171
+ hasMethod(serviceName: string, methodName: string): boolean;
172
+ entries(): GrpcMethodConfig[];
173
+ handleRequest(request: GrpcRequest): Promise<GrpcResponse>;
246
174
  }
247
175
  type UnaryHandlerResult<TResponse> = TResponse | {
248
176
  response: TResponse;
@@ -257,6 +185,128 @@ declare function createUnaryHandler<TRequest, TResponse>(methodName: string, han
257
185
  }): GrpcHandler;
258
186
  declare function createServiceHandler(methods: Record<string, GrpcHandler>): GrpcHandler;
259
187
 
188
+ interface StreamingResponseInit {
189
+ statusCode?: number;
190
+ headers?: Record<string, string>;
191
+ }
192
+ declare const STREAM_HANDLE_PROP: "__spikard_stream_handle";
193
+ type StreamChunk = JsonValue | string | Buffer | Uint8Array | ArrayBuffer | ArrayBufferView | null | undefined;
194
+ type ChunkIterator = AsyncIterator<StreamChunk> & AsyncIterable<StreamChunk>;
195
+ type StreamingHandle = {
196
+ kind: "native";
197
+ handle: number;
198
+ init: StreamingResponseInit;
199
+ } | {
200
+ kind: "js";
201
+ iterator: ChunkIterator;
202
+ init: StreamingResponseInit;
203
+ };
204
+ declare class StreamingResponse {
205
+ readonly [STREAM_HANDLE_PROP]: StreamingHandle;
206
+ constructor(stream: AsyncIterable<StreamChunk> | AsyncIterator<StreamChunk>, init?: StreamingResponseInit);
207
+ }
208
+
209
+ type JsonPrimitive = string | number | boolean | null;
210
+ type JsonValue = JsonPrimitive | JsonValue[] | {
211
+ [Key in string]: JsonValue;
212
+ };
213
+ type JsonRecord = Record<string, JsonValue>;
214
+ type MaybePromise<T> = T | Promise<T>;
215
+ interface Base64EncodedBody {
216
+ __spikard_base64__: string;
217
+ }
218
+ type HandlerBody = JsonValue | Base64EncodedBody | null;
219
+ interface StructuredHandlerResponse {
220
+ status?: number;
221
+ statusCode?: number;
222
+ headers?: Record<string, string>;
223
+ body?: HandlerBody;
224
+ }
225
+ type HandlerResult = StructuredHandlerResponse | JsonValue | StreamingResponse | undefined;
226
+ type HandlerFunction<TReturn extends HandlerResult = HandlerResult> = (request: Request) => MaybePromise<TReturn>;
227
+ type NativeHandlerFunction<TReturn extends HandlerResult = HandlerResult> = (requestJson: string) => MaybePromise<TReturn | string>;
228
+ type WebSocketHandler = (message: unknown) => MaybePromise<unknown>;
229
+ interface WebSocketOptions {
230
+ onConnect?: () => MaybePromise<void>;
231
+ onDisconnect?: () => MaybePromise<void>;
232
+ messageSchema?: unknown;
233
+ responseSchema?: unknown;
234
+ handlerName?: string;
235
+ }
236
+
237
+ interface Request {
238
+ method: string;
239
+ path: string;
240
+ params: Record<string, string>;
241
+ pathParams: Record<string, string>;
242
+ query: Record<string, string>;
243
+ queryParams: Record<string, string>;
244
+ headers: Record<string, string>;
245
+ cookies: Record<string, string>;
246
+ body: Buffer | null;
247
+ dependencies: Record<string, unknown> | undefined;
248
+ json<T = JsonValue>(): T;
249
+ form(): Record<string, string>;
250
+ }
251
+
252
+ type DependencyValue = unknown;
253
+ type DependencyFactory = (dependencies: Record<string, DependencyValue>) => MaybePromise<DependencyValue>;
254
+ interface DependencyOptions {
255
+ dependsOn?: string[];
256
+ singleton?: boolean;
257
+ cacheable?: boolean;
258
+ }
259
+ interface DependencyDescriptor {
260
+ isFactory: boolean;
261
+ value?: DependencyValue | undefined;
262
+ factory?: DependencyFactory | undefined;
263
+ dependsOn: string[];
264
+ singleton: boolean;
265
+ cacheable: boolean;
266
+ }
267
+ type LifecycleHookPayload = Request | StructuredHandlerResponse;
268
+ type LifecycleHookFunction = (payload: LifecycleHookPayload) => MaybePromise<LifecycleHookPayload>;
269
+ interface LifecycleHooks {
270
+ onRequest: LifecycleHookFunction[];
271
+ preValidation: LifecycleHookFunction[];
272
+ preHandler: LifecycleHookFunction[];
273
+ onResponse: LifecycleHookFunction[];
274
+ onError: LifecycleHookFunction[];
275
+ }
276
+ declare class Spikard implements SpikardApp {
277
+ routes: RouteMetadata[];
278
+ handlers: Record<string, HandlerFunction | NativeHandlerFunction>;
279
+ websocketRoutes: RouteMetadata[];
280
+ websocketHandlers: Record<string, Record<string, unknown>>;
281
+ grpcMethods: GrpcMethodRegistration[];
282
+ grpcHandlers: Record<string, Record<string, unknown>>;
283
+ lifecycleHooks: LifecycleHooks;
284
+ dependencies: Record<string, DependencyDescriptor>;
285
+ addRoute(metadata: RouteMetadata, handler: HandlerFunction | NativeHandlerFunction): void;
286
+ websocket(path: string, handler: WebSocketHandler, options?: WebSocketOptions): void;
287
+ addGrpcUnary(serviceName: string, methodName: string, handler: GrpcHandler): this;
288
+ addGrpcServerStreaming(serviceName: string, methodName: string, handler: GrpcServerStreamingHandler): this;
289
+ addGrpcClientStreaming(serviceName: string, methodName: string, handler: GrpcClientStreamingHandler): this;
290
+ addGrpcBidirectionalStreaming(serviceName: string, methodName: string, handler: GrpcBidirectionalStreamingHandler): this;
291
+ private registerGrpcMethod;
292
+ useGrpc(service: GrpcService): this;
293
+ run(config?: ServerConfig): void;
294
+ onRequest(hook: LifecycleHookFunction): LifecycleHookFunction;
295
+ preValidation(hook: LifecycleHookFunction): LifecycleHookFunction;
296
+ preHandler(hook: LifecycleHookFunction): LifecycleHookFunction;
297
+ onResponse(hook: LifecycleHookFunction): LifecycleHookFunction;
298
+ onError(hook: LifecycleHookFunction): LifecycleHookFunction;
299
+ provide(key: string, valueOrFactory: DependencyValue | DependencyFactory, options?: DependencyOptions): this;
300
+ getLifecycleHooks(): LifecycleHooks;
301
+ }
302
+
303
+ declare function run(work: () => void | Promise<void>): void;
304
+
305
+ declare const background_run: typeof run;
306
+ declare namespace background {
307
+ export { background_run as run };
308
+ }
309
+
260
310
  declare function wrapHandler(handler: HandlerFunction): NativeHandlerFunction;
261
311
  declare function wrapBodyHandler<TBody = unknown>(handler: (body: TBody, request: Request) => MaybePromise<HandlerResult>): NativeHandlerFunction;
262
312
 
@@ -280,6 +330,8 @@ declare function put(path: string, options?: Omit<RouteOptions, "methods">): (ha
280
330
  declare function del(path: string, options?: Omit<RouteOptions, "methods">): (handler: RouteHandler) => RouteHandler;
281
331
  declare function patch(path: string, options?: Omit<RouteOptions, "methods">): (handler: RouteHandler) => RouteHandler;
282
332
 
333
+ declare function runServer(app: SpikardApp, config?: ServerConfig): void;
334
+
283
335
  interface NativeTestResponse {
284
336
  statusCode: number;
285
337
  headers(): Record<string, string>;
@@ -402,14 +454,22 @@ interface RouteMetadata {
402
454
  is_async: boolean;
403
455
  cors?: CorsConfig | undefined;
404
456
  }
457
+ interface GrpcMethodRegistration {
458
+ serviceName: string;
459
+ methodName: string;
460
+ rpcMode: GrpcRpcMode;
461
+ handlerName: string;
462
+ }
405
463
  interface SpikardApp {
406
464
  routes: RouteMetadata[];
407
465
  handlers: Record<string, HandlerFunction | NativeHandlerFunction>;
408
466
  websocketRoutes?: RouteMetadata[];
409
467
  websocketHandlers?: Record<string, Record<string, unknown>>;
468
+ grpcMethods?: GrpcMethodRegistration[];
469
+ grpcHandlers?: Record<string, Record<string, unknown>>;
410
470
  config?: ServerConfig;
411
471
  lifecycleHooks?: Partial<LifecycleHooks>;
412
472
  dependencies?: Record<string, unknown>;
413
473
  }
414
474
 
415
- export { type ApiKeyConfig, type Base64EncodedBody, type Body, type CompressionConfig, type ContactInfo, type CorsConfig, type DependencyFactory, type DependencyOptions, type DependencyValue, type FileParam, GrpcError, type GrpcHandler, type GrpcMetadata, type GrpcRequest, type GrpcResponse, type GrpcServiceConfig, GrpcStatusCode, type HandlerFunction, type HandlerResult, type JsonPrimitive, type JsonRecord, type JsonRpcConfig, type JsonSchema, type JsonValue, type JwtConfig, type LicenseInfo, type LifecycleHookFunction, type LifecycleHooks, type MaybePromise, type NativeHandlerFunction, type OpenApiConfig, type Path, type Query, QueryDefault, type RateLimitConfig, type Request, type RouteMetadata, type RouteOptions, type SecuritySchemeInfo, type ServerConfig, type ServerInfo, type ServerOptions, Spikard, type SpikardApp, type StaticFilesConfig, StreamingResponse, type StreamingResponseInit, type StructuredHandlerResponse, TestClient, type TestResponse, UploadFile, type WebSocketHandler, type WebSocketOptions, background, createServiceHandler, createUnaryHandler, del, get, patch, post, put, route, runServer, wrapBodyHandler, wrapHandler };
475
+ export { type ApiKeyConfig, type Base64EncodedBody, type Body, type CompressionConfig, type ContactInfo, type CorsConfig, type DependencyFactory, type DependencyOptions, type DependencyValue, type FileParam, type GrpcBidiStreamRequest, type GrpcBidiStreamResponse, type GrpcBidirectionalStreamingHandler, type GrpcClientStreamRequest, type GrpcClientStreamingHandler, GrpcError, type GrpcHandler, type GrpcMetadata, type GrpcMethodConfig, type GrpcMethodHandler, type GrpcMethodRegistration, type GrpcRequest, type GrpcResponse, type GrpcRpcMode, type GrpcServerStreamResponse, type GrpcServerStreamingHandler, GrpcService, GrpcStatusCode, type HandlerFunction, type HandlerResult, type JsonPrimitive, type JsonRecord, type JsonRpcConfig, type JsonSchema, type JsonValue, type JwtConfig, type LicenseInfo, type LifecycleHookFunction, type LifecycleHooks, type MaybePromise, type NativeHandlerFunction, type OpenApiConfig, type Path, type Query, QueryDefault, type RateLimitConfig, type Request, type RouteMetadata, type RouteOptions, type SecuritySchemeInfo, type ServerConfig, type ServerInfo, Spikard, type SpikardApp, type StaticFilesConfig, StreamingResponse, type StreamingResponseInit, type StructuredHandlerResponse, TestClient, type TestResponse, UploadFile, type WebSocketHandler, type WebSocketOptions, background, createServiceHandler, createUnaryHandler, del, get, patch, post, put, route, runServer, wrapBodyHandler, wrapHandler };