oox 0.3.0-beta9 → 0.3.2

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.
Files changed (47) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +29 -32
  3. package/app.js +131 -143
  4. package/bin/argv.js +63 -70
  5. package/bin/cli.js +57 -43
  6. package/bin/configurer.js +60 -62
  7. package/bin/loader.mjs +392 -279
  8. package/bin/proxy-import.js +12 -0
  9. package/bin/proxy-require.js +88 -0
  10. package/bin/register.js +46 -55
  11. package/bin/starter.js +63 -66
  12. package/index.js +155 -168
  13. package/index.mjs +4 -4
  14. package/logger.js +25 -40
  15. package/modules/http/index.js +286 -192
  16. package/modules/http/router.js +205 -0
  17. package/modules/http/utils.js +75 -73
  18. package/modules/index.js +86 -88
  19. package/modules/module.js +11 -16
  20. package/modules/socketio/client.js +97 -101
  21. package/modules/socketio/index.js +171 -168
  22. package/modules/socketio/server.js +188 -136
  23. package/modules/socketio/socket.js +1 -4
  24. package/package.json +14 -12
  25. package/types/app.d.ts +50 -51
  26. package/types/bin/argv.d.ts +8 -8
  27. package/types/bin/cli.d.ts +6 -2
  28. package/types/bin/configurer.d.ts +3 -1
  29. package/types/bin/proxy-import.d.ts +4 -0
  30. package/types/bin/proxy-require.d.ts +5 -0
  31. package/types/bin/register.d.ts +1 -1
  32. package/types/bin/starter.d.ts +5 -1
  33. package/types/index.d.ts +78 -76
  34. package/types/logger.d.ts +5 -4
  35. package/types/modules/http/index.d.ts +65 -47
  36. package/types/modules/http/router.d.ts +49 -0
  37. package/types/modules/http/utils.d.ts +14 -17
  38. package/types/modules/index.d.ts +24 -24
  39. package/types/modules/module.d.ts +11 -13
  40. package/types/modules/socketio/client.d.ts +23 -23
  41. package/types/modules/socketio/index.d.ts +37 -37
  42. package/types/modules/socketio/server.d.ts +44 -35
  43. package/types/modules/socketio/socket.d.ts +11 -11
  44. package/types/utils.d.ts +6 -6
  45. package/utils.js +57 -63
  46. package/bin/proxyer.js +0 -61
  47. package/types/bin/proxyer.d.ts +0 -1
@@ -1,136 +1,188 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SocketIOConfig = void 0;
4
- const http = require("node:http");
5
- const socket_io_1 = require("socket.io");
6
- const oox = require("../../index");
7
- const index_1 = require("../../index");
8
- const socket_1 = require("./socket");
9
- class SocketIOConfig extends index_1.ModuleConfig {
10
- // listen port
11
- port = 0;
12
- // service path
13
- path = '/socket.io';
14
- // browser cross origin
15
- origin = '';
16
- }
17
- exports.SocketIOConfig = SocketIOConfig;
18
- class SocketIOServer extends index_1.Module {
19
- name = 'socketio';
20
- config = new SocketIOConfig;
21
- /**
22
- * means this.server created by myself<SocketIOServer>
23
- */
24
- #isSelfServer = false;
25
- server = null;
26
- socketServer = null;
27
- setConfig(config) {
28
- Object.assign(this.config, config);
29
- if (!config.hasOwnProperty('port')) {
30
- this.config.port = oox.config.port;
31
- }
32
- if (!config.hasOwnProperty('origin')) {
33
- this.config.origin = oox.config.origin;
34
- }
35
- }
36
- getConfig() {
37
- return this.config;
38
- }
39
- async serve() {
40
- await this.stop();
41
- const port = this.config.port;
42
- const isSelfServer = this.#isSelfServer = this.server ? true : false;
43
- const server = this.server = isSelfServer ? this.server :
44
- http.createServer((request, response) => response.end('No HTTP Gateway'));
45
- if (!server.listening)
46
- server.listen(port);
47
- const address = server.address();
48
- if (!address || 'object' !== typeof address)
49
- throw new Error('Cannot read socket.io server port');
50
- this.config.port = address.port;
51
- this.createSocketIOServer();
52
- }
53
- async stop() {
54
- if (this.socketServer)
55
- await new Promise((resolve, reject) => this.socketServer.close(error => error ? reject(error) : resolve()));
56
- if (this.#isSelfServer)
57
- await new Promise((resolve, reject) => this.server.close(error => error ? reject(error) : resolve()));
58
- }
59
- genSocketIOServerOptions() {
60
- const options = {
61
- /**
62
- * name of the path to capture
63
- * @default "/socket.io"
64
- */
65
- path: this.config.path,
66
- /**
67
- * how many ms before a client without namespace is closed
68
- * @default 45000
69
- */
70
- connectTimeout: 5000,
71
- /**
72
- * how many ms without a pong packet to consider the connection closed
73
- * @default 5000
74
- */
75
- pingTimeout: 2000,
76
- /**
77
- * how many ms before sending a new ping packet
78
- * @default 25000
79
- */
80
- pingInterval: 10000,
81
- /**
82
- * how many bytes or characters a message can be, before closing the session (to avoid DoS).
83
- * @default 1e5 (100 KB)
84
- */
85
- maxHttpBufferSize: 1e5
86
- };
87
- const { origin } = this.config;
88
- if (origin)
89
- options.cors = { origin };
90
- return options;
91
- }
92
- createSocketIOServer() {
93
- const socketServer = this.socketServer = new socket_io_1.Server(this.server, this.genSocketIOServerOptions());
94
- socketServer.on('connection', async (socket) => {
95
- try {
96
- this.serverOnSocketConnection(socket);
97
- }
98
- catch (error) {
99
- socket.send(error.message).disconnect(true);
100
- }
101
- });
102
- }
103
- /**
104
- * 服务端Socket连接事件
105
- */
106
- serverOnSocketConnection(socket) {
107
- const headers = socket.handshake.headers;
108
- const callerId = String(headers['x-caller-id'] || '') || socket.id;
109
- // 已经存在相同的连接
110
- if (socket_1.sockets.has(callerId))
111
- throw new Error('Connection Exists');
112
- // client ip or caller service ip
113
- const ip = String(headers['x-real-ip'] || headers['x-ip'] || socket.handshake.address);
114
- // service name
115
- const caller = String(headers['x-caller'] || 'anonymous');
116
- socket.data = { connected: true, host: ip, name: caller, id: callerId };
117
- // 保存 callerId 与 socket 对应关系
118
- socket_1.sockets.set(callerId, socket);
119
- socket.on('disconnect', reason => this.serverOnSocketDisconnect(socket, reason));
120
- socket.emit('oox_connected', { name: oox.config.name });
121
- this.serverOnConnection(socket);
122
- }
123
- serverOnConnection(socket) { }
124
- /**
125
- * 服务端Socket断开事件
126
- * @param {Socket} socket
127
- * @param {Error} reason
128
- */
129
- serverOnSocketDisconnect(socket, reason) {
130
- socket.data.connected = false;
131
- socket_1.sockets.delete(socket.data.id);
132
- this.serverOnDisconnect(socket, reason);
133
- }
134
- serverOnDisconnect(socket, reason) { }
135
- }
136
- exports.default = SocketIOServer;
1
+ import * as http from 'node:http';
2
+ import * as https from 'node:https';
3
+ import { Server } from 'socket.io';
4
+ import * as oox from '../../index.js';
5
+ import { Module, ModuleConfig } from '../../index.js';
6
+ import { sockets } from './socket.js';
7
+ export class SocketIOConfig extends ModuleConfig {
8
+ // listen port
9
+ port = 0;
10
+ // service path
11
+ path = '/socket.io';
12
+ // browser cross origin
13
+ origin = '';
14
+ // https options
15
+ ssl = {
16
+ // enable https
17
+ enabled: false,
18
+ // ssl certificate path
19
+ cert: '',
20
+ // ssl private key path
21
+ key: '',
22
+ // ssl ca path
23
+ ca: ''
24
+ };
25
+ }
26
+ export default class SocketIOServer extends Module {
27
+ name = 'socketio';
28
+ config = new SocketIOConfig;
29
+ /**
30
+ * means this.server created by myself<SocketIOServer>
31
+ */
32
+ #isSelfServer = false;
33
+ server = null;
34
+ socketServer = null;
35
+ static isWebSocketUrl(url) {
36
+ return /^wss?:\/\/.+$/.test(url);
37
+ }
38
+ static genWebSocketUrl(url) {
39
+ // :6000
40
+ if (url.startsWith(':'))
41
+ url = oox.config.host + url;
42
+ // 127.0.0.1:6000
43
+ if (!/^\w+?:\/.+$/.test(url))
44
+ url = 'ws://' + url;
45
+ const urlObject = new URL(url);
46
+ if (urlObject.protocol !== 'wss:') {
47
+ if (urlObject.port === '443')
48
+ urlObject.protocol = 'wss:';
49
+ else
50
+ urlObject.protocol = 'ws:';
51
+ }
52
+ return urlObject.toString();
53
+ }
54
+ getUrl() {
55
+ const { host } = oox.config;
56
+ const { port, path } = this.config;
57
+ const protocol = this.config.ssl.enabled ? 'wss:' : 'ws:';
58
+ return `${protocol}//${host}:${port}${path}`;
59
+ }
60
+ setConfig(config) {
61
+ Object.assign(this.config, config);
62
+ if (!config.hasOwnProperty('port')) {
63
+ this.config.port = oox.config.port;
64
+ }
65
+ if (!config.hasOwnProperty('origin')) {
66
+ this.config.origin = oox.config.origin;
67
+ }
68
+ }
69
+ getConfig() {
70
+ return this.config;
71
+ }
72
+ async serve() {
73
+ await this.stop();
74
+ const { port, ssl } = this.config;
75
+ const isSelfServer = this.#isSelfServer = this.server ? true : false;
76
+ let server;
77
+ if (isSelfServer) {
78
+ server = this.server;
79
+ }
80
+ else {
81
+ if (ssl.enabled) {
82
+ const fs = await import('node:fs');
83
+ const options = {
84
+ key: ssl.key ? fs.readFileSync(ssl.key) : null,
85
+ cert: ssl.cert ? fs.readFileSync(ssl.cert) : null,
86
+ ca: ssl.ca ? fs.readFileSync(ssl.ca) : null
87
+ };
88
+ if (!options.key || !options.cert) {
89
+ throw new Error('HTTPS enabled but missing key or cert');
90
+ }
91
+ server = https.createServer(options, (_request, response) => response.end('No HTTP Gateway'));
92
+ }
93
+ else {
94
+ server = http.createServer((_request, response) => response.end('No HTTP Gateway'));
95
+ }
96
+ }
97
+ this.server = server;
98
+ if (!server.listening)
99
+ server.listen(port);
100
+ const address = server.address();
101
+ if (!address || 'object' !== typeof address)
102
+ throw new Error('Cannot read socket.io server port');
103
+ this.config.port = address.port;
104
+ this.createSocketIOServer();
105
+ }
106
+ async stop() {
107
+ if (this.socketServer)
108
+ await new Promise((resolve, reject) => this.socketServer.close(error => error ? reject(error) : resolve()));
109
+ if (this.#isSelfServer)
110
+ await new Promise((resolve, reject) => this.server.listening && this.server.close(error => error ? reject(error) : resolve()));
111
+ }
112
+ genSocketIOServerOptions() {
113
+ const options = {
114
+ /**
115
+ * name of the path to capture
116
+ * @default "/socket.io"
117
+ */
118
+ path: this.config.path,
119
+ /**
120
+ * how many ms before a client without namespace is closed
121
+ * @default 45000
122
+ */
123
+ connectTimeout: 5000,
124
+ /**
125
+ * how many ms without a pong packet to consider the connection closed
126
+ * @default 5000
127
+ */
128
+ pingTimeout: 2000,
129
+ /**
130
+ * how many ms before sending a new ping packet
131
+ * @default 25000
132
+ */
133
+ pingInterval: 10000,
134
+ /**
135
+ * how many bytes or characters a message can be, before closing the session (to avoid DoS).
136
+ * @default 1e5 (100 KB)
137
+ */
138
+ maxHttpBufferSize: 1e5
139
+ };
140
+ const { origin } = this.config;
141
+ if (origin)
142
+ options.cors = { origin };
143
+ return options;
144
+ }
145
+ createSocketIOServer() {
146
+ const socketServer = this.socketServer = new Server(this.server, this.genSocketIOServerOptions());
147
+ socketServer.on('connection', async (socket) => {
148
+ try {
149
+ this.serverOnSocketConnection(socket);
150
+ }
151
+ catch (error) {
152
+ socket.send(error.message).disconnect(true);
153
+ }
154
+ });
155
+ }
156
+ /**
157
+ * 服务端Socket连接事件
158
+ */
159
+ serverOnSocketConnection(socket) {
160
+ const headers = socket.handshake.headers;
161
+ const callerId = String(headers['x-caller-id'] || '') || socket.id;
162
+ // 已经存在相同的连接
163
+ if (sockets.has(callerId))
164
+ throw new Error('Connection Exists');
165
+ // client ip or caller service ip
166
+ const ip = String(headers['x-real-ip'] || headers['x-ip'] || socket.handshake.address);
167
+ // service name
168
+ const caller = String(headers['x-caller'] || 'anonymous');
169
+ socket.data = { connected: true, host: ip, name: caller, id: callerId };
170
+ // 保存 callerId 与 socket 对应关系
171
+ sockets.set(callerId, socket);
172
+ socket.on('disconnect', reason => this.serverOnSocketDisconnect(socket, reason));
173
+ socket.emit('oox_connected', { name: oox.config.name });
174
+ this.serverOnConnection(socket);
175
+ }
176
+ serverOnConnection(socket) { }
177
+ /**
178
+ * 服务端Socket断开事件
179
+ * @param {Socket} socket
180
+ * @param {Error} reason
181
+ */
182
+ serverOnSocketDisconnect(socket, reason) {
183
+ socket.data.connected = false;
184
+ sockets.delete(socket.data.id);
185
+ this.serverOnDisconnect(socket, reason);
186
+ }
187
+ serverOnDisconnect(socket, reason) { }
188
+ }
@@ -1,4 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sockets = void 0;
4
- exports.sockets = new Map();
1
+ export const sockets = new Map();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "oox",
3
- "version": "0.3.0-beta9",
4
- "description": "Graceful NodeJS distributed application solution",
3
+ "version": "0.3.2",
4
+ "description": "OOX Service Engine",
5
5
  "keywords": [
6
6
  "http",
7
7
  "websocket",
@@ -12,28 +12,30 @@
12
12
  "distributed",
13
13
  "tracing"
14
14
  ],
15
- "type": "commonjs",
16
- "main": "index.js",
17
- "types": "types/index.d.ts",
15
+ "type": "module",
16
+ "main": "./index.js",
17
+ "types": "./types/index.d.ts",
18
18
  "exports": {
19
19
  ".": {
20
20
  "import": "./index.mjs",
21
- "require": "./index.js"
21
+ "require": "./index.js",
22
+ "types": "./types/index.d.ts"
22
23
  },
23
- "./loader": "./bin/loader.mjs"
24
+ "./loader": "./bin/loader.mjs",
25
+ "./cli": "./bin/cli.js"
24
26
  },
25
27
  "bin": {
26
- "oox": "bin/cli.js"
28
+ "oox": "./bin/cli.js"
27
29
  },
28
30
  "author": "lipingruan",
29
31
  "homepage": "https://github.com/lipingruan/oox",
30
32
  "license": "MIT",
31
33
  "dependencies": {
32
- "chalk": "^4.1.0",
33
- "socket.io": "^4.4.0",
34
- "socket.io-client": "^4.4.0"
34
+ "chalk": "^5.6.2",
35
+ "socket.io": "^4.8.3",
36
+ "socket.io-client": "^4.8.3"
35
37
  },
36
38
  "engines": {
37
- "node": ">=12.0.0"
39
+ "node": ">=18.0.0"
38
40
  }
39
41
  }
package/types/app.d.ts CHANGED
@@ -1,51 +1,50 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
- import { EventEmitter } from 'node:events';
4
- import { AsyncLocalStorage } from 'node:async_hooks';
5
- export * as logger from './logger';
6
- export interface ReturnsBody {
7
- traceId: string;
8
- success: boolean;
9
- body?: any;
10
- error?: {
11
- message: string;
12
- stack: string;
13
- };
14
- }
15
- export declare class Context {
16
- [x: string]: any;
17
- traceId?: string;
18
- }
19
- export declare const asyncStore: AsyncLocalStorage<Context>;
20
- export declare const eventHub: EventEmitter;
21
- /**
22
- * the kvMethods is all actions refs [has bind this]
23
- */
24
- export declare const kvMethods: Map<string, Function>;
25
- export declare const sourceKVMethods: Map<string, Function>;
26
- export declare function setMethods(methods: any): void;
27
- export declare function getMethods(): any;
28
- export declare function on(event: 'app:configured' | 'app:served' | 'app:stopped', listener: () => void): void;
29
- export declare function on(event: 'request', listener: (action: string, params: any[], context: Context) => void): void;
30
- export declare function on(event: 'success', listener: (action: string, params: any[], context: Context, result: ReturnsBody) => void): void;
31
- export declare function on(event: 'fail', listener: (action: string, params: any[], context: Context, error: Error) => void): void;
32
- export declare function on(event: 'log', listener: (context: Context, tag: string, msgs: any[]) => void): void;
33
- export declare function on(event: string, listener: (...args: any[]) => void): void;
34
- export declare function once(event: 'app:configured' | 'app:served' | 'app:stopped', listener: (...args: any[]) => void): void;
35
- export declare function once(event: 'request', listener: (action: string, params: any[], context: Context) => void): void;
36
- export declare function once(event: 'success', listener: (action: string, params: any[], context: Context, result: ReturnsBody) => void): void;
37
- export declare function once(event: 'fail', listener: (action: string, params: any[], context: Context, error: Error) => void): void;
38
- export declare function once(event: 'log', listener: (context: Context, tag: string, msgs: any[]) => void): void;
39
- export declare function once(event: string, listener: (...args: any[]) => void): void;
40
- export declare function off(event: 'app:configured' | 'app:served' | 'app:stopped' | 'request' | 'success' | 'fail' | 'log', listener: (...args: any[]) => void): void;
41
- export declare function off(event: string, listener: (...args: any[]) => void): void;
42
- export declare function emit(event: string, ...args: any[]): boolean;
43
- /**
44
- * Call an Function on RPC server
45
- * @param action
46
- * @param params
47
- * @param context
48
- * @returns
49
- */
50
- export declare function call(action: string, params: any[], context: Context): Promise<ReturnsBody>;
51
- export declare function execute(action: string, params: Array<any>, context: Context): Promise<any>;
1
+ import { EventEmitter } from 'node:events';
2
+ import { AsyncLocalStorage } from 'node:async_hooks';
3
+ export * as logger from './logger.js';
4
+ export interface ReturnsBody {
5
+ traceId: string;
6
+ success: boolean;
7
+ body?: any;
8
+ error?: {
9
+ message: string;
10
+ stack: string;
11
+ };
12
+ }
13
+ export declare class Context {
14
+ [x: string]: any;
15
+ traceId?: string;
16
+ }
17
+ export declare const asyncStore: AsyncLocalStorage<Context>;
18
+ export declare const eventHub: EventEmitter<[never]>;
19
+ /**
20
+ * the kvMethods is all actions refs [has bind this]
21
+ */
22
+ export declare const kvMethods: Map<string, Function>;
23
+ export declare const sourceKVMethods: Map<string, Function>;
24
+ export declare function setMethods(methods: any): void;
25
+ export declare function getMethods(): any;
26
+ export declare function on(event: 'app:configured' | 'app:served' | 'app:stopped', listener: () => void): void;
27
+ export declare function on(event: 'call:start', listener: (timestamp: number, action: string, params: any[], context: Context) => void): void;
28
+ export declare function on(event: 'call:success', listener: (timestamp: number, action: string, params: any[], context: Context, result: ReturnsBody) => void): void;
29
+ export declare function on(event: 'call:fail', listener: (timestamp: number, action: string, params: any[], context: Context, error: Error) => void): void;
30
+ export declare function on(event: 'log', listener: (timestamp: number, context: Context | null, level: string, msgs: any[]) => void): void;
31
+ export declare function once(event: 'app:configured' | 'app:served' | 'app:stopped', listener: (...args: any[]) => void): void;
32
+ export declare function once(event: 'call:start', listener: (timestamp: number, action: string, params: any[], context: Context) => void): void;
33
+ export declare function once(event: 'call:success', listener: (timestamp: number, action: string, params: any[], context: Context, result: ReturnsBody) => void): void;
34
+ export declare function once(event: 'call:fail', listener: (timestamp: number, action: string, params: any[], context: Context, error: Error) => void): void;
35
+ export declare function once(event: 'log', listener: (timestamp: number, context: Context | null, level: string, msgs: any[]) => void): void;
36
+ export declare function off(event: 'app:configured' | 'app:served' | 'app:stopped' | 'call:start' | 'call:success' | 'call:fail' | 'log', listener: (...args: any[]) => void): void;
37
+ export declare function emit(event: 'app:configured' | 'app:served' | 'app:stopped'): boolean;
38
+ export declare function emit(event: 'call:start', timestamp: number, action: string, params: any[], context: Context): boolean;
39
+ export declare function emit(event: 'call:success', timestamp: number, action: string, params: any[], context: Context, result: ReturnsBody): boolean;
40
+ export declare function emit(event: 'call:fail', timestamp: number, action: string, params: any[], context: Context, error: Error): boolean;
41
+ export declare function emit(event: 'log', timestamp: number, context: Context | null, level: string, content: any): boolean;
42
+ /**
43
+ * Call an Function on RPC server
44
+ * @param action
45
+ * @param params
46
+ * @param context
47
+ * @returns
48
+ */
49
+ export declare function call(action: string, params: any[], context: Context): Promise<ReturnsBody>;
50
+ export declare function execute(action: string, params: Array<any>, context: Context): Promise<any>;
@@ -1,8 +1,8 @@
1
- export declare function getAllEnvArgs(): {
2
- [x: string]: any;
3
- };
4
- export declare function getEnvArgs(names: string[]): {
5
- [x: string]: any;
6
- };
7
- export declare function getEnvArg(name: string): any;
8
- export declare function parseEnvArg(value: string): any;
1
+ export declare function getAllEnvArgs(): {
2
+ [x: string]: any;
3
+ };
4
+ export declare function getEnvArgs(names: string[]): {
5
+ [x: string]: any;
6
+ };
7
+ export declare function getEnvArg(name: string): any;
8
+ export declare function parseEnvArg(value: string): any;
@@ -1,2 +1,6 @@
1
- #! /usr/bin/env node
2
- export {};
1
+ #! /usr/bin/env node
2
+ import { configure, startup } from './starter.js';
3
+ import { inGroupConvertRequireToRPC } from './proxy-require.js';
4
+ import { registModuleLoader } from './proxy-import.js';
5
+ export declare const version: string;
6
+ export { configure, startup, inGroupConvertRequireToRPC, registModuleLoader, };
@@ -1 +1,3 @@
1
- export declare function configure(): Promise<any>;
1
+ export declare function buildConfig(mergeEnv?: {
2
+ [x: string]: any;
3
+ }): Promise<any>;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * 注册ECMAScript Module加载器
3
+ */
4
+ export declare function registModuleLoader(): Promise<void>;
@@ -0,0 +1,5 @@
1
+ export declare function proxyGroup(groupDirectory: string, excludes?: string[]): void;
2
+ /**
3
+ * 将所有 group 目录下的 commonjs require 转换为 RPC
4
+ */
5
+ export declare function inGroupConvertRequireToRPC(): void;
@@ -1 +1 @@
1
- export declare function registry(urls: string | string[]): Promise<void>;
1
+ export declare function registry(urls: string | string[]): Promise<void>;
@@ -1 +1,5 @@
1
- export declare function startup(): Promise<void>;
1
+ import * as oox from '../index.js';
2
+ export declare function configure(env?: {
3
+ [x: string]: any;
4
+ }, entryFilename?: string): Promise<oox.Config>;
5
+ export declare function startup(): Promise<void>;