imean-service-engine 1.7.3 → 1.8.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/mod.cjs +45 -153
- package/dist/mod.d.cts +6 -15
- package/dist/mod.d.ts +6 -15
- package/dist/mod.js +46 -153
- package/package.json +86 -87
package/dist/mod.cjs
CHANGED
@@ -14,10 +14,6 @@ var prettier = require('prettier');
|
|
14
14
|
var crypto2 = require('crypto');
|
15
15
|
var zlib = require('zlib');
|
16
16
|
var nodeWs = require('@hono/node-ws');
|
17
|
-
var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
|
18
|
-
var types_js = require('@modelcontextprotocol/sdk/types.js');
|
19
|
-
var streaming = require('hono/streaming');
|
20
|
-
var ulid = require('ulid');
|
21
17
|
var html = require('hono/html');
|
22
18
|
var jsxRuntime = require('hono/jsx/jsx-runtime');
|
23
19
|
var dayjs = require('dayjs');
|
@@ -92,8 +88,7 @@ function Action(options) {
|
|
92
88
|
printError: options.printError ?? false,
|
93
89
|
cache: options.cache,
|
94
90
|
ttl: options.ttl,
|
95
|
-
stream: options.stream
|
96
|
-
mcp: options.mcp
|
91
|
+
stream: options.stream
|
97
92
|
};
|
98
93
|
prototype[ACTION_METADATA] = existingMetadata;
|
99
94
|
});
|
@@ -471,14 +466,14 @@ var ActionHandler = class {
|
|
471
466
|
this.microservice = microservice;
|
472
467
|
this.moduleName = moduleName;
|
473
468
|
}
|
474
|
-
async handle(req) {
|
469
|
+
async handle(req, ctx) {
|
475
470
|
return await tracer2.startActiveSpan(
|
476
471
|
`handle ${this.moduleName}.${this.actionName}`,
|
477
472
|
async (span) => {
|
478
473
|
span.setAttribute("module", this.moduleName);
|
479
474
|
span.setAttribute("action", this.actionName);
|
480
475
|
try {
|
481
|
-
return await this._handle(req);
|
476
|
+
return await this._handle(req, ctx);
|
482
477
|
} catch (error) {
|
483
478
|
span.recordException(error);
|
484
479
|
span.setStatus({
|
@@ -523,7 +518,7 @@ var ActionHandler = class {
|
|
523
518
|
span.end();
|
524
519
|
}
|
525
520
|
}
|
526
|
-
async _handle(req) {
|
521
|
+
async _handle(req, ctx) {
|
527
522
|
const span = api.trace.getActiveSpan();
|
528
523
|
const { args, requestHash } = await this._validate(req);
|
529
524
|
const cacheHash = typeof this.metadata.cache === "function" ? this.metadata.cache(...args) : requestHash;
|
@@ -541,7 +536,7 @@ var ActionHandler = class {
|
|
541
536
|
try {
|
542
537
|
const result = await this.moduleInstance[this.actionName].apply(
|
543
538
|
this.moduleInstance,
|
544
|
-
args
|
539
|
+
args.concat(ctx)
|
545
540
|
);
|
546
541
|
if (this.metadata.stream) {
|
547
542
|
span?.setAttribute("stream", true);
|
@@ -610,9 +605,10 @@ function Page(options) {
|
|
610
605
|
existingMetadata[methodName] = {
|
611
606
|
name: methodName,
|
612
607
|
description: options.description || "",
|
613
|
-
method: options.method,
|
608
|
+
method: options.method || "get",
|
614
609
|
path: normalizePath(options.path),
|
615
|
-
absolutePath: options.absolutePath ?? false
|
610
|
+
absolutePath: options.absolutePath ?? false,
|
611
|
+
middlewares: options.middlewares ?? []
|
616
612
|
};
|
617
613
|
prototype[PAGE_METADATA] = existingMetadata;
|
618
614
|
});
|
@@ -667,8 +663,9 @@ var PageHandler = class {
|
|
667
663
|
}
|
668
664
|
};
|
669
665
|
var WebSocketHandler = class {
|
670
|
-
constructor(microservice, options) {
|
666
|
+
constructor(microservice, ctx, options) {
|
671
667
|
this.microservice = microservice;
|
668
|
+
this.ctx = ctx;
|
672
669
|
this.options = {
|
673
670
|
timeout: options?.timeout || 3e4
|
674
671
|
};
|
@@ -708,7 +705,7 @@ var WebSocketHandler = class {
|
|
708
705
|
await this.sendMessage(ws, { type: "pong" });
|
709
706
|
return;
|
710
707
|
}
|
711
|
-
const response = await this.handleRequest(ws, message);
|
708
|
+
const response = await this.handleRequest(ws, message, this.ctx);
|
712
709
|
if (response) {
|
713
710
|
await this.sendMessage(ws, response);
|
714
711
|
}
|
@@ -735,7 +732,7 @@ var WebSocketHandler = class {
|
|
735
732
|
onError(_error, ws) {
|
736
733
|
this.onClose(ws);
|
737
734
|
}
|
738
|
-
async handleRequest(ws, message) {
|
735
|
+
async handleRequest(ws, message, ctx) {
|
739
736
|
if (!message.id || !message.module || !message.action) {
|
740
737
|
throw new Error("Invalid request message");
|
741
738
|
}
|
@@ -771,7 +768,7 @@ var WebSocketHandler = class {
|
|
771
768
|
message.action
|
772
769
|
);
|
773
770
|
const args = message.args ? Object.values(message.args) : [];
|
774
|
-
const result = await handler.handle(args);
|
771
|
+
const result = await handler.handle(args, ctx);
|
775
772
|
if (handler.metadata.stream) {
|
776
773
|
try {
|
777
774
|
for await (const value of result) {
|
@@ -887,7 +884,6 @@ var Microservice = class {
|
|
887
884
|
};
|
888
885
|
this.cache = this.options.cacheAdapter;
|
889
886
|
this.fetch = this.app.request;
|
890
|
-
this.waitingInitialization = this.initialize();
|
891
887
|
ServiceContext.service = this;
|
892
888
|
}
|
893
889
|
async initialize() {
|
@@ -932,20 +928,20 @@ var Microservice = class {
|
|
932
928
|
);
|
933
929
|
this.actionHandlers.set(`${moduleName}.${actionName}`, handler);
|
934
930
|
logger_default.info(
|
935
|
-
`[ \u6CE8\u518C\u52A8\u4F5C ] ${moduleName}.${actionName} ${actionMetadata.description}
|
931
|
+
`[ \u6CE8\u518C\u52A8\u4F5C ] ${moduleName}.${actionName} ${actionMetadata.description}`
|
936
932
|
);
|
937
933
|
}
|
938
934
|
for (const [_, page] of Object.entries(pages)) {
|
939
|
-
const handler = new PageHandler(
|
940
|
-
moduleInstance,
|
941
|
-
page,
|
942
|
-
moduleName
|
943
|
-
);
|
935
|
+
const handler = new PageHandler(moduleInstance, page, moduleName);
|
944
936
|
this.pageHandlers.set(`${moduleName}.${page.name}`, handler);
|
945
937
|
const paths = Array.isArray(page.path) ? page.path : [page.path];
|
946
938
|
for (let path of paths) {
|
947
939
|
path = page.absolutePath ? path : `${this.options.prefix}${path}`;
|
948
|
-
this.app[page.method](
|
940
|
+
this.app[page.method](
|
941
|
+
path,
|
942
|
+
...page.middlewares ?? [],
|
943
|
+
(ctx) => handler.handle(ctx)
|
944
|
+
);
|
949
945
|
logger_default.info(
|
950
946
|
`[ \u6CE8\u518C\u9875\u9762 ] ${moduleName}.${page.name} ${page.method.toUpperCase()} ${page.path} ${page.description}`
|
951
947
|
);
|
@@ -1007,11 +1003,10 @@ var Microservice = class {
|
|
1007
1003
|
});
|
1008
1004
|
this.app.post(`${prefix}/:moduleName/:actionName`, this.handleRequest);
|
1009
1005
|
if (this.options.websocket?.enabled) {
|
1010
|
-
this.wsHandler = new WebSocketHandler(this);
|
1011
1006
|
this.app.get(
|
1012
1007
|
`${prefix}/ws`,
|
1013
|
-
this.nodeWebSocket.upgradeWebSocket((
|
1014
|
-
const wsHandler = new WebSocketHandler(this, {
|
1008
|
+
this.nodeWebSocket.upgradeWebSocket((ctx) => {
|
1009
|
+
const wsHandler = new WebSocketHandler(this, ctx, {
|
1015
1010
|
timeout: this.options.websocket?.timeout
|
1016
1011
|
});
|
1017
1012
|
return {
|
@@ -1118,7 +1113,7 @@ var Microservice = class {
|
|
1118
1113
|
* 启动服务
|
1119
1114
|
*/
|
1120
1115
|
async start(port = 3e3, silent = false) {
|
1121
|
-
await this.
|
1116
|
+
await this.init();
|
1122
1117
|
const prefix = this.options.prefix ?? "/api";
|
1123
1118
|
this.abortController = new AbortController();
|
1124
1119
|
!silent && console.log("");
|
@@ -1233,7 +1228,9 @@ Received SIGTERM signal`);
|
|
1233
1228
|
async waitForActiveRequests() {
|
1234
1229
|
const timeout = this.options.gracefulShutdown?.timeout || 3e4;
|
1235
1230
|
const startTime = Date.now();
|
1236
|
-
logger_default.info(
|
1231
|
+
logger_default.info(
|
1232
|
+
`Waiting for ${this.activeRequests.size} active requests to complete...`
|
1233
|
+
);
|
1237
1234
|
return new Promise((resolve) => {
|
1238
1235
|
const checkInterval = setInterval(() => {
|
1239
1236
|
const elapsed = Date.now() - startTime;
|
@@ -1243,10 +1240,14 @@ Received SIGTERM signal`);
|
|
1243
1240
|
resolve();
|
1244
1241
|
} else if (elapsed >= timeout) {
|
1245
1242
|
clearInterval(checkInterval);
|
1246
|
-
logger_default.warn(
|
1243
|
+
logger_default.warn(
|
1244
|
+
`Timeout waiting for requests to complete. ${this.activeRequests.size} requests still active`
|
1245
|
+
);
|
1247
1246
|
resolve();
|
1248
1247
|
} else {
|
1249
|
-
logger_default.info(
|
1248
|
+
logger_default.info(
|
1249
|
+
`Still waiting for ${this.activeRequests.size} requests... (${elapsed}ms elapsed)`
|
1250
|
+
);
|
1250
1251
|
}
|
1251
1252
|
}, 1e3);
|
1252
1253
|
});
|
@@ -1268,7 +1269,10 @@ Received SIGTERM signal`);
|
|
1268
1269
|
await Promise.race([
|
1269
1270
|
Promise.resolve(hook.cleanup()),
|
1270
1271
|
new Promise(
|
1271
|
-
(_, reject) => setTimeout(
|
1272
|
+
(_, reject) => setTimeout(
|
1273
|
+
() => reject(new Error(`Cleanup hook ${hook.name} timeout`)),
|
1274
|
+
timeout
|
1275
|
+
)
|
1272
1276
|
)
|
1273
1277
|
]);
|
1274
1278
|
logger_default.info(`Cleanup hook ${hook.name} completed successfully`);
|
@@ -1349,10 +1353,13 @@ Received SIGTERM signal`);
|
|
1349
1353
|
const requestId = crypto.randomUUID();
|
1350
1354
|
const startTime = Date.now();
|
1351
1355
|
if (this.status === "shutting_down") {
|
1352
|
-
return ctx.json(
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
+
return ctx.json(
|
1357
|
+
{
|
1358
|
+
success: false,
|
1359
|
+
error: "Service is shutting down"
|
1360
|
+
},
|
1361
|
+
503
|
1362
|
+
);
|
1356
1363
|
}
|
1357
1364
|
try {
|
1358
1365
|
const paramsText = await ctx.req.text();
|
@@ -1363,7 +1370,7 @@ Received SIGTERM signal`);
|
|
1363
1370
|
startTime,
|
1364
1371
|
params: paramsText
|
1365
1372
|
});
|
1366
|
-
const result = await handler.handle(paramsText);
|
1373
|
+
const result = await handler.handle(paramsText, ctx);
|
1367
1374
|
if (handler.metadata.stream) {
|
1368
1375
|
const encoder = new TextEncoder();
|
1369
1376
|
const microservice = this;
|
@@ -1419,124 +1426,10 @@ Received SIGTERM signal`);
|
|
1419
1426
|
}
|
1420
1427
|
}
|
1421
1428
|
async init() {
|
1429
|
+
this.waitingInitialization = this.initialize();
|
1422
1430
|
await this.waitingInitialization;
|
1423
1431
|
}
|
1424
1432
|
};
|
1425
|
-
var HonoTransport = class {
|
1426
|
-
constructor(url, stream, closeStream) {
|
1427
|
-
this.url = url;
|
1428
|
-
this.stream = stream;
|
1429
|
-
this.closeStream = closeStream;
|
1430
|
-
this.sessionId = ulid.ulid();
|
1431
|
-
}
|
1432
|
-
sessionId;
|
1433
|
-
onclose;
|
1434
|
-
onerror;
|
1435
|
-
onmessage;
|
1436
|
-
async start() {
|
1437
|
-
await this.stream.writeSSE({
|
1438
|
-
event: "endpoint",
|
1439
|
-
data: `${encodeURI(this.url)}?sessionId=${this.sessionId}`
|
1440
|
-
});
|
1441
|
-
this.stream.onAbort(() => {
|
1442
|
-
this.close();
|
1443
|
-
});
|
1444
|
-
}
|
1445
|
-
async handleMessage(message) {
|
1446
|
-
let parsedMessage;
|
1447
|
-
try {
|
1448
|
-
parsedMessage = types_js.JSONRPCMessageSchema.parse(message);
|
1449
|
-
} catch (error) {
|
1450
|
-
this.onerror?.(error);
|
1451
|
-
throw error;
|
1452
|
-
}
|
1453
|
-
this.onmessage?.(parsedMessage);
|
1454
|
-
}
|
1455
|
-
async send(message) {
|
1456
|
-
await this.stream.writeln(
|
1457
|
-
`event: message
|
1458
|
-
data: ${JSON.stringify(message)}
|
1459
|
-
|
1460
|
-
`
|
1461
|
-
);
|
1462
|
-
}
|
1463
|
-
async close() {
|
1464
|
-
this.onclose?.();
|
1465
|
-
this.closeStream();
|
1466
|
-
}
|
1467
|
-
};
|
1468
|
-
var ModelContextProtocolPlugin = class extends Plugin {
|
1469
|
-
mcpServer;
|
1470
|
-
transports = {};
|
1471
|
-
registerMcpTools(engine) {
|
1472
|
-
const modules = engine.getModules(true);
|
1473
|
-
for (const module of Object.values(modules)) {
|
1474
|
-
for (const action of Object.values(module.actions)) {
|
1475
|
-
if (action.mcp?.type !== "tool") {
|
1476
|
-
continue;
|
1477
|
-
}
|
1478
|
-
const args = {};
|
1479
|
-
const argsIndex = {};
|
1480
|
-
for (const [index, param] of (action.params ?? []).entries()) {
|
1481
|
-
args[param.description] = param;
|
1482
|
-
argsIndex[param.description] = index;
|
1483
|
-
}
|
1484
|
-
this.mcpServer.tool(
|
1485
|
-
`${module.name}.${action.name}`,
|
1486
|
-
action.description ?? "",
|
1487
|
-
args,
|
1488
|
-
async (params) => {
|
1489
|
-
const argsList = [];
|
1490
|
-
for (const [key, value] of Object.entries(params)) {
|
1491
|
-
argsList[argsIndex[key]] = value;
|
1492
|
-
}
|
1493
|
-
const result = await engine.getActionHandler(module.name, action.name).handle(argsList);
|
1494
|
-
return {
|
1495
|
-
content: [{ type: "text", text: JSON.stringify(result) }]
|
1496
|
-
};
|
1497
|
-
}
|
1498
|
-
);
|
1499
|
-
}
|
1500
|
-
}
|
1501
|
-
}
|
1502
|
-
initialize = async (engine) => {
|
1503
|
-
const app = engine.getApp();
|
1504
|
-
this.mcpServer = new mcp_js.McpServer({
|
1505
|
-
name: engine.options.name,
|
1506
|
-
version: engine.options.version
|
1507
|
-
});
|
1508
|
-
this.registerMcpTools(engine);
|
1509
|
-
app.get(`${engine.options.prefix}/mcp_sse`, async (ctx) => {
|
1510
|
-
return streaming.streamSSE(ctx, async (stream) => {
|
1511
|
-
return new Promise(async (resolve) => {
|
1512
|
-
const transport = new HonoTransport(
|
1513
|
-
`${engine.options.prefix}/mcp_messages`,
|
1514
|
-
stream,
|
1515
|
-
() => {
|
1516
|
-
delete this.transports[transport.sessionId];
|
1517
|
-
resolve();
|
1518
|
-
}
|
1519
|
-
);
|
1520
|
-
this.transports[transport.sessionId] = transport;
|
1521
|
-
await this.mcpServer.connect(transport);
|
1522
|
-
});
|
1523
|
-
});
|
1524
|
-
});
|
1525
|
-
app.post(`${engine.options.prefix}/mcp_messages`, async (ctx) => {
|
1526
|
-
const sessionId = ctx.req.query("sessionId");
|
1527
|
-
if (!sessionId) {
|
1528
|
-
return ctx.text("No transport found for sessionId", 400);
|
1529
|
-
}
|
1530
|
-
const transport = this.transports[sessionId];
|
1531
|
-
const message = await ctx.req.json();
|
1532
|
-
await transport.handleMessage(message);
|
1533
|
-
return ctx.text("Accepted", 202);
|
1534
|
-
});
|
1535
|
-
logger_default.info(
|
1536
|
-
`ModelContextProtocolPlugin endpoint: ${engine.options.prefix}/mcp_sse`
|
1537
|
-
);
|
1538
|
-
};
|
1539
|
-
};
|
1540
1433
|
var DEFAULT_FAVICON = /* @__PURE__ */ jsxRuntime.jsx(
|
1541
1434
|
"link",
|
1542
1435
|
{
|
@@ -1749,7 +1642,6 @@ exports.CacheAdapter = CacheAdapter;
|
|
1749
1642
|
exports.HtmxLayout = HtmxLayout;
|
1750
1643
|
exports.MemoryCacheAdapter = MemoryCacheAdapter;
|
1751
1644
|
exports.Microservice = Microservice;
|
1752
|
-
exports.ModelContextProtocolPlugin = ModelContextProtocolPlugin;
|
1753
1645
|
exports.Module = Module;
|
1754
1646
|
exports.Page = Page;
|
1755
1647
|
exports.PageRenderPlugin = PageRenderPlugin;
|
package/dist/mod.d.cts
CHANGED
@@ -3,7 +3,7 @@ export * from 'zod';
|
|
3
3
|
import { Redis, Cluster } from 'ioredis';
|
4
4
|
import { LRUCache } from 'lru-cache';
|
5
5
|
import { Lease, Etcd3 } from 'etcd3';
|
6
|
-
import { Hono } from 'hono';
|
6
|
+
import { MiddlewareHandler, Context, Hono } from 'hono';
|
7
7
|
export { default as dayjs } from 'dayjs';
|
8
8
|
import winston from 'winston';
|
9
9
|
import * as hono_utils_html from 'hono/utils/html';
|
@@ -27,9 +27,6 @@ declare class MemoryCacheAdapter extends CacheAdapter {
|
|
27
27
|
}
|
28
28
|
|
29
29
|
type CacheFn = (...args: any[]) => any;
|
30
|
-
type McpOptions = {
|
31
|
-
type: "tool";
|
32
|
-
};
|
33
30
|
interface ActionOptions {
|
34
31
|
params?: z.ZodType<any>[];
|
35
32
|
returns?: z.ZodType<any>;
|
@@ -39,16 +36,17 @@ interface ActionOptions {
|
|
39
36
|
cache?: boolean | CacheFn;
|
40
37
|
ttl?: number;
|
41
38
|
stream?: boolean;
|
42
|
-
mcp?: McpOptions;
|
43
39
|
}
|
44
40
|
interface PageOptions {
|
45
|
-
method
|
41
|
+
method?: "get" | "post" | "put" | "delete" | "patch" | "options";
|
42
|
+
middlewares?: MiddlewareHandler[];
|
46
43
|
path: string | string[];
|
47
44
|
absolutePath?: boolean;
|
48
45
|
description?: string;
|
49
46
|
}
|
50
47
|
interface PageMetadata extends PageOptions {
|
51
48
|
name: string;
|
49
|
+
method: "get" | "post" | "put" | "delete" | "patch" | "options";
|
52
50
|
}
|
53
51
|
interface ActionMetadata extends ActionOptions {
|
54
52
|
name: string;
|
@@ -213,7 +211,7 @@ declare class ActionHandler {
|
|
213
211
|
private microservice;
|
214
212
|
private moduleName;
|
215
213
|
constructor(moduleInstance: any, actionName: string, metadata: ActionMetadata, microservice: Microservice, moduleName: string);
|
216
|
-
handle(req: string | any[]): Promise<any>;
|
214
|
+
handle(req: string | any[], ctx: Context): Promise<any>;
|
217
215
|
private _validate;
|
218
216
|
private _handle;
|
219
217
|
}
|
@@ -316,13 +314,6 @@ declare class Microservice {
|
|
316
314
|
init(): Promise<void>;
|
317
315
|
}
|
318
316
|
|
319
|
-
declare class ModelContextProtocolPlugin extends Plugin {
|
320
|
-
private mcpServer;
|
321
|
-
private transports;
|
322
|
-
private registerMcpTools;
|
323
|
-
initialize: (engine: Microservice) => Promise<void>;
|
324
|
-
}
|
325
|
-
|
326
317
|
declare const BaseLayout: (props?: {
|
327
318
|
children?: any;
|
328
319
|
title?: string;
|
@@ -381,4 +372,4 @@ declare function Schedule(options: ScheduleOptions): Function;
|
|
381
372
|
|
382
373
|
declare const logger: winston.Logger;
|
383
374
|
|
384
|
-
export { Action, type ActionErrorEvent, type ActionMetadata, type ActionOptions, BaseLayout, CacheAdapter, type CacheFn, type CleanupHook, type EtcdConfig, type EventServiceInfo, HtmxLayout,
|
375
|
+
export { Action, type ActionErrorEvent, type ActionMetadata, type ActionOptions, BaseLayout, CacheAdapter, type CacheFn, type CleanupHook, type EtcdConfig, type EventServiceInfo, HtmxLayout, MemoryCacheAdapter, Microservice, type MicroserviceOptions, Module, type ModuleInfo, type ModuleMetadata, type ModuleOptions, Page, type PageMetadata, type PageOptions, PageRenderPlugin, type PageRenderPluginOptions, Plugin, type PreStartChecker, RedisCacheAdapter, type RequestInfo, Schedule, type ScheduleMetadata, ScheduleMode, type ScheduleOptions, ServiceContext, type ServiceInfo, ServiceInfoCards, type ServiceStats, ServiceStatusPage, type StatisticsEvent, type StreamResponse, logger, startCheck };
|
package/dist/mod.d.ts
CHANGED
@@ -3,7 +3,7 @@ export * from 'zod';
|
|
3
3
|
import { Redis, Cluster } from 'ioredis';
|
4
4
|
import { LRUCache } from 'lru-cache';
|
5
5
|
import { Lease, Etcd3 } from 'etcd3';
|
6
|
-
import { Hono } from 'hono';
|
6
|
+
import { MiddlewareHandler, Context, Hono } from 'hono';
|
7
7
|
export { default as dayjs } from 'dayjs';
|
8
8
|
import winston from 'winston';
|
9
9
|
import * as hono_utils_html from 'hono/utils/html';
|
@@ -27,9 +27,6 @@ declare class MemoryCacheAdapter extends CacheAdapter {
|
|
27
27
|
}
|
28
28
|
|
29
29
|
type CacheFn = (...args: any[]) => any;
|
30
|
-
type McpOptions = {
|
31
|
-
type: "tool";
|
32
|
-
};
|
33
30
|
interface ActionOptions {
|
34
31
|
params?: z.ZodType<any>[];
|
35
32
|
returns?: z.ZodType<any>;
|
@@ -39,16 +36,17 @@ interface ActionOptions {
|
|
39
36
|
cache?: boolean | CacheFn;
|
40
37
|
ttl?: number;
|
41
38
|
stream?: boolean;
|
42
|
-
mcp?: McpOptions;
|
43
39
|
}
|
44
40
|
interface PageOptions {
|
45
|
-
method
|
41
|
+
method?: "get" | "post" | "put" | "delete" | "patch" | "options";
|
42
|
+
middlewares?: MiddlewareHandler[];
|
46
43
|
path: string | string[];
|
47
44
|
absolutePath?: boolean;
|
48
45
|
description?: string;
|
49
46
|
}
|
50
47
|
interface PageMetadata extends PageOptions {
|
51
48
|
name: string;
|
49
|
+
method: "get" | "post" | "put" | "delete" | "patch" | "options";
|
52
50
|
}
|
53
51
|
interface ActionMetadata extends ActionOptions {
|
54
52
|
name: string;
|
@@ -213,7 +211,7 @@ declare class ActionHandler {
|
|
213
211
|
private microservice;
|
214
212
|
private moduleName;
|
215
213
|
constructor(moduleInstance: any, actionName: string, metadata: ActionMetadata, microservice: Microservice, moduleName: string);
|
216
|
-
handle(req: string | any[]): Promise<any>;
|
214
|
+
handle(req: string | any[], ctx: Context): Promise<any>;
|
217
215
|
private _validate;
|
218
216
|
private _handle;
|
219
217
|
}
|
@@ -316,13 +314,6 @@ declare class Microservice {
|
|
316
314
|
init(): Promise<void>;
|
317
315
|
}
|
318
316
|
|
319
|
-
declare class ModelContextProtocolPlugin extends Plugin {
|
320
|
-
private mcpServer;
|
321
|
-
private transports;
|
322
|
-
private registerMcpTools;
|
323
|
-
initialize: (engine: Microservice) => Promise<void>;
|
324
|
-
}
|
325
|
-
|
326
317
|
declare const BaseLayout: (props?: {
|
327
318
|
children?: any;
|
328
319
|
title?: string;
|
@@ -381,4 +372,4 @@ declare function Schedule(options: ScheduleOptions): Function;
|
|
381
372
|
|
382
373
|
declare const logger: winston.Logger;
|
383
374
|
|
384
|
-
export { Action, type ActionErrorEvent, type ActionMetadata, type ActionOptions, BaseLayout, CacheAdapter, type CacheFn, type CleanupHook, type EtcdConfig, type EventServiceInfo, HtmxLayout,
|
375
|
+
export { Action, type ActionErrorEvent, type ActionMetadata, type ActionOptions, BaseLayout, CacheAdapter, type CacheFn, type CleanupHook, type EtcdConfig, type EventServiceInfo, HtmxLayout, MemoryCacheAdapter, Microservice, type MicroserviceOptions, Module, type ModuleInfo, type ModuleMetadata, type ModuleOptions, Page, type PageMetadata, type PageOptions, PageRenderPlugin, type PageRenderPluginOptions, Plugin, type PreStartChecker, RedisCacheAdapter, type RequestInfo, Schedule, type ScheduleMetadata, ScheduleMode, type ScheduleOptions, ServiceContext, type ServiceInfo, ServiceInfoCards, type ServiceStats, ServiceStatusPage, type StatisticsEvent, type StreamResponse, logger, startCheck };
|
package/dist/mod.js
CHANGED
@@ -14,10 +14,6 @@ import crypto2 from 'node:crypto';
|
|
14
14
|
import { brotliDecompress } from 'node:zlib';
|
15
15
|
import { brotliCompress, constants } from 'zlib';
|
16
16
|
import { createNodeWebSocket } from '@hono/node-ws';
|
17
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
18
|
-
import { JSONRPCMessageSchema } from '@modelcontextprotocol/sdk/types.js';
|
19
|
-
import { streamSSE } from 'hono/streaming';
|
20
|
-
import { ulid } from 'ulid';
|
21
17
|
import { html } from 'hono/html';
|
22
18
|
import { jsx, jsxs } from 'hono/jsx/jsx-runtime';
|
23
19
|
export { default as dayjs } from 'dayjs';
|
@@ -83,8 +79,7 @@ function Action(options) {
|
|
83
79
|
printError: options.printError ?? false,
|
84
80
|
cache: options.cache,
|
85
81
|
ttl: options.ttl,
|
86
|
-
stream: options.stream
|
87
|
-
mcp: options.mcp
|
82
|
+
stream: options.stream
|
88
83
|
};
|
89
84
|
prototype[ACTION_METADATA] = existingMetadata;
|
90
85
|
});
|
@@ -462,14 +457,14 @@ var ActionHandler = class {
|
|
462
457
|
this.microservice = microservice;
|
463
458
|
this.moduleName = moduleName;
|
464
459
|
}
|
465
|
-
async handle(req) {
|
460
|
+
async handle(req, ctx) {
|
466
461
|
return await tracer2.startActiveSpan(
|
467
462
|
`handle ${this.moduleName}.${this.actionName}`,
|
468
463
|
async (span) => {
|
469
464
|
span.setAttribute("module", this.moduleName);
|
470
465
|
span.setAttribute("action", this.actionName);
|
471
466
|
try {
|
472
|
-
return await this._handle(req);
|
467
|
+
return await this._handle(req, ctx);
|
473
468
|
} catch (error) {
|
474
469
|
span.recordException(error);
|
475
470
|
span.setStatus({
|
@@ -514,7 +509,7 @@ var ActionHandler = class {
|
|
514
509
|
span.end();
|
515
510
|
}
|
516
511
|
}
|
517
|
-
async _handle(req) {
|
512
|
+
async _handle(req, ctx) {
|
518
513
|
const span = trace.getActiveSpan();
|
519
514
|
const { args, requestHash } = await this._validate(req);
|
520
515
|
const cacheHash = typeof this.metadata.cache === "function" ? this.metadata.cache(...args) : requestHash;
|
@@ -532,7 +527,7 @@ var ActionHandler = class {
|
|
532
527
|
try {
|
533
528
|
const result = await this.moduleInstance[this.actionName].apply(
|
534
529
|
this.moduleInstance,
|
535
|
-
args
|
530
|
+
args.concat(ctx)
|
536
531
|
);
|
537
532
|
if (this.metadata.stream) {
|
538
533
|
span?.setAttribute("stream", true);
|
@@ -601,9 +596,10 @@ function Page(options) {
|
|
601
596
|
existingMetadata[methodName] = {
|
602
597
|
name: methodName,
|
603
598
|
description: options.description || "",
|
604
|
-
method: options.method,
|
599
|
+
method: options.method || "get",
|
605
600
|
path: normalizePath(options.path),
|
606
|
-
absolutePath: options.absolutePath ?? false
|
601
|
+
absolutePath: options.absolutePath ?? false,
|
602
|
+
middlewares: options.middlewares ?? []
|
607
603
|
};
|
608
604
|
prototype[PAGE_METADATA] = existingMetadata;
|
609
605
|
});
|
@@ -658,8 +654,9 @@ var PageHandler = class {
|
|
658
654
|
}
|
659
655
|
};
|
660
656
|
var WebSocketHandler = class {
|
661
|
-
constructor(microservice, options) {
|
657
|
+
constructor(microservice, ctx, options) {
|
662
658
|
this.microservice = microservice;
|
659
|
+
this.ctx = ctx;
|
663
660
|
this.options = {
|
664
661
|
timeout: options?.timeout || 3e4
|
665
662
|
};
|
@@ -699,7 +696,7 @@ var WebSocketHandler = class {
|
|
699
696
|
await this.sendMessage(ws, { type: "pong" });
|
700
697
|
return;
|
701
698
|
}
|
702
|
-
const response = await this.handleRequest(ws, message);
|
699
|
+
const response = await this.handleRequest(ws, message, this.ctx);
|
703
700
|
if (response) {
|
704
701
|
await this.sendMessage(ws, response);
|
705
702
|
}
|
@@ -726,7 +723,7 @@ var WebSocketHandler = class {
|
|
726
723
|
onError(_error, ws) {
|
727
724
|
this.onClose(ws);
|
728
725
|
}
|
729
|
-
async handleRequest(ws, message) {
|
726
|
+
async handleRequest(ws, message, ctx) {
|
730
727
|
if (!message.id || !message.module || !message.action) {
|
731
728
|
throw new Error("Invalid request message");
|
732
729
|
}
|
@@ -762,7 +759,7 @@ var WebSocketHandler = class {
|
|
762
759
|
message.action
|
763
760
|
);
|
764
761
|
const args = message.args ? Object.values(message.args) : [];
|
765
|
-
const result = await handler.handle(args);
|
762
|
+
const result = await handler.handle(args, ctx);
|
766
763
|
if (handler.metadata.stream) {
|
767
764
|
try {
|
768
765
|
for await (const value of result) {
|
@@ -878,7 +875,6 @@ var Microservice = class {
|
|
878
875
|
};
|
879
876
|
this.cache = this.options.cacheAdapter;
|
880
877
|
this.fetch = this.app.request;
|
881
|
-
this.waitingInitialization = this.initialize();
|
882
878
|
ServiceContext.service = this;
|
883
879
|
}
|
884
880
|
async initialize() {
|
@@ -923,20 +919,20 @@ var Microservice = class {
|
|
923
919
|
);
|
924
920
|
this.actionHandlers.set(`${moduleName}.${actionName}`, handler);
|
925
921
|
logger_default.info(
|
926
|
-
`[ \u6CE8\u518C\u52A8\u4F5C ] ${moduleName}.${actionName} ${actionMetadata.description}
|
922
|
+
`[ \u6CE8\u518C\u52A8\u4F5C ] ${moduleName}.${actionName} ${actionMetadata.description}`
|
927
923
|
);
|
928
924
|
}
|
929
925
|
for (const [_, page] of Object.entries(pages)) {
|
930
|
-
const handler = new PageHandler(
|
931
|
-
moduleInstance,
|
932
|
-
page,
|
933
|
-
moduleName
|
934
|
-
);
|
926
|
+
const handler = new PageHandler(moduleInstance, page, moduleName);
|
935
927
|
this.pageHandlers.set(`${moduleName}.${page.name}`, handler);
|
936
928
|
const paths = Array.isArray(page.path) ? page.path : [page.path];
|
937
929
|
for (let path of paths) {
|
938
930
|
path = page.absolutePath ? path : `${this.options.prefix}${path}`;
|
939
|
-
this.app[page.method](
|
931
|
+
this.app[page.method](
|
932
|
+
path,
|
933
|
+
...page.middlewares ?? [],
|
934
|
+
(ctx) => handler.handle(ctx)
|
935
|
+
);
|
940
936
|
logger_default.info(
|
941
937
|
`[ \u6CE8\u518C\u9875\u9762 ] ${moduleName}.${page.name} ${page.method.toUpperCase()} ${page.path} ${page.description}`
|
942
938
|
);
|
@@ -998,11 +994,10 @@ var Microservice = class {
|
|
998
994
|
});
|
999
995
|
this.app.post(`${prefix}/:moduleName/:actionName`, this.handleRequest);
|
1000
996
|
if (this.options.websocket?.enabled) {
|
1001
|
-
this.wsHandler = new WebSocketHandler(this);
|
1002
997
|
this.app.get(
|
1003
998
|
`${prefix}/ws`,
|
1004
|
-
this.nodeWebSocket.upgradeWebSocket((
|
1005
|
-
const wsHandler = new WebSocketHandler(this, {
|
999
|
+
this.nodeWebSocket.upgradeWebSocket((ctx) => {
|
1000
|
+
const wsHandler = new WebSocketHandler(this, ctx, {
|
1006
1001
|
timeout: this.options.websocket?.timeout
|
1007
1002
|
});
|
1008
1003
|
return {
|
@@ -1109,7 +1104,7 @@ var Microservice = class {
|
|
1109
1104
|
* 启动服务
|
1110
1105
|
*/
|
1111
1106
|
async start(port = 3e3, silent = false) {
|
1112
|
-
await this.
|
1107
|
+
await this.init();
|
1113
1108
|
const prefix = this.options.prefix ?? "/api";
|
1114
1109
|
this.abortController = new AbortController();
|
1115
1110
|
!silent && console.log("");
|
@@ -1224,7 +1219,9 @@ Received SIGTERM signal`);
|
|
1224
1219
|
async waitForActiveRequests() {
|
1225
1220
|
const timeout = this.options.gracefulShutdown?.timeout || 3e4;
|
1226
1221
|
const startTime = Date.now();
|
1227
|
-
logger_default.info(
|
1222
|
+
logger_default.info(
|
1223
|
+
`Waiting for ${this.activeRequests.size} active requests to complete...`
|
1224
|
+
);
|
1228
1225
|
return new Promise((resolve) => {
|
1229
1226
|
const checkInterval = setInterval(() => {
|
1230
1227
|
const elapsed = Date.now() - startTime;
|
@@ -1234,10 +1231,14 @@ Received SIGTERM signal`);
|
|
1234
1231
|
resolve();
|
1235
1232
|
} else if (elapsed >= timeout) {
|
1236
1233
|
clearInterval(checkInterval);
|
1237
|
-
logger_default.warn(
|
1234
|
+
logger_default.warn(
|
1235
|
+
`Timeout waiting for requests to complete. ${this.activeRequests.size} requests still active`
|
1236
|
+
);
|
1238
1237
|
resolve();
|
1239
1238
|
} else {
|
1240
|
-
logger_default.info(
|
1239
|
+
logger_default.info(
|
1240
|
+
`Still waiting for ${this.activeRequests.size} requests... (${elapsed}ms elapsed)`
|
1241
|
+
);
|
1241
1242
|
}
|
1242
1243
|
}, 1e3);
|
1243
1244
|
});
|
@@ -1259,7 +1260,10 @@ Received SIGTERM signal`);
|
|
1259
1260
|
await Promise.race([
|
1260
1261
|
Promise.resolve(hook.cleanup()),
|
1261
1262
|
new Promise(
|
1262
|
-
(_, reject) => setTimeout(
|
1263
|
+
(_, reject) => setTimeout(
|
1264
|
+
() => reject(new Error(`Cleanup hook ${hook.name} timeout`)),
|
1265
|
+
timeout
|
1266
|
+
)
|
1263
1267
|
)
|
1264
1268
|
]);
|
1265
1269
|
logger_default.info(`Cleanup hook ${hook.name} completed successfully`);
|
@@ -1340,10 +1344,13 @@ Received SIGTERM signal`);
|
|
1340
1344
|
const requestId = crypto.randomUUID();
|
1341
1345
|
const startTime = Date.now();
|
1342
1346
|
if (this.status === "shutting_down") {
|
1343
|
-
return ctx.json(
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1347
|
+
return ctx.json(
|
1348
|
+
{
|
1349
|
+
success: false,
|
1350
|
+
error: "Service is shutting down"
|
1351
|
+
},
|
1352
|
+
503
|
1353
|
+
);
|
1347
1354
|
}
|
1348
1355
|
try {
|
1349
1356
|
const paramsText = await ctx.req.text();
|
@@ -1354,7 +1361,7 @@ Received SIGTERM signal`);
|
|
1354
1361
|
startTime,
|
1355
1362
|
params: paramsText
|
1356
1363
|
});
|
1357
|
-
const result = await handler.handle(paramsText);
|
1364
|
+
const result = await handler.handle(paramsText, ctx);
|
1358
1365
|
if (handler.metadata.stream) {
|
1359
1366
|
const encoder = new TextEncoder();
|
1360
1367
|
const microservice = this;
|
@@ -1410,124 +1417,10 @@ Received SIGTERM signal`);
|
|
1410
1417
|
}
|
1411
1418
|
}
|
1412
1419
|
async init() {
|
1420
|
+
this.waitingInitialization = this.initialize();
|
1413
1421
|
await this.waitingInitialization;
|
1414
1422
|
}
|
1415
1423
|
};
|
1416
|
-
var HonoTransport = class {
|
1417
|
-
constructor(url, stream, closeStream) {
|
1418
|
-
this.url = url;
|
1419
|
-
this.stream = stream;
|
1420
|
-
this.closeStream = closeStream;
|
1421
|
-
this.sessionId = ulid();
|
1422
|
-
}
|
1423
|
-
sessionId;
|
1424
|
-
onclose;
|
1425
|
-
onerror;
|
1426
|
-
onmessage;
|
1427
|
-
async start() {
|
1428
|
-
await this.stream.writeSSE({
|
1429
|
-
event: "endpoint",
|
1430
|
-
data: `${encodeURI(this.url)}?sessionId=${this.sessionId}`
|
1431
|
-
});
|
1432
|
-
this.stream.onAbort(() => {
|
1433
|
-
this.close();
|
1434
|
-
});
|
1435
|
-
}
|
1436
|
-
async handleMessage(message) {
|
1437
|
-
let parsedMessage;
|
1438
|
-
try {
|
1439
|
-
parsedMessage = JSONRPCMessageSchema.parse(message);
|
1440
|
-
} catch (error) {
|
1441
|
-
this.onerror?.(error);
|
1442
|
-
throw error;
|
1443
|
-
}
|
1444
|
-
this.onmessage?.(parsedMessage);
|
1445
|
-
}
|
1446
|
-
async send(message) {
|
1447
|
-
await this.stream.writeln(
|
1448
|
-
`event: message
|
1449
|
-
data: ${JSON.stringify(message)}
|
1450
|
-
|
1451
|
-
`
|
1452
|
-
);
|
1453
|
-
}
|
1454
|
-
async close() {
|
1455
|
-
this.onclose?.();
|
1456
|
-
this.closeStream();
|
1457
|
-
}
|
1458
|
-
};
|
1459
|
-
var ModelContextProtocolPlugin = class extends Plugin {
|
1460
|
-
mcpServer;
|
1461
|
-
transports = {};
|
1462
|
-
registerMcpTools(engine) {
|
1463
|
-
const modules = engine.getModules(true);
|
1464
|
-
for (const module of Object.values(modules)) {
|
1465
|
-
for (const action of Object.values(module.actions)) {
|
1466
|
-
if (action.mcp?.type !== "tool") {
|
1467
|
-
continue;
|
1468
|
-
}
|
1469
|
-
const args = {};
|
1470
|
-
const argsIndex = {};
|
1471
|
-
for (const [index, param] of (action.params ?? []).entries()) {
|
1472
|
-
args[param.description] = param;
|
1473
|
-
argsIndex[param.description] = index;
|
1474
|
-
}
|
1475
|
-
this.mcpServer.tool(
|
1476
|
-
`${module.name}.${action.name}`,
|
1477
|
-
action.description ?? "",
|
1478
|
-
args,
|
1479
|
-
async (params) => {
|
1480
|
-
const argsList = [];
|
1481
|
-
for (const [key, value] of Object.entries(params)) {
|
1482
|
-
argsList[argsIndex[key]] = value;
|
1483
|
-
}
|
1484
|
-
const result = await engine.getActionHandler(module.name, action.name).handle(argsList);
|
1485
|
-
return {
|
1486
|
-
content: [{ type: "text", text: JSON.stringify(result) }]
|
1487
|
-
};
|
1488
|
-
}
|
1489
|
-
);
|
1490
|
-
}
|
1491
|
-
}
|
1492
|
-
}
|
1493
|
-
initialize = async (engine) => {
|
1494
|
-
const app = engine.getApp();
|
1495
|
-
this.mcpServer = new McpServer({
|
1496
|
-
name: engine.options.name,
|
1497
|
-
version: engine.options.version
|
1498
|
-
});
|
1499
|
-
this.registerMcpTools(engine);
|
1500
|
-
app.get(`${engine.options.prefix}/mcp_sse`, async (ctx) => {
|
1501
|
-
return streamSSE(ctx, async (stream) => {
|
1502
|
-
return new Promise(async (resolve) => {
|
1503
|
-
const transport = new HonoTransport(
|
1504
|
-
`${engine.options.prefix}/mcp_messages`,
|
1505
|
-
stream,
|
1506
|
-
() => {
|
1507
|
-
delete this.transports[transport.sessionId];
|
1508
|
-
resolve();
|
1509
|
-
}
|
1510
|
-
);
|
1511
|
-
this.transports[transport.sessionId] = transport;
|
1512
|
-
await this.mcpServer.connect(transport);
|
1513
|
-
});
|
1514
|
-
});
|
1515
|
-
});
|
1516
|
-
app.post(`${engine.options.prefix}/mcp_messages`, async (ctx) => {
|
1517
|
-
const sessionId = ctx.req.query("sessionId");
|
1518
|
-
if (!sessionId) {
|
1519
|
-
return ctx.text("No transport found for sessionId", 400);
|
1520
|
-
}
|
1521
|
-
const transport = this.transports[sessionId];
|
1522
|
-
const message = await ctx.req.json();
|
1523
|
-
await transport.handleMessage(message);
|
1524
|
-
return ctx.text("Accepted", 202);
|
1525
|
-
});
|
1526
|
-
logger_default.info(
|
1527
|
-
`ModelContextProtocolPlugin endpoint: ${engine.options.prefix}/mcp_sse`
|
1528
|
-
);
|
1529
|
-
};
|
1530
|
-
};
|
1531
1424
|
var DEFAULT_FAVICON = /* @__PURE__ */ jsx(
|
1532
1425
|
"link",
|
1533
1426
|
{
|
@@ -1730,4 +1623,4 @@ async function startCheck(checkers, pass) {
|
|
1730
1623
|
if (pass) await pass();
|
1731
1624
|
}
|
1732
1625
|
|
1733
|
-
export { Action, BaseLayout, CacheAdapter, HtmxLayout, MemoryCacheAdapter, Microservice,
|
1626
|
+
export { Action, BaseLayout, CacheAdapter, HtmxLayout, MemoryCacheAdapter, Microservice, Module, Page, PageRenderPlugin, Plugin, RedisCacheAdapter, Schedule, ScheduleMode, ServiceContext, ServiceInfoCards, ServiceStatusPage, logger_default as logger, startCheck };
|
package/package.json
CHANGED
@@ -1,87 +1,86 @@
|
|
1
|
-
{
|
2
|
-
"name": "imean-service-engine",
|
3
|
-
"version": "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
|
-
"
|
43
|
-
"
|
44
|
-
"
|
45
|
-
"
|
46
|
-
"
|
47
|
-
"
|
48
|
-
"
|
49
|
-
"
|
50
|
-
"
|
51
|
-
"
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
"
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
"@opentelemetry/
|
60
|
-
"@opentelemetry/exporter-
|
61
|
-
"@opentelemetry/exporter-
|
62
|
-
"@opentelemetry/
|
63
|
-
"@opentelemetry/
|
64
|
-
"@opentelemetry/sdk-
|
65
|
-
"@opentelemetry/sdk-
|
66
|
-
"@opentelemetry/sdk-node": "^
|
67
|
-
"@opentelemetry/
|
68
|
-
"@
|
69
|
-
"@types/
|
70
|
-
"@types/
|
71
|
-
"@types/
|
72
|
-
"@
|
73
|
-
"
|
74
|
-
"
|
75
|
-
"
|
76
|
-
"
|
77
|
-
"
|
78
|
-
"
|
79
|
-
"
|
80
|
-
"
|
81
|
-
"
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
}
|
1
|
+
{
|
2
|
+
"name": "imean-service-engine",
|
3
|
+
"version": "1.8.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
|
+
"ulid": "^3.0.0",
|
50
|
+
"winston": "^3.17.0",
|
51
|
+
"zod": "^3.24.1"
|
52
|
+
},
|
53
|
+
"peerDependencies": {
|
54
|
+
"@opentelemetry/api": "^1.x",
|
55
|
+
"ioredis": "^5.6.0"
|
56
|
+
},
|
57
|
+
"devDependencies": {
|
58
|
+
"@opentelemetry/auto-instrumentations-node": "^0.55.3",
|
59
|
+
"@opentelemetry/exporter-logs-otlp-proto": "^0.57.1",
|
60
|
+
"@opentelemetry/exporter-metrics-otlp-proto": "^0.57.1",
|
61
|
+
"@opentelemetry/exporter-trace-otlp-proto": "^0.57.1",
|
62
|
+
"@opentelemetry/instrumentation-winston": "^0.44.0",
|
63
|
+
"@opentelemetry/sdk-logs": "^0.57.1",
|
64
|
+
"@opentelemetry/sdk-metrics": "^1.30.1",
|
65
|
+
"@opentelemetry/sdk-node": "^0.57.1",
|
66
|
+
"@opentelemetry/sdk-trace-node": "^1.30.1",
|
67
|
+
"@opentelemetry/winston-transport": "^0.10.0",
|
68
|
+
"@types/ejson": "^2.2.2",
|
69
|
+
"@types/fs-extra": "^11.0.4",
|
70
|
+
"@types/ioredis-mock": "^8.2.5",
|
71
|
+
"@types/node": "^20.0.0",
|
72
|
+
"@vitest/coverage-v8": "^3.0.4",
|
73
|
+
"imean-service-client": "^1.5.0",
|
74
|
+
"ioredis-mock": "^8.9.0",
|
75
|
+
"opentelemetry-instrumentation-fetch-node": "^1.2.3",
|
76
|
+
"tslib": "^2.8.1",
|
77
|
+
"tsup": "^8.0.1",
|
78
|
+
"tsx": "^4.19.2",
|
79
|
+
"typescript": "^5.3.3",
|
80
|
+
"vite-tsconfig-paths": "^5.1.4",
|
81
|
+
"vitest": "^3.0.3"
|
82
|
+
},
|
83
|
+
"engines": {
|
84
|
+
"node": ">=20"
|
85
|
+
}
|
86
|
+
}
|