@yumerijs/core 3.0.0-alpha.3 → 3.0.0-alpha.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/dist/context.d.ts +6 -1
- package/dist/context.js +7 -1
- package/dist/core.d.ts +5 -1
- package/dist/core.js +22 -13
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/route.d.ts +1 -1
- package/dist/route.js +10 -2
- package/dist/server.js +16 -4
- package/dist/session.d.ts +13 -7
- package/dist/session.js +47 -5
- package/dist/storage.d.ts +39 -0
- package/dist/storage.js +69 -0
- package/package.json +48 -46
- package/dist/command.d.ts +0 -144
- package/dist/command.js +0 -181
- package/dist/platform.d.ts +0 -164
- package/dist/platform.js +0 -199
package/dist/context.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Route } from './route.js';
|
|
|
3
3
|
import { HookHandler } from './hook.js';
|
|
4
4
|
import { Middleware } from './middleware.js';
|
|
5
5
|
import { IRenderer } from '@yumerijs/types';
|
|
6
|
+
import { SessionStorageProcessor, Storage, SessionStorageSnapshot } from './storage.js';
|
|
6
7
|
export interface Components {
|
|
7
8
|
[key: string]: any;
|
|
8
9
|
}
|
|
@@ -71,6 +72,10 @@ export declare class Context {
|
|
|
71
72
|
executeHook(name: string, ...args: any[]): Promise<any[]>;
|
|
72
73
|
/** 获取 Core 实例 */
|
|
73
74
|
getCore(): Core;
|
|
75
|
+
/**
|
|
76
|
+
* 替换 core 的 session 存储处理器或底层存储。
|
|
77
|
+
*/
|
|
78
|
+
setStorage(storage: SessionStorageProcessor | Storage<SessionStorageSnapshot>): void;
|
|
74
79
|
/**
|
|
75
80
|
* 触发事件
|
|
76
81
|
* @param event 事件名称
|
|
@@ -105,7 +110,7 @@ export declare class Context {
|
|
|
105
110
|
* @param module 插件模块
|
|
106
111
|
* @param config 插件配置
|
|
107
112
|
*/
|
|
108
|
-
plugin(module: Plugin, config?: any): Promise<Context>;
|
|
113
|
+
plugin(module: Plugin, config?: any): Promise<Context | undefined>;
|
|
109
114
|
/**
|
|
110
115
|
* 注册 i18n
|
|
111
116
|
* @param content 内容(可以是嵌套对象或单个key)
|
package/dist/context.js
CHANGED
|
@@ -102,6 +102,12 @@ export class Context {
|
|
|
102
102
|
getCore() {
|
|
103
103
|
return this.core;
|
|
104
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* 替换 core 的 session 存储处理器或底层存储。
|
|
107
|
+
*/
|
|
108
|
+
setStorage(storage) {
|
|
109
|
+
this.core.setStorage(storage);
|
|
110
|
+
}
|
|
105
111
|
/**
|
|
106
112
|
* 触发事件
|
|
107
113
|
* @param event 事件名称
|
|
@@ -139,7 +145,7 @@ export class Context {
|
|
|
139
145
|
*/
|
|
140
146
|
fork(name = this.pluginname, path) {
|
|
141
147
|
const ctx = new Context(this.core, name);
|
|
142
|
-
ctx.childpath = path;
|
|
148
|
+
ctx.childpath = path ?? '/';
|
|
143
149
|
this.childContexts.push(ctx);
|
|
144
150
|
return ctx;
|
|
145
151
|
}
|
package/dist/core.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { HookHandler, Hook } from './hook.js';
|
|
|
9
9
|
import { Server as CoreServer } from './server.js';
|
|
10
10
|
import { I18n } from './i18n.js';
|
|
11
11
|
import { IRenderer } from '@yumerijs/types';
|
|
12
|
+
import { SessionStorageProcessor, Storage, SessionStorageSnapshot } from './storage.js';
|
|
12
13
|
export interface Plugin {
|
|
13
14
|
apply?: (ctx: Context, config: Config) => Promise<void> | void;
|
|
14
15
|
disable?: (ctx: Context) => Promise<void> | void;
|
|
@@ -55,11 +56,14 @@ export declare class Core {
|
|
|
55
56
|
server: CoreServer;
|
|
56
57
|
i18n: I18n;
|
|
57
58
|
loader: any;
|
|
59
|
+
storage: SessionStorageProcessor;
|
|
58
60
|
renderers: Map<string, IRenderer>;
|
|
59
61
|
pluginRenderers: Map<string, string>;
|
|
60
62
|
constructor(loader?: any, coreConfig?: CoreOptions, loggersetCore?: boolean, splash?: boolean);
|
|
61
|
-
checkUpdate
|
|
63
|
+
private checkUpdate;
|
|
62
64
|
addRenderer(renderer: IRenderer): void;
|
|
65
|
+
setStorage(storage: SessionStorageProcessor | Storage<SessionStorageSnapshot>): void;
|
|
66
|
+
getStorage(): SessionStorageProcessor;
|
|
63
67
|
getRendererForPlugin(pluginName: string): string | undefined;
|
|
64
68
|
runCore(): Promise<void>;
|
|
65
69
|
getShortPluginName(pluginName: string): string;
|
package/dist/core.js
CHANGED
|
@@ -4,7 +4,9 @@ import { Logger } from './logger.js';
|
|
|
4
4
|
import { Route } from './route.js';
|
|
5
5
|
import { Hook } from './hook.js';
|
|
6
6
|
import { Server as CoreServer } from './server.js';
|
|
7
|
+
import { SessionStorageProcessor } from './storage.js';
|
|
7
8
|
import * as fs from 'fs';
|
|
9
|
+
import semver from 'semver';
|
|
8
10
|
const version = JSON.parse(await fs.promises.readFile(new URL('../package.json', import.meta.url), 'utf-8')).version;
|
|
9
11
|
function isClassPlugin(value) {
|
|
10
12
|
if (typeof value !== 'function')
|
|
@@ -28,14 +30,7 @@ function mergePluginMeta(target, source) {
|
|
|
28
30
|
return target;
|
|
29
31
|
}
|
|
30
32
|
export function resolvePluginModule(module, context, config) {
|
|
31
|
-
|
|
32
|
-
// 只有对象模块才取 default/apply
|
|
33
|
-
if (typeof module === 'object' && module !== null) {
|
|
34
|
-
candidate = module.default ?? module.apply ?? module;
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
candidate = module;
|
|
38
|
-
}
|
|
33
|
+
const candidate = module?.default ?? module?.apply ?? module;
|
|
39
34
|
let plugin;
|
|
40
35
|
if (isClassPlugin(candidate)) {
|
|
41
36
|
plugin = new candidate(context, config);
|
|
@@ -74,6 +69,7 @@ export class Core {
|
|
|
74
69
|
server;
|
|
75
70
|
i18n;
|
|
76
71
|
loader;
|
|
72
|
+
storage = new SessionStorageProcessor();
|
|
77
73
|
renderers = new Map();
|
|
78
74
|
pluginRenderers = new Map(); // Stores which plugin uses which renderer
|
|
79
75
|
constructor(loader, coreConfig = {}, loggersetCore = true, splash = true) {
|
|
@@ -88,15 +84,17 @@ export class Core {
|
|
|
88
84
|
}
|
|
89
85
|
async checkUpdate() {
|
|
90
86
|
try {
|
|
91
|
-
const response = await fetch('https://registry.npmjs.org/yumeri
|
|
87
|
+
const response = await fetch('https://registry.npmjs.org/yumeri');
|
|
92
88
|
if (!response.ok)
|
|
93
89
|
return;
|
|
94
|
-
const
|
|
95
|
-
|
|
90
|
+
const pkg = await response.json();
|
|
91
|
+
const currentMajor = semver.major(version);
|
|
92
|
+
const latest = Object.keys(pkg.versions)
|
|
93
|
+
.filter(v => semver.valid(v) && semver.major(v) === currentMajor)
|
|
94
|
+
.sort(semver.rcompare)[0];
|
|
95
|
+
if (latest && semver.gt(latest, version)) {
|
|
96
96
|
this.logger.info(`There is new version for Yumeri: ${version} -> ${latest}`);
|
|
97
97
|
}
|
|
98
|
-
else {
|
|
99
|
-
}
|
|
100
98
|
}
|
|
101
99
|
catch (error) {
|
|
102
100
|
this.logger.error('Error while checking updates: ', error.message);
|
|
@@ -108,6 +106,17 @@ export class Core {
|
|
|
108
106
|
}
|
|
109
107
|
this.renderers.set(renderer.name, renderer);
|
|
110
108
|
}
|
|
109
|
+
setStorage(storage) {
|
|
110
|
+
if (storage instanceof SessionStorageProcessor) {
|
|
111
|
+
this.storage = storage;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
this.storage.setStorage(storage);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
getStorage() {
|
|
118
|
+
return this.storage;
|
|
119
|
+
}
|
|
111
120
|
getRendererForPlugin(pluginName) {
|
|
112
121
|
return this.pluginRenderers.get(pluginName);
|
|
113
122
|
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/route.d.ts
CHANGED
package/dist/route.js
CHANGED
|
@@ -436,11 +436,19 @@ export class Route {
|
|
|
436
436
|
// after finishing pattern, path must be fully consumed (no extra segments)
|
|
437
437
|
if (j !== parts.length)
|
|
438
438
|
return null;
|
|
439
|
-
const
|
|
439
|
+
const normalizedHostParams = {};
|
|
440
|
+
for (const [key, value] of Object.entries(hostParams)) {
|
|
441
|
+
normalizedHostParams[key] = value ?? '';
|
|
442
|
+
}
|
|
443
|
+
const result = { params, pathParams, hostParams: normalizedHostParams };
|
|
440
444
|
return result;
|
|
441
445
|
}
|
|
442
446
|
else if (pathname.startsWith('root') && this.path == pathname) {
|
|
443
|
-
const
|
|
447
|
+
const normalizedHostParams = {};
|
|
448
|
+
for (const [key, value] of Object.entries(hostParams)) {
|
|
449
|
+
normalizedHostParams[key] = value ?? '';
|
|
450
|
+
}
|
|
451
|
+
const result = { params: { pathname }, pathParams: [pathname], hostParams: normalizedHostParams };
|
|
444
452
|
return result;
|
|
445
453
|
}
|
|
446
454
|
return null;
|
package/dist/server.js
CHANGED
|
@@ -28,7 +28,7 @@ export class Server {
|
|
|
28
28
|
* 创建一个新的会话对象
|
|
29
29
|
*/
|
|
30
30
|
createSession(ip, cookies, res, req, pathname, pluginContext, extra = {}) {
|
|
31
|
-
const session = new Session(ip, cookies, this, req, res, pathname, undefined, pluginContext);
|
|
31
|
+
const session = new Session(ip, cookies, this, req, res ?? undefined, pathname, undefined, pluginContext);
|
|
32
32
|
Object.assign(session.properties, extra);
|
|
33
33
|
session.protocol = extra.protocol ?? 'http';
|
|
34
34
|
return session;
|
|
@@ -90,9 +90,18 @@ export class Server {
|
|
|
90
90
|
const pluginContext = route ? route.context : (rootroute ? rootroute.context : undefined);
|
|
91
91
|
const session = this.createSession(ip, cookies, res, req, pathname, pluginContext, { protocol: 'http', header: req.headers });
|
|
92
92
|
session._startAt = Date.now();
|
|
93
|
+
await session.loadData();
|
|
93
94
|
/** 路由处理逻辑 */
|
|
94
95
|
const handleRoute = async (routePath) => {
|
|
95
|
-
|
|
96
|
+
let matched = false;
|
|
97
|
+
try {
|
|
98
|
+
matched = await this.core.executeRoute(routePath, session, queryParams);
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
if (matched) {
|
|
102
|
+
await session.saveData(true);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
96
105
|
if (!matched) {
|
|
97
106
|
// 核心层不再提供静态文件服务,直接返回 404
|
|
98
107
|
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
@@ -166,15 +175,18 @@ export class Server {
|
|
|
166
175
|
const route = this.core.getRoute(pathname);
|
|
167
176
|
const pluginContext = route ? route.context : undefined;
|
|
168
177
|
const session = this.createSession(ip, cookies, null, req, pathname, pluginContext, { protocol: 'http', header: req.headers });
|
|
178
|
+
await session.loadData();
|
|
169
179
|
if (route && route.ws != null) {
|
|
180
|
+
const wsServer = route.ws;
|
|
170
181
|
const matched = await this.core.executeRoute(pathname, session, queryParams);
|
|
171
182
|
if (!matched) {
|
|
172
183
|
socket.write('HTTP/1.1 400 Bad Request\r\n\r\n');
|
|
173
184
|
socket.destroy();
|
|
174
185
|
}
|
|
175
186
|
else {
|
|
176
|
-
|
|
177
|
-
|
|
187
|
+
await session.saveData(true);
|
|
188
|
+
wsServer.handleUpgrade(req, socket, head, (ws) => {
|
|
189
|
+
wsServer.emit('connection', ws, req, session);
|
|
178
190
|
});
|
|
179
191
|
}
|
|
180
192
|
}
|
package/dist/session.d.ts
CHANGED
|
@@ -12,9 +12,9 @@ type ParsedParams = Record<string, string | string[] | undefined>;
|
|
|
12
12
|
/** 客户端对象,包含原始的 HTTP 请求和响应对象 */
|
|
13
13
|
export interface Client {
|
|
14
14
|
/** 原始的 Node.js HTTP 请求对象 */
|
|
15
|
-
req
|
|
15
|
+
req?: IncomingMessage;
|
|
16
16
|
/** 原始的 Node.js HTTP 响应对象 */
|
|
17
|
-
res
|
|
17
|
+
res?: ServerResponse;
|
|
18
18
|
/** 经过处理后的规范化请求头 */
|
|
19
19
|
headers?: Record<string, string>;
|
|
20
20
|
}
|
|
@@ -90,14 +90,14 @@ declare class SessionRequest {
|
|
|
90
90
|
/** 请求使用的协议 */
|
|
91
91
|
protocol: string;
|
|
92
92
|
/** 原始的 IncomingMessage 对象 */
|
|
93
|
-
raw
|
|
93
|
+
raw?: IncomingMessage;
|
|
94
94
|
constructor(data: {
|
|
95
95
|
ip: string;
|
|
96
96
|
cookies: Record<string, string>;
|
|
97
97
|
query?: Record<string, string>;
|
|
98
98
|
pathname?: string;
|
|
99
99
|
headers: Record<string, string>;
|
|
100
|
-
raw
|
|
100
|
+
raw?: IncomingMessage;
|
|
101
101
|
});
|
|
102
102
|
}
|
|
103
103
|
/**
|
|
@@ -121,8 +121,8 @@ declare class SessionResponse {
|
|
|
121
121
|
/** 标识该响应是否已经处理完毕 */
|
|
122
122
|
handled: boolean;
|
|
123
123
|
/** 原始的 ServerResponse 对象 */
|
|
124
|
-
raw
|
|
125
|
-
constructor(res
|
|
124
|
+
raw?: ServerResponse;
|
|
125
|
+
constructor(res?: ServerResponse);
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
128
|
* 会话对象 (Session)
|
|
@@ -137,6 +137,8 @@ export declare class Session {
|
|
|
137
137
|
sessionid: string;
|
|
138
138
|
/** 持久化的会话数据存储 */
|
|
139
139
|
data: Record<string, any>;
|
|
140
|
+
private dataDirty;
|
|
141
|
+
private dataDestroyed;
|
|
140
142
|
/** 供插件或中间件挂载的临时属性 */
|
|
141
143
|
properties: Record<string, any>;
|
|
142
144
|
/** 对核心服务器实例的引用 */
|
|
@@ -160,7 +162,7 @@ export declare class Session {
|
|
|
160
162
|
/** 获取请求中的 Cookie 集合 */
|
|
161
163
|
get cookie(): Record<string, string>;
|
|
162
164
|
/** 获取 URL 查询参数 */
|
|
163
|
-
get query(): Record<string, string
|
|
165
|
+
get query(): Record<string, string> | undefined;
|
|
164
166
|
/** 获取请求路径 */
|
|
165
167
|
get pathname(): string;
|
|
166
168
|
/** 获取语言列表 */
|
|
@@ -227,6 +229,10 @@ export declare class Session {
|
|
|
227
229
|
* MD5 加密
|
|
228
230
|
*/
|
|
229
231
|
private md5;
|
|
232
|
+
/** 从 core 存储处理器加载会话数据 */
|
|
233
|
+
loadData(): Promise<void>;
|
|
234
|
+
/** 将当前会话数据保存到 core 存储处理器 */
|
|
235
|
+
saveData(force?: boolean): Promise<void>;
|
|
230
236
|
/** 设置会话数据 */
|
|
231
237
|
setData(key: string, value: any): void;
|
|
232
238
|
/** 删除会话数据 */
|
package/dist/session.js
CHANGED
|
@@ -72,6 +72,8 @@ export class Session {
|
|
|
72
72
|
sessionid;
|
|
73
73
|
/** 持久化的会话数据存储 */
|
|
74
74
|
data = {};
|
|
75
|
+
dataDirty = false;
|
|
76
|
+
dataDestroyed = false;
|
|
75
77
|
/** 供插件或中间件挂载的临时属性 */
|
|
76
78
|
properties = {};
|
|
77
79
|
/** 对核心服务器实例的引用 */
|
|
@@ -238,6 +240,8 @@ export class Session {
|
|
|
238
240
|
*/
|
|
239
241
|
async parseRequestBody(client = this.client) {
|
|
240
242
|
const req = client.req;
|
|
243
|
+
if (!req)
|
|
244
|
+
return {};
|
|
241
245
|
return new Promise((resolve, reject) => {
|
|
242
246
|
const contentType = (req.headers['content-type'] || '').toLowerCase();
|
|
243
247
|
if (contentType.includes('application/json') || contentType.includes('application/x-www-form-urlencoded')) {
|
|
@@ -295,14 +299,46 @@ export class Session {
|
|
|
295
299
|
hash.update(str);
|
|
296
300
|
return hash.digest('hex');
|
|
297
301
|
}
|
|
302
|
+
/** 从 core 存储处理器加载会话数据 */
|
|
303
|
+
async loadData() {
|
|
304
|
+
this.data = await this.server.core.storage.load(this.sessionid);
|
|
305
|
+
this.dataDirty = false;
|
|
306
|
+
this.dataDestroyed = false;
|
|
307
|
+
}
|
|
308
|
+
/** 将当前会话数据保存到 core 存储处理器 */
|
|
309
|
+
async saveData(force = false) {
|
|
310
|
+
if (this.dataDestroyed) {
|
|
311
|
+
await this.server.core.storage.delete(this.sessionid);
|
|
312
|
+
this.dataDirty = false;
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
if (force || this.dataDirty) {
|
|
316
|
+
await this.server.core.storage.save(this.sessionid, this.data);
|
|
317
|
+
this.dataDirty = false;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
298
320
|
/** 设置会话数据 */
|
|
299
|
-
setData(key, value) {
|
|
321
|
+
setData(key, value) {
|
|
322
|
+
this.data[key] = value;
|
|
323
|
+
this.dataDirty = true;
|
|
324
|
+
this.dataDestroyed = false;
|
|
325
|
+
}
|
|
300
326
|
/** 删除会话数据 */
|
|
301
|
-
deleteData(key) {
|
|
327
|
+
deleteData(key) {
|
|
328
|
+
delete this.data[key];
|
|
329
|
+
this.dataDirty = true;
|
|
330
|
+
}
|
|
302
331
|
/** 清空会话数据 */
|
|
303
|
-
clearData() {
|
|
332
|
+
clearData() {
|
|
333
|
+
this.data = {};
|
|
334
|
+
this.dataDirty = true;
|
|
335
|
+
}
|
|
304
336
|
/** 销毁会话 */
|
|
305
|
-
destroy() {
|
|
337
|
+
destroy() {
|
|
338
|
+
this.data = {};
|
|
339
|
+
this.dataDirty = true;
|
|
340
|
+
this.dataDestroyed = true;
|
|
341
|
+
}
|
|
306
342
|
/** 设置 MIME 类型 */
|
|
307
343
|
setMime(mimeType) {
|
|
308
344
|
const map = {
|
|
@@ -313,10 +349,16 @@ export class Session {
|
|
|
313
349
|
this.response.headers['Content-Type'] = map[mimeType] || mimeType;
|
|
314
350
|
}
|
|
315
351
|
/** 向响应流写入数据 */
|
|
316
|
-
send(data) {
|
|
352
|
+
send(data) {
|
|
353
|
+
if (!this.response.raw)
|
|
354
|
+
throw new Error('Cannot send data without a response object.');
|
|
355
|
+
return this.response.raw.write(data);
|
|
356
|
+
}
|
|
317
357
|
/** 结束响应 */
|
|
318
358
|
endsession(message) {
|
|
319
359
|
this.response.handled = true;
|
|
360
|
+
if (!this.response.raw)
|
|
361
|
+
throw new Error('Cannot end session without a response object.');
|
|
320
362
|
return this.response.raw.end(message);
|
|
321
363
|
}
|
|
322
364
|
/** 获取国际化文本 */
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type MaybePromise<T> = T | Promise<T>;
|
|
2
|
+
export interface Storage<T = any> {
|
|
3
|
+
get(key: string): MaybePromise<T | undefined | null>;
|
|
4
|
+
set(key: string, value: T): MaybePromise<void>;
|
|
5
|
+
delete(key: string): MaybePromise<void>;
|
|
6
|
+
clear?(): MaybePromise<void>;
|
|
7
|
+
}
|
|
8
|
+
export declare class MemoryStorage<T = any> implements Storage<T> {
|
|
9
|
+
private data;
|
|
10
|
+
get(key: string): T | undefined;
|
|
11
|
+
set(key: string, value: T): void;
|
|
12
|
+
delete(key: string): void;
|
|
13
|
+
clear(): void;
|
|
14
|
+
}
|
|
15
|
+
export interface SessionStorageSnapshot {
|
|
16
|
+
sessionid: string;
|
|
17
|
+
data: Record<string, any>;
|
|
18
|
+
createdAt: number;
|
|
19
|
+
updatedAt: number;
|
|
20
|
+
expiresAt?: number | null;
|
|
21
|
+
}
|
|
22
|
+
export interface SessionStorageOptions {
|
|
23
|
+
keyPrefix?: string;
|
|
24
|
+
ttl?: number;
|
|
25
|
+
}
|
|
26
|
+
export declare class SessionStorageProcessor {
|
|
27
|
+
private storage;
|
|
28
|
+
private keyPrefix;
|
|
29
|
+
private ttl?;
|
|
30
|
+
constructor(storage?: Storage<SessionStorageSnapshot>, options?: SessionStorageOptions);
|
|
31
|
+
setStorage(storage: Storage<SessionStorageSnapshot>): void;
|
|
32
|
+
getStorage(): Storage<SessionStorageSnapshot>;
|
|
33
|
+
load(sessionid: string): Promise<Record<string, any>>;
|
|
34
|
+
save(sessionid: string, data: Record<string, any>): Promise<void>;
|
|
35
|
+
delete(sessionid: string): Promise<void>;
|
|
36
|
+
clear(): Promise<void>;
|
|
37
|
+
private getKey;
|
|
38
|
+
private isExpired;
|
|
39
|
+
}
|
package/dist/storage.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export class MemoryStorage {
|
|
2
|
+
data = new Map();
|
|
3
|
+
get(key) {
|
|
4
|
+
return this.data.get(key);
|
|
5
|
+
}
|
|
6
|
+
set(key, value) {
|
|
7
|
+
this.data.set(key, value);
|
|
8
|
+
}
|
|
9
|
+
delete(key) {
|
|
10
|
+
this.data.delete(key);
|
|
11
|
+
}
|
|
12
|
+
clear() {
|
|
13
|
+
this.data.clear();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class SessionStorageProcessor {
|
|
17
|
+
storage;
|
|
18
|
+
keyPrefix;
|
|
19
|
+
ttl;
|
|
20
|
+
constructor(storage = new MemoryStorage(), options = {}) {
|
|
21
|
+
this.storage = storage;
|
|
22
|
+
this.keyPrefix = options.keyPrefix ?? 'session:';
|
|
23
|
+
this.ttl = options.ttl;
|
|
24
|
+
}
|
|
25
|
+
setStorage(storage) {
|
|
26
|
+
this.storage = storage;
|
|
27
|
+
}
|
|
28
|
+
getStorage() {
|
|
29
|
+
return this.storage;
|
|
30
|
+
}
|
|
31
|
+
async load(sessionid) {
|
|
32
|
+
const snapshot = await this.storage.get(this.getKey(sessionid));
|
|
33
|
+
if (!snapshot)
|
|
34
|
+
return {};
|
|
35
|
+
if (this.isExpired(snapshot)) {
|
|
36
|
+
await this.delete(sessionid);
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
return { ...(snapshot.data || {}) };
|
|
40
|
+
}
|
|
41
|
+
async save(sessionid, data) {
|
|
42
|
+
const key = this.getKey(sessionid);
|
|
43
|
+
const now = Date.now();
|
|
44
|
+
const current = await this.storage.get(key);
|
|
45
|
+
const createdAt = current && !this.isExpired(current) ? current.createdAt : now;
|
|
46
|
+
const snapshot = {
|
|
47
|
+
sessionid,
|
|
48
|
+
data: { ...(data || {}) },
|
|
49
|
+
createdAt,
|
|
50
|
+
updatedAt: now,
|
|
51
|
+
expiresAt: this.ttl ? now + this.ttl : null,
|
|
52
|
+
};
|
|
53
|
+
await this.storage.set(key, snapshot);
|
|
54
|
+
}
|
|
55
|
+
async delete(sessionid) {
|
|
56
|
+
await this.storage.delete(this.getKey(sessionid));
|
|
57
|
+
}
|
|
58
|
+
async clear() {
|
|
59
|
+
if (this.storage.clear) {
|
|
60
|
+
await this.storage.clear();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
getKey(sessionid) {
|
|
64
|
+
return `${this.keyPrefix}${sessionid}`;
|
|
65
|
+
}
|
|
66
|
+
isExpired(snapshot) {
|
|
67
|
+
return typeof snapshot.expiresAt === 'number' && snapshot.expiresAt > 0 && snapshot.expiresAt <= Date.now();
|
|
68
|
+
}
|
|
69
|
+
}
|
package/package.json
CHANGED
|
@@ -1,46 +1,48 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@yumerijs/core",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
4
|
-
"description": "Core module for yumeri",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
|
-
"type": "module",
|
|
8
|
-
"files": [
|
|
9
|
-
"dist"
|
|
10
|
-
],
|
|
11
|
-
"scripts": {
|
|
12
|
-
"build": "tsc",
|
|
13
|
-
"prepublishOnly": "yarn build"
|
|
14
|
-
},
|
|
15
|
-
"repository": {
|
|
16
|
-
"type": "git",
|
|
17
|
-
"url": "git+https://github.com/yumerijs/yumeri.git"
|
|
18
|
-
},
|
|
19
|
-
"keywords": [
|
|
20
|
-
"yumeri",
|
|
21
|
-
"API"
|
|
22
|
-
],
|
|
23
|
-
"author": "WindyPear-Team,FireGuo",
|
|
24
|
-
"license": "MIT",
|
|
25
|
-
"bugs": {
|
|
26
|
-
"url": "https://github.com/yumerijs/yumeri/issues"
|
|
27
|
-
},
|
|
28
|
-
"homepage": "https://github.com/yumerijs/yumeri#readme",
|
|
29
|
-
"devDependencies": {
|
|
30
|
-
"@types/formidable": "^3",
|
|
31
|
-
"@types/js-yaml": "^4.0.9",
|
|
32
|
-
"@types/mime-types": "^3",
|
|
33
|
-
"@types/node": "^22.13.10",
|
|
34
|
-
"@types/
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@yumerijs/core",
|
|
3
|
+
"version": "3.0.0-alpha.6",
|
|
4
|
+
"description": "Core module for yumeri",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"prepublishOnly": "yarn build"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/yumerijs/yumeri.git"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"yumeri",
|
|
21
|
+
"API"
|
|
22
|
+
],
|
|
23
|
+
"author": "WindyPear-Team,FireGuo",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/yumerijs/yumeri/issues"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/yumerijs/yumeri#readme",
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/formidable": "^3",
|
|
31
|
+
"@types/js-yaml": "^4.0.9",
|
|
32
|
+
"@types/mime-types": "^3",
|
|
33
|
+
"@types/node": "^22.13.10",
|
|
34
|
+
"@types/semver": "^7",
|
|
35
|
+
"@types/ws": "^8",
|
|
36
|
+
"typescript": "^6.0.3"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"chokidar": "^4.0.3",
|
|
40
|
+
"formidable": "^3.5.4",
|
|
41
|
+
"js-yaml": "^4.1.0",
|
|
42
|
+
"mime-types": "^3.0.1",
|
|
43
|
+
"picocolors": "^1.1.1",
|
|
44
|
+
"semver": "^7.8.4",
|
|
45
|
+
"ws": "^8.18.3"
|
|
46
|
+
},
|
|
47
|
+
"packageManager": "yarn@4.9.1"
|
|
48
|
+
}
|
package/dist/command.d.ts
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @time: 2025/08/14 09:48
|
|
3
|
-
* @author: FireGuo
|
|
4
|
-
* WindyPear-Team All right reserved
|
|
5
|
-
**/
|
|
6
|
-
import { Core } from './core';
|
|
7
|
-
import { Session } from './session';
|
|
8
|
-
import { Middleware } from './middleware';
|
|
9
|
-
/**
|
|
10
|
-
* 命令处理函数接口
|
|
11
|
-
* @param session 会话对象
|
|
12
|
-
* @param args 其他参数
|
|
13
|
-
* @returns Promise<any>
|
|
14
|
-
*/
|
|
15
|
-
interface ActionFn {
|
|
16
|
-
(session: any, ...args: any[]): Promise<any>;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* 支持的协议类型
|
|
20
|
-
* @enum {string}
|
|
21
|
-
*/
|
|
22
|
-
export declare enum ProtocolType {
|
|
23
|
-
/** HTTP 协议 */
|
|
24
|
-
HTTP = "http",
|
|
25
|
-
/** WebSocket 协议 */
|
|
26
|
-
WS = "ws",
|
|
27
|
-
/** 所有协议 */
|
|
28
|
-
ALL = "all"
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* 支持的 HTTP 方法
|
|
32
|
-
* @enum {string}
|
|
33
|
-
*/
|
|
34
|
-
export declare enum HttpMethod {
|
|
35
|
-
/** GET 请求方法 */
|
|
36
|
-
GET = "get",
|
|
37
|
-
/** POST 请求方法 */
|
|
38
|
-
POST = "post",
|
|
39
|
-
/** PUT 请求方法 */
|
|
40
|
-
PUT = "put",
|
|
41
|
-
/** DELETE 请求方法 */
|
|
42
|
-
DELETE = "delete",
|
|
43
|
-
/** PATCH 请求方法 */
|
|
44
|
-
PATCH = "patch",
|
|
45
|
-
/** HEAD 请求方法 */
|
|
46
|
-
HEAD = "head",
|
|
47
|
-
/** OPTIONS 请求方法 */
|
|
48
|
-
OPTIONS = "options",
|
|
49
|
-
/** 所有 HTTP 方法 */
|
|
50
|
-
ALL = "all"
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* 命令类,用于注册和执行命令
|
|
54
|
-
*/
|
|
55
|
-
/**
|
|
56
|
-
* @deprecated Use Route instead.
|
|
57
|
-
*/
|
|
58
|
-
export declare class Command {
|
|
59
|
-
/** 命令名称 */
|
|
60
|
-
name: string;
|
|
61
|
-
/** 命令处理函数 */
|
|
62
|
-
actionFn: ActionFn | null;
|
|
63
|
-
/** WebSocket 连接处理函数 */
|
|
64
|
-
connectFn: ActionFn | null;
|
|
65
|
-
/** WebSocket 关闭处理函数 */
|
|
66
|
-
closeFn: ActionFn | null;
|
|
67
|
-
/** 核心实例 */
|
|
68
|
-
core: Core;
|
|
69
|
-
/** 命令特定的中间件数组 */
|
|
70
|
-
middlewares: Middleware[];
|
|
71
|
-
/** 支持的协议类型,默认为所有协议 */
|
|
72
|
-
protocol: ProtocolType;
|
|
73
|
-
/** 支持的 HTTP 方法,默认为所有方法 */
|
|
74
|
-
httpMethods: HttpMethod[];
|
|
75
|
-
/**
|
|
76
|
-
* 创建命令实例
|
|
77
|
-
* @param core 核心实例
|
|
78
|
-
* @param name 命令名称
|
|
79
|
-
*/
|
|
80
|
-
constructor(core: Core, name: string);
|
|
81
|
-
/**
|
|
82
|
-
* 注册命令处理函数
|
|
83
|
-
* @param fn 处理函数
|
|
84
|
-
* @returns this 支持链式调用
|
|
85
|
-
*/
|
|
86
|
-
action(fn: ActionFn): this;
|
|
87
|
-
/**
|
|
88
|
-
* 注册 WebSocket 关闭处理函数
|
|
89
|
-
* @param fn 处理函数
|
|
90
|
-
* @returns this 支持链式调用
|
|
91
|
-
*/
|
|
92
|
-
close(fn: ActionFn): this;
|
|
93
|
-
/**
|
|
94
|
-
* 注册 WebSocket 连接处理函数
|
|
95
|
-
* @param fn 处理函数
|
|
96
|
-
* @returns this 支持链式调用
|
|
97
|
-
*/
|
|
98
|
-
connect(fn: ActionFn): this;
|
|
99
|
-
/**
|
|
100
|
-
* 设置命令支持的协议类型
|
|
101
|
-
* @param protocol 协议类型
|
|
102
|
-
* @returns this 支持链式调用
|
|
103
|
-
*/
|
|
104
|
-
setProtocol(protocol: ProtocolType): this;
|
|
105
|
-
/**
|
|
106
|
-
* 设置命令支持的 HTTP 方法
|
|
107
|
-
* @param methods 单个 HTTP 方法或 HTTP 方法数组
|
|
108
|
-
* @returns this 支持链式调用
|
|
109
|
-
*/
|
|
110
|
-
setHttpMethods(methods: HttpMethod | HttpMethod[]): this;
|
|
111
|
-
/**
|
|
112
|
-
* 检查命令是否支持指定的协议类型
|
|
113
|
-
* @param protocol 协议类型
|
|
114
|
-
* @returns 是否支持
|
|
115
|
-
*/
|
|
116
|
-
supportsProtocol(protocol: ProtocolType): boolean;
|
|
117
|
-
/**
|
|
118
|
-
* 检查命令是否支持指定的 HTTP 方法
|
|
119
|
-
* @param method HTTP 方法
|
|
120
|
-
* @returns 是否支持
|
|
121
|
-
*/
|
|
122
|
-
supportsHttpMethod(method: string): boolean;
|
|
123
|
-
/**
|
|
124
|
-
* 注册命令特定的中间件
|
|
125
|
-
* @param middleware 中间件函数
|
|
126
|
-
* @returns this 支持链式调用
|
|
127
|
-
*/
|
|
128
|
-
use(middleware: Middleware): this;
|
|
129
|
-
/**
|
|
130
|
-
* 执行命令,包括中间件链和处理函数
|
|
131
|
-
* @param session 会话对象
|
|
132
|
-
* @param args 其他参数
|
|
133
|
-
* @returns 处理后的会话对象
|
|
134
|
-
*/
|
|
135
|
-
execute(session: any, ...args: any[]): Promise<Session | null>;
|
|
136
|
-
/**
|
|
137
|
-
* 执行命令处理函数(不包含中间件)
|
|
138
|
-
* @param session 会话对象
|
|
139
|
-
* @param args 其他参数
|
|
140
|
-
* @returns 处理后的会话对象
|
|
141
|
-
*/
|
|
142
|
-
executeHandler(session: any, ...args: any[]): Promise<Session | null>;
|
|
143
|
-
}
|
|
144
|
-
export {};
|
package/dist/command.js
DELETED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @time: 2025/08/14 09:48
|
|
4
|
-
* @author: FireGuo
|
|
5
|
-
* WindyPear-Team All right reserved
|
|
6
|
-
**/
|
|
7
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.Command = exports.HttpMethod = exports.ProtocolType = void 0;
|
|
9
|
-
/**
|
|
10
|
-
* 支持的协议类型
|
|
11
|
-
* @enum {string}
|
|
12
|
-
*/
|
|
13
|
-
var ProtocolType;
|
|
14
|
-
(function (ProtocolType) {
|
|
15
|
-
/** HTTP 协议 */
|
|
16
|
-
ProtocolType["HTTP"] = "http";
|
|
17
|
-
/** WebSocket 协议 */
|
|
18
|
-
ProtocolType["WS"] = "ws";
|
|
19
|
-
/** 所有协议 */
|
|
20
|
-
ProtocolType["ALL"] = "all";
|
|
21
|
-
})(ProtocolType || (exports.ProtocolType = ProtocolType = {}));
|
|
22
|
-
/**
|
|
23
|
-
* 支持的 HTTP 方法
|
|
24
|
-
* @enum {string}
|
|
25
|
-
*/
|
|
26
|
-
var HttpMethod;
|
|
27
|
-
(function (HttpMethod) {
|
|
28
|
-
/** GET 请求方法 */
|
|
29
|
-
HttpMethod["GET"] = "get";
|
|
30
|
-
/** POST 请求方法 */
|
|
31
|
-
HttpMethod["POST"] = "post";
|
|
32
|
-
/** PUT 请求方法 */
|
|
33
|
-
HttpMethod["PUT"] = "put";
|
|
34
|
-
/** DELETE 请求方法 */
|
|
35
|
-
HttpMethod["DELETE"] = "delete";
|
|
36
|
-
/** PATCH 请求方法 */
|
|
37
|
-
HttpMethod["PATCH"] = "patch";
|
|
38
|
-
/** HEAD 请求方法 */
|
|
39
|
-
HttpMethod["HEAD"] = "head";
|
|
40
|
-
/** OPTIONS 请求方法 */
|
|
41
|
-
HttpMethod["OPTIONS"] = "options";
|
|
42
|
-
/** 所有 HTTP 方法 */
|
|
43
|
-
HttpMethod["ALL"] = "all";
|
|
44
|
-
})(HttpMethod || (exports.HttpMethod = HttpMethod = {}));
|
|
45
|
-
/**
|
|
46
|
-
* 命令类,用于注册和执行命令
|
|
47
|
-
*/
|
|
48
|
-
/**
|
|
49
|
-
* @deprecated Use Route instead.
|
|
50
|
-
*/
|
|
51
|
-
class Command {
|
|
52
|
-
/** 命令名称 */
|
|
53
|
-
name;
|
|
54
|
-
/** 命令处理函数 */
|
|
55
|
-
actionFn = null;
|
|
56
|
-
/** WebSocket 连接处理函数 */
|
|
57
|
-
connectFn = null;
|
|
58
|
-
/** WebSocket 关闭处理函数 */
|
|
59
|
-
closeFn = null;
|
|
60
|
-
/** 核心实例 */
|
|
61
|
-
core;
|
|
62
|
-
/** 命令特定的中间件数组 */
|
|
63
|
-
middlewares = [];
|
|
64
|
-
/** 支持的协议类型,默认为所有协议 */
|
|
65
|
-
protocol = ProtocolType.ALL;
|
|
66
|
-
/** 支持的 HTTP 方法,默认为所有方法 */
|
|
67
|
-
httpMethods = [HttpMethod.ALL];
|
|
68
|
-
/**
|
|
69
|
-
* 创建命令实例
|
|
70
|
-
* @param core 核心实例
|
|
71
|
-
* @param name 命令名称
|
|
72
|
-
*/
|
|
73
|
-
constructor(core, name) {
|
|
74
|
-
this.core = core;
|
|
75
|
-
this.name = name;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* 注册命令处理函数
|
|
79
|
-
* @param fn 处理函数
|
|
80
|
-
* @returns this 支持链式调用
|
|
81
|
-
*/
|
|
82
|
-
action(fn) {
|
|
83
|
-
this.actionFn = fn;
|
|
84
|
-
return this;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* 注册 WebSocket 关闭处理函数
|
|
88
|
-
* @param fn 处理函数
|
|
89
|
-
* @returns this 支持链式调用
|
|
90
|
-
*/
|
|
91
|
-
close(fn) {
|
|
92
|
-
this.closeFn = fn;
|
|
93
|
-
return this;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* 注册 WebSocket 连接处理函数
|
|
97
|
-
* @param fn 处理函数
|
|
98
|
-
* @returns this 支持链式调用
|
|
99
|
-
*/
|
|
100
|
-
connect(fn) {
|
|
101
|
-
this.connectFn = fn;
|
|
102
|
-
return this;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* 设置命令支持的协议类型
|
|
106
|
-
* @param protocol 协议类型
|
|
107
|
-
* @returns this 支持链式调用
|
|
108
|
-
*/
|
|
109
|
-
setProtocol(protocol) {
|
|
110
|
-
this.protocol = protocol;
|
|
111
|
-
return this;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* 设置命令支持的 HTTP 方法
|
|
115
|
-
* @param methods 单个 HTTP 方法或 HTTP 方法数组
|
|
116
|
-
* @returns this 支持链式调用
|
|
117
|
-
*/
|
|
118
|
-
setHttpMethods(methods) {
|
|
119
|
-
if (Array.isArray(methods)) {
|
|
120
|
-
this.httpMethods = methods;
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
this.httpMethods = [methods];
|
|
124
|
-
}
|
|
125
|
-
return this;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* 检查命令是否支持指定的协议类型
|
|
129
|
-
* @param protocol 协议类型
|
|
130
|
-
* @returns 是否支持
|
|
131
|
-
*/
|
|
132
|
-
supportsProtocol(protocol) {
|
|
133
|
-
return this.protocol === ProtocolType.ALL || this.protocol === protocol;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* 检查命令是否支持指定的 HTTP 方法
|
|
137
|
-
* @param method HTTP 方法
|
|
138
|
-
* @returns 是否支持
|
|
139
|
-
*/
|
|
140
|
-
supportsHttpMethod(method) {
|
|
141
|
-
const lowerMethod = method.toLowerCase();
|
|
142
|
-
return this.httpMethods.includes(HttpMethod.ALL) ||
|
|
143
|
-
this.httpMethods.some(m => m.toLowerCase() === lowerMethod);
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* 注册命令特定的中间件
|
|
147
|
-
* @param middleware 中间件函数
|
|
148
|
-
* @returns this 支持链式调用
|
|
149
|
-
*/
|
|
150
|
-
use(middleware) {
|
|
151
|
-
this.middlewares.push(middleware);
|
|
152
|
-
return this;
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* 执行命令,包括中间件链和处理函数
|
|
156
|
-
* @param session 会话对象
|
|
157
|
-
* @param args 其他参数
|
|
158
|
-
* @returns 处理后的会话对象
|
|
159
|
-
*/
|
|
160
|
-
async execute(session, ...args) {
|
|
161
|
-
if (this.actionFn) {
|
|
162
|
-
await this.actionFn(session, ...args);
|
|
163
|
-
return session;
|
|
164
|
-
}
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* 执行命令处理函数(不包含中间件)
|
|
169
|
-
* @param session 会话对象
|
|
170
|
-
* @param args 其他参数
|
|
171
|
-
* @returns 处理后的会话对象
|
|
172
|
-
*/
|
|
173
|
-
async executeHandler(session, ...args) {
|
|
174
|
-
if (this.actionFn) {
|
|
175
|
-
await this.actionFn(session, ...args);
|
|
176
|
-
return session;
|
|
177
|
-
}
|
|
178
|
-
return null;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
exports.Command = Command;
|
package/dist/platform.d.ts
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @time: 2025/08/14 09:48
|
|
3
|
-
* @author: FireGuo
|
|
4
|
-
* WindyPear-Team All right reserved
|
|
5
|
-
**/
|
|
6
|
-
import { Session } from './session';
|
|
7
|
-
import { Core } from './core';
|
|
8
|
-
import { ConfigSchema } from './config';
|
|
9
|
-
/**
|
|
10
|
-
* Platform 基类
|
|
11
|
-
* 作为平台接入的基础类,提供标准化的接口和通用能力
|
|
12
|
-
* 各平台实现类需继承此类并实现所有抽象方法
|
|
13
|
-
*/
|
|
14
|
-
export declare abstract class Platform {
|
|
15
|
-
protected status: 'idle' | 'starting' | 'running' | 'stopping' | 'error';
|
|
16
|
-
protected errorMessage: string | null;
|
|
17
|
-
protected config: Record<string, any>;
|
|
18
|
-
protected instanceId: string;
|
|
19
|
-
protected eventListeners: Record<string, Array<(...args: any[]) => void>>;
|
|
20
|
-
/**
|
|
21
|
-
* 构造函数
|
|
22
|
-
* @param config 平台配置
|
|
23
|
-
*/
|
|
24
|
-
constructor(config?: Record<string, any>);
|
|
25
|
-
/**
|
|
26
|
-
* 生成平台实例ID
|
|
27
|
-
* @returns 实例ID字符串
|
|
28
|
-
*/
|
|
29
|
-
protected generateInstanceId(): string;
|
|
30
|
-
/**
|
|
31
|
-
* 向客户端发送消息
|
|
32
|
-
* @param session 会话对象
|
|
33
|
-
* @param data 要发送的数据
|
|
34
|
-
* @returns 发送结果
|
|
35
|
-
*/
|
|
36
|
-
abstract sendMessage(session: Session, data: any): any;
|
|
37
|
-
/**
|
|
38
|
-
* 结束会话
|
|
39
|
-
* @param session 会话对象
|
|
40
|
-
* @param message 结束消息
|
|
41
|
-
* @returns 结束结果
|
|
42
|
-
*/
|
|
43
|
-
abstract terminationSession(session: Session, message: any): any;
|
|
44
|
-
/**
|
|
45
|
-
* 获取平台名称
|
|
46
|
-
* @returns 平台名称
|
|
47
|
-
*/
|
|
48
|
-
abstract getPlatformName(): string;
|
|
49
|
-
/**
|
|
50
|
-
* 获取平台版本号
|
|
51
|
-
* @returns 平台版本号
|
|
52
|
-
*/
|
|
53
|
-
abstract getPlatformVersionCode(): string;
|
|
54
|
-
/**
|
|
55
|
-
* 获取平台ID
|
|
56
|
-
* @returns 平台ID
|
|
57
|
-
*/
|
|
58
|
-
abstract getPlatformId(): string;
|
|
59
|
-
/**
|
|
60
|
-
* 获取平台状态
|
|
61
|
-
* @returns 平台状态对象
|
|
62
|
-
*/
|
|
63
|
-
abstract getPlatformStatus(): Record<string, any>;
|
|
64
|
-
/**
|
|
65
|
-
* 启动平台
|
|
66
|
-
* @param core Core实例
|
|
67
|
-
* @returns 启动结果
|
|
68
|
-
*/
|
|
69
|
-
abstract startPlatform(core?: Core): Promise<any>;
|
|
70
|
-
/**
|
|
71
|
-
* 停止平台
|
|
72
|
-
* @returns 停止结果
|
|
73
|
-
*/
|
|
74
|
-
abstract stopPlatform(): Promise<void>;
|
|
75
|
-
/**
|
|
76
|
-
* 重启平台
|
|
77
|
-
* @param core Core实例
|
|
78
|
-
* @returns 重启结果
|
|
79
|
-
*/
|
|
80
|
-
restartPlatform(core?: Core): Promise<any>;
|
|
81
|
-
/**
|
|
82
|
-
* 设置平台配置
|
|
83
|
-
* @param key 配置键
|
|
84
|
-
* @param value 配置值
|
|
85
|
-
*/
|
|
86
|
-
setConfig(key: string, value: any): void;
|
|
87
|
-
/**
|
|
88
|
-
* 获取平台配置
|
|
89
|
-
* @param key 配置键
|
|
90
|
-
* @param defaultValue 默认值
|
|
91
|
-
* @returns 配置值
|
|
92
|
-
*/
|
|
93
|
-
getConfig<T>(key: string, defaultValue?: T): T;
|
|
94
|
-
/**
|
|
95
|
-
* 获取平台实例ID
|
|
96
|
-
* @returns 实例ID
|
|
97
|
-
*/
|
|
98
|
-
getInstanceId(): string;
|
|
99
|
-
/**
|
|
100
|
-
* 获取当前平台状态
|
|
101
|
-
* @returns 状态字符串
|
|
102
|
-
*/
|
|
103
|
-
getStatus(): 'idle' | 'starting' | 'running' | 'stopping' | 'error';
|
|
104
|
-
/**
|
|
105
|
-
* 获取错误信息
|
|
106
|
-
* @returns 错误信息
|
|
107
|
-
*/
|
|
108
|
-
getErrorMessage(): string | null;
|
|
109
|
-
/**
|
|
110
|
-
* 添加平台事件监听器
|
|
111
|
-
* @param event 事件名称
|
|
112
|
-
* @param listener 监听器函数
|
|
113
|
-
*/
|
|
114
|
-
on(event: string, listener: (...args: any[]) => void): void;
|
|
115
|
-
/**
|
|
116
|
-
* 移除平台事件监听器
|
|
117
|
-
* @param event 事件名称
|
|
118
|
-
* @param listener 监听器函数
|
|
119
|
-
*/
|
|
120
|
-
off(event: string, listener: (...args: any[]) => void): void;
|
|
121
|
-
/**
|
|
122
|
-
* 触发平台事件
|
|
123
|
-
* @param event 事件名称
|
|
124
|
-
* @param args 事件参数
|
|
125
|
-
*/
|
|
126
|
-
protected emit(event: string, ...args: any[]): void;
|
|
127
|
-
/**
|
|
128
|
-
* 创建会话
|
|
129
|
-
* @param ip 客户端IP
|
|
130
|
-
* @param cookie Cookie对象
|
|
131
|
-
* @param query 查询参数
|
|
132
|
-
* @returns 会话对象
|
|
133
|
-
*/
|
|
134
|
-
createSession(ip: string, cookie: Record<string, string>, query?: Record<string, string>): Session;
|
|
135
|
-
/**
|
|
136
|
-
* 处理会话数据
|
|
137
|
-
* @param session 会话对象
|
|
138
|
-
* @param data 会话数据
|
|
139
|
-
* @returns 处理结果
|
|
140
|
-
*/
|
|
141
|
-
processSessionData(session: Session, data: any): any;
|
|
142
|
-
/**
|
|
143
|
-
* 验证会话
|
|
144
|
-
* @param session 会话对象
|
|
145
|
-
* @returns 验证结果
|
|
146
|
-
*/
|
|
147
|
-
validateSession(session: Session): boolean;
|
|
148
|
-
/**
|
|
149
|
-
* 获取平台支持的MIME类型
|
|
150
|
-
* @returns MIME类型数组
|
|
151
|
-
*/
|
|
152
|
-
getSupportedMimeTypes(): string[];
|
|
153
|
-
/**
|
|
154
|
-
* 获取平台元数据
|
|
155
|
-
* @returns 平台元数据
|
|
156
|
-
*/
|
|
157
|
-
getMetadata(): Record<string, any>;
|
|
158
|
-
/**
|
|
159
|
-
* 获取平台配置模式
|
|
160
|
-
* 子类可以覆盖此方法提供自定义配置模式
|
|
161
|
-
* @returns 配置模式对象
|
|
162
|
-
*/
|
|
163
|
-
static getConfigSchema(): Record<string, ConfigSchema>;
|
|
164
|
-
}
|
package/dist/platform.js
DELETED
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Platform = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* @time: 2025/08/14 09:48
|
|
6
|
-
* @author: FireGuo
|
|
7
|
-
* WindyPear-Team All right reserved
|
|
8
|
-
**/
|
|
9
|
-
const session_1 = require("./session");
|
|
10
|
-
/**
|
|
11
|
-
* Platform 基类
|
|
12
|
-
* 作为平台接入的基础类,提供标准化的接口和通用能力
|
|
13
|
-
* 各平台实现类需继承此类并实现所有抽象方法
|
|
14
|
-
*/
|
|
15
|
-
class Platform {
|
|
16
|
-
// 平台状态
|
|
17
|
-
status = 'idle';
|
|
18
|
-
// 平台错误信息
|
|
19
|
-
errorMessage = null;
|
|
20
|
-
// 平台配置
|
|
21
|
-
config = {};
|
|
22
|
-
// 平台实例ID
|
|
23
|
-
instanceId = '';
|
|
24
|
-
// 平台事件监听器
|
|
25
|
-
eventListeners = {};
|
|
26
|
-
/**
|
|
27
|
-
* 构造函数
|
|
28
|
-
* @param config 平台配置
|
|
29
|
-
*/
|
|
30
|
-
constructor(config) {
|
|
31
|
-
if (config) {
|
|
32
|
-
this.config = { ...config };
|
|
33
|
-
}
|
|
34
|
-
this.instanceId = this.generateInstanceId();
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* 生成平台实例ID
|
|
38
|
-
* @returns 实例ID字符串
|
|
39
|
-
*/
|
|
40
|
-
generateInstanceId() {
|
|
41
|
-
return `${this.getPlatformId()}-${Date.now()}-${Math.floor(Math.random() * 1000)}`;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* 重启平台
|
|
45
|
-
* @param core Core实例
|
|
46
|
-
* @returns 重启结果
|
|
47
|
-
*/
|
|
48
|
-
async restartPlatform(core) {
|
|
49
|
-
await this.stopPlatform();
|
|
50
|
-
return this.startPlatform(core);
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* 设置平台配置
|
|
54
|
-
* @param key 配置键
|
|
55
|
-
* @param value 配置值
|
|
56
|
-
*/
|
|
57
|
-
setConfig(key, value) {
|
|
58
|
-
this.config[key] = value;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* 获取平台配置
|
|
62
|
-
* @param key 配置键
|
|
63
|
-
* @param defaultValue 默认值
|
|
64
|
-
* @returns 配置值
|
|
65
|
-
*/
|
|
66
|
-
getConfig(key, defaultValue) {
|
|
67
|
-
return (this.config[key] !== undefined) ? this.config[key] : defaultValue;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* 获取平台实例ID
|
|
71
|
-
* @returns 实例ID
|
|
72
|
-
*/
|
|
73
|
-
getInstanceId() {
|
|
74
|
-
return this.instanceId;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* 获取当前平台状态
|
|
78
|
-
* @returns 状态字符串
|
|
79
|
-
*/
|
|
80
|
-
getStatus() {
|
|
81
|
-
return this.status;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* 获取错误信息
|
|
85
|
-
* @returns 错误信息
|
|
86
|
-
*/
|
|
87
|
-
getErrorMessage() {
|
|
88
|
-
return this.errorMessage;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* 添加平台事件监听器
|
|
92
|
-
* @param event 事件名称
|
|
93
|
-
* @param listener 监听器函数
|
|
94
|
-
*/
|
|
95
|
-
on(event, listener) {
|
|
96
|
-
if (!this.eventListeners[event]) {
|
|
97
|
-
this.eventListeners[event] = [];
|
|
98
|
-
}
|
|
99
|
-
this.eventListeners[event].push(listener);
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* 移除平台事件监听器
|
|
103
|
-
* @param event 事件名称
|
|
104
|
-
* @param listener 监听器函数
|
|
105
|
-
*/
|
|
106
|
-
off(event, listener) {
|
|
107
|
-
if (!this.eventListeners[event]) {
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
this.eventListeners[event] = this.eventListeners[event].filter(l => l !== listener);
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* 触发平台事件
|
|
114
|
-
* @param event 事件名称
|
|
115
|
-
* @param args 事件参数
|
|
116
|
-
*/
|
|
117
|
-
emit(event, ...args) {
|
|
118
|
-
if (!this.eventListeners[event]) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
for (const listener of this.eventListeners[event]) {
|
|
122
|
-
try {
|
|
123
|
-
listener(...args);
|
|
124
|
-
}
|
|
125
|
-
catch (error) {
|
|
126
|
-
console.error(`Error in platform event listener for "${event}":`, error);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* 创建会话
|
|
132
|
-
* @param ip 客户端IP
|
|
133
|
-
* @param cookie Cookie对象
|
|
134
|
-
* @param query 查询参数
|
|
135
|
-
* @returns 会话对象
|
|
136
|
-
*/
|
|
137
|
-
createSession(ip, cookie, query) {
|
|
138
|
-
return new session_1.Session(ip, cookie, this, query);
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* 处理会话数据
|
|
142
|
-
* @param session 会话对象
|
|
143
|
-
* @param data 会话数据
|
|
144
|
-
* @returns 处理结果
|
|
145
|
-
*/
|
|
146
|
-
processSessionData(session, data) {
|
|
147
|
-
// 默认实现,子类可覆盖
|
|
148
|
-
return data;
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* 验证会话
|
|
152
|
-
* @param session 会话对象
|
|
153
|
-
* @returns 验证结果
|
|
154
|
-
*/
|
|
155
|
-
validateSession(session) {
|
|
156
|
-
// 默认实现,子类可覆盖
|
|
157
|
-
return true;
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* 获取平台支持的MIME类型
|
|
161
|
-
* @returns MIME类型数组
|
|
162
|
-
*/
|
|
163
|
-
getSupportedMimeTypes() {
|
|
164
|
-
// 默认实现,子类可覆盖
|
|
165
|
-
return [
|
|
166
|
-
'text/plain',
|
|
167
|
-
'text/html',
|
|
168
|
-
'application/json',
|
|
169
|
-
'application/xml',
|
|
170
|
-
'image/png',
|
|
171
|
-
'image/jpeg',
|
|
172
|
-
'application/pdf'
|
|
173
|
-
];
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* 获取平台元数据
|
|
177
|
-
* @returns 平台元数据
|
|
178
|
-
*/
|
|
179
|
-
getMetadata() {
|
|
180
|
-
return {
|
|
181
|
-
id: this.getPlatformId(),
|
|
182
|
-
name: this.getPlatformName(),
|
|
183
|
-
version: this.getPlatformVersionCode(),
|
|
184
|
-
status: this.getStatus(),
|
|
185
|
-
instanceId: this.getInstanceId(),
|
|
186
|
-
supportedMimeTypes: this.getSupportedMimeTypes(),
|
|
187
|
-
...this.getPlatformStatus()
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* 获取平台配置模式
|
|
192
|
-
* 子类可以覆盖此方法提供自定义配置模式
|
|
193
|
-
* @returns 配置模式对象
|
|
194
|
-
*/
|
|
195
|
-
static getConfigSchema() {
|
|
196
|
-
return {};
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
exports.Platform = Platform;
|