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.
- package/dist/cjs/index.js +1 -1
- package/dist/dc.min.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/index.d.ts +934 -878
- package/package.json +4 -8
- package/dist/cjs/helia-core-B1Xqha7a.js +0 -1
- package/dist/cjs/helia-core-D8Uv1KjQ.js +0 -1
- package/dist/cjs/polkadot-api-7PhQf3ws.js +0 -1
- package/dist/cjs/polkadot-api-CtrJVWuZ.js +0 -1
- package/dist/esm/chunks/helia-core-BxMqyK2Y.js +0 -1
- package/dist/esm/chunks/helia-core-DMXRpcO-.js +0 -1
- package/dist/esm/chunks/polkadot-api-5Y9Bw8VT.js +0 -1
- package/dist/esm/chunks/polkadot-api-D69Ioun_.js +0 -1
- package/lib/common/blowfish/block.ts +0 -259
- package/lib/common/blowfish/cipher.ts +0 -144
- package/lib/common/blowfish/const.ts +0 -195
- package/lib/common/chain.ts +0 -469
- package/lib/common/commonclient.ts +0 -202
- package/lib/common/constants.ts +0 -55
- package/lib/common/dc-key/ed25519.ts +0 -343
- package/lib/common/dc-key/keyManager.ts +0 -424
- package/lib/common/dcapi.ts +0 -98
- package/lib/common/dcutil.ts +0 -627
- package/lib/common/define.ts +0 -70
- package/lib/common/error.ts +0 -67
- package/lib/common/grpc-dc.ts +0 -104
- package/lib/common/module-system.ts +0 -184
- package/lib/common/service-worker.ts +0 -234
- package/lib/common/types/types.ts +0 -344
- package/lib/dc.ts +0 -701
- package/lib/implements/account/client.ts +0 -185
- package/lib/implements/account/manager.ts +0 -683
- package/lib/implements/aiproxy/client.ts +0 -357
- package/lib/implements/aiproxy/manager.ts +0 -670
- package/lib/implements/cache/client.ts +0 -105
- package/lib/implements/cache/manager.ts +0 -127
- package/lib/implements/comment/client.ts +0 -982
- package/lib/implements/comment/manager.ts +0 -1151
- package/lib/implements/dc/client.ts +0 -51
- package/lib/implements/dc/manager.ts +0 -33
- package/lib/implements/file/client.ts +0 -253
- package/lib/implements/file/file-cache-manager.ts +0 -142
- package/lib/implements/file/manager.ts +0 -1240
- package/lib/implements/file/seekableFileStream.ts +0 -344
- package/lib/implements/file/streamwriter.ts +0 -322
- package/lib/implements/keyvalue/client.ts +0 -376
- package/lib/implements/keyvalue/manager.ts +0 -759
- package/lib/implements/message/client.ts +0 -250
- package/lib/implements/message/manager.ts +0 -215
- package/lib/implements/threaddb/cbor/coding.ts +0 -62
- package/lib/implements/threaddb/cbor/event.ts +0 -336
- package/lib/implements/threaddb/cbor/node.ts +0 -542
- package/lib/implements/threaddb/cbor/record.ts +0 -398
- package/lib/implements/threaddb/common/AsyncMutex.ts +0 -24
- package/lib/implements/threaddb/common/addrinfo.ts +0 -135
- package/lib/implements/threaddb/common/dispatcher.ts +0 -81
- package/lib/implements/threaddb/common/idbstore-adapter.ts +0 -260
- package/lib/implements/threaddb/common/json-patcher.ts +0 -204
- package/lib/implements/threaddb/common/key.ts +0 -290
- package/lib/implements/threaddb/common/level-adapter.ts +0 -235
- package/lib/implements/threaddb/common/lineReader.ts +0 -79
- package/lib/implements/threaddb/common/logstore.ts +0 -215
- package/lib/implements/threaddb/common/transformed-datastore.ts +0 -308
- package/lib/implements/threaddb/core/app.ts +0 -206
- package/lib/implements/threaddb/core/core.ts +0 -230
- package/lib/implements/threaddb/core/db.ts +0 -249
- package/lib/implements/threaddb/core/event.ts +0 -54
- package/lib/implements/threaddb/core/head.ts +0 -89
- package/lib/implements/threaddb/core/identity.ts +0 -171
- package/lib/implements/threaddb/core/logstore.ts +0 -137
- package/lib/implements/threaddb/core/options.ts +0 -14
- package/lib/implements/threaddb/core/record.ts +0 -54
- package/lib/implements/threaddb/db/collection.ts +0 -1910
- package/lib/implements/threaddb/db/db.ts +0 -698
- package/lib/implements/threaddb/db/json2Query.ts +0 -192
- package/lib/implements/threaddb/db/query.ts +0 -524
- package/lib/implements/threaddb/dbclient.ts +0 -543
- package/lib/implements/threaddb/dbmanager.ts +0 -1906
- package/lib/implements/threaddb/lsstoreds/addr_book.ts +0 -549
- package/lib/implements/threaddb/lsstoreds/cache.ts +0 -36
- package/lib/implements/threaddb/lsstoreds/cyclic_batch.ts +0 -87
- package/lib/implements/threaddb/lsstoreds/global.ts +0 -151
- package/lib/implements/threaddb/lsstoreds/headbook.ts +0 -373
- package/lib/implements/threaddb/lsstoreds/keybook.ts +0 -297
- package/lib/implements/threaddb/lsstoreds/logstore.ts +0 -29
- package/lib/implements/threaddb/lsstoreds/metadata.ts +0 -223
- package/lib/implements/threaddb/net/define.ts +0 -149
- package/lib/implements/threaddb/net/grpcClient.ts +0 -589
- package/lib/implements/threaddb/net/grpcserver.ts +0 -146
- package/lib/implements/threaddb/net/net.ts +0 -2047
- package/lib/implements/threaddb/pb/lstore.proto +0 -38
- package/lib/implements/threaddb/pb/lstore.ts +0 -393
- package/lib/implements/threaddb/pb/lstore_pb.d.ts +0 -433
- package/lib/implements/threaddb/pb/lstore_pb.js +0 -1085
- package/lib/implements/threaddb/pb/net.proto +0 -194
- package/lib/implements/threaddb/pb/net_pb.d.ts +0 -2349
- package/lib/implements/threaddb/pb/net_pb.js +0 -5525
- package/lib/implements/threaddb/pb/proto-custom-types.ts +0 -212
- package/lib/implements/util/client.ts +0 -72
- package/lib/implements/util/manager.ts +0 -146
- package/lib/implements/wallet/manager.ts +0 -671
- package/lib/index.ts +0 -57
- package/lib/interfaces/DCContext.ts +0 -51
- package/lib/interfaces/aiproxy-interface.ts +0 -145
- package/lib/interfaces/auth-interface.ts +0 -118
- package/lib/interfaces/cache-interface.ts +0 -22
- package/lib/interfaces/client-interface.ts +0 -11
- package/lib/interfaces/comment-interface.ts +0 -167
- package/lib/interfaces/components/news-component.ts +0 -0
- package/lib/interfaces/database-interface.ts +0 -169
- package/lib/interfaces/file-interface.ts +0 -120
- package/lib/interfaces/index.ts +0 -10
- package/lib/interfaces/keyvalue-interface.ts +0 -156
- package/lib/interfaces/message-interface.ts +0 -22
- package/lib/interfaces/util-interface.ts +0 -31
- package/lib/modules/aiproxy-module.ts +0 -246
- package/lib/modules/auth-module.ts +0 -753
- package/lib/modules/cache-module.ts +0 -99
- package/lib/modules/client-module.ts +0 -71
- package/lib/modules/comment-module.ts +0 -429
- package/lib/modules/components/news-components.ts +0 -390
- package/lib/modules/database-module.ts +0 -598
- package/lib/modules/file-module.ts +0 -291
- package/lib/modules/index.ts +0 -13
- package/lib/modules/keyvalue-module.ts +0 -379
- package/lib/modules/message-module.ts +0 -107
- package/lib/modules/util-module.ts +0 -148
- package/lib/polyfills/process-env-browser.ts +0 -1
- package/lib/proto/datasource.ts +0 -93
- package/lib/proto/dcnet.proto +0 -1601
- package/lib/proto/dcnet_proto.d.ts +0 -22857
- package/lib/proto/dcnet_proto.js +0 -55204
- package/lib/proto/dcnet_proto_sparse.js +0 -55166
- package/lib/proto/oidfetch.proto +0 -25
- package/lib/proto/oidfetch_proto.d.ts +0 -585
- package/lib/proto/oidfetch_proto.js +0 -1247
- package/lib/serverless/babel-browser.ts +0 -39
- package/lib/serverless/base_entity.ts +0 -78
- package/lib/serverless/base_repository.ts +0 -414
- package/lib/serverless/browser_schema_extractor.ts +0 -283
- package/lib/serverless/decorator_factory.ts +0 -322
- package/lib/util/BrowserLineReader.ts +0 -73
- package/lib/util/base64.ts +0 -105
- package/lib/util/bcrypt.ts +0 -206
- package/lib/util/curve25519Encryption.ts +0 -418
- package/lib/util/dccrypt.ts +0 -73
- package/lib/util/logger.ts +0 -104
- package/lib/util/utils.ts +0 -289
package/lib/common/error.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export class AppError extends Error {
|
|
4
|
-
constructor(
|
|
5
|
-
public readonly code: string,
|
|
6
|
-
message: string,
|
|
7
|
-
public readonly statusCode: number = 400
|
|
8
|
-
) {
|
|
9
|
-
super(message);
|
|
10
|
-
this.name = code;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const Errors = {
|
|
15
|
-
// Authentication errors (400-499)
|
|
16
|
-
// INVALID_SIGNATURE: new AppError('INVALID_SIGNATURE', 'bad signature', 401),
|
|
17
|
-
INVALID_TOKEN: new AppError('INVALID_TOKEN', 'invalid token', 401),
|
|
18
|
-
// REQ_TOKEN_TOO_OFTEN: new AppError('REQ_TOKEN_TOO_OFTEN', 'request token too often', 429),
|
|
19
|
-
|
|
20
|
-
// user not bind to this peer
|
|
21
|
-
USER_NOT_BIND_TO_PEER: new AppError('USER_NOT_BIND_TO_PEER', 'user not bind to this peer'),
|
|
22
|
-
|
|
23
|
-
NO_USER_INFO: new AppError("NO_USER_INFO", "no user info found"),
|
|
24
|
-
NO_DC_PEER_CONNECTED: new AppError("NO_DC_PEER_CONNECTED", "no dc peer connected"),
|
|
25
|
-
FAIL_TO_GET_BLOCKHEIGHT: new AppError("FAIL_TO_GET_BLOCKHEIGHT", "fail to get blockheight"),
|
|
26
|
-
FAIL_TO_GET_TOKEN: new AppError("FAIL_TO_GET_TOKEN", "fail to get token"),
|
|
27
|
-
NO_CHAIN_UTIL: new AppError("NO_CHAIN_UTIL", "no chain util found"),
|
|
28
|
-
// // User management errors
|
|
29
|
-
// USER_BINDED: new AppError('USER_BINDED', 'user has binded an account'),
|
|
30
|
-
// ACCOUNT_BINDED: new AppError('ACCOUNT_BINDED', 'account has been Binded with other user'),
|
|
31
|
-
|
|
32
|
-
// // Resource management errors
|
|
33
|
-
// NO_ENOUGH_USER_SPACE: new AppError('NO_ENOUGH_USER_SPACE', 'no enough user space', 507),
|
|
34
|
-
// DB_SPACE_LIMIT: new AppError('DB_SPACE_LIMIT', 'db space limit', 507),
|
|
35
|
-
// USER_SPACE_EXPIRED: new AppError('USER_SPACE_EXPIRED', 'store space has expired'),
|
|
36
|
-
|
|
37
|
-
// // Blockchain related errors
|
|
38
|
-
// BLOCKCHAIN_NOT_INIT: new AppError('BLOCKCHAIN_NOT_INIT', 'blockchain not init', 503),
|
|
39
|
-
// INVALID_ENCLAVE: new AppError('INVALID_ENCLAVE', 'invalid enclave'),
|
|
40
|
-
|
|
41
|
-
// // Network errors
|
|
42
|
-
// LOCAL_NET_FAIL: new AppError('LOCAL_NET_FAIL', 'local net fail', 502),
|
|
43
|
-
|
|
44
|
-
// // Thread management errors
|
|
45
|
-
// INVALID_THREADID: new AppError('INVALID_THREADID', 'invalid threadid'),
|
|
46
|
-
// THREAD_NOT_FOUND: new AppError('THREAD_NOT_FOUND', 'thread not found', 404),
|
|
47
|
-
|
|
48
|
-
// // Security errors
|
|
49
|
-
// INVALID_PRIVKEY: new AppError('INVALID_PRIVKEY', 'invalid privkey', 403),
|
|
50
|
-
|
|
51
|
-
// // Additional errors from original list
|
|
52
|
-
// INVALID_CID: new AppError('INVALID_CID', 'invalid cid'),
|
|
53
|
-
// PEER_NOT_INIT: new AppError('PEER_NOT_INIT', 'general datastore didn\'t init'),
|
|
54
|
-
// INVALID_IDENTITY: new AppError('INVALID_IDENTITY', 'invalid identity'),
|
|
55
|
-
// INVALID_REQUEST: new AppError('INVALID_REQUEST', 'invalid request', 400),
|
|
56
|
-
// INVALID_PEERID: new AppError('INVALID_PEERID', 'invalid peerid'),
|
|
57
|
-
// INVALID_PUBKEY: new AppError('INVALID_PUBKEY', 'invalid pubkey'),
|
|
58
|
-
// USER_NOT_OWN_THREAD: new AppError('USER_NOT_OWN_THREAD', 'user not own thread', 403),
|
|
59
|
-
// SUB_ACCOUNT_EXIST: new AppError('SUB_ACCOUNT_EXIST', 'sub account exist'),
|
|
60
|
-
// SELF_IS_SUB_ACCOUNT: new AppError('SELF_IS_SUB_ACCOUNT', 'self is sub account'),
|
|
61
|
-
// INVALID_SUB_ACCOUNT: new AppError('INVALID_SUB_ACCOUNT', 'invalid sub account'),
|
|
62
|
-
// INVALID_TEE_REPORT: new AppError('INVALID_TEE_REPORT', 'invalid tee report'),
|
|
63
|
-
// VACOUNT_MISMATCH: new AppError('VACOUNT_MISMATCH', 'vaccount mismatch')
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
// Type helper for error codes
|
|
67
|
-
export type ErrorCode = keyof typeof Errors;
|
package/lib/common/grpc-dc.ts
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import type { Libp2p } from "libp2p";
|
|
2
|
-
import type { Multiaddr } from "@multiformats/multiaddr";
|
|
3
|
-
import { dcnet } from "../proto/dcnet_proto";
|
|
4
|
-
import { Libp2pGrpcClient } from "grpc-libp2p-client";
|
|
5
|
-
import { DataSource } from "../proto/datasource";
|
|
6
|
-
import { Ed25519PubKey } from "./dc-key/ed25519";
|
|
7
|
-
|
|
8
|
-
export class DCGrpcClient {
|
|
9
|
-
grpcClient: Libp2pGrpcClient;
|
|
10
|
-
token: string;
|
|
11
|
-
|
|
12
|
-
constructor(
|
|
13
|
-
node: Libp2p,
|
|
14
|
-
peerAddr: Multiaddr,
|
|
15
|
-
token: string,
|
|
16
|
-
protocol?: string
|
|
17
|
-
) {
|
|
18
|
-
this.grpcClient = new Libp2pGrpcClient(node, peerAddr, token, protocol);
|
|
19
|
-
this.token = token;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async GetToken(
|
|
23
|
-
appId: string,
|
|
24
|
-
pubkey: string,
|
|
25
|
-
signCallback: (payload: Uint8Array) => Promise<Uint8Array> ,
|
|
26
|
-
): Promise<string> {
|
|
27
|
-
let token: string = "";
|
|
28
|
-
try {
|
|
29
|
-
let error: Error | null = null;
|
|
30
|
-
const signatureDataSource = new DataSource();
|
|
31
|
-
const message = new dcnet.pb.GetTokenRequest({});
|
|
32
|
-
message.key = appId + "_" + pubkey;
|
|
33
|
-
const messageBytes = dcnet.pb.GetTokenRequest.encode(message).finish();
|
|
34
|
-
const onDataCallback = async (payload: Uint8Array) => {
|
|
35
|
-
const decodedPayload = dcnet.pb.GetTokenReply.decode(payload);
|
|
36
|
-
if (decodedPayload.challenge) {
|
|
37
|
-
const challenge = decodedPayload.challenge;
|
|
38
|
-
const signature = await signCallback(challenge);
|
|
39
|
-
const message = new dcnet.pb.GetTokenRequest({});
|
|
40
|
-
|
|
41
|
-
message.signature = signature;
|
|
42
|
-
const messageBytes =
|
|
43
|
-
dcnet.pb.GetTokenRequest.encode(message).finish();
|
|
44
|
-
signatureDataSource.setData(messageBytes);
|
|
45
|
-
} else if (decodedPayload.token) {
|
|
46
|
-
//获取到token
|
|
47
|
-
console.log("GetToken success");
|
|
48
|
-
token = decodedPayload.token;
|
|
49
|
-
signatureDataSource.close(); //关闭数据源
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
// 使用方法
|
|
53
|
-
const dataSourceCallback = (): AsyncIterable<Uint8Array> => {
|
|
54
|
-
console.log("dataSourceCallback");
|
|
55
|
-
return signatureDataSource.getDataSource();
|
|
56
|
-
};
|
|
57
|
-
const onEndCallback = async () => {
|
|
58
|
-
signatureDataSource.close();
|
|
59
|
-
}
|
|
60
|
-
const onErrorCallback = async (err: unknown) => {
|
|
61
|
-
console.log("onErrorCallback", err);
|
|
62
|
-
error = err instanceof Error ? err : new Error(String(err));
|
|
63
|
-
signatureDataSource.close();
|
|
64
|
-
}
|
|
65
|
-
await this.grpcClient.Call(
|
|
66
|
-
"/dcnet.pb.Service/GetToken",
|
|
67
|
-
messageBytes,
|
|
68
|
-
30000,
|
|
69
|
-
"bidirectional",
|
|
70
|
-
onDataCallback,
|
|
71
|
-
dataSourceCallback,
|
|
72
|
-
onEndCallback,
|
|
73
|
-
onErrorCallback
|
|
74
|
-
);
|
|
75
|
-
if(error){
|
|
76
|
-
throw error;
|
|
77
|
-
}
|
|
78
|
-
this.token = token;
|
|
79
|
-
this.grpcClient.setToken(token);
|
|
80
|
-
return token;
|
|
81
|
-
} catch (err) {
|
|
82
|
-
throw err;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async ValidToken(): Promise<boolean> {
|
|
87
|
-
try {
|
|
88
|
-
const message = new dcnet.pb.ValidTokenRequest({});
|
|
89
|
-
const messageBytes =
|
|
90
|
-
dcnet.pb.ValidTokenRequest.encode(message).finish();
|
|
91
|
-
const responseData = await this.grpcClient.unaryCall(
|
|
92
|
-
"/dcnet.pb.Service/ValidToken",
|
|
93
|
-
messageBytes,
|
|
94
|
-
30000
|
|
95
|
-
);
|
|
96
|
-
dcnet.pb.ValidTokenReply.decode(responseData);
|
|
97
|
-
return true;
|
|
98
|
-
} catch (err) {
|
|
99
|
-
throw err;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
// module-system.ts
|
|
2
|
-
// 定义模块注册和管理系统
|
|
3
|
-
|
|
4
|
-
import { DCContext } from "../../lib/interfaces/DCContext";
|
|
5
|
-
import { createLogger } from "../util/logger";
|
|
6
|
-
|
|
7
|
-
const logger = createLogger("ModuleSystem");
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* 模块接口,所有功能模块必须实现此接口
|
|
11
|
-
*/
|
|
12
|
-
export interface DCModule {
|
|
13
|
-
/**
|
|
14
|
-
* 模块名称,用于标识和日志
|
|
15
|
-
*/
|
|
16
|
-
readonly moduleName: string;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* 模块初始化方法
|
|
20
|
-
* @param context DC上下文
|
|
21
|
-
* @returns 是否初始化成功
|
|
22
|
-
*/
|
|
23
|
-
initialize(context: DCContext): Promise<boolean>;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* 模块关闭方法
|
|
27
|
-
*/
|
|
28
|
-
shutdown(): Promise<void>;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* 核心模块名称枚举
|
|
33
|
-
*/
|
|
34
|
-
export enum CoreModuleName {
|
|
35
|
-
FILE = "file",
|
|
36
|
-
AUTH = "auth",
|
|
37
|
-
COMMENT = "comment",
|
|
38
|
-
DATABASE = "database",
|
|
39
|
-
MESSAGE = "message",
|
|
40
|
-
KEYVALUE = "keyvalue",
|
|
41
|
-
CACHE = "cache",
|
|
42
|
-
CLIENT = "client",
|
|
43
|
-
AIPROXY = "aiproxy",
|
|
44
|
-
UTIL = "util",
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* 模块系统
|
|
49
|
-
* 负责管理和协调所有功能模块
|
|
50
|
-
*/
|
|
51
|
-
export class ModuleSystem {
|
|
52
|
-
private modules: Map<string, DCModule> = new Map();
|
|
53
|
-
private context: DCContext;
|
|
54
|
-
private initialized: boolean = false;
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* 创建模块系统
|
|
58
|
-
* @param context DC上下文
|
|
59
|
-
*/
|
|
60
|
-
constructor(context: DCContext) {
|
|
61
|
-
this.context = context;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* 注册模块
|
|
66
|
-
* @param module 要注册的模块
|
|
67
|
-
* @returns 是否注册成功
|
|
68
|
-
*/
|
|
69
|
-
registerModule(module: DCModule): boolean {
|
|
70
|
-
if (this.modules.has(module.moduleName)) {
|
|
71
|
-
logger.warn(`模块 ${module.moduleName} 已存在,无法重复注册`);
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
this.modules.set(module.moduleName, module);
|
|
76
|
-
return true;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* 获取模块
|
|
81
|
-
* @param moduleName 模块名称
|
|
82
|
-
* @returns 模块实例或undefined
|
|
83
|
-
*/
|
|
84
|
-
getModule<T extends DCModule>(moduleName: string): T | undefined {
|
|
85
|
-
return this.modules.get(moduleName) as T | undefined;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* 初始化所有已注册的模块
|
|
90
|
-
* @returns 是否所有模块都成功初始化
|
|
91
|
-
*/
|
|
92
|
-
async initializeAll(): Promise<boolean> {
|
|
93
|
-
logger.info("开始初始化所有模块...");
|
|
94
|
-
|
|
95
|
-
// 按照特定顺序初始化核心模块
|
|
96
|
-
const initOrder = [
|
|
97
|
-
CoreModuleName.AUTH, // 认证模块优先,因为其他模块可能依赖认证
|
|
98
|
-
CoreModuleName.FILE, // 文件模块其次,许多功能依赖文件操作
|
|
99
|
-
CoreModuleName.DATABASE, // 数据库模块
|
|
100
|
-
CoreModuleName.COMMENT, // 评论模块
|
|
101
|
-
CoreModuleName.MESSAGE, // 消息模块
|
|
102
|
-
CoreModuleName.KEYVALUE, // 键值存储模块
|
|
103
|
-
CoreModuleName.CLIENT, // 客户端模块
|
|
104
|
-
CoreModuleName.CACHE, // 缓存模块
|
|
105
|
-
CoreModuleName.AIPROXY, // AIProxy模块
|
|
106
|
-
CoreModuleName.UTIL, // 工具模块
|
|
107
|
-
];
|
|
108
|
-
|
|
109
|
-
// 先初始化核心模块
|
|
110
|
-
for (const moduleName of initOrder) {
|
|
111
|
-
const module = this.modules.get(moduleName);
|
|
112
|
-
if (module) {
|
|
113
|
-
try {
|
|
114
|
-
const success = await module.initialize(this.context);
|
|
115
|
-
if (!success) {
|
|
116
|
-
logger.error(`核心模块 ${moduleName} 初始化失败`);
|
|
117
|
-
return false;
|
|
118
|
-
}
|
|
119
|
-
logger.info(`核心模块 ${moduleName} 初始化成功`);
|
|
120
|
-
} catch (error) {
|
|
121
|
-
logger.error(`核心模块 ${moduleName} 初始化出错:`, error);
|
|
122
|
-
return false;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// 然后初始化其余的扩展模块
|
|
128
|
-
for (const [name, module] of this.modules.entries()) {
|
|
129
|
-
if (!initOrder.includes(name as CoreModuleName)) {
|
|
130
|
-
logger.info(`初始化扩展模块: ${name}`);
|
|
131
|
-
try {
|
|
132
|
-
const success = await module.initialize(this.context);
|
|
133
|
-
if (!success) {
|
|
134
|
-
logger.error(`扩展模块 ${name} 初始化失败`);
|
|
135
|
-
return false;
|
|
136
|
-
}
|
|
137
|
-
} catch (error) {
|
|
138
|
-
logger.error(`扩展模块 ${name} 初始化出错:`, error);
|
|
139
|
-
return false;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
this.initialized = true;
|
|
145
|
-
logger.info("所有模块初始化完成");
|
|
146
|
-
return true;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* 关闭所有模块
|
|
151
|
-
*/
|
|
152
|
-
async shutdownAll(): Promise<void> {
|
|
153
|
-
logger.info("开始关闭所有模块...");
|
|
154
|
-
|
|
155
|
-
// 逆序关闭模块
|
|
156
|
-
const modules = Array.from(this.modules.entries());
|
|
157
|
-
for (let i = modules.length - 1; i >= 0; i--) {
|
|
158
|
-
const [name, module] = modules[i]!;
|
|
159
|
-
try {
|
|
160
|
-
logger.info(`关闭模块: ${name}`);
|
|
161
|
-
await module.shutdown();
|
|
162
|
-
} catch (error) {
|
|
163
|
-
logger.error(`关闭模块 ${name} 时出错:`, error);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
this.initialized = false;
|
|
168
|
-
logger.info("所有模块已关闭");
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* 检查模块系统是否已初始化
|
|
173
|
-
*/
|
|
174
|
-
isInitialized(): boolean {
|
|
175
|
-
return this.initialized;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* 获取已注册的模块列表
|
|
180
|
-
*/
|
|
181
|
-
getRegisteredModules(): string[] {
|
|
182
|
-
return Array.from(this.modules.keys());
|
|
183
|
-
}
|
|
184
|
-
}
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
// service-worker.ts
|
|
2
|
-
// 负责处理 Service Worker 相关的功能
|
|
3
|
-
|
|
4
|
-
import { IFileOperations } from "../interfaces";
|
|
5
|
-
import { createLogger } from "../util/logger";
|
|
6
|
-
|
|
7
|
-
const logger = createLogger('ServiceWorker');
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
let swMessageHandler: ((event: MessageEvent) => void) | null = null;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* 注册 Service Worker 并设置消息监听器
|
|
14
|
-
* @param fileOps 文件操作对象,用于处理IPFS请求
|
|
15
|
-
* @returns Promise<ServiceWorkerRegistration | null>
|
|
16
|
-
*/
|
|
17
|
-
export async function registerServiceWorker(fileOps?: IFileOperations, swUrl: string = ''): Promise<ServiceWorkerRegistration | null> {
|
|
18
|
-
if (!('serviceWorker' in navigator)) return Promise.reject('Service Worker not supported');
|
|
19
|
-
if (location.protocol !== 'https:' && location.hostname !== 'localhost') {
|
|
20
|
-
logger.error('ServiceWorker 仅支持 https 或 localhost');
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
if (window.location.protocol != 'https:' && window.location.hostname != 'localhost') {
|
|
24
|
-
logger.error('ServiceWorker 仅支持https协议');
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
const swPath = new URL(swUrl || '/sw.js', location.origin).href;
|
|
28
|
-
const registration = await navigator.serviceWorker.register(swPath);
|
|
29
|
-
// 只保留一个监听器,避免重复处理同一请求
|
|
30
|
-
if (swMessageHandler) {
|
|
31
|
-
navigator.serviceWorker.removeEventListener('message', swMessageHandler);
|
|
32
|
-
}
|
|
33
|
-
swMessageHandler = async (event: MessageEvent) => {
|
|
34
|
-
if (event.data && event.data.type === 'ipfs-fetch') {
|
|
35
|
-
const port = event.ports?.[0];
|
|
36
|
-
if (!port) {
|
|
37
|
-
logger.warn('SW 未提供 MessagePort');
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
//里面回一个消息,通知已经收到请求
|
|
41
|
-
port.postMessage({ success: true, message: 'Request received' ,status: 999 });
|
|
42
|
-
try {
|
|
43
|
-
await handleIpfsRequest(event.data, port, fileOps);
|
|
44
|
-
} catch (e) {
|
|
45
|
-
logger.error('handleIpfsRequest 处理异常:', e);
|
|
46
|
-
port.postMessage({ success: false, error: String(e) });
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
navigator.serviceWorker.addEventListener('message', swMessageHandler);
|
|
51
|
-
// 确保 SW 已 active
|
|
52
|
-
await navigator.serviceWorker.ready;
|
|
53
|
-
// 确保当前页已被控制,否则等待接管
|
|
54
|
-
if (!navigator.serviceWorker.controller) {
|
|
55
|
-
await new Promise<void>((resolve) => {
|
|
56
|
-
navigator.serviceWorker.addEventListener('controllerchange', () => resolve(), { once: true });
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
return registration;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* 处理IPFS请求
|
|
64
|
-
* @param data 请求数据
|
|
65
|
-
* @param port 消息端口
|
|
66
|
-
* @param fileOps 文件操作对象
|
|
67
|
-
*/
|
|
68
|
-
export async function handleIpfsRequest(
|
|
69
|
-
data: { id: string, pathname: string, range?: string },
|
|
70
|
-
port: MessagePort,
|
|
71
|
-
fileOps?: IFileOperations
|
|
72
|
-
): Promise<void> {
|
|
73
|
-
const { id, pathname, range } = data;
|
|
74
|
-
let fileSize = 0;
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
// 从路径提取IPFS路径和解密密钥
|
|
78
|
-
const pathParts = pathname.split('/');
|
|
79
|
-
let ipfsPath = pathParts[3]!; // <ipfs-hash>[_<key>]
|
|
80
|
-
|
|
81
|
-
// 提取加密密钥(如果有)
|
|
82
|
-
let decryptKey = '';
|
|
83
|
-
const keyParts = ipfsPath.split('_');
|
|
84
|
-
if (keyParts.length > 1) {
|
|
85
|
-
ipfsPath = keyParts[0]!;
|
|
86
|
-
decryptKey = keyParts[1]!;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
let fileData: Uint8Array | null = null;
|
|
90
|
-
const DEFAULT_CHUNK_SIZE = 3 * 1024 * 1024; // 默认返回3MB数据块
|
|
91
|
-
let start = 0;
|
|
92
|
-
let end = 0;
|
|
93
|
-
|
|
94
|
-
if (fileOps) {
|
|
95
|
-
if (range) {
|
|
96
|
-
// 处理范围请求(视频跳转等)
|
|
97
|
-
try {
|
|
98
|
-
const fileStream = await fileOps.getSeekableFileStream(ipfsPath, decryptKey);
|
|
99
|
-
fileSize = fileStream.getSize();
|
|
100
|
-
if (fileStream) {
|
|
101
|
-
const match = range.match(/bytes=(\d+)-(\d+)?/);
|
|
102
|
-
if (match) {
|
|
103
|
-
start = parseInt(match[1]!);
|
|
104
|
-
end = match[2] ? parseInt(match[2]) : start + DEFAULT_CHUNK_SIZE-1;
|
|
105
|
-
if (end >= fileSize) {
|
|
106
|
-
// 如果请求的结束范围超过文件大小,则调整为文件大小
|
|
107
|
-
end = fileSize - 1;
|
|
108
|
-
}
|
|
109
|
-
logger.info(`处理范围请求: ${start}-${end}, 总大小: ${fileStream.getSize()}`);
|
|
110
|
-
fileStream.seek(start);
|
|
111
|
-
fileData = await fileStream.read(end - start + 1);
|
|
112
|
-
|
|
113
|
-
// 如果读取到文件末尾,清理缓存
|
|
114
|
-
if (end >= fileStream.getSize() - 1) {
|
|
115
|
-
logger.info(`文件读取完成,清理缓存: ${pathname}`);
|
|
116
|
-
fileOps.clearFileCache(pathname);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
} catch (err) {
|
|
121
|
-
logger.error('文件流操作失败:', err);
|
|
122
|
-
// 发生错误时清理缓存
|
|
123
|
-
fileOps.clearFileCache(pathname);
|
|
124
|
-
port.postMessage({
|
|
125
|
-
success: false,
|
|
126
|
-
error: err instanceof Error ? err.message : 'File stream operation failed'
|
|
127
|
-
});
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
} else {
|
|
131
|
-
const [fileContent, error] = await fileOps.getFile(ipfsPath, decryptKey);
|
|
132
|
-
fileData = fileContent;
|
|
133
|
-
// 普通文件请求
|
|
134
|
-
fileSize = fileData ? fileData.length : 0;
|
|
135
|
-
// 非范围请求的文件读取完成后,清理缓存
|
|
136
|
-
fileOps.clearFileCache(pathname);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if (!fileData) {
|
|
140
|
-
port.postMessage({
|
|
141
|
-
success: false,
|
|
142
|
-
error: 'no data',
|
|
143
|
-
});
|
|
144
|
-
return
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (fileData && fileData.buffer) {
|
|
148
|
-
// 创建不包含 buffer 的基本响应对象
|
|
149
|
-
const responseObj = {
|
|
150
|
-
success: true,
|
|
151
|
-
status: range ? 206 : 200,
|
|
152
|
-
headers: {
|
|
153
|
-
'Content-Range': range ? `bytes ${start}-${end}/${fileSize}` : undefined,
|
|
154
|
-
'Accept-Ranges': 'bytes',
|
|
155
|
-
'Cache-Control': 'no-cache',
|
|
156
|
-
'Content-Length': fileData.length,
|
|
157
|
-
},
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
// 传递时才添加 data 字段
|
|
161
|
-
// 注意:在这个方法里 fileData.buffer 被转移后,fileData 将不再可用
|
|
162
|
-
port.postMessage({
|
|
163
|
-
...responseObj,
|
|
164
|
-
data: fileData.buffer
|
|
165
|
-
}, [fileData.buffer]);
|
|
166
|
-
|
|
167
|
-
// 手动清除引用
|
|
168
|
-
fileData = null;
|
|
169
|
-
} else {
|
|
170
|
-
port.postMessage({
|
|
171
|
-
success: false,
|
|
172
|
-
error: 'Missing data buffer'
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
} else {
|
|
176
|
-
// 文件操作对象不可用
|
|
177
|
-
port.postMessage({
|
|
178
|
-
success: false,
|
|
179
|
-
error: 'File operations not available'
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
} catch (error) {
|
|
183
|
-
logger.error('处理IPFS请求失败:', error);
|
|
184
|
-
// 全局错误捕获时也清理缓存
|
|
185
|
-
if (fileOps && pathname) {
|
|
186
|
-
fileOps.clearFileCache(pathname);
|
|
187
|
-
}
|
|
188
|
-
port.postMessage({
|
|
189
|
-
success: false,
|
|
190
|
-
error: error instanceof Error ? error.message : 'Unknown error'
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* 检查Service Worker状态
|
|
197
|
-
* @returns Promise<boolean> Service Worker是否活跃
|
|
198
|
-
*/
|
|
199
|
-
export async function isServiceWorkerActive(): Promise<boolean> {
|
|
200
|
-
if (!('serviceWorker' in navigator)) {
|
|
201
|
-
return false;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
try {
|
|
205
|
-
const registration = await navigator.serviceWorker.ready;
|
|
206
|
-
return !!registration.active;
|
|
207
|
-
} catch (error) {
|
|
208
|
-
logger.error('检查Service Worker状态失败:', error);
|
|
209
|
-
return false;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* 强制更新Service Worker
|
|
215
|
-
* @returns Promise<boolean> 是否成功更新
|
|
216
|
-
*/
|
|
217
|
-
export async function updateServiceWorker(): Promise<boolean> {
|
|
218
|
-
if (!('serviceWorker' in navigator)) {
|
|
219
|
-
return false;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
try {
|
|
223
|
-
const registration = await navigator.serviceWorker.getRegistration();
|
|
224
|
-
if (registration) {
|
|
225
|
-
await registration.update();
|
|
226
|
-
logger.info('Service Worker 已更新');
|
|
227
|
-
return true;
|
|
228
|
-
}
|
|
229
|
-
return false;
|
|
230
|
-
} catch (error) {
|
|
231
|
-
logger.error('更新Service Worker失败:', error);
|
|
232
|
-
return false;
|
|
233
|
-
}
|
|
234
|
-
}
|