@cicctencent/agent-server 0.1.1 → 0.2.0

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 (76) hide show
  1. package/README.md +93 -16
  2. package/dist/cjs/agent/agent-server.d.ts.map +1 -1
  3. package/dist/cjs/agent/agent-server.js +50 -15
  4. package/dist/cjs/agent/agent-server.js.map +1 -1
  5. package/dist/cjs/index.d.ts +2 -0
  6. package/dist/cjs/index.d.ts.map +1 -1
  7. package/dist/cjs/index.js +23 -1
  8. package/dist/cjs/index.js.map +1 -1
  9. package/dist/cjs/service/cache.service.d.ts +69 -0
  10. package/dist/cjs/service/cache.service.d.ts.map +1 -0
  11. package/dist/cjs/service/cache.service.js +243 -0
  12. package/dist/cjs/service/cache.service.js.map +1 -0
  13. package/dist/cjs/service/engine-pool.d.ts +15 -2
  14. package/dist/cjs/service/engine-pool.d.ts.map +1 -1
  15. package/dist/cjs/service/engine-pool.js +15 -4
  16. package/dist/cjs/service/engine-pool.js.map +1 -1
  17. package/dist/cjs/spi/adapters.d.ts +163 -0
  18. package/dist/cjs/spi/adapters.d.ts.map +1 -0
  19. package/dist/cjs/spi/adapters.js +341 -0
  20. package/dist/cjs/spi/adapters.js.map +1 -0
  21. package/dist/cjs/spi/examples/typeorm-example.d.ts +208 -0
  22. package/dist/cjs/spi/examples/typeorm-example.d.ts.map +1 -0
  23. package/dist/cjs/spi/examples/typeorm-example.js +274 -0
  24. package/dist/cjs/spi/examples/typeorm-example.js.map +1 -0
  25. package/dist/cjs/spi/index.d.ts +194 -0
  26. package/dist/cjs/spi/index.d.ts.map +1 -0
  27. package/dist/cjs/spi/index.js +227 -0
  28. package/dist/cjs/spi/index.js.map +1 -0
  29. package/dist/cjs/spi/storage.d.ts +109 -0
  30. package/dist/cjs/spi/storage.d.ts.map +1 -0
  31. package/dist/cjs/spi/storage.js +344 -0
  32. package/dist/cjs/spi/storage.js.map +1 -0
  33. package/dist/cjs/spi/types.d.ts +317 -0
  34. package/dist/cjs/spi/types.d.ts.map +1 -0
  35. package/dist/cjs/spi/types.js +6 -0
  36. package/dist/cjs/spi/types.js.map +1 -0
  37. package/dist/cjs/types.d.ts +63 -8
  38. package/dist/cjs/types.d.ts.map +1 -1
  39. package/dist/esm/agent/agent-server.d.ts.map +1 -1
  40. package/dist/esm/agent/agent-server.js +50 -15
  41. package/dist/esm/agent/agent-server.js.map +1 -1
  42. package/dist/esm/index.d.ts +2 -0
  43. package/dist/esm/index.d.ts.map +1 -1
  44. package/dist/esm/index.js +8 -0
  45. package/dist/esm/index.js.map +1 -1
  46. package/dist/esm/service/cache.service.d.ts +69 -0
  47. package/dist/esm/service/cache.service.d.ts.map +1 -0
  48. package/dist/esm/service/cache.service.js +237 -0
  49. package/dist/esm/service/cache.service.js.map +1 -0
  50. package/dist/esm/service/engine-pool.d.ts +15 -2
  51. package/dist/esm/service/engine-pool.d.ts.map +1 -1
  52. package/dist/esm/service/engine-pool.js +15 -4
  53. package/dist/esm/service/engine-pool.js.map +1 -1
  54. package/dist/esm/spi/adapters.d.ts +163 -0
  55. package/dist/esm/spi/adapters.d.ts.map +1 -0
  56. package/dist/esm/spi/adapters.js +329 -0
  57. package/dist/esm/spi/adapters.js.map +1 -0
  58. package/dist/esm/spi/examples/typeorm-example.d.ts +208 -0
  59. package/dist/esm/spi/examples/typeorm-example.d.ts.map +1 -0
  60. package/dist/esm/spi/examples/typeorm-example.js +315 -0
  61. package/dist/esm/spi/examples/typeorm-example.js.map +1 -0
  62. package/dist/esm/spi/index.d.ts +194 -0
  63. package/dist/esm/spi/index.d.ts.map +1 -0
  64. package/dist/esm/spi/index.js +215 -0
  65. package/dist/esm/spi/index.js.map +1 -0
  66. package/dist/esm/spi/storage.d.ts +109 -0
  67. package/dist/esm/spi/storage.d.ts.map +1 -0
  68. package/dist/esm/spi/storage.js +301 -0
  69. package/dist/esm/spi/storage.js.map +1 -0
  70. package/dist/esm/spi/types.d.ts +317 -0
  71. package/dist/esm/spi/types.d.ts.map +1 -0
  72. package/dist/esm/spi/types.js +5 -0
  73. package/dist/esm/spi/types.js.map +1 -0
  74. package/dist/esm/types.d.ts +63 -8
  75. package/dist/esm/types.d.ts.map +1 -1
  76. package/package.json +1 -1
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ // ============================================================
3
+ // SPI 模块导出
4
+ // ============================================================
5
+ /**
6
+ * # agent-server SPI (Service Provider Interface)
7
+ *
8
+ * ## 核心设计原则
9
+ *
10
+ * 1. **接口优先**:agent-server 核心只定义能力接口,不依赖具体实现
11
+ * 2. **参考实现可选**:提供常见框架的参考实现,业务层可选择使用或自己实现
12
+ * 3. **业务层自主**:完全控制实现细节,不受 agent-server 限制
13
+ *
14
+ * ## 使用方式
15
+ *
16
+ * ### 方式 1:直接使用参考实现(最简单)
17
+ *
18
+ * ```typescript
19
+ * import { KoaSSEAdapter, createAgentServer } from '@cicctencent/agent-server';
20
+ *
21
+ * const server = createAgentServer({ llmProvider: myProvider });
22
+ *
23
+ * // MidwayJS/Koa 项目
24
+ * @Get('/chat/stream')
25
+ * async chatStream(@Ctx() ctx: Context) {
26
+ * const adapter = new KoaSSEAdapter(ctx);
27
+ * await server.runAgentStream(adapter, { content: 'Hello' });
28
+ * }
29
+ * ```
30
+ *
31
+ * ### 方式 2:实现 SPI 接口(自定义存储)
32
+ *
33
+ * ```typescript
34
+ * import {
35
+ * createAgentServer,
36
+ * type ChatStoreProvider,
37
+ * type BaseThreadEntity,
38
+ * type BaseMessageEntity,
39
+ * } from '@cicctencent/agent-server';
40
+ *
41
+ * // 定义你的实体类型(可以自定义字段)
42
+ * interface MyThread extends BaseThreadEntity {
43
+ * userId: string;
44
+ * applicationId: number;
45
+ * }
46
+ *
47
+ * // 实现 ChatStoreProvider 接口
48
+ * class MyChatStore implements ChatStoreProvider<MyThread, MyMessage> {
49
+ * async getThreads(userId?: string): Promise<MyThread[]> {
50
+ * // 使用任意存储技术:TypeORM / Prisma / Mongoose / ...
51
+ * return this.database.query('SELECT * FROM threads WHERE userId = ?', [userId]);
52
+ * }
53
+ *
54
+ * // ... 实现其他方法
55
+ * }
56
+ *
57
+ * // 注入自定义实现
58
+ * const server = createAgentServer({
59
+ * llmProvider: myProvider,
60
+ * chatStoreProvider: new MyChatStore(),
61
+ * });
62
+ * ```
63
+ *
64
+ * ### 方式 3:只使用组件(不使用工厂)
65
+ *
66
+ * ```typescript
67
+ * import {
68
+ * KoaSSEAdapter,
69
+ * writeSSE,
70
+ * createBuiltinTools,
71
+ * MemoryService,
72
+ * } from '@cicctencent/agent-server';
73
+ *
74
+ * // 只使用需要的组件,不依赖 createAgentServer
75
+ * const tools = createBuiltinTools();
76
+ * const memoryService = new MemoryService('./data');
77
+ *
78
+ * @Get('/stream')
79
+ * async stream(@Ctx() ctx: Context) {
80
+ * const adapter = new KoaSSEAdapter(ctx);
81
+ * writeSSE(adapter, 'start', { message: 'Hello' });
82
+ * }
83
+ * ```
84
+ *
85
+ * ## 完整文档
86
+ *
87
+ * 详见 [README.md](./README.md)
88
+ */
89
+ Object.defineProperty(exports, "__esModule", { value: true });
90
+ exports.CustomSSEAdapter = exports.adaptRequest = exports.KoaRequestAdapter = exports.ExpressRequestAdapter = exports.adaptSSE = exports.NativeHttpSSEAdapter = exports.FastifySSEAdapter = exports.KoaSSEAdapter = exports.ExpressSSEAdapter = exports.createInMemoryStorage = exports.createJsonFileStorage = exports.DatabaseListStorage = exports.InMemoryListStorage = exports.InMemoryKVStorage = exports.JsonFileListStorage = exports.JsonFileKVStorage = void 0;
91
+ // ---- 存储适配器(参考实现) ----
92
+ var storage_ts_1 = require("./storage.js");
93
+ // JSON 文件存储(默认实现)
94
+ Object.defineProperty(exports, "JsonFileKVStorage", { enumerable: true, get: function () { return storage_ts_1.JsonFileKVStorage; } });
95
+ Object.defineProperty(exports, "JsonFileListStorage", { enumerable: true, get: function () { return storage_ts_1.JsonFileListStorage; } });
96
+ // 内存存储(测试用)
97
+ Object.defineProperty(exports, "InMemoryKVStorage", { enumerable: true, get: function () { return storage_ts_1.InMemoryKVStorage; } });
98
+ Object.defineProperty(exports, "InMemoryListStorage", { enumerable: true, get: function () { return storage_ts_1.InMemoryListStorage; } });
99
+ // 数据库存储基类(业务层继承)
100
+ Object.defineProperty(exports, "DatabaseListStorage", { enumerable: true, get: function () { return storage_ts_1.DatabaseListStorage; } });
101
+ // 工厂函数
102
+ Object.defineProperty(exports, "createJsonFileStorage", { enumerable: true, get: function () { return storage_ts_1.createJsonFileStorage; } });
103
+ Object.defineProperty(exports, "createInMemoryStorage", { enumerable: true, get: function () { return storage_ts_1.createInMemoryStorage; } });
104
+ // ---- 框架适配器(参考实现) ----
105
+ var adapters_ts_1 = require("./adapters.js");
106
+ // SSE 适配器
107
+ Object.defineProperty(exports, "ExpressSSEAdapter", { enumerable: true, get: function () { return adapters_ts_1.ExpressSSEAdapter; } });
108
+ Object.defineProperty(exports, "KoaSSEAdapter", { enumerable: true, get: function () { return adapters_ts_1.KoaSSEAdapter; } });
109
+ Object.defineProperty(exports, "FastifySSEAdapter", { enumerable: true, get: function () { return adapters_ts_1.FastifySSEAdapter; } });
110
+ Object.defineProperty(exports, "NativeHttpSSEAdapter", { enumerable: true, get: function () { return adapters_ts_1.NativeHttpSSEAdapter; } });
111
+ Object.defineProperty(exports, "adaptSSE", { enumerable: true, get: function () { return adapters_ts_1.adaptSSE; } });
112
+ // 请求适配器
113
+ Object.defineProperty(exports, "ExpressRequestAdapter", { enumerable: true, get: function () { return adapters_ts_1.ExpressRequestAdapter; } });
114
+ Object.defineProperty(exports, "KoaRequestAdapter", { enumerable: true, get: function () { return adapters_ts_1.KoaRequestAdapter; } });
115
+ Object.defineProperty(exports, "adaptRequest", { enumerable: true, get: function () { return adapters_ts_1.adaptRequest; } });
116
+ // 自定义适配器基类
117
+ Object.defineProperty(exports, "CustomSSEAdapter", { enumerable: true, get: function () { return adapters_ts_1.CustomSSEAdapter; } });
118
+ // ============================================================
119
+ // SPI 使用指南
120
+ // ============================================================
121
+ /**
122
+ * ## SPI 使用示例
123
+ *
124
+ * ### 1. 使用默认 JSON 文件存储
125
+ *
126
+ * ```typescript
127
+ * import { createAgentServer } from '@cicctencent/agent-server';
128
+ *
129
+ * const server = createAgentServer({
130
+ * llmProvider: myProvider,
131
+ * dataDir: './data', // 使用默认 JSON 文件存储
132
+ * });
133
+ * ```
134
+ *
135
+ * ### 2. 自定义存储(数据库)
136
+ *
137
+ * ```typescript
138
+ * import { createAgentServer, DatabaseListStorage, type ChatStoreProvider } from '@cicctencent/agent-server';
139
+ *
140
+ * // 实现数据库存储
141
+ * class TypeORMThreadStorage extends DatabaseListStorage<ThreadEntity> {
142
+ * constructor(private repository: Repository<ThreadEntity>) {
143
+ * super();
144
+ * }
145
+ * async list() { return this.repository.find(); }
146
+ * async findById(id) { return this.repository.findOne({ where: { id } }); }
147
+ * async add(entity) { return this.repository.save(entity); }
148
+ * // ...
149
+ * }
150
+ *
151
+ * // 实现 ChatStoreProvider
152
+ * class TypeORMChatStoreProvider implements ChatStoreProvider {
153
+ * constructor(private threadRepo: Repository<ThreadEntity>, private msgRepo: Repository<MessageEntity>) {}
154
+ * getThreads() { return this.threadRepo.find(); }
155
+ * // ...
156
+ * }
157
+ *
158
+ * const server = createAgentServer({
159
+ * llmProvider: myProvider,
160
+ * chatStoreProvider: new TypeORMChatStoreProvider(threadRepo, msgRepo),
161
+ * });
162
+ * ```
163
+ *
164
+ * ### 3. 自定义框架适配(MidwayJS)
165
+ *
166
+ * ```typescript
167
+ * import { createAgentServer, KoaSSEAdapter } from '@cicctencent/agent-server';
168
+ *
169
+ * @Provide()
170
+ * @Scope(ScopeEnum.Singleton)
171
+ * export class AgentService {
172
+ * private server: AgentServer;
173
+ *
174
+ * @Init()
175
+ * async init() {
176
+ * this.server = createAgentServer({
177
+ * llmProvider: await this.createProvider(),
178
+ * // 使用 Koa 适配器
179
+ * createSSEResponseAdapter: (ctx) => new KoaSSEAdapter(ctx),
180
+ * });
181
+ * }
182
+ *
183
+ * @Get('/chat/stream')
184
+ * async chatStream(@Ctx() ctx: Context) {
185
+ * const adapter = new KoaSSEAdapter(ctx);
186
+ * await this.server.runAgentStream(adapter, { content: ctx.query.message });
187
+ * }
188
+ * }
189
+ * ```
190
+ *
191
+ * ### 4. 自定义 Prompt 构建
192
+ *
193
+ * ```typescript
194
+ * import { createAgentServer, type PromptBuilderProvider } from '@cicctencent/agent-server';
195
+ *
196
+ * class CustomPromptBuilder implements PromptBuilderProvider {
197
+ * buildDefaultPrompt(profile, tools, memory) {
198
+ * // 自定义 Prompt 构建逻辑
199
+ * return `你是一个专业的 BI 分析助手...\n${memory || ''}`;
200
+ * }
201
+ * // ...
202
+ * }
203
+ *
204
+ * const server = createAgentServer({
205
+ * llmProvider: myProvider,
206
+ * promptBuilder: new CustomPromptBuilder(),
207
+ * });
208
+ * ```
209
+ *
210
+ * ### 5. 组件级使用(不使用工厂)
211
+ *
212
+ * ```typescript
213
+ * import { MemoryService, writeSSE, createBuiltinTools, KoaSSEAdapter } from '@cicctencent/agent-server';
214
+ *
215
+ * // 只使用需要的组件,不依赖 createAgentServer
216
+ * const memoryService = new MemoryService('./data');
217
+ * const tools = createBuiltinTools();
218
+ *
219
+ * // 在 MidwayJS 中使用 SSE
220
+ * @Get('/stream')
221
+ * async stream(@Ctx() ctx: Context) {
222
+ * const adapter = new KoaSSEAdapter(ctx);
223
+ * writeSSE(adapter, 'start', { message: 'Hello' });
224
+ * }
225
+ * ```
226
+ */
227
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/spi/index.ts"],"names":[],"mappings":";AAAA,+DAA+D;AAC/D,WAAW;AACX,+DAA+D;AAC/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmFG;;;AAsCH,wBAAwB;AACxB,2CAesB;AAdpB,kBAAkB;AAClB,+GAAA,iBAAiB,OAAA;AACjB,iHAAA,mBAAmB,OAAA;AAEnB,YAAY;AACZ,+GAAA,iBAAiB,OAAA;AACjB,iHAAA,mBAAmB,OAAA;AAEnB,iBAAiB;AACjB,iHAAA,mBAAmB,OAAA;AAEnB,OAAO;AACP,mHAAA,qBAAqB,OAAA;AACrB,mHAAA,qBAAqB,OAAA;AAGvB,wBAAwB;AACxB,6CAeuB;AAdrB,UAAU;AACV,gHAAA,iBAAiB,OAAA;AACjB,4GAAA,aAAa,OAAA;AACb,gHAAA,iBAAiB,OAAA;AACjB,mHAAA,oBAAoB,OAAA;AACpB,uGAAA,QAAQ,OAAA;AAER,QAAQ;AACR,oHAAA,qBAAqB,OAAA;AACrB,gHAAA,iBAAiB,OAAA;AACjB,2GAAA,YAAY,OAAA;AAEZ,WAAW;AACX,+GAAA,gBAAgB,OAAA;AAGlB,+DAA+D;AAC/D,WAAW;AACX,+DAA+D;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyGG"}
@@ -0,0 +1,109 @@
1
+ import type { KVStorageAdapter, ListStorageAdapter, QueryOptions } from './types.js';
2
+ /**
3
+ * JSON 文件键值存储
4
+ * 适用于小型应用、本地开发
5
+ */
6
+ export declare class JsonFileKVStorage implements KVStorageAdapter {
7
+ private filePath;
8
+ private cache;
9
+ constructor(filePath: string);
10
+ private load;
11
+ private save;
12
+ get<T>(key: string): Promise<T | null>;
13
+ set<T>(key: string, value: T): Promise<void>;
14
+ delete(key: string): Promise<void>;
15
+ exists(key: string): Promise<boolean>;
16
+ keys(prefix?: string): Promise<string[]>;
17
+ /** 清除缓存(用于重新加载) */
18
+ clearCache(): void;
19
+ }
20
+ /**
21
+ * JSON 文件列表存储
22
+ * 支持实体 CRUD 操作
23
+ */
24
+ export declare class JsonFileListStorage<T extends {
25
+ id: number | string;
26
+ }> implements ListStorageAdapter<T> {
27
+ private filePath;
28
+ private data;
29
+ constructor(filePath: string);
30
+ private load;
31
+ private save;
32
+ list(): Promise<T[]>;
33
+ findById(id: number | string): Promise<T | null>;
34
+ add(entity: T): Promise<T>;
35
+ update(id: number | string, data: Partial<T>): Promise<T | null>;
36
+ remove(id: number | string): Promise<boolean>;
37
+ batch(operations: Array<{
38
+ type: 'add' | 'update' | 'delete';
39
+ data: T | Partial<T>;
40
+ id?: number | string;
41
+ }>): Promise<void>;
42
+ /** 获取最大 ID */
43
+ maxId(): number;
44
+ /** 清除缓存 */
45
+ clearCache(): void;
46
+ /** 获取文件路径 */
47
+ getPath(): string;
48
+ }
49
+ /**
50
+ * 内存键值存储
51
+ * 适用于测试、临时数据
52
+ */
53
+ export declare class InMemoryKVStorage implements KVStorageAdapter {
54
+ private data;
55
+ get<T>(key: string): Promise<T | null>;
56
+ set<T>(key: string, value: T): Promise<void>;
57
+ delete(key: string): Promise<void>;
58
+ exists(key: string): Promise<boolean>;
59
+ keys(prefix?: string): Promise<string[]>;
60
+ /** 清空所有数据 */
61
+ clear(): void;
62
+ }
63
+ /**
64
+ * 内存列表存储
65
+ */
66
+ export declare class InMemoryListStorage<T extends {
67
+ id: number | string;
68
+ }> implements ListStorageAdapter<T> {
69
+ private data;
70
+ list(): Promise<T[]>;
71
+ findById(id: number | string): Promise<T | null>;
72
+ add(entity: T): Promise<T>;
73
+ update(id: number | string, data: Partial<T>): Promise<T | null>;
74
+ remove(id: number | string): Promise<boolean>;
75
+ /** 清空所有数据 */
76
+ clear(): void;
77
+ }
78
+ /**
79
+ * 数据库存储基类
80
+ * 应用层继承并实现具体的数据库操作(TypeORM / Prisma / Sequelize 等)
81
+ */
82
+ export declare abstract class DatabaseListStorage<T extends {
83
+ id: number | string;
84
+ }> implements ListStorageAdapter<T> {
85
+ abstract list(): Promise<T[]>;
86
+ abstract findById(id: number | string): Promise<T | null>;
87
+ abstract add(entity: T): Promise<T>;
88
+ abstract update(id: number | string, data: Partial<T>): Promise<T | null>;
89
+ abstract remove(id: number | string): Promise<boolean>;
90
+ /** 扩展:带查询条件的列表 */
91
+ query(options: QueryOptions): Promise<{
92
+ items: T[];
93
+ total: number;
94
+ hasMore: boolean;
95
+ }>;
96
+ }
97
+ /**
98
+ * 创建 JSON 文件存储
99
+ */
100
+ export declare function createJsonFileStorage(filePath: string, type: 'kv' | 'list'): KVStorageAdapter | ListStorageAdapter<{
101
+ id: number | string;
102
+ }>;
103
+ /**
104
+ * 创建内存存储
105
+ */
106
+ export declare function createInMemoryStorage(type: 'kv' | 'list'): KVStorageAdapter | ListStorageAdapter<{
107
+ id: number | string;
108
+ }>;
109
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/spi/storage.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAMrF;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,gBAAgB;IACxD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAAqC;gBAEtC,QAAQ,EAAE,MAAM;IAI5B,OAAO,CAAC,IAAI;IAeZ,OAAO,CAAC,IAAI;IAON,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAKtC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAM9C,mBAAmB;IACnB,UAAU,IAAI,IAAI;CAGnB;AAED;;;GAGG;AACH,qBAAa,mBAAmB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAE,YAAW,kBAAkB,CAAC,CAAC,CAAC;IAClG,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,IAAI,CAAoB;gBAEpB,QAAQ,EAAE,MAAM;IAI5B,OAAO,CAAC,IAAI;IAcZ,OAAO,CAAC,IAAI;IAON,IAAI,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC;IAIpB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAKhD,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAM1B,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAShE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS7C,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;QAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBhI,cAAc;IACd,KAAK,IAAI,MAAM;IAOf,WAAW;IACX,UAAU,IAAI,IAAI;IAIlB,aAAa;IACb,OAAO,IAAI,MAAM;CAGlB;AAMD;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,gBAAgB;IACxD,OAAO,CAAC,IAAI,CAAmC;IAEzC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAItC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAM9C,aAAa;IACb,KAAK,IAAI,IAAI;CAGd;AAED;;GAEG;AACH,qBAAa,mBAAmB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAE,YAAW,kBAAkB,CAAC,CAAC,CAAC;IAClG,OAAO,CAAC,IAAI,CAAW;IAEjB,IAAI,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC;IAIpB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAKhD,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAK1B,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAOhE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOnD,aAAa;IACb,KAAK,IAAI,IAAI;CAGd;AAMD;;;GAGG;AACH,8BAAsB,mBAAmB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAE,YAAW,kBAAkB,CAAC,CAAC,CAAC;IAC3G,QAAQ,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IACzD,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAEtD,kBAAkB;IACZ,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CAkC7F;AAMD;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,IAAI,GAAG,MAAM,GAClB,gBAAgB,GAAG,kBAAkB,CAAC;IAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC,CAKhE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,IAAI,GAAG,MAAM,GAClB,gBAAgB,GAAG,kBAAkB,CAAC;IAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC,CAKhE"}
@@ -0,0 +1,344 @@
1
+ "use strict";
2
+ // ============================================================
3
+ // 存储适配器实现 — 应用层可替换底层存储
4
+ // ============================================================
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.DatabaseListStorage = exports.InMemoryListStorage = exports.InMemoryKVStorage = exports.JsonFileListStorage = exports.JsonFileKVStorage = void 0;
40
+ exports.createJsonFileStorage = createJsonFileStorage;
41
+ exports.createInMemoryStorage = createInMemoryStorage;
42
+ const fs = __importStar(require("fs"));
43
+ const path = __importStar(require("path"));
44
+ // ============================================================
45
+ // JSON 文件存储(默认实现)
46
+ // ============================================================
47
+ /**
48
+ * JSON 文件键值存储
49
+ * 适用于小型应用、本地开发
50
+ */
51
+ class JsonFileKVStorage {
52
+ filePath;
53
+ cache = null;
54
+ constructor(filePath) {
55
+ this.filePath = filePath;
56
+ }
57
+ load() {
58
+ if (this.cache)
59
+ return this.cache;
60
+ try {
61
+ if (fs.existsSync(this.filePath)) {
62
+ const data = JSON.parse(fs.readFileSync(this.filePath, 'utf-8'));
63
+ this.cache = new Map(Object.entries(data));
64
+ }
65
+ else {
66
+ this.cache = new Map();
67
+ }
68
+ }
69
+ catch {
70
+ this.cache = new Map();
71
+ }
72
+ return this.cache;
73
+ }
74
+ save() {
75
+ if (!this.cache)
76
+ return;
77
+ const dir = path.dirname(this.filePath);
78
+ if (!fs.existsSync(dir))
79
+ fs.mkdirSync(dir, { recursive: true });
80
+ fs.writeFileSync(this.filePath, JSON.stringify(Object.fromEntries(this.cache), null, 2));
81
+ }
82
+ async get(key) {
83
+ const data = this.load();
84
+ return data.get(key) ?? null;
85
+ }
86
+ async set(key, value) {
87
+ this.load().set(key, value);
88
+ this.save();
89
+ }
90
+ async delete(key) {
91
+ this.load().delete(key);
92
+ this.save();
93
+ }
94
+ async exists(key) {
95
+ return this.load().has(key);
96
+ }
97
+ async keys(prefix) {
98
+ const allKeys = Array.from(this.load().keys());
99
+ if (prefix)
100
+ return allKeys.filter(k => k.startsWith(prefix));
101
+ return allKeys;
102
+ }
103
+ /** 清除缓存(用于重新加载) */
104
+ clearCache() {
105
+ this.cache = null;
106
+ }
107
+ }
108
+ exports.JsonFileKVStorage = JsonFileKVStorage;
109
+ /**
110
+ * JSON 文件列表存储
111
+ * 支持实体 CRUD 操作
112
+ */
113
+ class JsonFileListStorage {
114
+ filePath;
115
+ data = null;
116
+ constructor(filePath) {
117
+ this.filePath = filePath;
118
+ }
119
+ load() {
120
+ if (this.data)
121
+ return this.data;
122
+ try {
123
+ if (fs.existsSync(this.filePath)) {
124
+ this.data = JSON.parse(fs.readFileSync(this.filePath, 'utf-8'));
125
+ }
126
+ else {
127
+ this.data = [];
128
+ }
129
+ }
130
+ catch {
131
+ this.data = [];
132
+ }
133
+ return this.data;
134
+ }
135
+ save() {
136
+ if (!this.data)
137
+ return;
138
+ const dir = path.dirname(this.filePath);
139
+ if (!fs.existsSync(dir))
140
+ fs.mkdirSync(dir, { recursive: true });
141
+ fs.writeFileSync(this.filePath, JSON.stringify(this.data, null, 2));
142
+ }
143
+ async list() {
144
+ return [...this.load()];
145
+ }
146
+ async findById(id) {
147
+ const item = this.load().find(item => item.id === id);
148
+ return item ?? null;
149
+ }
150
+ async add(entity) {
151
+ this.load().push(entity);
152
+ this.save();
153
+ return entity;
154
+ }
155
+ async update(id, data) {
156
+ const items = this.load();
157
+ const idx = items.findIndex(item => item.id === id);
158
+ if (idx === -1)
159
+ return null;
160
+ items[idx] = { ...items[idx], ...data };
161
+ this.save();
162
+ return items[idx];
163
+ }
164
+ async remove(id) {
165
+ const items = this.load();
166
+ const idx = items.findIndex(item => item.id === id);
167
+ if (idx === -1)
168
+ return false;
169
+ items.splice(idx, 1);
170
+ this.save();
171
+ return true;
172
+ }
173
+ async batch(operations) {
174
+ const items = this.load();
175
+ for (const op of operations) {
176
+ if (op.type === 'add') {
177
+ items.push(op.data);
178
+ }
179
+ else if (op.type === 'update' && op.id) {
180
+ const idx = items.findIndex(item => item.id === op.id);
181
+ if (idx !== -1)
182
+ items[idx] = { ...items[idx], ...op.data };
183
+ }
184
+ else if (op.type === 'delete' && op.id) {
185
+ const idx = items.findIndex(item => item.id === op.id);
186
+ if (idx !== -1)
187
+ items.splice(idx, 1);
188
+ }
189
+ }
190
+ this.save();
191
+ }
192
+ /** 获取最大 ID */
193
+ maxId() {
194
+ const items = this.load();
195
+ if (items.length === 0)
196
+ return 0;
197
+ const ids = items.map(item => typeof item.id === 'number' ? item.id : parseInt(String(item.id), 10) || 0);
198
+ return Math.max(...ids);
199
+ }
200
+ /** 清除缓存 */
201
+ clearCache() {
202
+ this.data = null;
203
+ }
204
+ /** 获取文件路径 */
205
+ getPath() {
206
+ return this.filePath;
207
+ }
208
+ }
209
+ exports.JsonFileListStorage = JsonFileListStorage;
210
+ // ============================================================
211
+ // 内存存储(测试用)
212
+ // ============================================================
213
+ /**
214
+ * 内存键值存储
215
+ * 适用于测试、临时数据
216
+ */
217
+ class InMemoryKVStorage {
218
+ data = new Map();
219
+ async get(key) {
220
+ return this.data.get(key) ?? null;
221
+ }
222
+ async set(key, value) {
223
+ this.data.set(key, value);
224
+ }
225
+ async delete(key) {
226
+ this.data.delete(key);
227
+ }
228
+ async exists(key) {
229
+ return this.data.has(key);
230
+ }
231
+ async keys(prefix) {
232
+ const allKeys = Array.from(this.data.keys());
233
+ if (prefix)
234
+ return allKeys.filter(k => k.startsWith(prefix));
235
+ return allKeys;
236
+ }
237
+ /** 清空所有数据 */
238
+ clear() {
239
+ this.data.clear();
240
+ }
241
+ }
242
+ exports.InMemoryKVStorage = InMemoryKVStorage;
243
+ /**
244
+ * 内存列表存储
245
+ */
246
+ class InMemoryListStorage {
247
+ data = [];
248
+ async list() {
249
+ return [...this.data];
250
+ }
251
+ async findById(id) {
252
+ const item = this.data.find(item => item.id === id);
253
+ return item ?? null;
254
+ }
255
+ async add(entity) {
256
+ this.data.push(entity);
257
+ return entity;
258
+ }
259
+ async update(id, data) {
260
+ const idx = this.data.findIndex(item => item.id === id);
261
+ if (idx === -1)
262
+ return null;
263
+ this.data[idx] = { ...this.data[idx], ...data };
264
+ return this.data[idx];
265
+ }
266
+ async remove(id) {
267
+ const idx = this.data.findIndex(item => item.id === id);
268
+ if (idx === -1)
269
+ return false;
270
+ this.data.splice(idx, 1);
271
+ return true;
272
+ }
273
+ /** 清空所有数据 */
274
+ clear() {
275
+ this.data = [];
276
+ }
277
+ }
278
+ exports.InMemoryListStorage = InMemoryListStorage;
279
+ // ============================================================
280
+ // 数据库存储抽象(应用层实现)
281
+ // ============================================================
282
+ /**
283
+ * 数据库存储基类
284
+ * 应用层继承并实现具体的数据库操作(TypeORM / Prisma / Sequelize 等)
285
+ */
286
+ class DatabaseListStorage {
287
+ /** 扩展:带查询条件的列表 */
288
+ async query(options) {
289
+ const all = await this.list();
290
+ let filtered = all;
291
+ // 应用过滤器
292
+ if (options.filter) {
293
+ filtered = filtered.filter(item => {
294
+ for (const [key, value] of Object.entries(options.filter)) {
295
+ if (item[key] !== value)
296
+ return false;
297
+ }
298
+ return true;
299
+ });
300
+ }
301
+ // 排序
302
+ if (options.orderBy) {
303
+ filtered.sort((a, b) => {
304
+ const aVal = a[options.orderBy];
305
+ const bVal = b[options.orderBy];
306
+ if (aVal < bVal)
307
+ return options.orderDirection === 'desc' ? 1 : -1;
308
+ if (aVal > bVal)
309
+ return options.orderDirection === 'desc' ? -1 : 1;
310
+ return 0;
311
+ });
312
+ }
313
+ // 分页
314
+ const total = filtered.length;
315
+ const offset = options.offset ?? 0;
316
+ const limit = options.limit ?? 50;
317
+ const items = filtered.slice(offset, offset + limit);
318
+ const hasMore = offset + items.length < total;
319
+ return { items, total, hasMore };
320
+ }
321
+ }
322
+ exports.DatabaseListStorage = DatabaseListStorage;
323
+ // ============================================================
324
+ // 存储工厂函数
325
+ // ============================================================
326
+ /**
327
+ * 创建 JSON 文件存储
328
+ */
329
+ function createJsonFileStorage(filePath, type) {
330
+ if (type === 'kv') {
331
+ return new JsonFileKVStorage(filePath);
332
+ }
333
+ return new JsonFileListStorage(filePath);
334
+ }
335
+ /**
336
+ * 创建内存存储
337
+ */
338
+ function createInMemoryStorage(type) {
339
+ if (type === 'kv') {
340
+ return new InMemoryKVStorage();
341
+ }
342
+ return new InMemoryListStorage();
343
+ }
344
+ //# sourceMappingURL=storage.js.map