@zap-js/client 0.0.2 → 0.0.4

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.
Files changed (115) hide show
  1. package/README.md +310 -24
  2. package/bin/zap +0 -0
  3. package/bin/zap-codegen +0 -0
  4. package/dist/cli/commands/build.d.ts +11 -0
  5. package/dist/cli/commands/build.js +282 -0
  6. package/dist/cli/commands/codegen.d.ts +8 -0
  7. package/dist/cli/commands/codegen.js +95 -0
  8. package/dist/cli/commands/dev.d.ts +20 -0
  9. package/dist/cli/commands/dev.js +78 -0
  10. package/dist/cli/commands/new.d.ts +9 -0
  11. package/dist/cli/commands/new.js +307 -0
  12. package/dist/cli/commands/routes-old.d.ts +9 -0
  13. package/dist/cli/commands/routes-old.js +106 -0
  14. package/dist/cli/commands/routes.d.ts +11 -0
  15. package/dist/cli/commands/routes.js +280 -0
  16. package/dist/cli/commands/serve.d.ts +17 -0
  17. package/dist/cli/commands/serve.js +386 -0
  18. package/dist/cli/index.d.ts +2 -0
  19. package/dist/cli/index.js +76 -0
  20. package/dist/cli/utils/index.d.ts +2 -0
  21. package/dist/cli/utils/index.js +2 -0
  22. package/dist/cli/utils/logger.d.ts +84 -0
  23. package/dist/cli/utils/logger.js +181 -0
  24. package/dist/cli/utils/port-finder.d.ts +8 -0
  25. package/dist/cli/utils/port-finder.js +48 -0
  26. package/dist/dev-server/codegen-runner.d.ts +41 -0
  27. package/dist/dev-server/codegen-runner.js +172 -0
  28. package/dist/dev-server/hot-reload.d.ts +72 -0
  29. package/dist/dev-server/hot-reload.js +280 -0
  30. package/dist/dev-server/index.d.ts +8 -0
  31. package/dist/dev-server/index.js +8 -0
  32. package/dist/dev-server/route-scanner.d.ts +71 -0
  33. package/dist/dev-server/route-scanner.js +114 -0
  34. package/dist/dev-server/rust-builder.d.ts +66 -0
  35. package/dist/dev-server/rust-builder.js +286 -0
  36. package/dist/dev-server/server.d.ts +147 -0
  37. package/dist/dev-server/server.js +658 -0
  38. package/dist/dev-server/vite-proxy.d.ts +56 -0
  39. package/dist/dev-server/vite-proxy.js +212 -0
  40. package/dist/dev-server/watcher.d.ts +48 -0
  41. package/dist/dev-server/watcher.js +127 -0
  42. package/dist/router/codegen-enhanced.d.ts +5 -0
  43. package/dist/router/codegen-enhanced.js +275 -0
  44. package/dist/router/codegen.d.ts +17 -0
  45. package/dist/router/codegen.js +654 -0
  46. package/dist/router/index.d.ts +16 -0
  47. package/dist/router/index.js +19 -0
  48. package/dist/router/scanner.d.ts +86 -0
  49. package/dist/router/scanner.js +689 -0
  50. package/dist/router/ssg.d.ts +115 -0
  51. package/dist/router/ssg.js +202 -0
  52. package/dist/router/types.d.ts +124 -0
  53. package/dist/router/types.js +9 -0
  54. package/dist/router/watch.d.ts +38 -0
  55. package/dist/router/watch.js +135 -0
  56. package/dist/runtime/csrf.d.ts +146 -0
  57. package/dist/runtime/csrf.js +166 -0
  58. package/dist/runtime/error-boundary.d.ts +129 -0
  59. package/dist/runtime/error-boundary.js +287 -0
  60. package/dist/runtime/hooks.d.ts +83 -0
  61. package/dist/runtime/hooks.js +96 -0
  62. package/dist/runtime/index.d.ts +229 -0
  63. package/dist/runtime/index.js +449 -0
  64. package/dist/runtime/ipc-client.d.ts +144 -0
  65. package/dist/runtime/ipc-client.js +621 -0
  66. package/dist/runtime/logger.d.ts +71 -0
  67. package/dist/runtime/logger.js +164 -0
  68. package/dist/runtime/middleware.d.ts +66 -0
  69. package/dist/runtime/middleware.js +114 -0
  70. package/dist/runtime/process-manager.d.ts +51 -0
  71. package/dist/runtime/process-manager.js +207 -0
  72. package/dist/runtime/router-simple.d.ts +98 -0
  73. package/dist/runtime/router-simple.js +330 -0
  74. package/dist/runtime/router.d.ts +103 -0
  75. package/dist/runtime/router.js +435 -0
  76. package/dist/runtime/rpc-client.d.ts +35 -0
  77. package/dist/runtime/rpc-client.js +140 -0
  78. package/dist/runtime/streaming-utils.d.ts +86 -0
  79. package/dist/runtime/streaming-utils.js +150 -0
  80. package/dist/runtime/types.d.ts +465 -0
  81. package/dist/runtime/types.js +60 -0
  82. package/dist/runtime/websockets-utils.d.ts +50 -0
  83. package/dist/runtime/websockets-utils.js +92 -0
  84. package/package.json +30 -20
  85. package/index.js +0 -29
  86. package/internal/cli/package.json +0 -46
  87. package/internal/cli/tsconfig.tsbuildinfo +0 -1
  88. package/internal/dev-server/node_modules/ora/index.d.ts +0 -332
  89. package/internal/dev-server/node_modules/ora/index.js +0 -416
  90. package/internal/dev-server/node_modules/ora/license +0 -9
  91. package/internal/dev-server/node_modules/ora/node_modules/string-width/index.d.ts +0 -36
  92. package/internal/dev-server/node_modules/ora/node_modules/string-width/index.js +0 -65
  93. package/internal/dev-server/node_modules/ora/node_modules/string-width/license +0 -9
  94. package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/LICENSE-MIT.txt +0 -20
  95. package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/README.md +0 -107
  96. package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/index.d.ts +0 -3
  97. package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/index.js +0 -4
  98. package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/index.mjs +0 -4
  99. package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/package.json +0 -46
  100. package/internal/dev-server/node_modules/ora/node_modules/string-width/package.json +0 -60
  101. package/internal/dev-server/node_modules/ora/node_modules/string-width/readme.md +0 -62
  102. package/internal/dev-server/node_modules/ora/package.json +0 -66
  103. package/internal/dev-server/node_modules/ora/readme.md +0 -325
  104. package/internal/dev-server/package.json +0 -41
  105. package/internal/router/package.json +0 -28
  106. package/internal/runtime/package.json +0 -41
  107. package/internal/runtime/src/error-boundary.tsx +0 -476
  108. package/internal/runtime/src/router-simple.tsx +0 -640
  109. package/internal/runtime/src/router.tsx +0 -771
  110. package/internal/runtime/tsconfig.tsbuildinfo +0 -1
  111. package/src/errors.js +0 -33
  112. package/src/logger.js +0 -10
  113. package/src/middleware.js +0 -32
  114. package/src/router.js +0 -41
  115. package/src/types.js +0 -39
@@ -0,0 +1,449 @@
1
+ import { join } from "path";
2
+ import { tmpdir } from "os";
3
+ import { existsSync, readFileSync } from "fs";
4
+ import { ProcessManager } from "./process-manager.js";
5
+ import { IpcServer } from "./ipc-client.js";
6
+ // Re-export type guards
7
+ export { isInvokeHandlerMessage, isHandlerResponseMessage, isErrorMessage, isHealthCheckMessage, isHealthCheckResponseMessage, isRpcResponseMessage, isRpcErrorMessage, isAsyncIterable, } from "./types.js";
8
+ // Re-export internal modules for dev-server usage
9
+ export { ProcessManager } from "./process-manager.js";
10
+ export { IpcServer, IpcClient } from "./ipc-client.js";
11
+ // Re-export error boundary components and hooks (Phase 10.3)
12
+ export { ErrorBoundary, DefaultErrorComponent, RouteErrorContext, createRouteError, ZapError, } from "./error-boundary.js";
13
+ export { useRouteError, useIsErrorState, useErrorState, } from "./hooks.js";
14
+ // Re-export logger (Phase 10.2)
15
+ export { Logger, logger } from "./logger.js";
16
+ // Re-export client router
17
+ export {
18
+ // Provider
19
+ RouterProvider,
20
+ // Hooks
21
+ useRouter, useParams, usePathname, useSearchParams, useRouteMatch, useIsPending,
22
+ // Components
23
+ Link, NavLink, Outlet, Redirect, } from "./router.js";
24
+ // Re-export CSRF protection utilities
25
+ export { getCsrfToken, useCsrfToken, createCsrfFetch, CsrfTokenInput, CsrfForm, addCsrfToFormData, getCsrfHeaders, } from "./csrf.js";
26
+ // Re-export RPC client utilities
27
+ export { rpcCall, } from "./rpc-client.js";
28
+ /**
29
+ * Zap - Ultra-fast HTTP server for Node.js and Bun
30
+ *
31
+ * This is the main API entry point. It manages:
32
+ * 1. Route registration from TypeScript
33
+ * 2. Spawning and managing the Rust binary process
34
+ * 3. IPC communication between TypeScript handlers and Rust server
35
+ *
36
+ * Usage:
37
+ * ```
38
+ * const app = new Zap({ port: 3000 });
39
+ * app.get('/', () => ({ message: 'Hello!' }));
40
+ * app.post('/api/data', (req) => ({ received: req.body }));
41
+ * await app.listen();
42
+ * ```
43
+ */
44
+ export class Zap {
45
+ constructor(options) {
46
+ this.handlers = new Map();
47
+ this.routes = [];
48
+ this.staticFiles = [];
49
+ this.port = 3000;
50
+ this.hostname = "127.0.0.1";
51
+ this.logLevel = "info";
52
+ this.healthCheckPath = "/health";
53
+ this.metricsPath = null;
54
+ this.enableCors = false;
55
+ this.enableLogging = false;
56
+ this.enableCompression = false;
57
+ this.fileRoutingEnabled = false;
58
+ this.fileRoutingConfig = {};
59
+ // Parse options
60
+ if (options?.port)
61
+ this.port = options.port;
62
+ if (options?.hostname)
63
+ this.hostname = options.hostname;
64
+ if (options?.logLevel)
65
+ this.logLevel = options.logLevel;
66
+ // Create IPC socket path (unique per instance)
67
+ const socketPath = join(tmpdir(), `zap-${Date.now()}-${Math.random().toString(36).substring(7)}.sock`);
68
+ // Initialize managers
69
+ this.processManager = new ProcessManager(undefined, socketPath);
70
+ this.ipcServer = new IpcServer(socketPath);
71
+ }
72
+ // ============================================================================
73
+ // Fluent Configuration API
74
+ // ============================================================================
75
+ /**
76
+ * Set the server port
77
+ */
78
+ setPort(port) {
79
+ this.port = port;
80
+ return this;
81
+ }
82
+ /**
83
+ * Set the server hostname
84
+ */
85
+ setHostname(hostname) {
86
+ this.hostname = hostname;
87
+ return this;
88
+ }
89
+ /**
90
+ * Enable CORS middleware
91
+ */
92
+ cors() {
93
+ this.enableCors = true;
94
+ return this;
95
+ }
96
+ /**
97
+ * Enable request logging middleware
98
+ */
99
+ logging() {
100
+ this.enableLogging = true;
101
+ return this;
102
+ }
103
+ /**
104
+ * Enable response compression middleware
105
+ */
106
+ compression() {
107
+ this.enableCompression = true;
108
+ return this;
109
+ }
110
+ /**
111
+ * Set custom health check path
112
+ */
113
+ healthCheck(path) {
114
+ this.healthCheckPath = path;
115
+ return this;
116
+ }
117
+ /**
118
+ * Set metrics endpoint path
119
+ */
120
+ metrics(path) {
121
+ this.metricsPath = path;
122
+ return this;
123
+ }
124
+ /**
125
+ * Enable file-based routing (TanStack style)
126
+ *
127
+ * Automatically registers routes from the routes/ directory
128
+ * using the generated route manifest from @zapjs/router
129
+ */
130
+ useFileRouting(config) {
131
+ this.fileRoutingEnabled = true;
132
+ this.fileRoutingConfig = config || {};
133
+ return this;
134
+ }
135
+ // ============================================================================
136
+ // Route Registration API
137
+ // ============================================================================
138
+ /**
139
+ * Register a GET route
140
+ */
141
+ get(path, handler) {
142
+ return this.registerRoute("GET", path, handler);
143
+ }
144
+ /**
145
+ * Register a POST route
146
+ */
147
+ post(path, handler) {
148
+ return this.registerRoute("POST", path, handler);
149
+ }
150
+ /**
151
+ * Register a PUT route
152
+ */
153
+ put(path, handler) {
154
+ return this.registerRoute("PUT", path, handler);
155
+ }
156
+ /**
157
+ * Register a DELETE route
158
+ */
159
+ delete(path, handler) {
160
+ return this.registerRoute("DELETE", path, handler);
161
+ }
162
+ /**
163
+ * Register a PATCH route
164
+ */
165
+ patch(path, handler) {
166
+ return this.registerRoute("PATCH", path, handler);
167
+ }
168
+ /**
169
+ * Register a HEAD route
170
+ */
171
+ head(path, handler) {
172
+ return this.registerRoute("HEAD", path, handler);
173
+ }
174
+ /**
175
+ * Convenience method for GET routes that return JSON
176
+ */
177
+ getJson(path, handler) {
178
+ return this.get(path, handler);
179
+ }
180
+ /**
181
+ * Convenience method for POST routes that return JSON
182
+ */
183
+ postJson(path, handler) {
184
+ return this.post(path, handler);
185
+ }
186
+ /**
187
+ * Register static file serving
188
+ */
189
+ static(prefix, directory) {
190
+ this.staticFiles.push({ prefix, directory });
191
+ return this;
192
+ }
193
+ /**
194
+ * Register a route with a handler (internal)
195
+ */
196
+ registerRoute(method, path, handler) {
197
+ const handlerId = `handler_${this.handlers.size}`;
198
+ this.handlers.set(handlerId, handler);
199
+ this.routes.push({
200
+ method,
201
+ path,
202
+ handler_id: handlerId,
203
+ is_typescript: true,
204
+ });
205
+ return this;
206
+ }
207
+ // ============================================================================
208
+ // Server Lifecycle
209
+ // ============================================================================
210
+ /**
211
+ * Start the server
212
+ */
213
+ async listen(port) {
214
+ // Allow overriding port in listen()
215
+ if (port !== undefined) {
216
+ this.port = port;
217
+ }
218
+ try {
219
+ // Load file-based routes if enabled
220
+ if (this.fileRoutingEnabled) {
221
+ await this.loadFileRoutes();
222
+ }
223
+ // Start IPC server first
224
+ console.log("[Zap] Starting IPC server...");
225
+ await this.ipcServer.start();
226
+ // Register all handlers with IPC server
227
+ console.log(`[Zap] Registering ${this.handlers.size} handlers...`);
228
+ for (const [handlerId, handler] of this.handlers) {
229
+ this.ipcServer.registerHandler(handlerId, async (req) => {
230
+ const result = await handler(req);
231
+ // Handle different response types
232
+ if (result instanceof Response) {
233
+ // Convert Headers to Record<string, string>
234
+ const headersObj = {};
235
+ result.headers.forEach((value, key) => {
236
+ headersObj[key] = value;
237
+ });
238
+ return {
239
+ status: result.status,
240
+ headers: headersObj,
241
+ body: await result.text(),
242
+ };
243
+ }
244
+ if (typeof result === "string") {
245
+ return {
246
+ status: 200,
247
+ headers: { "content-type": "text/plain" },
248
+ body: result,
249
+ };
250
+ }
251
+ // Default to JSON
252
+ return {
253
+ status: 200,
254
+ headers: { "content-type": "application/json" },
255
+ body: JSON.stringify(result),
256
+ };
257
+ });
258
+ }
259
+ // Build Rust configuration
260
+ const config = {
261
+ port: this.port,
262
+ hostname: this.hostname,
263
+ ipc_socket_path: this.processManager.getSocketPath(),
264
+ routes: this.routes,
265
+ static_files: this.staticFiles,
266
+ middleware: {
267
+ enable_cors: this.enableCors,
268
+ enable_logging: this.enableLogging,
269
+ enable_compression: this.enableCompression,
270
+ },
271
+ health_check_path: this.healthCheckPath,
272
+ metrics_path: this.metricsPath ?? undefined,
273
+ };
274
+ // Start Rust server process
275
+ console.log("[Zap] Starting Rust server process...");
276
+ await this.processManager.start(config, this.logLevel);
277
+ console.log(`[Zap] Server listening on http://${this.hostname}:${this.port}`);
278
+ }
279
+ catch (error) {
280
+ const message = error instanceof Error ? error.message : String(error);
281
+ console.error("[Zap] Failed to start server:", message);
282
+ await this.close();
283
+ throw error;
284
+ }
285
+ }
286
+ /**
287
+ * Close the server gracefully
288
+ */
289
+ async close() {
290
+ console.log("[Zap] Closing server...");
291
+ try {
292
+ await this.processManager.stop();
293
+ await this.ipcServer.stop();
294
+ console.log("[Zap] Server closed");
295
+ }
296
+ catch (error) {
297
+ const message = error instanceof Error ? error.message : String(error);
298
+ console.error("[Zap] Error closing server:", message);
299
+ throw error;
300
+ }
301
+ }
302
+ /**
303
+ * Check if server is running
304
+ */
305
+ isRunning() {
306
+ return this.processManager.isRunning();
307
+ }
308
+ /**
309
+ * Load routes from generated route manifest
310
+ */
311
+ async loadFileRoutes() {
312
+ const generatedDir = this.fileRoutingConfig.generatedDir || join(process.cwd(), 'src', 'generated');
313
+ const manifestPath = join(generatedDir, 'routeManifest.json');
314
+ if (!existsSync(manifestPath)) {
315
+ console.log("[Zap] No route manifest found. Run route scanner first.");
316
+ return;
317
+ }
318
+ try {
319
+ const manifestContent = readFileSync(manifestPath, 'utf-8');
320
+ const manifest = JSON.parse(manifestContent);
321
+ console.log(`[Zap] Loading ${manifest.apiRoutes?.length ?? 0} API routes from manifest...`);
322
+ // Register API routes
323
+ for (const route of manifest.apiRoutes ?? []) {
324
+ // Convert :param to Rust radix router format
325
+ const rustPath = route.urlPath;
326
+ // Import the route handler module
327
+ const routeFile = join(process.cwd(), 'routes', route.filePath);
328
+ if (existsSync(routeFile.replace(/\.ts$/, '.js')) || existsSync(routeFile)) {
329
+ try {
330
+ const routeModule = await import(routeFile);
331
+ // Register each HTTP method handler
332
+ const methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'];
333
+ for (const method of methods) {
334
+ const methodHandler = routeModule[method];
335
+ if (methodHandler) {
336
+ this.registerRoute(method, rustPath, methodHandler);
337
+ console.log(`[Zap] ${method} ${rustPath}`);
338
+ }
339
+ }
340
+ }
341
+ catch (err) {
342
+ const message = err instanceof Error ? err.message : String(err);
343
+ console.log(`[Zap] Failed to import ${routeFile}: ${message}`);
344
+ }
345
+ }
346
+ }
347
+ }
348
+ catch (err) {
349
+ const message = err instanceof Error ? err.message : String(err);
350
+ console.error("[Zap] Failed to load route manifest:", message);
351
+ }
352
+ }
353
+ }
354
+ // ============================================================================
355
+ // Namespace Exports (Clean API)
356
+ // ============================================================================
357
+ /**
358
+ * Router namespace - all routing functionality
359
+ * Usage: import { router } from '@zap-js/client'
360
+ */
361
+ import { RouterProvider, useRouter as useRouterFn, useParams as useParamsFn, usePathname as usePathnameFn, useSearchParams as useSearchParamsFn, useRouteMatch as useRouteMatchFn, useIsPending as useIsPendingFn, Link, NavLink, Outlet, Redirect, } from "./router.js";
362
+ export const router = {
363
+ RouterProvider,
364
+ useRouter: useRouterFn,
365
+ useParams: useParamsFn,
366
+ usePathname: usePathnameFn,
367
+ useSearchParams: useSearchParamsFn,
368
+ useRouteMatch: useRouteMatchFn,
369
+ useIsPending: useIsPendingFn,
370
+ Link,
371
+ NavLink,
372
+ Outlet,
373
+ Redirect,
374
+ };
375
+ /**
376
+ * Errors namespace - error handling and boundaries
377
+ * Usage: import { errors } from '@zap-js/client'
378
+ */
379
+ import { ErrorBoundary, DefaultErrorComponent, createRouteError, ZapError, } from "./error-boundary.js";
380
+ import { useRouteError, useIsErrorState, useErrorState, } from "./hooks.js";
381
+ export const errors = {
382
+ ErrorBoundary,
383
+ DefaultErrorComponent,
384
+ createRouteError,
385
+ ZapError,
386
+ useRouteError,
387
+ useIsErrorState,
388
+ useErrorState,
389
+ };
390
+ /**
391
+ * Middleware namespace - route middleware utilities
392
+ * Usage: import { middleware } from '@zap-js/client'
393
+ */
394
+ import { composeMiddleware, requireAuth, requireRole, routeLogger, preloadData, } from "./middleware.js";
395
+ export const middleware = {
396
+ compose: composeMiddleware,
397
+ requireAuth,
398
+ requireRole,
399
+ logger: routeLogger,
400
+ preloadData,
401
+ };
402
+ /**
403
+ * Types namespace - type definitions and guards
404
+ * Usage: import { types } from '@zap-js/client'
405
+ */
406
+ import * as TypeGuards from "./types.js";
407
+ export const types = {
408
+ isInvokeHandlerMessage: TypeGuards.isInvokeHandlerMessage,
409
+ isHandlerResponseMessage: TypeGuards.isHandlerResponseMessage,
410
+ isErrorMessage: TypeGuards.isErrorMessage,
411
+ isHealthCheckMessage: TypeGuards.isHealthCheckMessage,
412
+ isHealthCheckResponseMessage: TypeGuards.isHealthCheckResponseMessage,
413
+ isRpcResponseMessage: TypeGuards.isRpcResponseMessage,
414
+ isRpcErrorMessage: TypeGuards.isRpcErrorMessage,
415
+ isAsyncIterable: TypeGuards.isAsyncIterable,
416
+ };
417
+ /**
418
+ * WebSockets namespace - WebSocket utilities and helpers
419
+ * Usage: import { websockets } from '@zap-js/client'
420
+ */
421
+ import * as WebSocketUtils from "./websockets-utils.js";
422
+ export const websockets = {
423
+ isWsMessage: WebSocketUtils.isWsMessage,
424
+ broadcast: WebSocketUtils.broadcast,
425
+ broadcastExcept: WebSocketUtils.broadcastExcept,
426
+ sendJson: WebSocketUtils.sendJson,
427
+ parseMessage: WebSocketUtils.parseMessage,
428
+ createErrorMessage: WebSocketUtils.createErrorMessage,
429
+ createSuccessMessage: WebSocketUtils.createSuccessMessage,
430
+ };
431
+ /**
432
+ * Streaming namespace - Streaming response utilities
433
+ * Usage: import { streaming } from '@zap-js/client'
434
+ */
435
+ import * as StreamingUtils from "./streaming-utils.js";
436
+ export const streaming = {
437
+ isAsyncIterable: StreamingUtils.isAsyncIterable,
438
+ createChunk: StreamingUtils.createChunk,
439
+ createStream: StreamingUtils.createStream,
440
+ streamJson: StreamingUtils.streamJson,
441
+ streamSSE: StreamingUtils.streamSSE,
442
+ mapStream: StreamingUtils.mapStream,
443
+ filterStream: StreamingUtils.filterStream,
444
+ batchStream: StreamingUtils.batchStream,
445
+ delayStream: StreamingUtils.delayStream,
446
+ fromReadableStream: StreamingUtils.fromReadableStream,
447
+ intervalStream: StreamingUtils.intervalStream,
448
+ };
449
+ export default Zap;
@@ -0,0 +1,144 @@
1
+ import { EventEmitter } from "events";
2
+ import type { ZapRequest, ZapHandlerResponse, IpcMessage, StreamChunk, WsHandler } from "./types.js";
3
+ export type { ZapRequest as IpcRequest } from "./types.js";
4
+ /**
5
+ * IPC encoding format
6
+ */
7
+ export type IpcEncoding = "msgpack" | "json";
8
+ /**
9
+ * Handler function type for IPC server (supports regular and streaming responses)
10
+ */
11
+ export type HandlerFunction = (req: ZapRequest) => Promise<ZapHandlerResponse> | AsyncIterable<StreamChunk>;
12
+ /**
13
+ * Streaming handler function type
14
+ */
15
+ export type StreamingHandlerFunction = (req: ZapRequest) => AsyncIterable<StreamChunk>;
16
+ /**
17
+ * WebSocket handler function type
18
+ */
19
+ export type WsHandlerFunction = WsHandler;
20
+ /**
21
+ * Serialize an IPC message to bytes
22
+ */
23
+ declare function serializeMessage(msg: IpcMessage, encoding: IpcEncoding): Buffer;
24
+ /**
25
+ * Deserialize an IPC message from bytes (auto-detects encoding)
26
+ */
27
+ declare function deserializeMessage(data: Buffer): IpcMessage;
28
+ /**
29
+ * FrameReader - reads length-prefixed frames from a socket
30
+ */
31
+ declare class FrameReader {
32
+ private buffer;
33
+ private onFrame;
34
+ constructor(onFrame: (frame: Buffer) => void);
35
+ /**
36
+ * Process incoming data chunks
37
+ */
38
+ push(chunk: Buffer): void;
39
+ /**
40
+ * Reset the buffer
41
+ */
42
+ reset(): void;
43
+ }
44
+ /**
45
+ * IpcServer
46
+ *
47
+ * Listens on a Unix socket for IPC messages from the Rust backend.
48
+ * The Rust server sends handler invocation requests, which we dispatch
49
+ * to the registered TypeScript handlers and send responses back.
50
+ *
51
+ * Protocol: Length-prefixed MessagePack (default) with JSON fallback
52
+ * Frame format: [4-byte big-endian length][payload]
53
+ */
54
+ export declare class IpcServer {
55
+ private server;
56
+ private socketPath;
57
+ private handlers;
58
+ private wsHandlers;
59
+ private wsConnections;
60
+ private encoding;
61
+ private currentSocket;
62
+ constructor(socketPath: string, encoding?: IpcEncoding);
63
+ /**
64
+ * Register a handler function for a specific handler ID
65
+ */
66
+ registerHandler(handlerId: string, handler: HandlerFunction): void;
67
+ /**
68
+ * Register a WebSocket handler for a specific handler ID
69
+ */
70
+ registerWsHandler(handlerId: string, handler: WsHandlerFunction): void;
71
+ /**
72
+ * Start the IPC server listening on the Unix socket
73
+ */
74
+ start(): Promise<void>;
75
+ /**
76
+ * Handle a new IPC connection from the Rust server
77
+ */
78
+ private handleConnection;
79
+ /**
80
+ * Handle a complete frame
81
+ */
82
+ private handleFrame;
83
+ /**
84
+ * Process an incoming IPC message
85
+ */
86
+ private processMessage;
87
+ /**
88
+ * Handle a streaming response from a handler
89
+ */
90
+ private handleStreamingResponse;
91
+ /**
92
+ * Send a message to a WebSocket client via the Rust server
93
+ */
94
+ sendWsMessage(connectionId: string, data: string, binary: boolean): void;
95
+ /**
96
+ * Close a WebSocket connection via the Rust server
97
+ */
98
+ closeWsConnection(connectionId: string, code?: number, reason?: string): void;
99
+ /**
100
+ * Stop the IPC server
101
+ */
102
+ stop(): Promise<void>;
103
+ }
104
+ /**
105
+ * IpcClient
106
+ *
107
+ * Connects to a Unix socket to communicate with the Rust server.
108
+ * Used for RPC calls from TypeScript to Rust.
109
+ *
110
+ * Protocol: Length-prefixed MessagePack (default) with JSON fallback
111
+ */
112
+ export declare class IpcClient extends EventEmitter {
113
+ private socket;
114
+ private socketPath;
115
+ private connected;
116
+ private frameReader;
117
+ private encoding;
118
+ constructor(socketPath: string, encoding?: IpcEncoding);
119
+ /**
120
+ * Connect to the Unix socket
121
+ */
122
+ private connect;
123
+ /**
124
+ * Send a message to the server
125
+ */
126
+ send(message: IpcMessage): void;
127
+ /**
128
+ * Send a message and wait for response
129
+ */
130
+ sendRecv(message: IpcMessage): Promise<IpcMessage>;
131
+ /**
132
+ * Close the connection
133
+ */
134
+ close(): Promise<void>;
135
+ /**
136
+ * Check if connected
137
+ */
138
+ isConnected(): boolean;
139
+ /**
140
+ * Get the encoding being used
141
+ */
142
+ getEncoding(): IpcEncoding;
143
+ }
144
+ export { serializeMessage, deserializeMessage, FrameReader };