@bakit/service 2.0.1 → 3.1.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/dist/index.d.ts CHANGED
@@ -39,6 +39,8 @@ interface BaseClientDriverEvents {
39
39
  }
40
40
 
41
41
  interface BaseServerDriverEvents {
42
+ listen: [];
43
+ close: [];
42
44
  message: [connection: unknown, message: Serializable];
43
45
  clientConnect: [connection: unknown];
44
46
  clientDisconnect: [connection: unknown];
@@ -66,8 +68,6 @@ interface IPCServerEvents extends BaseServerDriverEvents {
66
68
  clientDisconnect: [socket: Socket];
67
69
  clientError: [socket: Socket, error: Error];
68
70
  drain: [socket: Socket];
69
- listen: [];
70
- close: [];
71
71
  }
72
72
  interface IPCClientEvents extends BaseClientDriverEvents {
73
73
  }
@@ -162,12 +162,12 @@ type TransportServerOptions = {
162
162
  driver: D;
163
163
  } & TransportServerDriverSpecificOptions[D];
164
164
  }[TransportDriver];
165
- interface TransportClient extends TransportClientProtocol, EventBus<TransportEvents> {
165
+ interface TransportClient extends TransportClientProtocol, EventBus<TransportClientEvents> {
166
166
  send: BaseServerDriver["send"];
167
167
  connect: BaseClientDriver["connect"];
168
168
  disconnect: BaseClientDriver["disconnect"];
169
169
  }
170
- interface TransportServer extends TransportServerProtocol, EventBus<TransportEvents> {
170
+ interface TransportServer extends TransportServerProtocol, EventBus<TransportServerEvents> {
171
171
  broadcast: BaseServerDriver["broadcast"];
172
172
  listen: BaseServerDriver["listen"];
173
173
  close: BaseServerDriver["close"];
@@ -193,13 +193,15 @@ type RPCResponseMessage = {
193
193
  }, {
194
194
  error: RPCErrorPayload;
195
195
  }>;
196
- interface TransportEvents {
196
+ interface TransportClientEvents {
197
197
  connect: [];
198
198
  disconnect: [];
199
199
  error: [error: Error];
200
- request: [id: string, method: string];
201
- response: [id: string];
202
- timeout: [id: string];
200
+ }
201
+ interface TransportServerEvents {
202
+ listen: [];
203
+ close: [];
204
+ error: [error: Error];
203
205
  clientConnect: [connection: unknown];
204
206
  clientDisconnect: [connection: unknown];
205
207
  }
@@ -212,28 +214,35 @@ interface ServiceOptions {
212
214
  name: string;
213
215
  transport: TransportClientOptions & TransportServerOptions;
214
216
  }
215
- interface ServiceServer {
217
+ interface Service {
218
+ readonly name: string;
219
+ readonly role: ServiceRole;
216
220
  define<F extends ServiceFunction>(method: string, handler: F): Promisify<F>;
217
- transport: TransportServer;
218
221
  }
219
- interface ServiceClient {
220
- define<F extends ServiceFunction>(method: string, handler: F): Promisify<F>;
222
+ type ServiceFunction = FunctionLike<any[], Awaitable<any>>;
223
+ declare const ServiceRole: {
224
+ readonly Client: "client";
225
+ readonly Server: "server";
226
+ };
227
+ type ServiceRole = ValueOf<typeof ServiceRole>;
228
+ interface ServiceClientRuntime {
229
+ role: typeof ServiceRole.Client;
221
230
  transport: TransportClient;
222
231
  }
223
- interface Service {
224
- define<F extends ServiceFunction>(method: string, handler: F): Promisify<F>;
225
- start(): void;
226
- stop(): void;
232
+ interface ServiceServerRuntime {
233
+ role: typeof ServiceRole.Server;
234
+ transport: TransportServer;
235
+ }
236
+ type ServiceRuntime = ServiceClientRuntime | ServiceServerRuntime;
237
+ interface MutableRuntime {
238
+ role: ServiceRole | "unknown";
239
+ transport?: TransportClient | TransportServer;
240
+ }
241
+ interface ServiceInteral {
242
+ runtime: ServiceRuntime;
243
+ bind(role: "client" | "server"): void;
227
244
  }
228
- type ServiceFunction = FunctionLike<any[], Awaitable<any>>;
229
245
  declare function createService(options: ServiceOptions): Service;
230
- /**
231
- * Create a service client instance.
232
- *
233
- * @param {options} options.
234
- * @return {ServiceClient} Service client instance.
235
- */
236
- declare function createServiceClient(options: ServiceOptions): ServiceClient;
237
- declare function createServiceServer(options: ServiceOptions): ServiceServer;
246
+ declare function getInternalService(service: Service): ServiceInteral;
238
247
 
239
- export { type BaseClientDriver, type BaseClientDriverEvents, type BaseServerDriver, type BaseServerDriverEvents, DEFAULT_IPC_SOCKET_CONNECTION_OPTIONS, type IPCClientEvents, type IPCClientOptions, type IPCServer, type IPCServerEvents, type IPCServerOptions, IPCServerState, type IPCSocketConnection, type IPCSocketConnectionOptions, type IPCSocketMessageHandler, type IPCSocketMessageHandlerOptions, RPCError, type RPCErrorPayload, type RPCHandler, type RPCRequestMessage, type RPCResponseMessage, type Serializable, type Service, type ServiceClient, type ServiceFunction, type ServiceOptions, type ServiceServer, SocketState, type TransportClient, type TransportClientDriverSpecificOptions, type TransportClientOptions, type TransportClientProtocol, TransportDriver, type TransportEvents, type TransportServer, type TransportServerDriverSpecificOptions, type TransportServerOptions, type TransportServerProtocol, createIPCClient, createIPCServer, createIPCSocketConnection, createIPCSocketMessageHandler, createService, createServiceClient, createServiceServer, createTransportClient, createTransportClientProtocol, createTransportServer, createTransportServerProtocol, deserializeRPCError, getIPCPath, serializeRPCError };
248
+ export { type BaseClientDriver, type BaseClientDriverEvents, type BaseServerDriver, type BaseServerDriverEvents, DEFAULT_IPC_SOCKET_CONNECTION_OPTIONS, type IPCClientEvents, type IPCClientOptions, type IPCServer, type IPCServerEvents, type IPCServerOptions, IPCServerState, type IPCSocketConnection, type IPCSocketConnectionOptions, type IPCSocketMessageHandler, type IPCSocketMessageHandlerOptions, type MutableRuntime, RPCError, type RPCErrorPayload, type RPCHandler, type RPCRequestMessage, type RPCResponseMessage, type Serializable, type Service, type ServiceClientRuntime, type ServiceFunction, type ServiceInteral, type ServiceOptions, ServiceRole, type ServiceRuntime, type ServiceServerRuntime, SocketState, type TransportClient, type TransportClientDriverSpecificOptions, type TransportClientEvents, type TransportClientOptions, type TransportClientProtocol, TransportDriver, type TransportServer, type TransportServerDriverSpecificOptions, type TransportServerEvents, type TransportServerOptions, type TransportServerProtocol, createIPCClient, createIPCServer, createIPCSocketConnection, createIPCSocketMessageHandler, createService, createTransportClient, createTransportClientProtocol, createTransportServer, createTransportServerProtocol, deserializeRPCError, getIPCPath, getInternalService, serializeRPCError };
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { join } from 'path';
3
3
  import { existsSync, rmSync } from 'fs';
4
4
  import { pack, unpack } from 'msgpackr';
5
5
  import PQueue from 'p-queue';
6
- import { attachEventBus, Collection, isPlainObject, promisify } from '@bakit/utils';
6
+ import { attachEventBus, Collection, isPlainObject } from '@bakit/utils';
7
7
  import { randomUUID } from 'crypto';
8
8
 
9
9
  // src/lib/driver/ipc.ts
@@ -255,7 +255,7 @@ function createTransportServer(options) {
255
255
  listen: driver.listen,
256
256
  close: driver.close
257
257
  }, self = attachEventBus(base);
258
- return driver.on("clientConnect", (conn) => self.emit("clientConnect", conn)), driver.on("clientDisconnect", (conn) => self.emit("clientDisconnect", conn)), driver.on("clientError", (_, error) => self.emit("error", error)), self;
258
+ return driver.on("listen", () => self.emit("listen")), driver.on("clientConnect", (conn) => self.emit("clientConnect", conn)), driver.on("clientDisconnect", (conn) => self.emit("clientDisconnect", conn)), driver.on("clientError", (_, error) => self.emit("error", error)), self;
259
259
  }
260
260
  function createTransportClientProtocol(driver) {
261
261
  let requests = new Collection();
@@ -341,42 +341,64 @@ function createTransportServerProtocol(driver) {
341
341
  handle
342
342
  };
343
343
  }
344
+ var ServiceRole = {
345
+ Client: "client",
346
+ Server: "server"
347
+ }, SERVICE_INTERNAL = Symbol("service-internal");
344
348
  function createService(options) {
345
- if (process.env.BAKIT_SERVICE_NAME === options.name) {
346
- let server = createServiceServer(options);
347
- return {
348
- define: server.define,
349
- start: server.transport.listen,
350
- stop: server.transport.close
351
- };
352
- } else {
353
- let client = createServiceClient(options);
354
- return {
355
- define: client.define,
356
- start: client.transport.connect,
357
- stop: client.transport.disconnect
358
- };
359
- }
360
- }
361
- function createServiceClient(options) {
362
- let transport = createTransportClient(options.transport);
363
- function define(method, _handler) {
364
- return (...args) => transport.request(method, ...args);
365
- }
366
- return {
367
- define,
368
- transport
349
+ let handlers = new Collection(), runtime = { role: "unknown" }, service = {
350
+ get name() {
351
+ return options.name;
352
+ },
353
+ get role() {
354
+ if (runtime.role === "unknown")
355
+ throw new Error(`Service "${options.name}" is not bound`);
356
+ return runtime.role;
357
+ },
358
+ define
369
359
  };
370
- }
371
- function createServiceServer(options) {
372
- let transport = createTransportServer(options.transport);
373
360
  function define(method, handler) {
374
- return transport.handle(method, handler), promisify(handler);
361
+ if (handlers.has(method))
362
+ throw new Error(`Service method "${method}" already defined`);
363
+ return handlers.set(method, handler), (async (...args) => {
364
+ if (ensureClientBound(), runtime.role === "unknown")
365
+ throw new Error(`Service "${options.name}" is not bound (method "${method}")`);
366
+ return runtime.role === "server" ? handler(...args) : (assertClient(runtime), runtime.transport.request(method, ...args));
367
+ });
375
368
  }
376
- return {
377
- define,
378
- transport
379
- };
369
+ function ensureClientBound() {
370
+ runtime.role !== "unknown" || process.env.BAKIT_SERVICE_NAME === options.name || bind(ServiceRole.Client);
371
+ }
372
+ function assertClient(runtime2) {
373
+ if (runtime2.role !== "client")
374
+ throw new Error(`Service "${options.name}" is not a client`);
375
+ }
376
+ function bind(role) {
377
+ if (runtime.role !== "unknown")
378
+ throw new Error(`Service "${options.name}" already bound`);
379
+ if (role === "server") {
380
+ let server = createTransportServer(options.transport);
381
+ for (let [method, handler] of handlers)
382
+ server.handle(method, handler);
383
+ runtime.role = "server", runtime.transport = server, server.listen();
384
+ } else if (role === "client") {
385
+ let client = createTransportClient(options.transport);
386
+ runtime.role = "client", runtime.transport = client, client.connect();
387
+ }
388
+ }
389
+ return Object.defineProperty(service, SERVICE_INTERNAL, {
390
+ value: {
391
+ get runtime() {
392
+ if (runtime.role === "unknown")
393
+ throw new Error(`Service "${options.name}" is not bound`);
394
+ return runtime;
395
+ },
396
+ bind
397
+ }
398
+ }), service;
399
+ }
400
+ function getInternalService(service) {
401
+ return service[SERVICE_INTERNAL];
380
402
  }
381
403
 
382
- export { DEFAULT_IPC_SOCKET_CONNECTION_OPTIONS, IPCServerState, RPCError, SocketState, TransportDriver, createIPCClient, createIPCServer, createIPCSocketConnection, createIPCSocketMessageHandler, createService, createServiceClient, createServiceServer, createTransportClient, createTransportClientProtocol, createTransportServer, createTransportServerProtocol, deserializeRPCError, getIPCPath, serializeRPCError };
404
+ export { DEFAULT_IPC_SOCKET_CONNECTION_OPTIONS, IPCServerState, RPCError, ServiceRole, SocketState, TransportDriver, createIPCClient, createIPCServer, createIPCSocketConnection, createIPCSocketMessageHandler, createService, createTransportClient, createTransportClientProtocol, createTransportServer, createTransportServerProtocol, deserializeRPCError, getIPCPath, getInternalService, serializeRPCError };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bakit/service",
3
- "version": "2.0.1",
3
+ "version": "3.1.0",
4
4
  "description": "Service manager for bakit framework",
5
5
  "type": "module",
6
6
  "exports": {