@bakit/service 3.1.0 → 3.2.1

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
@@ -22,6 +22,7 @@ interface BaseClientDriver extends EventBus<BaseClientDriverEvents> {
22
22
  send(message: Serializable): void;
23
23
  connect(): void;
24
24
  disconnect(): void;
25
+ readonly ready: boolean;
25
26
  }
26
27
 
27
28
  interface BaseServerDriver extends EventBus<BaseServerDriverEvents> {
@@ -85,6 +86,7 @@ interface IPCSocketConnection extends EventBus<IPCClientEvents>, IPCSocketMessag
85
86
  reconnect: () => void;
86
87
  write: (chunk: Buffer) => void;
87
88
  readonly state: SocketState;
89
+ readonly ready: boolean;
88
90
  }
89
91
  interface IPCSocketMessageHandler extends BaseClientDriver {
90
92
  handleData: (chunk: Buffer) => void;
@@ -166,6 +168,7 @@ interface TransportClient extends TransportClientProtocol, EventBus<TransportCli
166
168
  send: BaseServerDriver["send"];
167
169
  connect: BaseClientDriver["connect"];
168
170
  disconnect: BaseClientDriver["disconnect"];
171
+ readonly ready: boolean;
169
172
  }
170
173
  interface TransportServer extends TransportServerProtocol, EventBus<TransportServerEvents> {
171
174
  broadcast: BaseServerDriver["broadcast"];
@@ -217,6 +220,8 @@ interface ServiceOptions {
217
220
  interface Service {
218
221
  readonly name: string;
219
222
  readonly role: ServiceRole;
223
+ initialize?: FunctionLike<[], Awaitable<void>>;
224
+ onReady?: FunctionLike<[], Awaitable<void>>;
220
225
  define<F extends ServiceFunction>(method: string, handler: F): Promisify<F>;
221
226
  }
222
227
  type ServiceFunction = FunctionLike<any[], Awaitable<any>>;
@@ -243,6 +248,9 @@ interface ServiceInteral {
243
248
  bind(role: "client" | "server"): void;
244
249
  }
245
250
  declare function createService(options: ServiceOptions): Service;
251
+ declare function startServiceServer(service: Service): Promise<void>;
252
+ declare function assertRuntimeClient(service: Service, runtime: MutableRuntime): asserts runtime is ServiceClientRuntime;
253
+ declare function assertRuntimeServer(service: Service, runtime: MutableRuntime): asserts runtime is ServiceServerRuntime;
246
254
  declare function getInternalService(service: Service): ServiceInteral;
247
255
 
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 };
256
+ 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, assertRuntimeClient, assertRuntimeServer, createIPCClient, createIPCServer, createIPCSocketConnection, createIPCSocketMessageHandler, createService, createTransportClient, createTransportClientProtocol, createTransportServer, createTransportServerProtocol, deserializeRPCError, getIPCPath, getInternalService, serializeRPCError, startServiceServer };
package/dist/index.js CHANGED
@@ -104,6 +104,9 @@ function createIPCSocketConnection(socketPath, options = {}) {
104
104
  write,
105
105
  get state() {
106
106
  return state;
107
+ },
108
+ get ready() {
109
+ return state === SocketState.Connected;
107
110
  }
108
111
  });
109
112
  function connect() {
@@ -239,7 +242,10 @@ function createTransportClient(options) {
239
242
  ...createTransportClientProtocol(driver),
240
243
  send: driver.send,
241
244
  connect: driver.connect,
242
- disconnect: driver.disconnect
245
+ disconnect: driver.disconnect,
246
+ get ready() {
247
+ return driver.ready;
248
+ }
243
249
  }, self = attachEventBus(base);
244
250
  return driver.on("connect", () => self.emit("connect")), driver.on("disconnect", () => self.emit("disconnect")), driver.on("error", (error) => self.emit("error", error)), self;
245
251
  }
@@ -268,17 +274,12 @@ function createTransportClientProtocol(driver) {
268
274
  function isResponseMessage(message) {
269
275
  if (!isPlainObject(message))
270
276
  return false;
271
- let hasType = "type" in message && message.type === "response", hasId = "id" in message && typeof message.id == "string", hasResult = "result" in message && message.result !== void 0, hasError = "error" in message && message.error !== void 0;
277
+ let hasType = "type" in message && message.type === "response", hasId = "id" in message && typeof message.id == "string", hasResult = "result" in message, hasError = "error" in message && message.error !== void 0;
272
278
  return hasType && hasId && hasResult !== hasError;
273
279
  }
274
280
  function request(method, ...args) {
275
281
  let requestId = randomUUID();
276
- return driver.send({
277
- type: "request",
278
- id: requestId,
279
- method,
280
- args
281
- }), new Promise((resolve, reject) => {
282
+ return new Promise((resolve, reject) => {
282
283
  let timeout = setTimeout(() => {
283
284
  let request2 = requests.get(requestId);
284
285
  request2 && (request2.reject(new Error("RPC timeout")), requests.delete(requestId));
@@ -290,6 +291,11 @@ function createTransportClientProtocol(driver) {
290
291
  reject: (e) => {
291
292
  clearTimeout(timeout), reject(e);
292
293
  }
294
+ }), driver.send({
295
+ type: "request",
296
+ id: requestId,
297
+ method,
298
+ args
293
299
  });
294
300
  });
295
301
  }
@@ -363,15 +369,11 @@ function createService(options) {
363
369
  return handlers.set(method, handler), (async (...args) => {
364
370
  if (ensureClientBound(), runtime.role === "unknown")
365
371
  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));
372
+ return runtime.role === "server" ? handler(...args) : (assertRuntimeClient(service, runtime), runtime.transport.request(method, ...args));
367
373
  });
368
374
  }
369
375
  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`);
376
+ runtime.role !== "unknown" || process.env.BAKIT_SERVICE_NAME === options.name || (bind(ServiceRole.Client), assertRuntimeClient(service, runtime), runtime.transport.ready || runtime.transport.connect());
375
377
  }
376
378
  function bind(role) {
377
379
  if (runtime.role !== "unknown")
@@ -380,10 +382,10 @@ function createService(options) {
380
382
  let server = createTransportServer(options.transport);
381
383
  for (let [method, handler] of handlers)
382
384
  server.handle(method, handler);
383
- runtime.role = "server", runtime.transport = server, server.listen();
385
+ runtime.role = "server", runtime.transport = server;
384
386
  } else if (role === "client") {
385
387
  let client = createTransportClient(options.transport);
386
- runtime.role = "client", runtime.transport = client, client.connect();
388
+ runtime.role = "client", runtime.transport = client;
387
389
  }
388
390
  }
389
391
  return Object.defineProperty(service, SERVICE_INTERNAL, {
@@ -397,8 +399,24 @@ function createService(options) {
397
399
  }
398
400
  }), service;
399
401
  }
402
+ async function startServiceServer(service) {
403
+ let internal = getInternalService(service);
404
+ return internal.bind(ServiceRole.Server), await service.initialize?.(), await new Promise((resolve) => {
405
+ assertRuntimeServer(service, internal.runtime), internal.runtime.transport.once("listen", async () => {
406
+ resolve(), await service.onReady?.();
407
+ }), internal.runtime.transport.listen();
408
+ });
409
+ }
410
+ function assertRuntimeClient(service, runtime) {
411
+ if (runtime.role !== "client")
412
+ throw new Error(`Service "${service.name}" is not a client`);
413
+ }
414
+ function assertRuntimeServer(service, runtime) {
415
+ if (runtime.role !== "server")
416
+ throw new Error(`Service "${service.name}" is not a server`);
417
+ }
400
418
  function getInternalService(service) {
401
419
  return service[SERVICE_INTERNAL];
402
420
  }
403
421
 
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 };
422
+ export { DEFAULT_IPC_SOCKET_CONNECTION_OPTIONS, IPCServerState, RPCError, ServiceRole, SocketState, TransportDriver, assertRuntimeClient, assertRuntimeServer, createIPCClient, createIPCServer, createIPCSocketConnection, createIPCSocketMessageHandler, createService, createTransportClient, createTransportClientProtocol, createTransportServer, createTransportServerProtocol, deserializeRPCError, getIPCPath, getInternalService, serializeRPCError, startServiceServer };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bakit/service",
3
- "version": "3.1.0",
3
+ "version": "3.2.1",
4
4
  "description": "Service manager for bakit framework",
5
5
  "type": "module",
6
6
  "exports": {