@simplysm/service-server 13.0.97 → 13.0.99

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 ADDED
@@ -0,0 +1,163 @@
1
+ # @simplysm/service-server
2
+
3
+ Simplysm package - service module (server)
4
+
5
+ Fastify-based service server with WebSocket support, JWT authentication, and built-in ORM/SMTP/auto-update services. Works with `@simplysm/service-client` for client-server communication.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @simplysm/service-server
11
+ ```
12
+
13
+ ## API Overview
14
+
15
+ ### Types
16
+ | API | Type | Description |
17
+ |-----|------|-------------|
18
+ | `ServiceServerOptions` | interface | Server config (rootPath, port, ssl, auth, services) |
19
+
20
+ -> See [docs/server.md](./docs/server.md) for details.
21
+
22
+ ### Auth
23
+ | API | Type | Description |
24
+ |-----|------|-------------|
25
+ | `AuthTokenPayload` | interface | JWT payload with roles and custom data |
26
+ | `signJwt` | function | Sign a JWT token (HS256, 12h expiry) |
27
+ | `verifyJwt` | function | Verify and decode a JWT token |
28
+ | `decodeJwt` | function | Decode JWT without verification |
29
+
30
+ -> See [docs/auth.md](./docs/auth.md) for details.
31
+
32
+ ### Core
33
+ | API | Type | Description |
34
+ |-----|------|-------------|
35
+ | `ServiceContext` | interface | Context with server, socket, auth, config access |
36
+ | `createServiceContext` | function | Create a service context |
37
+ | `ServiceDefinition` | interface | Service definition (name, factory, auth) |
38
+ | `defineService` | function | Define a service with name and factory |
39
+ | `auth` | function | Auth wrapper for services/methods (login/roles) |
40
+ | `getServiceAuthPermissions` | function | Read auth permissions from wrapped function |
41
+ | `ServiceMethods` | type | Extract method types from ServiceDefinition |
42
+ | `executeServiceMethod` | function | Execute service method with auth checks |
43
+
44
+ -> See [docs/core.md](./docs/core.md) for details.
45
+
46
+ ### Transport - Socket
47
+ | API | Type | Description |
48
+ |-----|------|-------------|
49
+ | `WebSocketHandler` | interface | Multi-connection WebSocket manager |
50
+ | `createWebSocketHandler` | function | Create WebSocket handler |
51
+ | `ServiceSocket` | interface | Single WebSocket connection manager |
52
+ | `createServiceSocket` | function | Create service socket |
53
+
54
+ -> See [docs/transport.md](./docs/transport.md) for details.
55
+
56
+ ### Transport - HTTP
57
+ | API | Type | Description |
58
+ |-----|------|-------------|
59
+ | `handleHttpRequest` | function | Handle HTTP API requests |
60
+ | `handleUpload` | function | Handle file upload (multipart) |
61
+ | `handleStaticFile` | function | Serve static files from www/ |
62
+
63
+ -> See [docs/transport.md](./docs/transport.md) for details.
64
+
65
+ ### Protocol
66
+ | API | Type | Description |
67
+ |-----|------|-------------|
68
+ | `ServerProtocolWrapper` | interface | Server protocol with worker thread offloading |
69
+ | `createServerProtocolWrapper` | function | Create server protocol wrapper |
70
+
71
+ -> See [docs/transport.md](./docs/transport.md) for details.
72
+
73
+ ### Services
74
+ | API | Type | Description |
75
+ |-----|------|-------------|
76
+ | `OrmService` | const | Built-in ORM service (DB connection, queries) |
77
+ | `AutoUpdateService` | const | Built-in auto-update service |
78
+ | `SmtpClientService` | const | Built-in SMTP email service |
79
+
80
+ -> See [docs/services.md](./docs/services.md) for details.
81
+
82
+ ### Utils
83
+ | API | Type | Description |
84
+ |-----|------|-------------|
85
+ | `getConfig` | function | Read JSON config with caching and live-reload |
86
+
87
+ -> See [docs/server.md](./docs/server.md) for details.
88
+
89
+ ### Main
90
+ | API | Type | Description |
91
+ |-----|------|-------------|
92
+ | `ServiceServer` | class | Main server (Fastify, WebSocket, auth, events) |
93
+ | `createServiceServer` | function | Factory to create ServiceServer |
94
+
95
+ -> See [docs/server.md](./docs/server.md) for details.
96
+
97
+ ### Legacy
98
+ | API | Type | Description |
99
+ |-----|------|-------------|
100
+ | `handleV1Connection` | function | V1 legacy client handler (auto-update only) |
101
+
102
+ -> See [docs/server.md](./docs/server.md) for details.
103
+
104
+ ## Usage Examples
105
+
106
+ ### Basic Server Setup
107
+
108
+ ```typescript
109
+ import { createServiceServer, defineService, auth } from "@simplysm/service-server";
110
+ import { OrmService, AutoUpdateService } from "@simplysm/service-server";
111
+
112
+ // Define a custom service
113
+ const HealthService = defineService("Health", (ctx) => ({
114
+ check: () => ({ status: "ok", time: new Date().toISOString() }),
115
+ }));
116
+
117
+ // Define an authenticated service
118
+ const UserService = defineService("User", auth((ctx) => ({
119
+ getProfile: () => ctx.authInfo,
120
+ adminOnly: auth(["admin"], () => "admin-only data"),
121
+ })));
122
+
123
+ // Create and start server
124
+ const server = createServiceServer({
125
+ rootPath: "/app",
126
+ port: 3000,
127
+ auth: { jwtSecret: "my-secret" },
128
+ services: [HealthService, UserService, OrmService, AutoUpdateService],
129
+ });
130
+
131
+ await server.listen();
132
+ ```
133
+
134
+ ### JWT Authentication
135
+
136
+ ```typescript
137
+ import { signJwt, verifyJwt } from "@simplysm/service-server";
138
+
139
+ // Sign token (in login handler)
140
+ const token = await server.signAuthToken({
141
+ roles: ["user", "admin"],
142
+ data: { userId: 123, name: "John" },
143
+ });
144
+
145
+ // Verify token
146
+ const payload = await server.verifyAuthToken(token);
147
+ console.log(payload.data.name); // "John"
148
+ ```
149
+
150
+ ### Server-Side Event Emission
151
+
152
+ ```typescript
153
+ import { defineEvent } from "@simplysm/service-common";
154
+
155
+ const OrderUpdated = defineEvent<{ orderId: number }, { status: string }>("OrderUpdated");
156
+
157
+ // Emit to all listeners with matching orderId
158
+ await server.emitEvent(
159
+ OrderUpdated,
160
+ (info) => info.orderId === 123,
161
+ { status: "shipped" },
162
+ );
163
+ ```
package/docs/auth.md ADDED
@@ -0,0 +1,59 @@
1
+ # Auth
2
+
3
+ JWT-based authentication utilities using the `jose` library (HS256 algorithm).
4
+
5
+ ## `AuthTokenPayload`
6
+
7
+ JWT token payload with roles and custom data. Extends `JWTPayload` from `jose`.
8
+
9
+ ```typescript
10
+ interface AuthTokenPayload<TAuthInfo = unknown> extends JWTPayload {
11
+ roles: string[];
12
+ data: TAuthInfo;
13
+ }
14
+ ```
15
+
16
+ | Field | Type | Description |
17
+ |-------|------|-------------|
18
+ | `roles` | `string[]` | User roles for permission checking |
19
+ | `data` | `TAuthInfo` | Custom auth data (user info, etc.) |
20
+
21
+ ## `signJwt`
22
+
23
+ Sign a JWT token with HS256 algorithm. Token expires in 12 hours.
24
+
25
+ ```typescript
26
+ async function signJwt<TAuthInfo = unknown>(
27
+ jwtSecret: string,
28
+ payload: AuthTokenPayload<TAuthInfo>,
29
+ ): Promise<string>;
30
+ ```
31
+
32
+ | Parameter | Type | Description |
33
+ |-----------|------|-------------|
34
+ | `jwtSecret` | `string` | Secret key for signing |
35
+ | `payload` | `AuthTokenPayload<TAuthInfo>` | Token payload |
36
+
37
+ ## `verifyJwt`
38
+
39
+ Verify and decode a JWT token. Throws on expired or invalid tokens.
40
+
41
+ ```typescript
42
+ async function verifyJwt<TAuthInfo = unknown>(
43
+ jwtSecret: string,
44
+ token: string,
45
+ ): Promise<AuthTokenPayload<TAuthInfo>>;
46
+ ```
47
+
48
+ | Parameter | Type | Description |
49
+ |-----------|------|-------------|
50
+ | `jwtSecret` | `string` | Secret key for verification |
51
+ | `token` | `string` | JWT token string |
52
+
53
+ ## `decodeJwt`
54
+
55
+ Decode a JWT token without verification (for reading payload only).
56
+
57
+ ```typescript
58
+ function decodeJwt<TAuthInfo = unknown>(token: string): AuthTokenPayload<TAuthInfo>;
59
+ ```
package/docs/core.md ADDED
@@ -0,0 +1,133 @@
1
+ # Core
2
+
3
+ ## `ServiceContext`
4
+
5
+ Context object passed to service factory functions. Provides access to server, socket, auth info, and configuration.
6
+
7
+ ```typescript
8
+ interface ServiceContext<TAuthInfo = unknown> {
9
+ server: ServiceServer<TAuthInfo>;
10
+ socket?: ServiceSocket;
11
+ http?: {
12
+ clientName: string;
13
+ authTokenPayload?: AuthTokenPayload<TAuthInfo>;
14
+ };
15
+ legacy?: {
16
+ clientName?: string;
17
+ };
18
+
19
+ get authInfo(): TAuthInfo | undefined;
20
+ get clientName(): string | undefined;
21
+ get clientPath(): string | undefined;
22
+ getConfig<T>(section: string): Promise<T>;
23
+ }
24
+ ```
25
+
26
+ | Property | Type | Description |
27
+ |----------|------|-------------|
28
+ | `server` | `ServiceServer<TAuthInfo>` | Server instance |
29
+ | `socket` | `ServiceSocket` | WebSocket connection (if via WebSocket) |
30
+ | `http` | `object` | HTTP request info (if via HTTP) |
31
+ | `legacy` | `object` | V1 legacy context (auto-update only) |
32
+ | `authInfo` | `TAuthInfo \| undefined` | Authenticated user data |
33
+ | `clientName` | `string \| undefined` | Client name |
34
+ | `clientPath` | `string \| undefined` | Resolved client path on disk |
35
+ | `getConfig()` | `<T>(section) => Promise<T>` | Read config from `.config.json` files |
36
+
37
+ ## `createServiceContext`
38
+
39
+ Create a service context instance.
40
+
41
+ ```typescript
42
+ function createServiceContext<TAuthInfo = unknown>(
43
+ server: ServiceServer<TAuthInfo>,
44
+ socket?: ServiceSocket,
45
+ http?: { clientName: string; authTokenPayload?: AuthTokenPayload<TAuthInfo> },
46
+ legacy?: { clientName?: string },
47
+ ): ServiceContext<TAuthInfo>;
48
+ ```
49
+
50
+ ## `ServiceDefinition`
51
+
52
+ Service definition object. Contains name, factory function, and optional auth permissions.
53
+
54
+ ```typescript
55
+ interface ServiceDefinition<TMethods = Record<string, (...args: any[]) => any>> {
56
+ name: string;
57
+ factory: (ctx: ServiceContext) => TMethods;
58
+ authPermissions?: string[];
59
+ }
60
+ ```
61
+
62
+ | Field | Type | Description |
63
+ |-------|------|-------------|
64
+ | `name` | `string` | Service name |
65
+ | `factory` | `(ctx: ServiceContext) => TMethods` | Factory function that creates method object |
66
+ | `authPermissions` | `string[]` | Required permissions (from `auth()` wrapper) |
67
+
68
+ ## `defineService`
69
+
70
+ Define a service with a name and factory function.
71
+
72
+ ```typescript
73
+ function defineService<TMethods extends Record<string, (...args: any[]) => any>>(
74
+ name: string,
75
+ factory: (ctx: ServiceContext) => TMethods,
76
+ ): ServiceDefinition<TMethods>;
77
+ ```
78
+
79
+ | Parameter | Type | Description |
80
+ |-----------|------|-------------|
81
+ | `name` | `string` | Service name |
82
+ | `factory` | `(ctx: ServiceContext) => TMethods` | Factory function |
83
+
84
+ ## `auth`
85
+
86
+ Auth wrapper for service factories and methods. Can be applied at service-level or method-level with optional role requirements.
87
+
88
+ ```typescript
89
+ function auth<TFunction extends (...args: any[]) => any>(fn: TFunction): TFunction;
90
+ function auth<TFunction extends (...args: any[]) => any>(
91
+ permissions: string[],
92
+ fn: TFunction,
93
+ ): TFunction;
94
+ ```
95
+
96
+ | Overload | Description |
97
+ |----------|-------------|
98
+ | `auth(fn)` | Require login (any authenticated user) |
99
+ | `auth(["admin"], fn)` | Require specific roles |
100
+
101
+ ## `getServiceAuthPermissions`
102
+
103
+ Read auth permissions from an `auth()`-wrapped function. Returns `undefined` if not wrapped.
104
+
105
+ ```typescript
106
+ function getServiceAuthPermissions(fn: Function): string[] | undefined;
107
+ ```
108
+
109
+ ## `ServiceMethods`
110
+
111
+ Extract method signatures from a `ServiceDefinition` for client-side type sharing.
112
+
113
+ ```typescript
114
+ type ServiceMethods<TDefinition> =
115
+ TDefinition extends ServiceDefinition<infer M> ? M : never;
116
+ ```
117
+
118
+ ## `executeServiceMethod`
119
+
120
+ Execute a service method with authentication and authorization checks.
121
+
122
+ ```typescript
123
+ async function executeServiceMethod(
124
+ server: ServiceServer,
125
+ def: {
126
+ serviceName: string;
127
+ methodName: string;
128
+ params: unknown[];
129
+ socket?: ServiceSocket;
130
+ http?: { clientName: string; authTokenPayload?: AuthTokenPayload };
131
+ },
132
+ ): Promise<unknown>;
133
+ ```
package/docs/server.md ADDED
@@ -0,0 +1,126 @@
1
+ # Server
2
+
3
+ ## `ServiceServerOptions`
4
+
5
+ Configuration options for `ServiceServer`.
6
+
7
+ ```typescript
8
+ interface ServiceServerOptions {
9
+ rootPath: string;
10
+ port: number;
11
+ ssl?: {
12
+ pfxBytes: Uint8Array;
13
+ passphrase: string;
14
+ };
15
+ auth?: {
16
+ jwtSecret: string;
17
+ };
18
+ services: ServiceDefinition[];
19
+ }
20
+ ```
21
+
22
+ | Field | Type | Description |
23
+ |-------|------|-------------|
24
+ | `rootPath` | `string` | Root path for static files, uploads, and config |
25
+ | `port` | `number` | Server port |
26
+ | `ssl` | `object` | SSL/TLS config (PFX certificate) |
27
+ | `ssl.pfxBytes` | `Uint8Array` | PFX certificate bytes |
28
+ | `ssl.passphrase` | `string` | Certificate passphrase |
29
+ | `auth` | `object` | Authentication config |
30
+ | `auth.jwtSecret` | `string` | JWT signing secret |
31
+ | `services` | `ServiceDefinition[]` | Service definitions to register |
32
+
33
+ ## `ServiceServer`
34
+
35
+ Fastify-based service server with WebSocket support, JWT authentication, and built-in services. Extends `EventEmitter`.
36
+
37
+ ```typescript
38
+ class ServiceServer<TAuthInfo = unknown> extends EventEmitter<{
39
+ ready: void;
40
+ close: void;
41
+ }> {
42
+ isOpen: boolean;
43
+ readonly fastify: FastifyInstance;
44
+ readonly options: ServiceServerOptions;
45
+
46
+ constructor(options: ServiceServerOptions);
47
+
48
+ listen(): Promise<void>;
49
+ close(): Promise<void>;
50
+ broadcastReload(clientName: string | undefined, changedFileSet: Set<string>): Promise<void>;
51
+ emitEvent<TInfo, TData>(
52
+ eventDef: ServiceEventDef<TInfo, TData>,
53
+ infoSelector: (item: TInfo) => boolean,
54
+ data: TData,
55
+ ): Promise<void>;
56
+ signAuthToken(payload: AuthTokenPayload<TAuthInfo>): Promise<string>;
57
+ verifyAuthToken(token: string): Promise<AuthTokenPayload<TAuthInfo>>;
58
+ }
59
+ ```
60
+
61
+ | Property | Type | Description |
62
+ |----------|------|-------------|
63
+ | `isOpen` | `boolean` | Whether server is listening |
64
+ | `fastify` | `FastifyInstance` | Underlying Fastify instance |
65
+ | `options` | `ServiceServerOptions` | Server options |
66
+
67
+ | Method | Description |
68
+ |--------|-------------|
69
+ | `listen()` | Start the server (registers plugins, routes, WebSocket, graceful shutdown) |
70
+ | `close()` | Stop the server (close all connections) |
71
+ | `broadcastReload()` | Broadcast reload to all connected clients |
72
+ | `emitEvent()` | Emit event to matching clients |
73
+ | `signAuthToken()` | Sign a JWT token |
74
+ | `verifyAuthToken()` | Verify and decode a JWT token |
75
+
76
+ ### Registered Routes
77
+
78
+ | Route | Method | Description |
79
+ |-------|--------|-------------|
80
+ | `/api/:service/:method` | GET/POST | HTTP service method endpoint |
81
+ | `/upload` | POST | File upload endpoint (multipart) |
82
+ | `/ws` | WebSocket | WebSocket service endpoint (Protocol V2) |
83
+ | `/` | WebSocket | WebSocket endpoint (V1 legacy + V2) |
84
+ | `/*` | GET | Static file serving from `www/` |
85
+
86
+ ### Registered Plugins
87
+
88
+ - `@fastify/websocket` - WebSocket support
89
+ - `@fastify/helmet` - Security headers (CSP, HSTS)
90
+ - `@fastify/multipart` - File upload
91
+ - `@fastify/static` - Static file serving
92
+ - `@fastify/cors` - CORS support
93
+
94
+ ## `createServiceServer`
95
+
96
+ Factory function to create a `ServiceServer` instance.
97
+
98
+ ```typescript
99
+ function createServiceServer<TAuthInfo = unknown>(
100
+ options: ServiceServerOptions,
101
+ ): ServiceServer<TAuthInfo>;
102
+ ```
103
+
104
+ ## Utils
105
+
106
+ ### `getConfig`
107
+
108
+ Read JSON configuration from file with caching and live-reload via file watcher. Cache expires after 1 hour.
109
+
110
+ ```typescript
111
+ async function getConfig<TConfig>(filePath: string): Promise<TConfig | undefined>;
112
+ ```
113
+
114
+ ## Legacy
115
+
116
+ ### `handleV1Connection`
117
+
118
+ V1 legacy client handler. Only auto-update is supported; all other requests return an upgrade-required error.
119
+
120
+ ```typescript
121
+ function handleV1Connection(
122
+ socket: WebSocket,
123
+ autoUpdateMethods: { getLastVersion: (platform: string) => Promise<any> },
124
+ clientNameSetter?: (clientName: string | undefined) => void,
125
+ ): void;
126
+ ```
@@ -0,0 +1,58 @@
1
+ # Built-in Services
2
+
3
+ Pre-defined service definitions ready to use with `ServiceServer`.
4
+
5
+ ## `OrmService`
6
+
7
+ Server-side ORM service implementation. Requires authentication. Manages database connections per WebSocket socket (using `WeakMap`). Supports MySQL, MSSQL, and PostgreSQL via `@simplysm/orm-node`.
8
+
9
+ ```typescript
10
+ const OrmService: ServiceDefinition;
11
+ ```
12
+
13
+ Implements the `OrmService` interface from `@simplysm/service-common`:
14
+
15
+ | Method | Description |
16
+ |--------|-------------|
17
+ | `getInfo()` | Get database dialect and connection info from config |
18
+ | `connect()` | Open a new database connection, returns connection ID |
19
+ | `close()` | Close a database connection |
20
+ | `beginTransaction()` | Begin transaction |
21
+ | `commitTransaction()` | Commit transaction |
22
+ | `rollbackTransaction()` | Rollback transaction |
23
+ | `executeParametrized()` | Execute parameterized SQL |
24
+ | `executeDefs()` | Execute QueryDef array (builds SQL via QueryBuilder) |
25
+ | `bulkInsert()` | Bulk insert records |
26
+
27
+ **Note:** ORM service requires WebSocket connection (cannot be used over HTTP).
28
+
29
+ ## `AutoUpdateService`
30
+
31
+ Server-side auto-update service implementation. Scans the client's platform-specific `updates/` directory for version files.
32
+
33
+ ```typescript
34
+ const AutoUpdateService: ServiceDefinition;
35
+ ```
36
+
37
+ Implements the `AutoUpdateService` interface from `@simplysm/service-common`:
38
+
39
+ | Method | Description |
40
+ |--------|-------------|
41
+ | `getLastVersion(platform)` | Find latest version file for platform (win32, android, etc.) |
42
+
43
+ Supported platforms and file extensions:
44
+ - `android`: `.apk` files
45
+ - Other platforms: `.exe` files
46
+
47
+ ## `SmtpClientService`
48
+
49
+ Server-side SMTP email sending service. Uses `nodemailer` under the hood.
50
+
51
+ ```typescript
52
+ const SmtpClientService: ServiceDefinition;
53
+ ```
54
+
55
+ | Method | Description |
56
+ |--------|-------------|
57
+ | `send(options)` | Send email with full SMTP options |
58
+ | `sendByDefault(options)` | Send email using server's default SMTP config |
@@ -0,0 +1,164 @@
1
+ # Transport
2
+
3
+ ## WebSocket Transport
4
+
5
+ ### `WebSocketHandler`
6
+
7
+ WebSocket handler interface. Manages multiple WebSocket connections, routes messages to services, and handles event broadcasting.
8
+
9
+ ```typescript
10
+ interface WebSocketHandler {
11
+ addSocket(socket: WebSocket, clientId: string, clientName: string, connReq: FastifyRequest): void;
12
+ closeAll(): void;
13
+ broadcastReload(clientName: string | undefined, changedFileSet: Set<string>): Promise<void>;
14
+ emit<TInfo, TData>(
15
+ eventDef: ServiceEventDef<TInfo, TData>,
16
+ infoSelector: (item: TInfo) => boolean,
17
+ data: TData,
18
+ ): Promise<void>;
19
+ }
20
+ ```
21
+
22
+ | Method | Description |
23
+ |--------|-------------|
24
+ | `addSocket()` | Add a new WebSocket connection |
25
+ | `closeAll()` | Close all active connections |
26
+ | `broadcastReload()` | Broadcast reload message to all clients |
27
+ | `emit()` | Emit event to matching clients |
28
+
29
+ ### `createWebSocketHandler`
30
+
31
+ Create a WebSocket handler instance.
32
+
33
+ ```typescript
34
+ function createWebSocketHandler(
35
+ runMethod: (def: {
36
+ serviceName: string;
37
+ methodName: string;
38
+ params: unknown[];
39
+ socket: ServiceSocket;
40
+ }) => Promise<unknown>,
41
+ jwtSecret?: string,
42
+ ): WebSocketHandler;
43
+ ```
44
+
45
+ ### `ServiceSocket`
46
+
47
+ Service socket interface. Manages a single WebSocket connection with protocol encoding/decoding, ping/pong keep-alive, and event listener tracking.
48
+
49
+ ```typescript
50
+ interface ServiceSocket {
51
+ readonly connectedAtDateTime: DateTime;
52
+ readonly clientName: string;
53
+ readonly connReq: FastifyRequest;
54
+ authTokenPayload?: AuthTokenPayload;
55
+
56
+ close(): void;
57
+ send(uuid: string, msg: ServiceServerMessage): Promise<number>;
58
+ addListener(key: string, eventName: string, info: unknown): void;
59
+ removeListener(key: string): void;
60
+ getEventListeners(eventName: string): Array<{ key: string; info: unknown }>;
61
+ filterEventTargetKeys(targetKeys: string[]): string[];
62
+ on(event: "error", handler: (err: Error) => void): void;
63
+ on(event: "close", handler: (code: number) => void): void;
64
+ on(event: "message", handler: (data: { uuid: string; msg: ServiceClientMessage }) => void): void;
65
+ }
66
+ ```
67
+
68
+ | Property | Type | Description |
69
+ |----------|------|-------------|
70
+ | `connectedAtDateTime` | `DateTime` | Connection time |
71
+ | `clientName` | `string` | Client name |
72
+ | `connReq` | `FastifyRequest` | Original Fastify request |
73
+ | `authTokenPayload` | `AuthTokenPayload` | Authenticated token payload |
74
+
75
+ | Method | Description |
76
+ |--------|-------------|
77
+ | `close()` | Close the WebSocket connection |
78
+ | `send()` | Send a message to the client |
79
+ | `addListener()` | Register an event listener |
80
+ | `removeListener()` | Remove an event listener |
81
+ | `getEventListeners()` | Get all listeners for an event name |
82
+ | `filterEventTargetKeys()` | Filter target keys that exist in this socket |
83
+ | `on()` | Register event handlers (error, close, message) |
84
+
85
+ ### `createServiceSocket`
86
+
87
+ Create a service socket instance.
88
+
89
+ ```typescript
90
+ function createServiceSocket(
91
+ socket: WebSocket,
92
+ clientId: string,
93
+ clientName: string,
94
+ connReq: FastifyRequest,
95
+ ): ServiceSocket;
96
+ ```
97
+
98
+ ## HTTP Transport
99
+
100
+ ### `handleHttpRequest`
101
+
102
+ Handle HTTP API requests. Routes `POST/GET /api/:service/:method` to service methods.
103
+
104
+ ```typescript
105
+ async function handleHttpRequest<TAuthInfo = unknown>(
106
+ req: FastifyRequest,
107
+ reply: FastifyReply,
108
+ jwtSecret: string | undefined,
109
+ runMethod: (def: {
110
+ serviceName: string;
111
+ methodName: string;
112
+ params: unknown[];
113
+ http: { clientName: string; authTokenPayload?: AuthTokenPayload<TAuthInfo> };
114
+ }) => Promise<unknown>,
115
+ ): Promise<void>;
116
+ ```
117
+
118
+ ### `handleUpload`
119
+
120
+ Handle file upload requests. Accepts multipart form data with auth token.
121
+
122
+ ```typescript
123
+ async function handleUpload(
124
+ req: FastifyRequest,
125
+ reply: FastifyReply,
126
+ rootPath: string,
127
+ jwtSecret: string | undefined,
128
+ ): Promise<void>;
129
+ ```
130
+
131
+ ### `handleStaticFile`
132
+
133
+ Handle static file serving. Serves files from `www/` directory with security checks (path traversal protection, hidden file blocking).
134
+
135
+ ```typescript
136
+ async function handleStaticFile(
137
+ req: FastifyRequest,
138
+ reply: FastifyReply,
139
+ rootPath: string,
140
+ urlPath: string,
141
+ ): Promise<void>;
142
+ ```
143
+
144
+ ## Protocol
145
+
146
+ ### `ServerProtocolWrapper`
147
+
148
+ Server-side protocol wrapper interface. Automatically offloads heavy encoding/decoding to a worker thread (>30KB threshold).
149
+
150
+ ```typescript
151
+ interface ServerProtocolWrapper {
152
+ encode(uuid: string, message: ServiceMessage): Promise<{ chunks: Bytes[]; totalSize: number }>;
153
+ decode(bytes: Bytes): Promise<ServiceMessageDecodeResult<ServiceMessage>>;
154
+ dispose(): void;
155
+ }
156
+ ```
157
+
158
+ ### `createServerProtocolWrapper`
159
+
160
+ Create a server protocol wrapper instance.
161
+
162
+ ```typescript
163
+ function createServerProtocolWrapper(): ServerProtocolWrapper;
164
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/service-server",
3
- "version": "13.0.97",
3
+ "version": "13.0.99",
4
4
  "description": "Simplysm package - service module (server)",
5
5
  "author": "simplysm",
6
6
  "license": "Apache-2.0",
@@ -36,11 +36,11 @@
36
36
  "semver": "^7.7.4",
37
37
  "utf-8-validate": "^6.0.6",
38
38
  "ws": "^8.19.0",
39
- "@simplysm/core-common": "13.0.97",
40
- "@simplysm/core-node": "13.0.97",
41
- "@simplysm/orm-node": "13.0.97",
42
- "@simplysm/orm-common": "13.0.97",
43
- "@simplysm/service-common": "13.0.97"
39
+ "@simplysm/core-common": "13.0.99",
40
+ "@simplysm/orm-node": "13.0.99",
41
+ "@simplysm/core-node": "13.0.99",
42
+ "@simplysm/service-common": "13.0.99",
43
+ "@simplysm/orm-common": "13.0.99"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/nodemailer": "^7.0.11",