imean-service-engine 1.1.0 → 1.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/README.md CHANGED
@@ -1,9 +1,7 @@
1
- # Microservice Framework for Deno
1
+ # Microservice Framework
2
2
 
3
3
  一个轻量级的 TypeScript 微服务框架。提供了类型安全、自动客户端生成、请求重试等特性。
4
4
 
5
- [![JSR](https://jsr.io/badges/@imean/service-engine)](https://jsr.io/@imean/service-engine)
6
-
7
5
  ## 特性
8
6
 
9
7
  - 📝 完全的 TypeScript 支持
@@ -14,7 +12,6 @@
14
12
  - 🌟 优雅的装饰器 API
15
13
  - 🚦 优雅停机支持
16
14
  - 📡 生成基于 fetch 的客户端代码,可以在 Deno 、Node.js、Bun 以及浏览器中使用
17
- - 🌟 服务间调用可以利用 Deno 的分布式模块引入快速集成生成的客户端
18
15
  - 🌟 支持 Stream 流传输,客户端使用 AsyncIterator 迭代
19
16
  - 🌟 服务引擎支持通过 WebSocket 进行实时通信,相比 HTTP 请求具有以下优势:
20
17
  - 保持长连接,减少连接建立的开销
@@ -30,7 +27,7 @@
30
27
  ## 安装
31
28
 
32
29
  ```typescript
33
- import { Action, Microservice, Module } from "jsr:@imean/microservice";
30
+ import { Action, Microservice, Module } from "imean-service-engine";
34
31
  ```
35
32
 
36
33
  ## 快速开始
@@ -126,7 +123,7 @@ TypeScript 客户端代码。
126
123
 
127
124
  ```typescript
128
125
  const client = new MicroserviceClient({
129
- baseUrl: "http://localhost:3000/client.ts?cache=v1",
126
+ baseUrl: "http://localhost:3000",
130
127
  });
131
128
  // 创建用户
132
129
  const user = await client.users.createUser("张三", 25);
@@ -230,7 +227,7 @@ interface ClientOptions {
230
227
 
231
228
  ```typescript
232
229
  // main.ts
233
- import { startCheck } from "jsr:@imean/microservice";
230
+ import { startCheck } from "imean-service-engine";
234
231
 
235
232
  // 数据库连接检查
236
233
  async function checkDatabase() {
@@ -326,17 +323,17 @@ your-service/
326
323
  // config/index.ts
327
324
  export const config = {
328
325
  database: {
329
- host: Deno.env.get("DB_HOST") || "localhost",
330
- port: parseInt(Deno.env.get("DB_PORT") || "5432"),
326
+ host: process.env.DB_HOST || "localhost",
327
+ port: parseInt(process.env.DB_PORT || "5432"),
331
328
  // ...
332
329
  },
333
330
  redis: {
334
- url: Deno.env.get("REDIS_URL") || "redis://localhost:6379",
331
+ url: process.env.REDIS_URL || "redis://localhost:6379",
335
332
  // ...
336
333
  },
337
334
  service: {
338
- port: parseInt(Deno.env.get("PORT") || "3000"),
339
- prefix: Deno.env.get("API_PREFIX") || "/api",
335
+ port: parseInt(process.env.PORT || "3000"),
336
+ prefix: process.env.API_PREFIX || "/api",
340
337
  },
341
338
  };
342
339
 
@@ -550,7 +547,7 @@ const client = new MicroserviceClient({
550
547
 
551
548
  ### Node.js 环境使用 WebSocket
552
549
 
553
- Node.js 环境下,可以使用 `isomorphic-ws` 包来提供 WebSocket 实现:
550
+ 最新Node.js已经提供了 WebSocket 实现,可以直接使用。如果在较低 Node.js 环境下,可以使用 `isomorphic-ws` 包来提供 WebSocket 实现:
554
551
 
555
552
  ```typescript
556
553
  import WebSocket from "isomorphic-ws";
package/dist/mod.cjs CHANGED
@@ -7,10 +7,9 @@ var etcd3 = require('etcd3');
7
7
  var fs = require('fs-extra');
8
8
  var hono = require('hono');
9
9
  var lruCache = require('lru-cache');
10
+ var api = require('@opentelemetry/api');
10
11
  var winston = require('winston');
11
12
  var prettier = require('prettier');
12
- var api = require('@opentelemetry/api');
13
- var apiLogs = require('@opentelemetry/api-logs');
14
13
  var crypto2 = require('crypto');
15
14
  var zlib = require('zlib');
16
15
  var nodeWs = require('@hono/node-ws');
@@ -110,6 +109,7 @@ var logger = winston__default.default.createLogger({
110
109
  var logger_default = logger;
111
110
 
112
111
  // decorators/schedule.ts
112
+ var tracer = api.trace.getTracer("scheduler");
113
113
  var SCHEDULE_METADATA = Symbol("schedule:metadata");
114
114
  function Schedule(options) {
115
115
  return function(_originalMethod, context) {
@@ -162,20 +162,44 @@ var Scheduler = class {
162
162
  });
163
163
  campaign.on("elected", () => {
164
164
  this.isLeader.set(serviceId, true);
165
- this.startTimer(serviceId, metadata, method);
165
+ this.startTimer(serviceId, metadata, moduleName, method);
166
166
  logger_default.info(`become leader for ${moduleName}.${methodName}`);
167
167
  });
168
168
  }
169
169
  /**
170
170
  * 启动定时器
171
171
  */
172
- startTimer(serviceId, metadata, method) {
172
+ startTimer(serviceId, metadata, moduleName, method) {
173
173
  this.stopTimer(serviceId);
174
+ const wrappedMethod = async () => {
175
+ tracer.startActiveSpan(
176
+ `ScheduleTask ${moduleName}.${metadata.name}`,
177
+ { root: true },
178
+ async (span) => {
179
+ span.setAttribute("serviceId", serviceId);
180
+ span.setAttribute("methodName", metadata.name);
181
+ span.setAttribute("moduleName", moduleName);
182
+ span.setAttribute("interval", metadata.interval);
183
+ span.setAttribute("mode", metadata.mode);
184
+ try {
185
+ await method();
186
+ } catch (error) {
187
+ span.setStatus({
188
+ code: api.SpanStatusCode.ERROR,
189
+ message: error.message
190
+ });
191
+ } finally {
192
+ span.setStatus({ code: api.SpanStatusCode.OK });
193
+ span.end();
194
+ }
195
+ }
196
+ );
197
+ };
174
198
  if (metadata.mode === "FIXED_DELAY" /* FIXED_DELAY */) {
175
199
  const runTask = async () => {
176
200
  if (!this.isLeader.get(serviceId)) return;
177
201
  try {
178
- await method();
202
+ await wrappedMethod();
179
203
  } finally {
180
204
  this.timers.set(serviceId, setTimeout(runTask, metadata.interval));
181
205
  }
@@ -186,7 +210,7 @@ var Scheduler = class {
186
210
  serviceId,
187
211
  setInterval(async () => {
188
212
  if (!this.isLeader.get(serviceId)) return;
189
- await method();
213
+ await wrappedMethod();
190
214
  }, metadata.interval)
191
215
  );
192
216
  }
@@ -389,8 +413,7 @@ var brotli = {
389
413
  };
390
414
 
391
415
  // core/handler.ts
392
- var tracer = api.trace.getTracer("action-handler");
393
- var logger2 = apiLogs.logs.getLogger("action-handler");
416
+ var tracer2 = api.trace.getTracer("action-handler");
394
417
  var ActionHandler = class {
395
418
  constructor(moduleInstance, actionName, metadata, microservice, moduleName) {
396
419
  this.moduleInstance = moduleInstance;
@@ -400,46 +423,66 @@ var ActionHandler = class {
400
423
  this.moduleName = moduleName;
401
424
  }
402
425
  async handle(req) {
403
- const span = tracer.startSpan("handle");
404
- span.addEvent("logs");
405
- logger2.emit({
406
- attributes: { module: this.moduleName, action: this.actionName }
407
- });
408
- const startTime = Date.now();
409
- let args;
410
- if (typeof req === "string") {
411
- try {
412
- args = Object.values(ejson3__default.default.parse(req));
413
- } catch (error) {
414
- throw new Error(`Invalid request body: ${error.message}`);
426
+ return await tracer2.startActiveSpan(
427
+ `handle ${this.moduleName}.${this.actionName}`,
428
+ async (span) => {
429
+ span.setAttribute("module", this.moduleName);
430
+ span.setAttribute("action", this.actionName);
431
+ try {
432
+ return await this._handle(req);
433
+ } catch (error) {
434
+ span.recordException(error);
435
+ span.setStatus({
436
+ code: api.SpanStatusCode.ERROR,
437
+ message: error.message
438
+ });
439
+ throw error;
440
+ } finally {
441
+ span.end();
442
+ }
415
443
  }
416
- } else {
417
- args = req;
418
- }
419
- if (this.metadata.params) {
420
- args = args.map((arg, index) => {
444
+ );
445
+ }
446
+ async _validate(req) {
447
+ const span = tracer2.startSpan("validate");
448
+ try {
449
+ let args;
450
+ if (typeof req === "string") {
421
451
  try {
422
- return this.metadata.params[index].parse(arg);
452
+ args = Object.values(ejson3__default.default.parse(req));
423
453
  } catch (error) {
424
- throw new Error(
425
- `Invalid argument ${index}: ${error.message}`
426
- );
454
+ throw new Error(`Invalid request body: ${error.message}`);
427
455
  }
428
- });
456
+ } else {
457
+ args = req;
458
+ }
459
+ if (this.metadata.params) {
460
+ args = args.map((arg, index) => {
461
+ try {
462
+ return this.metadata.params[index].parse(arg);
463
+ } catch (error) {
464
+ throw new Error(
465
+ `Invalid argument ${index}: ${error.message}`
466
+ );
467
+ }
468
+ });
469
+ }
470
+ const requestHash = hashText(ejson3__default.default.stringify(args));
471
+ span.setAttribute("requestHash", requestHash);
472
+ return { args, requestHash };
473
+ } finally {
474
+ span.end();
429
475
  }
430
- const requestHash = hashText(ejson3__default.default.stringify(args));
476
+ }
477
+ async _handle(req) {
478
+ const span = api.trace.getActiveSpan();
479
+ const { args, requestHash } = await this._validate(req);
431
480
  if (!this.metadata.stream && this.metadata.cache && !this.microservice.options.disableCache) {
432
481
  const cacheKey = `${this.moduleName}.${this.actionName}.${requestHash}`;
433
482
  const cached = await this.microservice.cache.get(cacheKey);
434
483
  const now = Date.now();
435
484
  if (cached !== null && (!this.metadata.ttl || cached?.expireAt > now)) {
436
- this.microservice.updateMethodStats(
437
- this.moduleName,
438
- this.actionName,
439
- 0,
440
- true,
441
- true
442
- );
485
+ span?.setAttribute("cacheHit", true);
443
486
  return cached.data;
444
487
  }
445
488
  }
@@ -449,38 +492,24 @@ var ActionHandler = class {
449
492
  args
450
493
  );
451
494
  if (this.metadata.stream) {
495
+ span?.setAttribute("stream", true);
452
496
  if (!isAsyncIterable(result)) {
453
497
  throw new Error("Stream action must return AsyncIterator");
454
498
  }
455
499
  let count = 0;
456
- const self = this;
457
500
  return {
458
501
  [Symbol.asyncIterator]() {
459
502
  const iterator = result[Symbol.asyncIterator]();
460
503
  return {
461
504
  async next() {
462
- try {
463
- const { value, done } = await iterator.next();
464
- if (!done) count++;
465
- if (done) {
466
- const responseTime = Date.now() - startTime;
467
- self.microservice.updateMethodStats(
468
- self.moduleName,
469
- self.actionName,
470
- responseTime / count,
471
- true
472
- );
473
- }
474
- return { value, done };
475
- } catch (error) {
476
- self.microservice.updateMethodStats(
477
- self.moduleName,
478
- self.actionName,
479
- 0,
480
- false
481
- );
482
- throw error;
505
+ const { value, done } = await iterator.next();
506
+ span?.addEvent("stream.next");
507
+ if (!done) count++;
508
+ if (done) {
509
+ span?.setAttribute("streamCount", count);
510
+ span?.addEvent("stream.end");
483
511
  }
512
+ return { value, done };
484
513
  }
485
514
  };
486
515
  }
@@ -506,36 +535,12 @@ var ActionHandler = class {
506
535
  { ttl: this.metadata.ttl }
507
536
  );
508
537
  }
509
- this.microservice.updateMethodStats(
510
- this.moduleName,
511
- this.actionName,
512
- 0,
513
- true
514
- );
515
538
  return parsedResult;
516
539
  } catch (error) {
517
540
  if (this.metadata.printError !== false && this.microservice.options.printError !== false) {
518
541
  console.error(`Error in ${this.moduleName}.${this.actionName}:`, error);
519
542
  }
520
- if (this.microservice.options.events?.onError) {
521
- this.microservice.options.events.onError({
522
- requestHash,
523
- service: {
524
- id: this.microservice.serviceId,
525
- name: this.microservice.options.name,
526
- version: this.microservice.options.version,
527
- env: this.microservice.options.env
528
- },
529
- module: this.moduleName,
530
- action: this.actionName,
531
- params: args,
532
- time: Date.now(),
533
- error: error.message
534
- });
535
- }
536
543
  throw error;
537
- } finally {
538
- span.end();
539
544
  }
540
545
  }
541
546
  };
package/dist/mod.d.cts CHANGED
@@ -149,6 +149,8 @@ declare class ActionHandler {
149
149
  private moduleName;
150
150
  constructor(moduleInstance: any, actionName: string, metadata: ActionMetadata, microservice: Microservice, moduleName: string);
151
151
  handle(req: string | any[]): Promise<any>;
152
+ private _validate;
153
+ private _handle;
152
154
  }
153
155
 
154
156
  declare const ServiceContext: {
package/dist/mod.d.ts CHANGED
@@ -149,6 +149,8 @@ declare class ActionHandler {
149
149
  private moduleName;
150
150
  constructor(moduleInstance: any, actionName: string, metadata: ActionMetadata, microservice: Microservice, moduleName: string);
151
151
  handle(req: string | any[]): Promise<any>;
152
+ private _validate;
153
+ private _handle;
152
154
  }
153
155
 
154
156
  declare const ServiceContext: {
package/dist/mod.js CHANGED
@@ -6,10 +6,9 @@ import { Etcd3 } from 'etcd3';
6
6
  import fs from 'fs-extra';
7
7
  import { Hono } from 'hono';
8
8
  import { LRUCache } from 'lru-cache';
9
+ import { trace, SpanStatusCode } from '@opentelemetry/api';
9
10
  import winston, { format } from 'winston';
10
11
  import prettier from 'prettier';
11
- import { trace } from '@opentelemetry/api';
12
- import { logs } from '@opentelemetry/api-logs';
13
12
  import crypto2 from 'node:crypto';
14
13
  import { brotliDecompress } from 'node:zlib';
15
14
  import { brotliCompress, constants } from 'zlib';
@@ -101,6 +100,7 @@ var logger = winston.createLogger({
101
100
  var logger_default = logger;
102
101
 
103
102
  // decorators/schedule.ts
103
+ var tracer = trace.getTracer("scheduler");
104
104
  var SCHEDULE_METADATA = Symbol("schedule:metadata");
105
105
  function Schedule(options) {
106
106
  return function(_originalMethod, context) {
@@ -153,20 +153,44 @@ var Scheduler = class {
153
153
  });
154
154
  campaign.on("elected", () => {
155
155
  this.isLeader.set(serviceId, true);
156
- this.startTimer(serviceId, metadata, method);
156
+ this.startTimer(serviceId, metadata, moduleName, method);
157
157
  logger_default.info(`become leader for ${moduleName}.${methodName}`);
158
158
  });
159
159
  }
160
160
  /**
161
161
  * 启动定时器
162
162
  */
163
- startTimer(serviceId, metadata, method) {
163
+ startTimer(serviceId, metadata, moduleName, method) {
164
164
  this.stopTimer(serviceId);
165
+ const wrappedMethod = async () => {
166
+ tracer.startActiveSpan(
167
+ `ScheduleTask ${moduleName}.${metadata.name}`,
168
+ { root: true },
169
+ async (span) => {
170
+ span.setAttribute("serviceId", serviceId);
171
+ span.setAttribute("methodName", metadata.name);
172
+ span.setAttribute("moduleName", moduleName);
173
+ span.setAttribute("interval", metadata.interval);
174
+ span.setAttribute("mode", metadata.mode);
175
+ try {
176
+ await method();
177
+ } catch (error) {
178
+ span.setStatus({
179
+ code: SpanStatusCode.ERROR,
180
+ message: error.message
181
+ });
182
+ } finally {
183
+ span.setStatus({ code: SpanStatusCode.OK });
184
+ span.end();
185
+ }
186
+ }
187
+ );
188
+ };
165
189
  if (metadata.mode === "FIXED_DELAY" /* FIXED_DELAY */) {
166
190
  const runTask = async () => {
167
191
  if (!this.isLeader.get(serviceId)) return;
168
192
  try {
169
- await method();
193
+ await wrappedMethod();
170
194
  } finally {
171
195
  this.timers.set(serviceId, setTimeout(runTask, metadata.interval));
172
196
  }
@@ -177,7 +201,7 @@ var Scheduler = class {
177
201
  serviceId,
178
202
  setInterval(async () => {
179
203
  if (!this.isLeader.get(serviceId)) return;
180
- await method();
204
+ await wrappedMethod();
181
205
  }, metadata.interval)
182
206
  );
183
207
  }
@@ -380,8 +404,7 @@ var brotli = {
380
404
  };
381
405
 
382
406
  // core/handler.ts
383
- var tracer = trace.getTracer("action-handler");
384
- var logger2 = logs.getLogger("action-handler");
407
+ var tracer2 = trace.getTracer("action-handler");
385
408
  var ActionHandler = class {
386
409
  constructor(moduleInstance, actionName, metadata, microservice, moduleName) {
387
410
  this.moduleInstance = moduleInstance;
@@ -391,46 +414,66 @@ var ActionHandler = class {
391
414
  this.moduleName = moduleName;
392
415
  }
393
416
  async handle(req) {
394
- const span = tracer.startSpan("handle");
395
- span.addEvent("logs");
396
- logger2.emit({
397
- attributes: { module: this.moduleName, action: this.actionName }
398
- });
399
- const startTime = Date.now();
400
- let args;
401
- if (typeof req === "string") {
402
- try {
403
- args = Object.values(ejson3.parse(req));
404
- } catch (error) {
405
- throw new Error(`Invalid request body: ${error.message}`);
417
+ return await tracer2.startActiveSpan(
418
+ `handle ${this.moduleName}.${this.actionName}`,
419
+ async (span) => {
420
+ span.setAttribute("module", this.moduleName);
421
+ span.setAttribute("action", this.actionName);
422
+ try {
423
+ return await this._handle(req);
424
+ } catch (error) {
425
+ span.recordException(error);
426
+ span.setStatus({
427
+ code: SpanStatusCode.ERROR,
428
+ message: error.message
429
+ });
430
+ throw error;
431
+ } finally {
432
+ span.end();
433
+ }
406
434
  }
407
- } else {
408
- args = req;
409
- }
410
- if (this.metadata.params) {
411
- args = args.map((arg, index) => {
435
+ );
436
+ }
437
+ async _validate(req) {
438
+ const span = tracer2.startSpan("validate");
439
+ try {
440
+ let args;
441
+ if (typeof req === "string") {
412
442
  try {
413
- return this.metadata.params[index].parse(arg);
443
+ args = Object.values(ejson3.parse(req));
414
444
  } catch (error) {
415
- throw new Error(
416
- `Invalid argument ${index}: ${error.message}`
417
- );
445
+ throw new Error(`Invalid request body: ${error.message}`);
418
446
  }
419
- });
447
+ } else {
448
+ args = req;
449
+ }
450
+ if (this.metadata.params) {
451
+ args = args.map((arg, index) => {
452
+ try {
453
+ return this.metadata.params[index].parse(arg);
454
+ } catch (error) {
455
+ throw new Error(
456
+ `Invalid argument ${index}: ${error.message}`
457
+ );
458
+ }
459
+ });
460
+ }
461
+ const requestHash = hashText(ejson3.stringify(args));
462
+ span.setAttribute("requestHash", requestHash);
463
+ return { args, requestHash };
464
+ } finally {
465
+ span.end();
420
466
  }
421
- const requestHash = hashText(ejson3.stringify(args));
467
+ }
468
+ async _handle(req) {
469
+ const span = trace.getActiveSpan();
470
+ const { args, requestHash } = await this._validate(req);
422
471
  if (!this.metadata.stream && this.metadata.cache && !this.microservice.options.disableCache) {
423
472
  const cacheKey = `${this.moduleName}.${this.actionName}.${requestHash}`;
424
473
  const cached = await this.microservice.cache.get(cacheKey);
425
474
  const now = Date.now();
426
475
  if (cached !== null && (!this.metadata.ttl || cached?.expireAt > now)) {
427
- this.microservice.updateMethodStats(
428
- this.moduleName,
429
- this.actionName,
430
- 0,
431
- true,
432
- true
433
- );
476
+ span?.setAttribute("cacheHit", true);
434
477
  return cached.data;
435
478
  }
436
479
  }
@@ -440,38 +483,24 @@ var ActionHandler = class {
440
483
  args
441
484
  );
442
485
  if (this.metadata.stream) {
486
+ span?.setAttribute("stream", true);
443
487
  if (!isAsyncIterable(result)) {
444
488
  throw new Error("Stream action must return AsyncIterator");
445
489
  }
446
490
  let count = 0;
447
- const self = this;
448
491
  return {
449
492
  [Symbol.asyncIterator]() {
450
493
  const iterator = result[Symbol.asyncIterator]();
451
494
  return {
452
495
  async next() {
453
- try {
454
- const { value, done } = await iterator.next();
455
- if (!done) count++;
456
- if (done) {
457
- const responseTime = Date.now() - startTime;
458
- self.microservice.updateMethodStats(
459
- self.moduleName,
460
- self.actionName,
461
- responseTime / count,
462
- true
463
- );
464
- }
465
- return { value, done };
466
- } catch (error) {
467
- self.microservice.updateMethodStats(
468
- self.moduleName,
469
- self.actionName,
470
- 0,
471
- false
472
- );
473
- throw error;
496
+ const { value, done } = await iterator.next();
497
+ span?.addEvent("stream.next");
498
+ if (!done) count++;
499
+ if (done) {
500
+ span?.setAttribute("streamCount", count);
501
+ span?.addEvent("stream.end");
474
502
  }
503
+ return { value, done };
475
504
  }
476
505
  };
477
506
  }
@@ -497,36 +526,12 @@ var ActionHandler = class {
497
526
  { ttl: this.metadata.ttl }
498
527
  );
499
528
  }
500
- this.microservice.updateMethodStats(
501
- this.moduleName,
502
- this.actionName,
503
- 0,
504
- true
505
- );
506
529
  return parsedResult;
507
530
  } catch (error) {
508
531
  if (this.metadata.printError !== false && this.microservice.options.printError !== false) {
509
532
  console.error(`Error in ${this.moduleName}.${this.actionName}:`, error);
510
533
  }
511
- if (this.microservice.options.events?.onError) {
512
- this.microservice.options.events.onError({
513
- requestHash,
514
- service: {
515
- id: this.microservice.serviceId,
516
- name: this.microservice.options.name,
517
- version: this.microservice.options.version,
518
- env: this.microservice.options.env
519
- },
520
- module: this.moduleName,
521
- action: this.actionName,
522
- params: args,
523
- time: Date.now(),
524
- error: error.message
525
- });
526
- }
527
534
  throw error;
528
- } finally {
529
- span.end();
530
535
  }
531
536
  }
532
537
  };
package/package.json CHANGED
@@ -1,75 +1,82 @@
1
- {
2
- "name": "imean-service-engine",
3
- "version": "1.1.0",
4
- "description": "microservice engine",
5
- "keywords": [
6
- "microservice",
7
- "websocket",
8
- "http",
9
- "node"
10
- ],
11
- "author": "imean",
12
- "type": "module",
13
- "license": "MIT",
14
- "repository": {
15
- "type": "git",
16
- "url": "git+https://git.imean.tech/imean/imean-microservice-framework.git"
17
- },
18
- "main": "dist/mod.js",
19
- "module": "dist/mod.js",
20
- "types": "dist/mod.d.ts",
21
- "exports": {
22
- ".": {
23
- "types": "./dist/mod.d.ts",
24
- "import": "./dist/mod.js",
25
- "require": "./dist/mod.cjs"
26
- }
27
- },
28
- "files": [
29
- "dist",
30
- "README.md",
31
- "LICENSE"
32
- ],
33
- "scripts": {
34
- "dev": "tsx dev/index.ts",
35
- "build": "tsup",
36
- "lint": "deno lint",
37
- "fmt": "deno fmt",
38
- "test": "vitest",
39
- "coverage": "vitest --coverage",
40
- "prepublishOnly": "npm run build && npm run test"
41
- },
42
- "dependencies": {
43
- "@hono/node-server": "^1.13.7",
44
- "@hono/node-ws": "^1.0.6",
45
- "@opentelemetry/api": "^1.9.0",
46
- "@opentelemetry/api-logs": "^0.57.1",
47
- "dayjs": "^1.11.13",
48
- "ejson": "^2.2.3",
49
- "etcd3": "^1.1.2",
50
- "fs-extra": "^11.3.0",
51
- "hono": "^4.6.17",
52
- "lru-cache": "^11.0.2",
53
- "prettier": "^3.4.2",
54
- "winston": "^3.17.0",
55
- "zod": "^3.24.1"
56
- },
57
- "peerDependencies": {
58
- "isomorphic-ws": "^5.0.0"
59
- },
60
- "devDependencies": {
61
- "@types/ejson": "^2.2.2",
62
- "@types/fs-extra": "^11.0.4",
63
- "@types/node": "^20.0.0",
64
- "imean-service-client": "^1.4.4",
65
- "tslib": "^2.8.1",
66
- "tsup": "^8.0.1",
67
- "tsx": "^4.19.2",
68
- "typescript": "^5.3.3",
69
- "vite-tsconfig-paths": "^5.1.4",
70
- "vitest": "^3.0.3"
71
- },
72
- "engines": {
73
- "node": ">=20"
74
- }
75
- }
1
+ {
2
+ "name": "imean-service-engine",
3
+ "version": "1.2.1",
4
+ "description": "microservice engine",
5
+ "keywords": [
6
+ "microservice",
7
+ "websocket",
8
+ "http",
9
+ "node"
10
+ ],
11
+ "author": "imean",
12
+ "type": "module",
13
+ "license": "MIT",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://git.imean.tech/imean/imean-microservice-framework.git"
17
+ },
18
+ "main": "dist/mod.js",
19
+ "module": "dist/mod.js",
20
+ "types": "dist/mod.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/mod.d.ts",
24
+ "import": "./dist/mod.js",
25
+ "require": "./dist/mod.cjs"
26
+ }
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "README.md",
31
+ "LICENSE"
32
+ ],
33
+ "scripts": {
34
+ "dev": "tsx watch dev/index.ts",
35
+ "build": "tsup",
36
+ "test": "vitest run",
37
+ "prepublishOnly": "npm run build && npm run test"
38
+ },
39
+ "dependencies": {
40
+ "@hono/node-server": "^1.13.7",
41
+ "@hono/node-ws": "^1.0.6",
42
+ "dayjs": "^1.11.13",
43
+ "ejson": "^2.2.3",
44
+ "etcd3": "^1.1.2",
45
+ "fs-extra": "^11.3.0",
46
+ "hono": "^4.6.17",
47
+ "lru-cache": "^11.0.2",
48
+ "prettier": "^3.4.2",
49
+ "winston": "^3.17.0",
50
+ "zod": "^3.24.1"
51
+ },
52
+ "peerDependencies": {
53
+ "@opentelemetry/api": "^1.x"
54
+ },
55
+ "devDependencies": {
56
+ "@opentelemetry/auto-instrumentations-node": "^0.55.3",
57
+ "@opentelemetry/exporter-logs-otlp-proto": "^0.57.1",
58
+ "@opentelemetry/exporter-metrics-otlp-proto": "^0.57.1",
59
+ "@opentelemetry/exporter-trace-otlp-proto": "^0.57.1",
60
+ "@opentelemetry/instrumentation-winston": "^0.44.0",
61
+ "@opentelemetry/sdk-logs": "^0.57.1",
62
+ "@opentelemetry/sdk-metrics": "^1.30.1",
63
+ "@opentelemetry/sdk-node": "^0.57.1",
64
+ "@opentelemetry/sdk-trace-node": "^1.30.1",
65
+ "@opentelemetry/winston-transport": "^0.10.0",
66
+ "@types/ejson": "^2.2.2",
67
+ "@types/fs-extra": "^11.0.4",
68
+ "@types/node": "^20.0.0",
69
+ "@vitest/coverage-v8": "^3.0.4",
70
+ "imean-service-client": "^1.5.0",
71
+ "opentelemetry-instrumentation-fetch-node": "^1.2.3",
72
+ "tslib": "^2.8.1",
73
+ "tsup": "^8.0.1",
74
+ "tsx": "^4.19.2",
75
+ "typescript": "^5.3.3",
76
+ "vite-tsconfig-paths": "^5.1.4",
77
+ "vitest": "^3.0.3"
78
+ },
79
+ "engines": {
80
+ "node": ">=20"
81
+ }
82
+ }