oox 0.3.5 → 0.3.6

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/app.js CHANGED
@@ -1,12 +1,6 @@
1
1
  import { EventEmitter } from 'node:events';
2
- import { AsyncLocalStorage } from 'node:async_hooks';
3
2
  import { genKVMethods } from './utils.js';
4
- export * as logger from './logger.js';
5
- export class AppContext {
6
- // 请求溯源ID
7
- traceId = '';
8
- }
9
- export const asyncStore = new AsyncLocalStorage();
3
+ import { asyncStore } from './context.js';
10
4
  export const eventHub = new EventEmitter();
11
5
  /**
12
6
  * sourceMethods => methods
@@ -4,10 +4,6 @@ import * as path from 'node:path';
4
4
  import * as oox from '../index.js';
5
5
  import { Module } from 'node:module';
6
6
  const require = createRequire(import.meta.url);
7
- /**
8
- * 为了不重复创建Proxy,这个对象用于保存各个RPC服务的各个属性Proxy
9
- */
10
- const rpcServiceAttrMap = Object.create(null);
11
7
  /**
12
8
  * 重写 require 缓存
13
9
  */
@@ -24,24 +20,6 @@ function rewriteModuleCache(id, exports) {
24
20
  m.paths = paths;
25
21
  require.cache[id] = m;
26
22
  }
27
- function dotCall(name, action) {
28
- return new Proxy(function () { }, {
29
- get(target, key) {
30
- const attrKey = name + '.' + (action ? action + '.' + key : key);
31
- if (rpcServiceAttrMap) {
32
- // 不重复创建Proxy
33
- return rpcServiceAttrMap[attrKey];
34
- }
35
- const attrProxy = dotCall(name, attrKey);
36
- rpcServiceAttrMap[attrKey] = attrProxy;
37
- return attrProxy;
38
- },
39
- has(target, key) { return true; },
40
- apply(target, thisArg, args) {
41
- return oox.rpc(name, action, args);
42
- }
43
- });
44
- }
45
23
  export function proxyGroup(groupDirectory, excludes = []) {
46
24
  if (!groupDirectory)
47
25
  return;
@@ -70,7 +48,7 @@ export function proxyGroup(groupDirectory, excludes = []) {
70
48
  name = scriptMatch[1];
71
49
  }
72
50
  if (!excludes.includes(name))
73
- rewriteModuleCache(id, dotCall(name, ''));
51
+ rewriteModuleCache(id, oox.proxy(name));
74
52
  }
75
53
  }
76
54
  /**
package/bin/starter.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as path from 'node:path';
2
2
  import chalk from 'chalk';
3
- import { formatters as configFormatters } from '../config.js';
3
+ import { configFormatters } from '../config.js';
4
4
  import * as oox from '../index.js';
5
5
  import { buildConfig } from './configurer.js';
6
6
  import { registry } from './register.js';
package/config.js CHANGED
@@ -43,7 +43,7 @@ export class Config {
43
43
  caller: [],
44
44
  };
45
45
  }
46
- export const formatters = {
46
+ export const configFormatters = {
47
47
  id: function (value) {
48
48
  return String(value || randomUUID());
49
49
  },
@@ -114,3 +114,32 @@ export const formatters = {
114
114
  return value;
115
115
  }
116
116
  };
117
+ /**
118
+ * 检查连接是否被允许
119
+ * @param ip 连接主机 IP
120
+ * @param caller 连接服务名称
121
+ * @param token 令牌
122
+ * @returns 是否被允许
123
+ */
124
+ export function checkAllow(ip, caller, token) {
125
+ // check trusted token
126
+ const trusted = !config.token || token === config.token;
127
+ if (!trusted) {
128
+ const { allow } = config;
129
+ if (!allow.untrusted) {
130
+ return { allow: false, reason: 'untrusted' };
131
+ }
132
+ if (Array.isArray(allow.ip) && allow.ip.length) {
133
+ let allowed = allow.ip.some(item => item === '*' || new RegExp(item).test(ip));
134
+ if (!allowed)
135
+ return { allow: false, reason: 'not allow ip=' + ip };
136
+ }
137
+ if (Array.isArray(allow.caller) && allow.caller.length) {
138
+ let allowed = allow.caller.some(item => item === '*' || new RegExp(item).test(caller));
139
+ if (!allowed)
140
+ return { allow: false, reason: 'not allow caller=' + caller };
141
+ }
142
+ }
143
+ return { allow: true };
144
+ }
145
+ export const config = new Config();
package/context.js ADDED
@@ -0,0 +1,58 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { AsyncLocalStorage } from 'node:async_hooks';
3
+ export const asyncStore = new AsyncLocalStorage();
4
+ export class AppContext {
5
+ // 请求溯源ID
6
+ traceId = '';
7
+ }
8
+ export class Context extends AppContext {
9
+ // 请求溯源IP
10
+ sourceIP = '';
11
+ // 请求者IP
12
+ ip = '';
13
+ // 请求者名称
14
+ caller = 'anonymous';
15
+ // 请求者ID (长连接专用)
16
+ callerId = '';
17
+ // 请求者连接把柄
18
+ connection;
19
+ constructor(context) {
20
+ super();
21
+ if (context) {
22
+ if ('toJSON' in context && typeof context.toJSON !== 'function') {
23
+ throw new Error('Context.toJSON must be a function');
24
+ }
25
+ Object.assign(this, context);
26
+ }
27
+ }
28
+ toJSON() {
29
+ const context = Object.assign({}, this);
30
+ delete context.connection;
31
+ return context;
32
+ }
33
+ }
34
+ let genTraceIdFunction = () => randomUUID();
35
+ export function setGenTraceIdFunction(fn) {
36
+ genTraceIdFunction = fn;
37
+ }
38
+ /**
39
+ * 生成随机不重复id
40
+ */
41
+ export function genTraceId() {
42
+ return genTraceIdFunction();
43
+ }
44
+ /**
45
+ * 获取链路跟踪上下文
46
+ */
47
+ export function genContext(context) {
48
+ const newContext = new Context(context);
49
+ if (!newContext.traceId)
50
+ newContext.traceId = genTraceId();
51
+ if (!newContext.sourceIP)
52
+ newContext.sourceIP = newContext.ip;
53
+ return newContext;
54
+ }
55
+ export function getContext() {
56
+ const context = asyncStore.getStore();
57
+ return context || genContext();
58
+ }
package/index.js CHANGED
@@ -1,61 +1,3 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { asyncStore, AppContext, } from './app.js';
3
- import * as registry from './registry.js';
4
- import { Config } from './config.js';
5
- import Module from './modules/module.js';
6
- import { KeepAliveConnection, keepAliveConnections, enabledKeepAliveConnections, KeepAliveConnectionError, } from './keepalive-connection.js';
7
- export class Context extends AppContext {
8
- // 请求溯源IP
9
- sourceIP = '';
10
- // 请求者IP
11
- ip = '';
12
- // 请求者名称
13
- caller = 'anonymous';
14
- // 请求者ID (长连接专用)
15
- callerId = '';
16
- // 请求者连接把柄
17
- connection;
18
- constructor(context) {
19
- super();
20
- if (context) {
21
- if ('toJSON' in context && typeof context.toJSON !== 'function') {
22
- throw new Error('Context.toJSON must be a function');
23
- }
24
- Object.assign(this, context);
25
- }
26
- }
27
- toJSON() {
28
- const context = Object.assign({}, this);
29
- delete context.connection;
30
- return context;
31
- }
32
- }
33
- export const config = new Config();
34
- let genTraceIdFunction = () => randomUUID();
35
- export function setGenTraceIdFunction(fn) {
36
- genTraceIdFunction = fn;
37
- }
38
- /**
39
- * 生成随机不重复id
40
- */
41
- export function genTraceId() {
42
- return genTraceIdFunction();
43
- }
44
- /**
45
- * 获取链路跟踪上下文
46
- */
47
- export function genContext(context) {
48
- const newContext = new Context(context);
49
- if (!newContext.traceId)
50
- newContext.traceId = genTraceId();
51
- if (!newContext.sourceIP)
52
- newContext.sourceIP = newContext.ip;
53
- return newContext;
54
- }
55
- export function getContext() {
56
- const context = asyncStore.getStore();
57
- return context || genContext();
58
- }
59
1
  export async function serve() {
60
2
  await modules.serve();
61
3
  registry.startBroadcastTimer();
@@ -64,96 +6,14 @@ export async function stop() {
64
6
  await modules.stop();
65
7
  registry.stopBroadcastTimer();
66
8
  }
67
- /**
68
- * 检查连接是否被允许
69
- * @param ip 连接主机 IP
70
- * @param caller 连接服务名称
71
- * @param token 令牌
72
- * @returns 是否被允许
73
- */
74
- export function checkAllow(ip, caller, token) {
75
- // check trusted token
76
- const trusted = !config.token || token === config.token;
77
- if (!trusted) {
78
- const { allow } = config;
79
- if (!allow.untrusted) {
80
- return { allow: false, reason: 'untrusted' };
81
- }
82
- if (Array.isArray(allow.ip) && allow.ip.length) {
83
- let allowed = allow.ip.some(item => item === '*' || new RegExp(item).test(ip));
84
- if (!allowed)
85
- return { allow: false, reason: 'not allow ip=' + ip };
86
- }
87
- if (Array.isArray(allow.caller) && allow.caller.length) {
88
- let allowed = allow.caller.some(item => item === '*' || new RegExp(item).test(caller));
89
- if (!allowed)
90
- return { allow: false, reason: 'not allow caller=' + caller };
91
- }
92
- }
93
- return { allow: true };
94
- }
95
- /**
96
- * 添加长连接
97
- * @throws {KeepAliveConnectionError} 连接已存在
98
- * @param connection
99
- */
100
- export function addKeepAliveConnection(connection) {
101
- if (keepAliveConnections.has(connection.data.name, connection.data.id)) {
102
- connection.disconnect();
103
- throw new KeepAliveConnectionError('Connection already exists', connection);
104
- }
105
- keepAliveConnections.add(connection);
106
- }
107
- export function removeKeepAliveConnection(arg1, arg2) {
108
- if (typeof arg1 === 'string') {
109
- const connection = keepAliveConnections.get(arg1, arg2);
110
- if (connection)
111
- connection.disconnect();
112
- keepAliveConnections.remove(arg1, arg2);
113
- enabledKeepAliveConnections.remove(arg1, arg2);
114
- }
115
- else {
116
- arg1.disconnect();
117
- keepAliveConnections.remove(arg1);
118
- enabledKeepAliveConnections.remove(arg1);
119
- }
120
- }
121
- /**
122
- * random connection select for default load balance policy
123
- * @param name service name
124
- * @returns selected connection
125
- */
126
- let loadBalancePolicy = (name) => {
127
- const connections = enabledKeepAliveConnections.getConnectionsOfService(name);
128
- if (!connections || !connections.size)
129
- return null;
130
- const arrayConnections = Array.from(connections.values());
131
- const index = Math.floor(Math.random() * arrayConnections.length);
132
- return arrayConnections[index];
133
- };
134
- export function setLoadBalancePolicy(policy) {
135
- loadBalancePolicy = policy;
136
- }
137
- export async function rpc(arg1, action, params, context) {
138
- if (!context || !context.traceId) {
139
- context = getContext();
140
- }
141
- let connection = null;
142
- if (arg1 instanceof KeepAliveConnection) {
143
- connection = arg1;
144
- }
145
- else if ('string' === typeof arg1) {
146
- connection = loadBalancePolicy(arg1);
147
- }
148
- else
149
- throw new Error(`Unknown rpc arg1<${arg1}>`);
150
- if (!connection)
151
- throw new Error(`Connection<${arg1}> not found`);
152
- return connection.adapter.rpc(connection, action, params, context);
153
- }
154
9
  export * from './app.js';
10
+ export * from './config.js';
11
+ export * from './context.js';
155
12
  export * from './keepalive-connection.js';
156
- export { Module };
13
+ export * from './modules/module.js';
14
+ export * as logger from './logger.js';
15
+ export * from './proxy.js';
16
+ import * as registry from './registry.js';
157
17
  export { registry };
158
18
  // 放在最后导入,避免循环依赖问题
159
19
  import * as modules from './modules/index.js';
@@ -1,4 +1,5 @@
1
1
  import EventEmitter from 'node:events';
2
+ import { getContext } from './context.js';
2
3
  export class KeepAliveConnectionError extends Error {
3
4
  connection;
4
5
  constructor(message, connection) {
@@ -104,6 +105,65 @@ export class KeepAliveConnectionStore {
104
105
  }
105
106
  }
106
107
  }
108
+ /**
109
+ * 添加长连接
110
+ * @throws {KeepAliveConnectionError} 连接已存在
111
+ * @param connection
112
+ */
113
+ export function addKeepAliveConnection(connection) {
114
+ if (keepAliveConnections.has(connection.data.name, connection.data.id)) {
115
+ connection.disconnect();
116
+ throw new KeepAliveConnectionError('Connection already exists', connection);
117
+ }
118
+ keepAliveConnections.add(connection);
119
+ }
120
+ export function removeKeepAliveConnection(arg1, arg2) {
121
+ if (typeof arg1 === 'string') {
122
+ const connection = keepAliveConnections.get(arg1, arg2);
123
+ if (connection)
124
+ connection.disconnect();
125
+ keepAliveConnections.remove(arg1, arg2);
126
+ enabledKeepAliveConnections.remove(arg1, arg2);
127
+ }
128
+ else {
129
+ arg1.disconnect();
130
+ keepAliveConnections.remove(arg1);
131
+ enabledKeepAliveConnections.remove(arg1);
132
+ }
133
+ }
134
+ /**
135
+ * random connection select for default load balance policy
136
+ * @param name service name
137
+ * @returns selected connection
138
+ */
139
+ let loadBalancePolicy = (name) => {
140
+ const connections = enabledKeepAliveConnections.getConnectionsOfService(name);
141
+ if (!connections || !connections.size)
142
+ return null;
143
+ const arrayConnections = Array.from(connections.values());
144
+ const index = Math.floor(Math.random() * arrayConnections.length);
145
+ return arrayConnections[index];
146
+ };
147
+ export function setLoadBalancePolicy(policy) {
148
+ loadBalancePolicy = policy;
149
+ }
150
+ export async function rpc(arg1, action, params, context) {
151
+ if (!context || !context.traceId) {
152
+ context = getContext();
153
+ }
154
+ let connection = null;
155
+ if (arg1 instanceof KeepAliveConnection) {
156
+ connection = arg1;
157
+ }
158
+ else if ('string' === typeof arg1) {
159
+ connection = loadBalancePolicy(arg1);
160
+ }
161
+ else
162
+ throw new Error(`Unknown rpc arg1<${arg1}>`);
163
+ if (!connection)
164
+ throw new Error(`Connection<${arg1}> not found`);
165
+ return connection.adapter.rpc(connection, action, params, context);
166
+ }
107
167
  export const keepAliveConnectionAdapters = new Map();
108
168
  export const keepAliveConnections = new KeepAliveConnectionStore();
109
169
  export const enabledKeepAliveConnections = new KeepAliveConnectionStore();
package/logger.js CHANGED
@@ -1,4 +1,5 @@
1
- import { emit, asyncStore } from './app.js';
1
+ import { emit } from './app.js';
2
+ import { asyncStore } from './context.js';
2
3
  export function info(...content) {
3
4
  const context = asyncStore.getStore() || null;
4
5
  emit('log', Date.now(), context, 'info', content);
@@ -3,7 +3,7 @@ import * as https from 'node:https';
3
3
  import { parseHTTPBody } from './utils.js';
4
4
  import Router from './router.js';
5
5
  import * as oox from '../../index.js';
6
- import Module from '../module.js';
6
+ import { Module } from '../module.js';
7
7
  export class HTTPConfig {
8
8
  enabled = true;
9
9
  // listen port
package/modules/module.js CHANGED
@@ -1,2 +1,2 @@
1
- export default class Module {
1
+ export class Module {
2
2
  }
@@ -6,7 +6,6 @@ import { SampleKeepAliveConnectionAdapter } from '../../samples/index.js';
6
6
  export default class SocketIOAdapter extends SampleKeepAliveConnectionAdapter {
7
7
  name = 'socketio';
8
8
  OOXEvent = OOXEvent;
9
- nativeEvent = { CONNECT: 'connect', DISCONNECT: 'disconnect', ERROR: 'connect_error' };
10
9
  newConnection(identify) {
11
10
  const { id, name } = oox.config;
12
11
  const headers = {
@@ -2,9 +2,10 @@ import * as http from 'node:http';
2
2
  import * as https from 'node:https';
3
3
  import { Server } from 'socket.io';
4
4
  import * as oox from '../../index.js';
5
- import { Module } from '../../index.js';
5
+ import { Module } from '../module.js';
6
6
  import SocketIOAdapter from './adapter.js';
7
7
  import { OOXEvent } from './utils.js';
8
+ import { randomUUID } from 'node:crypto';
8
9
  export class SocketIOConfig {
9
10
  enabled = true;
10
11
  // listen port
@@ -137,7 +138,9 @@ export default class SocketIOServer extends Module {
137
138
  const { server } = this;
138
139
  if (!server)
139
140
  throw new Error('HTTP Server is not created');
140
- const socketServer = this.socketServer = new Server(server, this.genSocketIOServerOptions());
141
+ const socketServer = this.socketServer = new Server(server, {
142
+ ...this.genSocketIOServerOptions(),
143
+ });
141
144
  socketServer.on('connection', async (socket) => {
142
145
  try {
143
146
  this.serverOnSocketConnection(socket);
@@ -153,7 +156,7 @@ export default class SocketIOServer extends Module {
153
156
  */
154
157
  serverOnSocketConnection(socket) {
155
158
  const headers = socket.handshake.headers;
156
- const callerId = String(headers['x-caller-id'] || '') || socket.id;
159
+ const callerId = String(headers['x-caller-id'] || randomUUID());
157
160
  // client ip or caller service ip
158
161
  const ip = String(headers['x-real-ip'] || socket.handshake.address);
159
162
  // service name
@@ -1,12 +1,15 @@
1
- export var OOXEvent;
2
- (function (OOXEvent) {
3
- OOXEvent["READY"] = "oox:ready";
4
- OOXEvent["ENABLED"] = "oox:enabled";
5
- OOXEvent["DISABLED"] = "oox:disabled";
6
- OOXEvent["REGISTRY_SYNC_CONNECTIONS"] = "oox:registry:sync_connections";
7
- OOXEvent["REGISTRY_SUBSCRIBE"] = "oox:registry:subscribe";
8
- OOXEvent["REGISTRY_NOTIFY"] = "oox:registry:notify";
9
- })(OOXEvent || (OOXEvent = {}));
1
+ export const OOXEvent = {
2
+ CONNECT: 'connect',
3
+ DISCONNECT: 'disconnect',
4
+ ERROR: 'error',
5
+ CALL: 'call',
6
+ READY: 'oox:ready',
7
+ ENABLED: 'oox:enabled',
8
+ DISABLED: 'oox:disabled',
9
+ REGISTRY_SYNC_CONNECTIONS: 'oox:registry:sync_connections',
10
+ REGISTRY_SUBSCRIBE: 'oox:registry:subscribe',
11
+ REGISTRY_NOTIFY: 'oox:registry:notify',
12
+ };
10
13
  export function isWebSocketURL(url) {
11
14
  if ('string' === typeof url) {
12
15
  return /^wss?:\/\/.+$/.test(url);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oox",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "description": "OOX Service Engine",
5
5
  "keywords": [
6
6
  "http",
@@ -24,7 +24,10 @@
24
24
  "types": "./types/index.d.ts"
25
25
  },
26
26
  "./loader": "./bin/loader.mjs",
27
- "./cli": "./bin/cli.js",
27
+ "./cli": {
28
+ "default": "./bin/cli.js",
29
+ "types": "./types/bin/cli.d.ts"
30
+ },
28
31
  "./samples": {
29
32
  "types": "./types/samples/index.d.ts",
30
33
  "default": "./samples/index.js"
package/proxy.js ADDED
@@ -0,0 +1,30 @@
1
+ import { rpc } from './keepalive-connection.js';
2
+ /**
3
+ * 为了不重复创建Proxy,这个对象用于保存各个RPC服务的各个属性Proxy
4
+ */
5
+ const rpcServiceAttrMap = Object.create(null);
6
+ export function proxy(name, action = '') {
7
+ return new Proxy(function () { }, {
8
+ get(target, key) {
9
+ if (typeof key !== 'string')
10
+ return undefined;
11
+ const attrKey = action ? action + '.' + key : key;
12
+ const attrKeyPath = name + '.' + attrKey;
13
+ if (attrKeyPath in rpcServiceAttrMap) {
14
+ // 不重复创建Proxy
15
+ return rpcServiceAttrMap[attrKeyPath];
16
+ }
17
+ const attrProxy = proxy(name, attrKey);
18
+ rpcServiceAttrMap[attrKeyPath] = attrProxy;
19
+ return attrProxy;
20
+ },
21
+ has(target, key) {
22
+ if (typeof key !== 'string')
23
+ return false;
24
+ return true;
25
+ },
26
+ apply(target, thisArg, args) {
27
+ return rpc(name, action, args);
28
+ }
29
+ });
30
+ }
package/registry.js CHANGED
@@ -1,4 +1,4 @@
1
- import { config } from './index.js';
1
+ import { config } from './config.js';
2
2
  import { enabledKeepAliveConnections, keepAliveConnectionAdapters, keepAliveConnections } from './keepalive-connection.js';
3
3
  const unsubscribeListeners = new Map();
4
4
  const subscribes = new Map();
package/samples/index.js CHANGED
@@ -1 +1 @@
1
- export { SampleKeepAliveConnectionAdapter } from './keepalive-connection-sample.js';
1
+ export * from './keepalive-connection-sample.js';
@@ -1,6 +1,14 @@
1
- import * as oox from '../index.js';
1
+ import * as registry from '../registry.js';
2
+ import { config } from '../config.js';
3
+ import { getContext, genContext, } from '../context.js';
4
+ import { KeepAliveConnectionError, addKeepAliveConnection, removeKeepAliveConnection, } from '../keepalive-connection.js';
5
+ import { call, } from '../app.js';
2
6
  export class SampleKeepAliveConnectionAdapter {
3
7
  OOXEvent = {
8
+ CONNECT: 'connect',
9
+ DISCONNECT: 'disconnect',
10
+ ERROR: 'error',
11
+ CALL: 'call',
4
12
  READY: 'oox:ready',
5
13
  ENABLED: 'oox:enabled',
6
14
  DISABLED: 'oox:disabled',
@@ -8,11 +16,6 @@ export class SampleKeepAliveConnectionAdapter {
8
16
  REGISTRY_SUBSCRIBE: 'oox:registry:subscribe',
9
17
  REGISTRY_NOTIFY: 'oox:registry:notify',
10
18
  };
11
- nativeEvent = {
12
- CONNECT: 'connect',
13
- DISCONNECT: 'disconnect',
14
- ERROR: 'error',
15
- };
16
19
  /**
17
20
  * 通知连接列表
18
21
  */
@@ -29,10 +32,10 @@ export class SampleKeepAliveConnectionAdapter {
29
32
  const socket = connection.nativeConnection;
30
33
  socket.on(this.OOXEvent.READY, (params) => {
31
34
  connection.ready(params);
32
- socket.emit(this.OOXEvent.REGISTRY_SYNC_CONNECTIONS, oox.registry.syncConnections);
35
+ socket.emit(this.OOXEvent.REGISTRY_SYNC_CONNECTIONS, registry.syncConnections);
33
36
  });
34
37
  socket.on(this.OOXEvent.REGISTRY_NOTIFY, (datas) => {
35
- oox.registry.syncConnections({
38
+ registry.syncConnections({
36
39
  success: true,
37
40
  body: datas,
38
41
  });
@@ -43,23 +46,23 @@ export class SampleKeepAliveConnectionAdapter {
43
46
  socket.on(this.OOXEvent.DISABLED, () => {
44
47
  connection.enabled = false;
45
48
  });
46
- socket.on(this.nativeEvent.DISCONNECT, (reason) => {
47
- oox.removeKeepAliveConnection(connection);
49
+ socket.on(this.OOXEvent.DISCONNECT, () => {
50
+ removeKeepAliveConnection(connection);
48
51
  socket.removeAllListeners();
49
52
  connection.emit('disconnect');
50
53
  });
51
- socket.on(this.nativeEvent.CONNECT, () => {
54
+ socket.on(this.OOXEvent.CONNECT, () => {
52
55
  connection.emit('connect');
53
56
  });
54
- socket.on(this.nativeEvent.ERROR, (error) => {
55
- oox.removeKeepAliveConnection(connection);
57
+ socket.on(this.OOXEvent.ERROR, (error) => {
58
+ removeKeepAliveConnection(connection);
56
59
  socket.removeAllListeners();
57
- connection.emit('error', new oox.KeepAliveConnectionError(error.message, connection));
60
+ connection.emit('error', new KeepAliveConnectionError(error.message, connection));
58
61
  });
59
62
  }
60
63
  async open(identify) {
61
64
  const connection = this.newConnection(identify);
62
- oox.addKeepAliveConnection(connection);
65
+ addKeepAliveConnection(connection);
63
66
  this.bindConnectionEvents(connection);
64
67
  this.bindCall(connection);
65
68
  await new Promise((resolve, reject) => {
@@ -93,9 +96,9 @@ export class SampleKeepAliveConnectionAdapter {
93
96
  reject(new Error(message));
94
97
  };
95
98
  // RPC 执行时中断连接
96
- socket.once(this.nativeEvent.DISCONNECT, onError);
99
+ socket.once(this.OOXEvent.DISCONNECT, onError);
97
100
  socket.emit(event, ...params, (returns) => {
98
- socket.off(this.nativeEvent.DISCONNECT, onError);
101
+ socket.off(this.OOXEvent.DISCONNECT, onError);
99
102
  resolve(returns);
100
103
  });
101
104
  });
@@ -105,12 +108,12 @@ export class SampleKeepAliveConnectionAdapter {
105
108
  */
106
109
  async rpc(connection, action, params, context) {
107
110
  if (!context)
108
- context = oox.getContext();
111
+ context = getContext();
109
112
  const miniContext = {
110
113
  sourceIP: context.sourceIP,
111
114
  traceId: context.traceId,
112
115
  };
113
- const { success, error, body } = await this.emit(connection.nativeConnection, 'call', [action, params, miniContext]);
116
+ const { success, error, body } = await this.emit(connection.nativeConnection, this.OOXEvent.CALL, [action, params, miniContext]);
114
117
  if (success)
115
118
  return body;
116
119
  else if (error)
@@ -124,8 +127,9 @@ export class SampleKeepAliveConnectionAdapter {
124
127
  */
125
128
  bindCall(connection) {
126
129
  const { id, name, ip } = connection.data;
127
- connection.nativeConnection.on('call', async (action, params, context, callback) => {
128
- const validContext = new oox.Context({
130
+ connection.nativeConnection.on(this.OOXEvent.CALL, async (action, params, context, callback) => {
131
+ const validContext = genContext({
132
+ sourceIP: ip,
129
133
  ...context,
130
134
  ip: ip,
131
135
  caller: name,
@@ -136,8 +140,8 @@ export class SampleKeepAliveConnectionAdapter {
136
140
  });
137
141
  }
138
142
  async call(action, params, context, callback) {
139
- const returns = await oox.call(action, params, context);
140
- if (returns.error && !oox.config.errorStack) {
143
+ const returns = await call(action, params, context);
144
+ if (returns.error && !config.errorStack) {
141
145
  // 不返回错误调用栈信息
142
146
  delete returns.error.stack;
143
147
  }
package/types/app.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { EventEmitter } from 'node:events';
2
- import { AsyncLocalStorage } from 'node:async_hooks';
3
- export * as logger from './logger.js';
2
+ import { AppContext } from './context.js';
4
3
  export interface ReturnsBody<T = any> {
5
4
  traceId?: string;
6
5
  success: boolean;
@@ -10,11 +9,6 @@ export interface ReturnsBody<T = any> {
10
9
  stack?: string;
11
10
  };
12
11
  }
13
- export declare class AppContext {
14
- [x: string]: any;
15
- traceId?: string | undefined;
16
- }
17
- export declare const asyncStore: AsyncLocalStorage<AppContext>;
18
12
  export declare const eventHub: EventEmitter<[never]>;
19
13
  /**
20
14
  * the kvMethods is all actions refs [has bind this]
@@ -1,4 +1,5 @@
1
+ import * as oox from '../index.js';
1
2
  export declare function configure(env?: {
2
3
  [x: string]: any;
3
- }, entryFilename?: string): Promise<import("../config.js").Config>;
4
+ }, entryFilename?: string): Promise<oox.Config>;
4
5
  export declare function startup(): Promise<void>;
package/types/config.d.ts CHANGED
@@ -48,7 +48,19 @@ export declare class Config implements ConfigInterface {
48
48
  type StrictFormatter<T> = {
49
49
  [K in keyof T]: (value: any) => T[K];
50
50
  };
51
- export declare const formatters: StrictFormatter<ConfigInterface> & {
51
+ export declare const configFormatters: StrictFormatter<ConfigInterface> & {
52
52
  [x: string]: (v: any) => any;
53
53
  };
54
+ /**
55
+ * 检查连接是否被允许
56
+ * @param ip 连接主机 IP
57
+ * @param caller 连接服务名称
58
+ * @param token 令牌
59
+ * @returns 是否被允许
60
+ */
61
+ export declare function checkAllow(ip: string, caller: string, token: string): {
62
+ allow: boolean;
63
+ reason?: string;
64
+ };
65
+ export declare const config: Config;
54
66
  export {};
@@ -0,0 +1,30 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import { KeepAliveConnection, KeepAliveNativeConnection } from './keepalive-connection.js';
3
+ export declare const asyncStore: AsyncLocalStorage<AppContext>;
4
+ export declare class AppContext {
5
+ [x: string]: any;
6
+ traceId?: string | undefined;
7
+ }
8
+ export interface KeepAliveRPCContext {
9
+ traceId?: string;
10
+ sourceIP?: string;
11
+ }
12
+ export declare class Context extends AppContext {
13
+ sourceIP: string;
14
+ ip: string;
15
+ caller: string;
16
+ callerId: string;
17
+ connection?: KeepAliveConnection<KeepAliveNativeConnection>;
18
+ constructor(context?: Partial<Context>);
19
+ toJSON?(): {} & this;
20
+ }
21
+ export declare function setGenTraceIdFunction(fn: () => string): void;
22
+ /**
23
+ * 生成随机不重复id
24
+ */
25
+ export declare function genTraceId(): string;
26
+ /**
27
+ * 获取链路跟踪上下文
28
+ */
29
+ export declare function genContext(context?: Context): Context;
30
+ export declare function getContext(): Context;
package/types/index.d.ts CHANGED
@@ -1,59 +1,13 @@
1
- import { AppContext } from './app.js';
2
- import * as registry from './registry.js';
3
- import { Config } from './config.js';
4
- import Module, { ModuleConfig } from './modules/module.js';
5
- import { KeepAliveConnection, KeepAliveNativeConnection } from './keepalive-connection.js';
6
- export interface KeepAliveRPCContext {
7
- traceId?: string;
8
- sourceIP?: string;
9
- }
10
- export declare class Context extends AppContext {
11
- sourceIP: string;
12
- ip: string;
13
- caller: string;
14
- callerId: string;
15
- connection?: KeepAliveConnection<KeepAliveNativeConnection>;
16
- constructor(context?: Partial<Context>);
17
- toJSON?(): {} & this;
18
- }
19
- export declare const config: Config;
20
- export declare function setGenTraceIdFunction(fn: () => string): void;
21
- /**
22
- * 生成随机不重复id
23
- */
24
- export declare function genTraceId(): string;
25
- /**
26
- * 获取链路跟踪上下文
27
- */
28
- export declare function genContext(context?: Context): Context;
29
- export declare function getContext(): Context;
30
1
  export declare function serve(): Promise<void>;
31
2
  export declare function stop(): Promise<void>;
32
- /**
33
- * 检查连接是否被允许
34
- * @param ip 连接主机 IP
35
- * @param caller 连接服务名称
36
- * @param token 令牌
37
- * @returns 是否被允许
38
- */
39
- export declare function checkAllow(ip: string, caller: string, token: string): {
40
- allow: boolean;
41
- reason?: string;
42
- };
43
- /**
44
- * 添加长连接
45
- * @throws {KeepAliveConnectionError} 连接已存在
46
- * @param connection
47
- */
48
- export declare function addKeepAliveConnection(connection: KeepAliveConnection<KeepAliveNativeConnection>): void;
49
- export declare function removeKeepAliveConnection(connection: KeepAliveConnection<KeepAliveNativeConnection>): void;
50
- export declare function removeKeepAliveConnection(name: string, id: string): void;
51
- export declare function setLoadBalancePolicy(policy: (name: string) => KeepAliveConnection<KeepAliveNativeConnection>): void;
52
- export declare function rpc(appName: string, action: string, params: any[], context?: Context): Promise<any>;
53
- export declare function rpc(connection: KeepAliveConnection<KeepAliveNativeConnection>, action: string, params: any[], context?: Context): Promise<any>;
54
3
  export * from './app.js';
4
+ export * from './config.js';
5
+ export * from './context.js';
55
6
  export * from './keepalive-connection.js';
56
- export { Module, ModuleConfig };
7
+ export * from './modules/module.js';
8
+ export * as logger from './logger.js';
9
+ export * from './proxy.js';
10
+ import * as registry from './registry.js';
57
11
  export { registry };
58
12
  import * as modules from './modules/index.js';
59
13
  export { modules };
@@ -1,5 +1,5 @@
1
1
  import EventEmitter from 'node:events';
2
- import { Context } from './index.js';
2
+ import { Context } from './context.js';
3
3
  type MakeOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
4
4
  export declare class KeepAliveConnectionError extends Error {
5
5
  connection: KeepAliveConnection<KeepAliveNativeConnection>;
@@ -98,6 +98,17 @@ export declare class KeepAliveConnectionStore<T extends KeepAliveNativeConnectio
98
98
  remove(connection: KeepAliveConnection<T>): void;
99
99
  remove(name: string, id: string): void;
100
100
  }
101
+ /**
102
+ * 添加长连接
103
+ * @throws {KeepAliveConnectionError} 连接已存在
104
+ * @param connection
105
+ */
106
+ export declare function addKeepAliveConnection(connection: KeepAliveConnection<KeepAliveNativeConnection>): void;
107
+ export declare function removeKeepAliveConnection(connection: KeepAliveConnection<KeepAliveNativeConnection>): void;
108
+ export declare function removeKeepAliveConnection(name: string, id: string): void;
109
+ export declare function setLoadBalancePolicy(policy: (name: string) => KeepAliveConnection<KeepAliveNativeConnection>): void;
110
+ export declare function rpc(appName: string, action: string, params: any[], context?: Context): Promise<any>;
111
+ export declare function rpc(connection: KeepAliveConnection<KeepAliveNativeConnection>, action: string, params: any[], context?: Context): Promise<any>;
101
112
  export declare const keepAliveConnectionAdapters: Map<string, KeepAliveConnectionAdapter<KeepAliveNativeConnection>>;
102
113
  export declare const keepAliveConnections: KeepAliveConnectionStore<KeepAliveNativeConnection>;
103
114
  export declare const enabledKeepAliveConnections: KeepAliveConnectionStore<KeepAliveNativeConnection>;
@@ -1,7 +1,7 @@
1
1
  import * as http from 'node:http';
2
2
  import * as https from 'node:https';
3
3
  import Router, { Middleware } from './router.js';
4
- import Module, { ModuleConfig } from '../module.js';
4
+ import { Module, ModuleConfig } from '../module.js';
5
5
  export declare class HTTPConfig implements ModuleConfig {
6
6
  enabled: boolean;
7
7
  port: number;
@@ -1,4 +1,4 @@
1
- import Module from './module.js';
1
+ import { Module } from './module.js';
2
2
  import HTTP from './http/index.js';
3
3
  import SocketIO from './socketio/index.js';
4
4
  /**
@@ -1,7 +1,7 @@
1
1
  export interface ModuleConfig {
2
2
  enabled?: boolean;
3
3
  }
4
- export default abstract class Module {
4
+ export declare abstract class Module {
5
5
  abstract config: ModuleConfig;
6
6
  abstract name: string;
7
7
  abstract setConfig(config: any): void;
@@ -1,14 +1,19 @@
1
1
  import * as oox from '../../index.js';
2
2
  import { Socket } from './socket.js';
3
- import { OOXEvent } from './utils.js';
4
3
  import { SampleKeepAliveConnectionAdapter } from '../../samples/index.js';
5
4
  export default class SocketIOAdapter extends SampleKeepAliveConnectionAdapter<Socket> {
6
5
  name: string;
7
- OOXEvent: typeof OOXEvent;
8
- nativeEvent: {
6
+ OOXEvent: {
9
7
  CONNECT: string;
10
8
  DISCONNECT: string;
11
9
  ERROR: string;
10
+ CALL: string;
11
+ READY: string;
12
+ ENABLED: string;
13
+ DISABLED: string;
14
+ REGISTRY_SYNC_CONNECTIONS: string;
15
+ REGISTRY_SUBSCRIBE: string;
16
+ REGISTRY_NOTIFY: string;
12
17
  };
13
18
  newConnection(identify: string | URL | oox.KeepAliveConnectionData): oox.KeepAliveConnection<Socket>;
14
19
  }
@@ -2,7 +2,7 @@ import * as http from 'node:http';
2
2
  import * as https from 'node:https';
3
3
  import { Server, ServerOptions } from 'socket.io';
4
4
  import * as oox from '../../index.js';
5
- import { Module, ModuleConfig } from '../../index.js';
5
+ import { Module, ModuleConfig } from '../module.js';
6
6
  import { Socket } from './socket.js';
7
7
  import SocketIOAdapter from './adapter.js';
8
8
  export declare class SocketIOConfig implements ModuleConfig {
@@ -1,10 +1,14 @@
1
- export declare enum OOXEvent {
2
- READY = "oox:ready",
3
- ENABLED = "oox:enabled",
4
- DISABLED = "oox:disabled",
5
- REGISTRY_SYNC_CONNECTIONS = "oox:registry:sync_connections",
6
- REGISTRY_SUBSCRIBE = "oox:registry:subscribe",
7
- REGISTRY_NOTIFY = "oox:registry:notify"
8
- }
1
+ export declare const OOXEvent: {
2
+ CONNECT: string;
3
+ DISCONNECT: string;
4
+ ERROR: string;
5
+ CALL: string;
6
+ READY: string;
7
+ ENABLED: string;
8
+ DISABLED: string;
9
+ REGISTRY_SYNC_CONNECTIONS: string;
10
+ REGISTRY_SUBSCRIBE: string;
11
+ REGISTRY_NOTIFY: string;
12
+ };
9
13
  export declare function isWebSocketURL(url: string | URL): boolean;
10
14
  export declare function genWebSocketURL(url: string): URL;
@@ -0,0 +1 @@
1
+ export declare function proxy(name: string, action?: string): () => void;
@@ -1,4 +1,4 @@
1
- import { ReturnsBody } from './index.js';
1
+ import { ReturnsBody } from './app.js';
2
2
  import { KeepAliveConnection, KeepAliveConnectionData, KeepAliveNativeConnection } from './keepalive-connection.js';
3
3
  export interface SyncConnectionsQuery {
4
4
  name?: string | string[];
@@ -1 +1 @@
1
- export { SampleKeepAliveConnectionAdapter, SampleKeepAliveNativeConnection } from './keepalive-connection-sample.js';
1
+ export * from './keepalive-connection-sample.js';
@@ -1,16 +1,22 @@
1
- import * as oox from '../index.js';
2
- export interface SampleKeepAliveNativeConnection extends oox.KeepAliveNativeConnection {
1
+ import { Context, KeepAliveRPCContext } from '../context.js';
2
+ import { KeepAliveConnection, KeepAliveConnectionData, KeepAliveNativeConnection, KeepAliveConnectionAdapter, KeepAliveSyncConnectionsQuery } from '../keepalive-connection.js';
3
+ import { ReturnsBody } from '../app.js';
4
+ export interface SampleKeepAliveNativeConnection extends KeepAliveNativeConnection {
3
5
  connected: boolean;
4
6
  connect?(): void;
5
- on(event: string | symbol, listener: (...args: any[]) => any): any;
6
- once(event: string | symbol, listener: (...args: any[]) => any): any;
7
- off(event?: string | symbol, listener?: (...args: any[]) => any): any;
8
- emit(event: string | symbol, ...args: any[]): any;
9
- removeAllListeners(event?: string | symbol): any;
7
+ on(event: string, listener: (...args: any[]) => any): any;
8
+ once(event: string, listener: (...args: any[]) => any): any;
9
+ off(event: string, listener?: (...args: any[]) => any): any;
10
+ emit(event: string, ...args: any[]): any;
11
+ removeAllListeners(event?: string): any;
10
12
  }
11
- export declare abstract class SampleKeepAliveConnectionAdapter<NativeConnection extends SampleKeepAliveNativeConnection> implements oox.KeepAliveConnectionAdapter<NativeConnection> {
13
+ export declare abstract class SampleKeepAliveConnectionAdapter<NativeConnection extends SampleKeepAliveNativeConnection> implements KeepAliveConnectionAdapter<NativeConnection> {
12
14
  abstract name: string;
13
15
  OOXEvent: {
16
+ CONNECT: string;
17
+ DISCONNECT: string;
18
+ ERROR: string;
19
+ CALL: string;
14
20
  READY: string;
15
21
  ENABLED: string;
16
22
  DISABLED: string;
@@ -18,23 +24,18 @@ export declare abstract class SampleKeepAliveConnectionAdapter<NativeConnection
18
24
  REGISTRY_SUBSCRIBE: string;
19
25
  REGISTRY_NOTIFY: string;
20
26
  };
21
- nativeEvent: {
22
- CONNECT: string;
23
- DISCONNECT: string;
24
- ERROR: string;
25
- };
26
- abstract newConnection(identify: string | URL | oox.KeepAliveConnectionData): oox.KeepAliveConnection<NativeConnection>;
27
+ abstract newConnection(identify: string | URL | KeepAliveConnectionData): KeepAliveConnection<NativeConnection>;
27
28
  /**
28
29
  * 通知连接列表
29
30
  */
30
- ['registry:notify'](connection: oox.KeepAliveConnection<NativeConnection>, datas: oox.KeepAliveConnectionData[]): void;
31
+ ['registry:notify'](connection: KeepAliveConnection<NativeConnection>, datas: KeepAliveConnectionData[]): void;
31
32
  /**
32
33
  * 订阅连接列表
33
34
  */
34
- ['registry:subscribe'](connection: oox.KeepAliveConnection<NativeConnection>, query: oox.KeepAliveSyncConnectionsQuery): void;
35
- bindConnectionEvents(connection: oox.KeepAliveConnection<NativeConnection>): void;
36
- open(identify: string | URL | oox.KeepAliveConnectionData): Promise<oox.KeepAliveConnection<NativeConnection>>;
37
- close(connection: oox.KeepAliveConnection<NativeConnection>): Promise<void>;
35
+ ['registry:subscribe'](connection: KeepAliveConnection<NativeConnection>, query: KeepAliveSyncConnectionsQuery): void;
36
+ bindConnectionEvents(connection: KeepAliveConnection<NativeConnection>): void;
37
+ open(identify: string | URL | KeepAliveConnectionData): Promise<KeepAliveConnection<NativeConnection>>;
38
+ close(connection: KeepAliveConnection<NativeConnection>): Promise<void>;
38
39
  /**
39
40
  * 发送事件
40
41
  * @param socket
@@ -45,11 +46,11 @@ export declare abstract class SampleKeepAliveConnectionAdapter<NativeConnection
45
46
  /**
46
47
  * RPC
47
48
  */
48
- rpc(connection: oox.KeepAliveConnection<NativeConnection>, action: string, params: any[], context?: oox.KeepAliveRPCContext): Promise<any>;
49
+ rpc(connection: KeepAliveConnection<NativeConnection>, action: string, params: any[], context?: KeepAliveRPCContext): Promise<any>;
49
50
  /**
50
51
  * 绑定 call 事件
51
52
  * @param connection
52
53
  */
53
- bindCall(connection: oox.KeepAliveConnection<NativeConnection>): void;
54
- call(action: string, params: any[], context: oox.Context, callback?: (returns: any) => void): Promise<oox.ReturnsBody<any>>;
54
+ bindCall(connection: KeepAliveConnection<NativeConnection>): void;
55
+ call(action: string, params: any[], context: Context, callback?: (returns: any) => void): Promise<ReturnsBody<any>>;
55
56
  }
package/utils.js CHANGED
@@ -1,4 +1,4 @@
1
- import { networkInterfaces } from 'os';
1
+ import { networkInterfaces } from 'node:os';
2
2
  export function getIPAddress(version = 4) {
3
3
  const interfaces = networkInterfaces();
4
4
  const ip = [];