web-dc-api 0.1.5 → 0.1.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.
Files changed (148) hide show
  1. package/dist/cjs/index.js +1 -1
  2. package/dist/dc.min.js +1 -1
  3. package/dist/esm/index.js +1 -1
  4. package/dist/index.d.ts +934 -878
  5. package/package.json +4 -8
  6. package/dist/cjs/helia-core-B1Xqha7a.js +0 -1
  7. package/dist/cjs/helia-core-D8Uv1KjQ.js +0 -1
  8. package/dist/cjs/polkadot-api-7PhQf3ws.js +0 -1
  9. package/dist/cjs/polkadot-api-CtrJVWuZ.js +0 -1
  10. package/dist/esm/chunks/helia-core-BxMqyK2Y.js +0 -1
  11. package/dist/esm/chunks/helia-core-DMXRpcO-.js +0 -1
  12. package/dist/esm/chunks/polkadot-api-5Y9Bw8VT.js +0 -1
  13. package/dist/esm/chunks/polkadot-api-D69Ioun_.js +0 -1
  14. package/lib/common/blowfish/block.ts +0 -259
  15. package/lib/common/blowfish/cipher.ts +0 -144
  16. package/lib/common/blowfish/const.ts +0 -195
  17. package/lib/common/chain.ts +0 -469
  18. package/lib/common/commonclient.ts +0 -202
  19. package/lib/common/constants.ts +0 -55
  20. package/lib/common/dc-key/ed25519.ts +0 -343
  21. package/lib/common/dc-key/keyManager.ts +0 -424
  22. package/lib/common/dcapi.ts +0 -98
  23. package/lib/common/dcutil.ts +0 -627
  24. package/lib/common/define.ts +0 -70
  25. package/lib/common/error.ts +0 -67
  26. package/lib/common/grpc-dc.ts +0 -104
  27. package/lib/common/module-system.ts +0 -184
  28. package/lib/common/service-worker.ts +0 -234
  29. package/lib/common/types/types.ts +0 -344
  30. package/lib/dc.ts +0 -701
  31. package/lib/implements/account/client.ts +0 -185
  32. package/lib/implements/account/manager.ts +0 -683
  33. package/lib/implements/aiproxy/client.ts +0 -357
  34. package/lib/implements/aiproxy/manager.ts +0 -670
  35. package/lib/implements/cache/client.ts +0 -105
  36. package/lib/implements/cache/manager.ts +0 -127
  37. package/lib/implements/comment/client.ts +0 -982
  38. package/lib/implements/comment/manager.ts +0 -1151
  39. package/lib/implements/dc/client.ts +0 -51
  40. package/lib/implements/dc/manager.ts +0 -33
  41. package/lib/implements/file/client.ts +0 -253
  42. package/lib/implements/file/file-cache-manager.ts +0 -142
  43. package/lib/implements/file/manager.ts +0 -1240
  44. package/lib/implements/file/seekableFileStream.ts +0 -344
  45. package/lib/implements/file/streamwriter.ts +0 -322
  46. package/lib/implements/keyvalue/client.ts +0 -376
  47. package/lib/implements/keyvalue/manager.ts +0 -759
  48. package/lib/implements/message/client.ts +0 -250
  49. package/lib/implements/message/manager.ts +0 -215
  50. package/lib/implements/threaddb/cbor/coding.ts +0 -62
  51. package/lib/implements/threaddb/cbor/event.ts +0 -336
  52. package/lib/implements/threaddb/cbor/node.ts +0 -542
  53. package/lib/implements/threaddb/cbor/record.ts +0 -398
  54. package/lib/implements/threaddb/common/AsyncMutex.ts +0 -24
  55. package/lib/implements/threaddb/common/addrinfo.ts +0 -135
  56. package/lib/implements/threaddb/common/dispatcher.ts +0 -81
  57. package/lib/implements/threaddb/common/idbstore-adapter.ts +0 -260
  58. package/lib/implements/threaddb/common/json-patcher.ts +0 -204
  59. package/lib/implements/threaddb/common/key.ts +0 -290
  60. package/lib/implements/threaddb/common/level-adapter.ts +0 -235
  61. package/lib/implements/threaddb/common/lineReader.ts +0 -79
  62. package/lib/implements/threaddb/common/logstore.ts +0 -215
  63. package/lib/implements/threaddb/common/transformed-datastore.ts +0 -308
  64. package/lib/implements/threaddb/core/app.ts +0 -206
  65. package/lib/implements/threaddb/core/core.ts +0 -230
  66. package/lib/implements/threaddb/core/db.ts +0 -249
  67. package/lib/implements/threaddb/core/event.ts +0 -54
  68. package/lib/implements/threaddb/core/head.ts +0 -89
  69. package/lib/implements/threaddb/core/identity.ts +0 -171
  70. package/lib/implements/threaddb/core/logstore.ts +0 -137
  71. package/lib/implements/threaddb/core/options.ts +0 -14
  72. package/lib/implements/threaddb/core/record.ts +0 -54
  73. package/lib/implements/threaddb/db/collection.ts +0 -1910
  74. package/lib/implements/threaddb/db/db.ts +0 -698
  75. package/lib/implements/threaddb/db/json2Query.ts +0 -192
  76. package/lib/implements/threaddb/db/query.ts +0 -524
  77. package/lib/implements/threaddb/dbclient.ts +0 -543
  78. package/lib/implements/threaddb/dbmanager.ts +0 -1906
  79. package/lib/implements/threaddb/lsstoreds/addr_book.ts +0 -549
  80. package/lib/implements/threaddb/lsstoreds/cache.ts +0 -36
  81. package/lib/implements/threaddb/lsstoreds/cyclic_batch.ts +0 -87
  82. package/lib/implements/threaddb/lsstoreds/global.ts +0 -151
  83. package/lib/implements/threaddb/lsstoreds/headbook.ts +0 -373
  84. package/lib/implements/threaddb/lsstoreds/keybook.ts +0 -297
  85. package/lib/implements/threaddb/lsstoreds/logstore.ts +0 -29
  86. package/lib/implements/threaddb/lsstoreds/metadata.ts +0 -223
  87. package/lib/implements/threaddb/net/define.ts +0 -149
  88. package/lib/implements/threaddb/net/grpcClient.ts +0 -589
  89. package/lib/implements/threaddb/net/grpcserver.ts +0 -146
  90. package/lib/implements/threaddb/net/net.ts +0 -2047
  91. package/lib/implements/threaddb/pb/lstore.proto +0 -38
  92. package/lib/implements/threaddb/pb/lstore.ts +0 -393
  93. package/lib/implements/threaddb/pb/lstore_pb.d.ts +0 -433
  94. package/lib/implements/threaddb/pb/lstore_pb.js +0 -1085
  95. package/lib/implements/threaddb/pb/net.proto +0 -194
  96. package/lib/implements/threaddb/pb/net_pb.d.ts +0 -2349
  97. package/lib/implements/threaddb/pb/net_pb.js +0 -5525
  98. package/lib/implements/threaddb/pb/proto-custom-types.ts +0 -212
  99. package/lib/implements/util/client.ts +0 -72
  100. package/lib/implements/util/manager.ts +0 -146
  101. package/lib/implements/wallet/manager.ts +0 -671
  102. package/lib/index.ts +0 -57
  103. package/lib/interfaces/DCContext.ts +0 -51
  104. package/lib/interfaces/aiproxy-interface.ts +0 -145
  105. package/lib/interfaces/auth-interface.ts +0 -118
  106. package/lib/interfaces/cache-interface.ts +0 -22
  107. package/lib/interfaces/client-interface.ts +0 -11
  108. package/lib/interfaces/comment-interface.ts +0 -167
  109. package/lib/interfaces/components/news-component.ts +0 -0
  110. package/lib/interfaces/database-interface.ts +0 -169
  111. package/lib/interfaces/file-interface.ts +0 -120
  112. package/lib/interfaces/index.ts +0 -10
  113. package/lib/interfaces/keyvalue-interface.ts +0 -156
  114. package/lib/interfaces/message-interface.ts +0 -22
  115. package/lib/interfaces/util-interface.ts +0 -31
  116. package/lib/modules/aiproxy-module.ts +0 -246
  117. package/lib/modules/auth-module.ts +0 -753
  118. package/lib/modules/cache-module.ts +0 -99
  119. package/lib/modules/client-module.ts +0 -71
  120. package/lib/modules/comment-module.ts +0 -429
  121. package/lib/modules/components/news-components.ts +0 -390
  122. package/lib/modules/database-module.ts +0 -598
  123. package/lib/modules/file-module.ts +0 -291
  124. package/lib/modules/index.ts +0 -13
  125. package/lib/modules/keyvalue-module.ts +0 -379
  126. package/lib/modules/message-module.ts +0 -107
  127. package/lib/modules/util-module.ts +0 -148
  128. package/lib/polyfills/process-env-browser.ts +0 -1
  129. package/lib/proto/datasource.ts +0 -93
  130. package/lib/proto/dcnet.proto +0 -1601
  131. package/lib/proto/dcnet_proto.d.ts +0 -22857
  132. package/lib/proto/dcnet_proto.js +0 -55204
  133. package/lib/proto/dcnet_proto_sparse.js +0 -55166
  134. package/lib/proto/oidfetch.proto +0 -25
  135. package/lib/proto/oidfetch_proto.d.ts +0 -585
  136. package/lib/proto/oidfetch_proto.js +0 -1247
  137. package/lib/serverless/babel-browser.ts +0 -39
  138. package/lib/serverless/base_entity.ts +0 -78
  139. package/lib/serverless/base_repository.ts +0 -414
  140. package/lib/serverless/browser_schema_extractor.ts +0 -283
  141. package/lib/serverless/decorator_factory.ts +0 -322
  142. package/lib/util/BrowserLineReader.ts +0 -73
  143. package/lib/util/base64.ts +0 -105
  144. package/lib/util/bcrypt.ts +0 -206
  145. package/lib/util/curve25519Encryption.ts +0 -418
  146. package/lib/util/dccrypt.ts +0 -73
  147. package/lib/util/logger.ts +0 -104
  148. package/lib/util/utils.ts +0 -289
@@ -1,283 +0,0 @@
1
- import "../polyfills/process-env-browser";
2
- import type { NodePath, Visitor } from "@babel/traverse";
3
- import type * as T from "@babel/types";
4
- import { loadBabel } from "./babel-browser";
5
-
6
- export type PrintableSchema = {
7
- entityName: string;
8
- namespace?: string;
9
- ttlSeconds?: number;
10
- versioned?: boolean;
11
- columns: Array<{
12
- name: string;
13
- type?: string;
14
- required?: boolean;
15
- unique?: boolean;
16
- index?: boolean;
17
- default?: unknown;
18
- }>;
19
- indexes: Array<{
20
- name: string;
21
- fields: Array<{ field: string; order: "asc" | "desc" }>;
22
- unique?: boolean;
23
- ttlSeconds?: number;
24
- }>;
25
- };
26
-
27
- interface FileContentMap {
28
- [fileName: string]: string;
29
- }
30
-
31
- export async function extractSchemasFromSources(sources: FileContentMap): Promise<PrintableSchema[]> {
32
- const { parse, t, traverse } = await loadBabel();
33
- const result: PrintableSchema[] = [];
34
-
35
- // 解析源码(优先标准装饰器,失败回退 legacy)
36
- function tryParse(code: string) {
37
- const common = {
38
- sourceType: "module" as const,
39
- errorRecovery: true,
40
- plugins: ["typescript"] as any[],
41
- };
42
- try {
43
- return parse(code, {
44
- ...common,
45
- plugins: [
46
- ["decorators", { decoratorsBeforeExport: true }],
47
- "classProperties",
48
- "classPrivateProperties",
49
- ...common.plugins,
50
- ],
51
- } as any);
52
- } catch {
53
- return parse(code, {
54
- ...common,
55
- plugins: [
56
- "decorators-legacy",
57
- "classProperties",
58
- "classPrivateProperties",
59
- ...common.plugins,
60
- ],
61
- } as any);
62
- }
63
- }
64
-
65
- // 将装饰器参数表达式转 JS 值(常见字面量/对象/数组)
66
- function exprToValue(node: any): any {
67
- if (!node) return undefined;
68
- if (t.isStringLiteral(node) || t.isNumericLiteral(node) || t.isBooleanLiteral(node)) return (node as any).value;
69
- if (t.isNullLiteral(node)) return null;
70
- if (t.isIdentifier(node) && (node.name === "undefined")) return undefined;
71
- if (t.isObjectExpression(node)) {
72
- const obj: any = {};
73
- for (const p of node.properties) {
74
- if (t.isObjectProperty(p)) {
75
- const key = t.isIdentifier(p.key) ? p.key.name : t.isStringLiteral(p.key) ? p.key.value : undefined;
76
- if (!key) continue;
77
- obj[key] = exprToValue(p.value as any);
78
- }
79
- }
80
- return obj;
81
- }
82
- if (t.isArrayExpression(node)) return node.elements.map((e: any) => exprToValue(e ));
83
- return undefined;
84
- }
85
-
86
- // 规范化索引字段
87
- function normIndexFields(fields: any, fallbackField?: string): Array<{ field: string; order: "asc" | "desc" }> {
88
- const out: Array<{ field: string; order: "asc" | "desc" }> = [];
89
- const arr = Array.isArray(fields) ? fields : (fields ? [fields] : []);
90
- if (arr.length === 0 && fallbackField) return [{ field: fallbackField, order: "asc" }];
91
- for (const it of arr) {
92
- if (typeof it === "string") out.push({ field: it, order: "asc" });
93
- else if (it && typeof it === "object" && typeof it.field === "string") {
94
- out.push({ field: it.field, order: it.order === "desc" ? "desc" : "asc" });
95
- }
96
- }
97
- return out;
98
- }
99
-
100
- // 默认索引名
101
- function defaultIndexName(fields: Array<{ field: string; order: "asc" | "desc" }>) {
102
- const seg = fields.map(f => f.field + (f.order === "desc" ? "_desc" : "")).join("_");
103
- return `idx_${seg}`;
104
- }
105
-
106
- // 去重 key
107
- function indexKey(name: string | undefined, fields: Array<{ field: string; order: "asc" | "desc" }>) {
108
- const seg = fields.map(f => `${f.field}:${f.order}`).join(",");
109
- return `${name ?? defaultIndexName(fields)}|${seg}`;
110
- }
111
-
112
- // 装饰器名/参数
113
- function getDecoratorName(dec: any): string | undefined {
114
- const ex = dec.expression;
115
- if (t.isIdentifier(ex)) return ex.name;
116
- if (t.isCallExpression(ex) && t.isIdentifier(ex.callee)) return ex.callee.name;
117
- return undefined;
118
- }
119
- function getDecoratorArgs(dec: any): any[] {
120
- const ex = dec.expression;
121
- if (t.isCallExpression(ex)) return ex.arguments.map((arg: any) => exprToValue(arg as any));
122
- return [];
123
- }
124
-
125
- // 统一处理类(ClassDeclaration / ClassExpression)
126
- const visitClass = (path: NodePath<T.ClassDeclaration | T.ClassExpression>) => {
127
- const node = path.node as any;
128
- const className = (node.id && node.id.name) || "AnonymousClass";
129
- const decorators: any[] = node.decorators ?? [];
130
-
131
- // 解析 @Entity
132
- let entityName = className;
133
- let entityOpts: any = {};
134
- for (const d of decorators) {
135
- const name = getDecoratorName(d);
136
- if (name === "Entity") {
137
- const [opt] = getDecoratorArgs(d);
138
- if (opt && typeof opt === "object") {
139
- entityOpts = opt;
140
- if (typeof opt.name === "string") entityName = opt.name;
141
- }
142
- }
143
- }
144
-
145
- // 字段与字段级装饰器
146
- const columns: PrintableSchema["columns"] = [];
147
- const fieldLevelIndexes: PrintableSchema["indexes"] = [];
148
-
149
- for (const m of node.body.body as any[]) {
150
- const isClassProp = (t as any).isClassProperty?.(m) || (t as any).isPropertyDefinition?.(m);
151
- const isPrivateProp = (t as any).isClassPrivateProperty?.(m);
152
- if (!isClassProp && !isPrivateProp) continue;
153
-
154
- const keyNode = m.key;
155
- const key =
156
- t.isIdentifier(keyNode) ? keyNode.name :
157
- t.isStringLiteral(keyNode) ? keyNode.value :
158
- undefined;
159
- if (!key) continue;
160
-
161
- let columnOpts: any | undefined = undefined;
162
- const explicitIndexFromDecorator: any[] = [];
163
- const mDecos: any[] = m.decorators ?? [];
164
-
165
- for (const d of mDecos) {
166
- const dn = getDecoratorName(d);
167
- const args = getDecoratorArgs(d);
168
- if (dn === "Column") {
169
- columnOpts = args[0] && typeof args[0] === "object" ? args[0] : {};
170
- } else if (dn === "Index") {
171
- explicitIndexFromDecorator.push(args);
172
- }
173
- }
174
-
175
- const resolvedName = (columnOpts?.name as string) ?? key;
176
- columns.push({
177
- name: resolvedName,
178
- ...(columnOpts?.type !== undefined ? { type: columnOpts.type } : {}),
179
- ...(columnOpts?.required !== undefined ? { required: !!columnOpts.required } : {}),
180
- ...(columnOpts?.unique !== undefined ? { unique: !!columnOpts.unique } : {}),
181
- ...(columnOpts?.index !== undefined ? { index: !!columnOpts.index } : {}),
182
- ...(columnOpts?.default !== undefined ? { default: columnOpts.default } : {}),
183
- });
184
-
185
- // Column 的 index/unique → 单列索引
186
- if (columnOpts?.index || columnOpts?.unique) {
187
- const fields = [{ field: resolvedName, order: "asc" as const }];
188
- fieldLevelIndexes.push({
189
- name: defaultIndexName(fields),
190
- fields,
191
- ...(columnOpts?.unique ? { unique: true } : {}),
192
- });
193
- }
194
-
195
- // 字段级 @Index
196
- for (const args of explicitIndexFromDecorator) {
197
- let idxName: string | undefined;
198
- let idxFields: any;
199
- let idxUnique: boolean | undefined;
200
- let idxTTL: number | undefined;
201
- if (args.length === 0) {
202
- idxFields = [resolvedName];
203
- } else if (typeof args[0] === "string") {
204
- idxName = args[0];
205
- idxFields = args[1] ?? [resolvedName];
206
- } else if (typeof args[0] === "object") {
207
- idxName = args[0].name;
208
- idxFields = args[0].fields ?? [resolvedName];
209
- idxUnique = args[0].unique;
210
- idxTTL = args[0].ttlSeconds;
211
- }
212
- const fields = normIndexFields(idxFields, resolvedName);
213
- if (fields.length === 0) continue;
214
- const name2 = idxName ?? defaultIndexName(fields);
215
- fieldLevelIndexes.push({
216
- name: name2,
217
- fields,
218
- ...(idxUnique !== undefined ? { unique: !!idxUnique } : {}),
219
- ...(idxTTL !== undefined ? { ttlSeconds: idxTTL } : {}),
220
- });
221
- }
222
- }
223
-
224
- // 类级 @Index
225
- const classLevelIndexes: PrintableSchema["indexes"] = [];
226
- for (const d of decorators) {
227
- const dn = getDecoratorName(d);
228
- if (dn !== "Index") continue;
229
- const args = getDecoratorArgs(d);
230
- let idxName: string | undefined;
231
- let idxFields: any;
232
- let idxUnique: boolean | undefined;
233
- let idxTTL: number | undefined;
234
- if (args.length === 0) continue;
235
- else if (typeof args[0] === "string") {
236
- idxName = args[0]; idxFields = args[1] ?? [];
237
- } else if (typeof args[0] === "object") {
238
- idxName = args[0].name; idxFields = args[0].fields ?? [];
239
- idxUnique = args[0].unique; idxTTL = args[0].ttlSeconds;
240
- }
241
- const fields = normIndexFields(idxFields);
242
- if (fields.length === 0) continue;
243
- const name2 = idxName ?? defaultIndexName(fields);
244
- classLevelIndexes.push({
245
- name: name2,
246
- fields,
247
- ...(idxUnique !== undefined ? { unique: !!idxUnique } : {}),
248
- ...(idxTTL !== undefined ? { ttlSeconds: idxTTL } : {}),
249
- });
250
- }
251
-
252
- // 合并去重
253
- const allIndexes = [...fieldLevelIndexes, ...classLevelIndexes];
254
- const dedup = new Map<string, PrintableSchema["indexes"][number]>();
255
- for (const ix of allIndexes) {
256
- const key = indexKey(ix.name, ix.fields);
257
- if (!dedup.has(key)) dedup.set(key, ix);
258
- }
259
-
260
- const printable: PrintableSchema = {
261
- entityName: (entityOpts?.name as string) ?? entityName,
262
- ...(entityOpts?.namespace !== undefined ? { namespace: entityOpts.namespace } : {}),
263
- ...(entityOpts?.ttlSeconds !== undefined ? { ttlSeconds: entityOpts.ttlSeconds } : {}),
264
- ...(entityOpts?.versioned !== undefined ? { versioned: entityOpts.versioned } : {}),
265
- columns,
266
- indexes: Array.from(dedup.values()),
267
- };
268
-
269
- result.push(printable);
270
- };
271
-
272
- // 遍历每个文件的 AST
273
- for (const [, content] of Object.entries(sources)) {
274
- const ast = tryParse(content);
275
- const visitors: Visitor = {
276
- ClassDeclaration(path: NodePath<T.ClassDeclaration>) { visitClass(path); },
277
- ClassExpression(path: NodePath<T.ClassExpression>) { visitClass(path); },
278
- };
279
- traverse(ast as any, visitors);
280
- }
281
-
282
- return result;
283
- }
@@ -1,322 +0,0 @@
1
- /* Serverless-friendly decorators (TS 5 standard + legacy)
2
- - @Entity(options?)
3
- - @Column(options?)
4
- - @Index(nameOrOptions[, fields])
5
- */
6
-
7
- export type PrimitiveType = 'string' | 'number' | 'boolean' | 'date' | 'json' | 'binary';
8
-
9
- export interface EntityOptions {
10
- name?: string; // 实体名(默认类名)
11
- namespace?: string; // 可选命名空间/前缀
12
- ttlSeconds?: number; // 过期秒数,用于 serverless KV/缓存等
13
- versioned?: boolean; // 是否启用版本
14
- }
15
-
16
- export interface ColumnOptions<T = unknown> {
17
- name?: string; // 存储层字段名(默认属性名)
18
- type?: PrimitiveType; // 简化类型映射
19
- required?: boolean; // 是否必填
20
- default?: T | (() => T); // 默认值
21
- index?: boolean; // 单列索引
22
- unique?: boolean; // 唯一约束(需要底层支持)
23
- }
24
-
25
- export type IndexField =
26
- | string
27
- | { field: string; order?: 'asc' | 'desc' };
28
-
29
- export interface IndexOptions {
30
- name?: string;
31
- fields: IndexField[];
32
- unique?: boolean;
33
- ttlSeconds?: number;
34
- }
35
-
36
- export interface EntityMeta {
37
- target: Function;
38
- name: string;
39
- options: EntityOptions;
40
- }
41
-
42
- export interface ColumnMeta {
43
- target: Function;
44
- propertyKey: string | symbol;
45
- options: ColumnOptions;
46
- resolvedName: string;
47
- }
48
-
49
- export interface NormalizedIndexField {
50
- field: string;
51
- order: 'asc' | 'desc';
52
- }
53
-
54
- export interface IndexMeta {
55
- target: Function;
56
- name: string;
57
- fields: NormalizedIndexField[];
58
- unique?: boolean;
59
- ttlSeconds?: number;
60
- }
61
-
62
- type StdDecoratorContext = {
63
- kind: 'class' | 'field' | 'accessor' | 'method' | 'getter' | 'setter';
64
- name?: string | symbol;
65
- addInitializer?: (fn: () => void) => void;
66
- };
67
-
68
- function isStdCtx(v: unknown): v is StdDecoratorContext {
69
- return !!v && typeof v === 'object' && 'kind' in (v as any);
70
- }
71
-
72
- class MetadataStorage {
73
- private entities = new WeakMap<Function, EntityMeta>();
74
- private columns = new WeakMap<Function, Map<string | symbol, ColumnMeta>>();
75
- private indexes = new WeakMap<Function, IndexMeta[]>();
76
-
77
- registerEntity(target: Function, options: EntityOptions = {}, nameHint?: string) {
78
- const name = options.name ?? nameHint ?? target.name;
79
- const meta: EntityMeta = { target, name, options: { ...options, name } };
80
- this.entities.set(target, meta);
81
- return meta;
82
- }
83
-
84
- registerColumn(target: Function, propertyKey: string | symbol, options: ColumnOptions = {}) {
85
- const colMap = this.columns.get(target) ?? new Map();
86
- const resolvedName = options.name ?? String(propertyKey);
87
- const meta: ColumnMeta = { target, propertyKey, options, resolvedName };
88
- colMap.set(propertyKey, meta);
89
- this.columns.set(target, colMap);
90
- return meta;
91
- }
92
-
93
- registerIndex(target: Function, input: { name?: string; fields: IndexField[]; unique?: boolean; ttlSeconds?: number }) {
94
- if (!input.fields || input.fields.length === 0) {
95
- throw new Error('@Index requires at least one field');
96
- }
97
- const normalizedFields: NormalizedIndexField[] = input.fields.map(f =>
98
- typeof f === 'string' ? { field: f, order: 'asc' } : { field: f.field, order: f.order ?? 'asc' }
99
- );
100
- const name = input.name ?? this.defaultIndexName(normalizedFields);
101
-
102
- const arr = this.indexes.get(target) ?? [];
103
- const dedupKey = this.makeIndexKey(name, normalizedFields);
104
- const exists = arr.some(i => this.makeIndexKey(i.name, i.fields) === dedupKey);
105
-
106
- if (!exists) {
107
- const norm: IndexMeta = {
108
- target,
109
- name,
110
- fields: normalizedFields,
111
- ...(input.unique !== undefined ? { unique: input.unique } : {}),
112
- ...(input.ttlSeconds !== undefined ? { ttlSeconds: input.ttlSeconds } : {}),
113
- };
114
- arr.push(norm);
115
- this.indexes.set(target, arr);
116
- }
117
- }
118
-
119
- getEntity(target: Function | object): EntityMeta | undefined {
120
- const ctor = typeof target === 'function' ? target : (target as any)?.constructor;
121
- return this.entities.get(ctor);
122
- }
123
-
124
- getColumns(target: Function | object): ColumnMeta[] {
125
- const ctor = typeof target === 'function' ? target : (target as any)?.constructor;
126
- const map = this.columns.get(ctor);
127
- return map ? Array.from(map.values()) : [];
128
- }
129
-
130
- getIndexes(target: Function | object): IndexMeta[] {
131
- const ctor = typeof target === 'function' ? target : (target as any)?.constructor;
132
- return this.indexes.get(ctor) ?? [];
133
- }
134
-
135
- getSchema(target: Function | object) {
136
- return {
137
- entity: this.getEntity(target),
138
- columns: this.getColumns(target),
139
- indexes: this.getIndexes(target),
140
- };
141
- }
142
-
143
- private defaultIndexName(fields: NormalizedIndexField[]) {
144
- const part = fields.map(f => `${f.field}_${f.order}`).join('_');
145
- return `idx_${part}`;
146
- }
147
-
148
- private makeIndexKey(name: string, fields: NormalizedIndexField[]) {
149
- return `${name}|${fields.map(f => `${f.field}:${f.order}`).join(',')}`;
150
- }
151
- }
152
-
153
- export const metadata = new MetadataStorage();
154
-
155
- // ---------- Decorators (dual-mode: standard + legacy) ----------
156
-
157
- export function Entity(options: EntityOptions = {}) {
158
- // Standard: (value, context)
159
- // Legacy: (ctor)
160
- return function entityDecorator(valueOrTarget: any, maybeContext?: unknown) {
161
- if (isStdCtx(maybeContext) && maybeContext.kind === 'class') {
162
- const ctor = valueOrTarget as Function;
163
- metadata.registerEntity(ctor, options, maybeContext.name ? String(maybeContext.name) : undefined);
164
- return;
165
- }
166
- // Legacy
167
- const ctor = valueOrTarget as Function;
168
- metadata.registerEntity(ctor, options, ctor.name);
169
- };
170
- }
171
-
172
- export function Column(options: ColumnOptions = {}) {
173
- // Standard: (initialValue, context)
174
- // Legacy: (target, propertyKey)
175
- return function columnDecorator(a: any, b: any) {
176
- // Standard field/accessor
177
- if (isStdCtx(b) && (b.kind === 'field' || b.kind === 'accessor')) {
178
- const ctx = b as StdDecoratorContext;
179
- const prop = ctx.name as string | symbol;
180
-
181
- ctx.addInitializer?.(function (this: any) {
182
- const ctor = this?.constructor;
183
- if (!ctor) return;
184
- const colMeta = metadata.registerColumn(ctor, prop, options);
185
- if (options.index || options.unique) {
186
- metadata.registerIndex(ctor, {
187
- name: `idx_${String(colMeta.resolvedName)}`,
188
- fields: [String(colMeta.resolvedName)],
189
- ...(options.unique !== undefined ? { unique: options.unique } : {}),
190
- });
191
- }
192
- });
193
- return;
194
- }
195
- // Legacy property decorator
196
- const target = a;
197
- const propertyKey = b as string | symbol;
198
- const ctor = target?.constructor;
199
- const colMeta = metadata.registerColumn(ctor, propertyKey, options);
200
- if (options.index || options.unique) {
201
- metadata.registerIndex(ctor, {
202
- name: `idx_${String(colMeta.resolvedName)}`,
203
- fields: [String(colMeta.resolvedName)],
204
- ...(options.unique !== undefined ? { unique: options.unique } : {}),
205
- });
206
- }
207
- };
208
- }
209
-
210
- export function Index(nameOrOptions: string | IndexOptions, fields?: IndexOptions['fields']) {
211
- return function indexDecorator(valueOrTarget: any, maybeContext?: unknown) {
212
- // Standard mode
213
- if (isStdCtx(maybeContext)) {
214
- const ctx = maybeContext as StdDecoratorContext;
215
-
216
- if (ctx.kind === 'class') {
217
- const ctor = valueOrTarget as Function;
218
- const opts: IndexOptions = typeof nameOrOptions === 'string'
219
- ? { name: nameOrOptions, fields: fields ?? [] }
220
- : nameOrOptions;
221
- if (!opts.fields || opts.fields.length === 0) {
222
- throw new Error(`@Index on class ${ctx.name?.toString() ?? ctor.name} requires fields`);
223
- }
224
- metadata.registerIndex(ctor, opts as any);
225
- return;
226
- }
227
-
228
- if (ctx.kind === 'field' || ctx.kind === 'accessor') {
229
- const prop = ctx.name as string | symbol;
230
- const base: IndexOptions =
231
- typeof nameOrOptions === 'string'
232
- ? { name: nameOrOptions, fields: [String(prop)] }
233
- : { ...(nameOrOptions ?? {}), fields: (nameOrOptions as IndexOptions)?.fields?.length ? (nameOrOptions as IndexOptions).fields : [String(prop)] };
234
-
235
- ctx.addInitializer?.(function (this: any) {
236
- const ctor = this?.constructor;
237
- if (!ctor) return;
238
- metadata.registerIndex(ctor, {
239
- ...(base.name ? { name: base.name } : {}),
240
- fields: base.fields,
241
- ...(base.unique !== undefined ? { unique: base.unique } : {}),
242
- ...(base.ttlSeconds !== undefined ? { ttlSeconds: base.ttlSeconds } : {}),
243
- });
244
- });
245
- return;
246
- }
247
- }
248
-
249
- // Legacy mode
250
- if (typeof maybeContext === 'string' || typeof maybeContext === 'symbol') {
251
- // Property decorator
252
- const target = valueOrTarget;
253
- const prop = maybeContext as string | symbol;
254
- const ctor = target?.constructor;
255
- const base: IndexOptions =
256
- typeof nameOrOptions === 'string'
257
- ? { name: nameOrOptions, fields: [String(prop)] }
258
- : { ...(nameOrOptions ?? {}), fields: (nameOrOptions as IndexOptions)?.fields?.length ? (nameOrOptions as IndexOptions).fields : [String(prop)] };
259
-
260
- metadata.registerIndex(ctor, {
261
- ...(base.name ? { name: base.name } : {}),
262
- fields: base.fields,
263
- ...(base.unique !== undefined ? { unique: base.unique } : {}),
264
- ...(base.ttlSeconds !== undefined ? { ttlSeconds: base.ttlSeconds } : {}),
265
- });
266
- } else {
267
- // Class decorator
268
- const ctor = valueOrTarget as Function;
269
- const opts: IndexOptions =
270
- typeof nameOrOptions === 'string'
271
- ? { name: nameOrOptions, fields: fields ?? [] }
272
- : nameOrOptions;
273
-
274
- if (!opts.fields || opts.fields.length === 0) {
275
- throw new Error(`@Index on class ${ctor.name} requires fields`);
276
- }
277
- metadata.registerIndex(ctor, {
278
- ...(opts.name ? { name: opts.name } : {}),
279
- fields: opts.fields,
280
- ...(opts.unique !== undefined ? { unique: opts.unique } : {}),
281
- ...(opts.ttlSeconds !== undefined ? { ttlSeconds: opts.ttlSeconds } : {}),
282
- });
283
- }
284
- };
285
- }
286
-
287
- // ---------- Helpers for consumers ----------
288
-
289
- export function getEntitySchema(target: Function | object) {
290
- return metadata.getSchema(target);
291
- }
292
-
293
- export function getEntityName(target: Function | object) {
294
- return metadata.getEntity(target)?.name;
295
- }
296
-
297
- export function getColumns(target: Function | object) {
298
- return metadata.getColumns(target);
299
- }
300
-
301
- export function getIndexes(target: Function | object) {
302
- return metadata.getIndexes(target);
303
- }
304
-
305
- /*
306
- Usage example:
307
-
308
- @Entity({ name: 'User', namespace: 'app', ttlSeconds: 86400 })
309
- class User {
310
- @Column({ type: 'string', required: true })
311
- id!: string;
312
-
313
- @Column({ type: 'string', index: true })
314
- email!: string;
315
-
316
- @Column({ type: 'date', default: () => new Date() })
317
- createdAt!: Date;
318
-
319
- @Index('idx_email_unique', ['email'])
320
- // or put @Index() on the field to use single-column default index
321
- }
322
- */
@@ -1,73 +0,0 @@
1
- /**
2
- * 浏览器环境的行读取器
3
- * 实现类似Go bufio.Reader的行读取功能
4
- */
5
- export class BrowserLineReader {
6
- text: any;
7
- position: number;
8
- lines: any;
9
- currentLine: number;
10
- constructor(text: string) {
11
- this.text = text;
12
- this.position = 0;
13
- this.lines = text.split(/\r?\n/);
14
- this.currentLine = 0;
15
- }
16
-
17
- /**
18
- * 读取一行,模拟Go的bufio.Reader.ReadLine()
19
- * @returns {{line: Uint8Array, isPrefix: boolean, error: Error|null}} 读取结果
20
- */
21
- readLine() {
22
- if (this.currentLine >= this.lines.length) {
23
- return {
24
- line: new Uint8Array(0),
25
- isPrefix: false,
26
- error: new Error('EOF')
27
- };
28
- }
29
-
30
- const line = this.lines[this.currentLine];
31
- this.currentLine++;
32
-
33
- // 将字符串转换为Uint8Array (类似Go的[]byte)
34
- const encoder = new TextEncoder();
35
- const lineBytes = encoder.encode(line);
36
-
37
- // 这里简化了,假设单次可以读完整行
38
- return {
39
- line: lineBytes,
40
- isPrefix: false,
41
- error: null
42
- };
43
- }
44
- }
45
-
46
- /**
47
- * 从Reader中读取完整行
48
- * @param {BrowserLineReader} reader - 行读取器
49
- * @returns {{line: Uint8Array, error: Error|null}} 读取结果
50
- */
51
- export function readLine(reader: BrowserLineReader): {line: Uint8Array, error: Error|null} {
52
- let ln = new Uint8Array(0);
53
- let isPrefix = true;
54
- let error = null;
55
-
56
- while (isPrefix && error === null) {
57
- const result = reader.readLine();
58
-
59
- // 更新变量
60
- isPrefix = result.isPrefix;
61
- error = result.error;
62
-
63
- if (result.line.length > 0) {
64
- // 合并数组 (类似Go的append)
65
- const newArray = new Uint8Array(ln.length + result.line.length);
66
- newArray.set(ln);
67
- newArray.set(result.line, ln.length);
68
- ln = newArray;
69
- }
70
- }
71
-
72
- return { line: ln, error };
73
- }