web-dc-api 0.0.87 → 0.0.89
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 -0
- package/dist/cjs/protobuf-BVBdi7Hh.js +1 -0
- package/dist/dc.min.js +1 -19
- package/dist/esm/chunks/protobuf-CbxDm-Gy.js +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/index.d.ts +947 -886
- package/package.json +14 -17
- package/dist/index.cjs.js +0 -19
- package/dist/index.esm.js +0 -19
- 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 -595
- package/lib/common/define.ts +0 -66
- 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 -694
- 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 -202
- 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 -443
- package/lib/implements/threaddb/dbmanager.ts +0 -1901
- package/lib/implements/threaddb/lsstoreds/addr_book.ts +0 -452
- 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 -280
- 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 -138
- package/lib/implements/threaddb/net/grpcClient.ts +0 -582
- package/lib/implements/threaddb/net/grpcserver.ts +0 -146
- package/lib/implements/threaddb/net/net.ts +0 -2006
- 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 -664
- 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/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/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
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
// Package logstore provides local store for thread logs. The subpackages provide creators for different types of store implementations.
|
|
2
|
-
|
|
3
|
-
import { Mutex } from 'async-mutex';
|
|
4
|
-
import { KeyBook, AddrBook, IThreadMetadata, HeadBook, ILogstore } from '../core/logstore';
|
|
5
|
-
import {IThreadInfo,IThreadLogInfo} from '../core/core';
|
|
6
|
-
import {SymmetricKey} from './key';
|
|
7
|
-
import { ThreadID } from '@textile/threads-id';
|
|
8
|
-
import type { PeerId } from "@libp2p/interface";
|
|
9
|
-
import { compareByteArrays } from '../../../util/utils';
|
|
10
|
-
import {Key as ThreadKey} from './key';
|
|
11
|
-
import {ThreadInfo} from '../core/core';
|
|
12
|
-
import {Errors} from '../core/db';
|
|
13
|
-
|
|
14
|
-
export const PermanentAddrTTL = 2^53-1; // 使用 bigint 精确表示 64 位整数
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const managedSuffix = "/managed";
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// NewLogstore creates a new log store from the given books.
|
|
21
|
-
export function newLogstore(kb: KeyBook, ab: AddrBook, hb: HeadBook, md: IThreadMetadata): ILogstore {
|
|
22
|
-
return new Logstore(kb, ab, hb, md);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// logstore is a collection of books for storing thread logs.
|
|
26
|
-
class Logstore implements ILogstore {
|
|
27
|
-
private mutex = new Mutex();
|
|
28
|
-
|
|
29
|
-
constructor(
|
|
30
|
-
public keyBook: KeyBook,
|
|
31
|
-
public addrBook: AddrBook,
|
|
32
|
-
public headBook: HeadBook,
|
|
33
|
-
public metadata: IThreadMetadata
|
|
34
|
-
) {}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
// Close the logstore.
|
|
38
|
-
async close(): Promise<void> {
|
|
39
|
-
const errs: Error[] = [];
|
|
40
|
-
const weakClose = async (name: string, c: any) => {
|
|
41
|
-
if (c && typeof c.close === 'function') {
|
|
42
|
-
try {
|
|
43
|
-
await c.close();
|
|
44
|
-
} catch (err) {
|
|
45
|
-
errs.push(new Error(`${name} error: ${err}`));
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
await weakClose("keybook", this.keyBook);
|
|
51
|
-
await weakClose("addressbook", this.addrBook);
|
|
52
|
-
await weakClose("headbook", this.headBook);
|
|
53
|
-
await weakClose("threadmetadata", this.metadata);
|
|
54
|
-
|
|
55
|
-
if (errs.length > 0) {
|
|
56
|
-
throw new Error(`failed while closing logstore; err(s): ${errs.map(e => e.message).join(', ')}`);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Threads returns a list of the thread IDs in the store.
|
|
61
|
-
async threads(): Promise<ThreadID[]> {
|
|
62
|
-
return this.mutex.runExclusive(async () => {
|
|
63
|
-
const set: Set<ThreadID> = new Set();
|
|
64
|
-
const threadsFromKeys = await this.keyBook.threadsFromKeys();
|
|
65
|
-
threadsFromKeys.forEach(t => set.add(t));
|
|
66
|
-
const threadsFromAddrs = await this.addrBook.threadsFromAddrs();
|
|
67
|
-
threadsFromAddrs.forEach(t => set.add(t));
|
|
68
|
-
return Array.from(set);
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// AddThread adds a thread with keys.
|
|
73
|
-
async addThread(info: IThreadInfo): Promise<void> {
|
|
74
|
-
if (!info.key?.service()) {
|
|
75
|
-
throw new Error("a service-key is required to add a thread");
|
|
76
|
-
}
|
|
77
|
-
const sk = await this.keyBook.serviceKey(info.id);
|
|
78
|
-
const symKey = await info.key.service()?.toSymKey();
|
|
79
|
-
if (!sk) {
|
|
80
|
-
if (!symKey) {
|
|
81
|
-
throw new Error("service-key is required");
|
|
82
|
-
}
|
|
83
|
-
await this.keyBook.addServiceKey(info.id, symKey);
|
|
84
|
-
} else if (!symKey || !compareByteArrays(symKey.raw, sk.raw)) {
|
|
85
|
-
throw new Error("service-key mismatch");
|
|
86
|
-
}
|
|
87
|
-
if (info.key.canRead()) {
|
|
88
|
-
const rk = await this.keyBook.readKey(info.id);
|
|
89
|
-
const readKey = await info.key.read()?.toSymKey();
|
|
90
|
-
if (!rk) {
|
|
91
|
-
if (!readKey) {
|
|
92
|
-
throw new Error("read-key is required");
|
|
93
|
-
}
|
|
94
|
-
await this.keyBook.addReadKey(info.id, readKey);
|
|
95
|
-
} else if (!readKey || !compareByteArrays(readKey.raw, rk.raw)) {
|
|
96
|
-
throw new Error("read-key mismatch");
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// GetThread returns thread info of the given id.
|
|
103
|
-
async getThread(id: ThreadID):Promise<IThreadInfo> {
|
|
104
|
-
const sk = await this.keyBook.serviceKey(id);
|
|
105
|
-
if (!sk) {
|
|
106
|
-
throw Errors.ErrThreadNotFound
|
|
107
|
-
}
|
|
108
|
-
const rk = await this.keyBook.readKey(id);
|
|
109
|
-
const set = await this.getLogIDs(id);
|
|
110
|
-
const logs: IThreadLogInfo[] = [];
|
|
111
|
-
for (const l of set) {
|
|
112
|
-
const i = await this.getLog(id, l);
|
|
113
|
-
logs.push(i);
|
|
114
|
-
}
|
|
115
|
-
let threadKey = new ThreadKey(SymmetricKey.fromSymKey(sk));
|
|
116
|
-
if(rk) {
|
|
117
|
-
threadKey = new ThreadKey(SymmetricKey.fromSymKey(sk), SymmetricKey.fromSymKey(rk));
|
|
118
|
-
}
|
|
119
|
-
const threadInfo = new ThreadInfo(id, logs, [], threadKey );
|
|
120
|
-
return threadInfo;
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
private async getLogIDs(id: ThreadID): Promise<Set<PeerId>> {
|
|
125
|
-
const set: Set<PeerId> = new Set();
|
|
126
|
-
const logsWithKeys = await this.keyBook.logsWithKeys(id);
|
|
127
|
-
logsWithKeys.forEach(l => set.add(l));
|
|
128
|
-
const logsWithAddrs = await this.addrBook.logsWithAddrs(id);
|
|
129
|
-
logsWithAddrs.forEach(l => set.add(l));
|
|
130
|
-
return set;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// DeleteThread deletes a thread.
|
|
134
|
-
async deleteThread(id: ThreadID): Promise<void> {
|
|
135
|
-
await this.keyBook.clearKeys(id);
|
|
136
|
-
await this.metadata.clearMetadata(id);
|
|
137
|
-
const set = await this.getLogIDs(id);
|
|
138
|
-
for (const l of set) {
|
|
139
|
-
await this.addrBook.clearAddrs(id, l);
|
|
140
|
-
await this.headBook.clearHeads(id, l);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// AddLog adds a log under the given thread.
|
|
145
|
-
async addLog(id: ThreadID, lg: IThreadLogInfo): Promise<void> {
|
|
146
|
-
if (lg.privKey) {
|
|
147
|
-
const pk = await this.keyBook.privKey(id, lg.id);
|
|
148
|
-
if (pk) {
|
|
149
|
-
throw Errors.ErrLogExists;
|
|
150
|
-
}
|
|
151
|
-
await this.keyBook.addPrivKey(id, lg.id, lg.privKey);
|
|
152
|
-
}
|
|
153
|
-
if (!lg.pubKey) {
|
|
154
|
-
throw new Error("public key is required");
|
|
155
|
-
}
|
|
156
|
-
await this.keyBook.addPubKey(id, lg.id, lg.pubKey);
|
|
157
|
-
await this.addrBook.addAddrs(id, lg.id, lg.addrs, PermanentAddrTTL);
|
|
158
|
-
if (lg.head ) {
|
|
159
|
-
await this.headBook.setHead(id, lg.id, lg.head);
|
|
160
|
-
}
|
|
161
|
-
if (lg.managed || lg.privKey) {
|
|
162
|
-
await this.metadata.putBool(id, lg.id.toString() + managedSuffix, true);
|
|
163
|
-
}
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// GetLog returns info about the given thread.
|
|
168
|
-
async getLog(id: ThreadID, lid: PeerId): Promise<IThreadLogInfo> {
|
|
169
|
-
return this.getLogInternal(id, lid);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
private async getLogInternal(id: ThreadID, lid: PeerId): Promise<IThreadLogInfo> {
|
|
173
|
-
const pk = await this.keyBook.pubKey(id, lid);
|
|
174
|
-
if (!pk) {
|
|
175
|
-
throw Errors.ErrLogNotFound;
|
|
176
|
-
}
|
|
177
|
-
const sk = await this.keyBook.privKey(id, lid);
|
|
178
|
-
const addrs = await this.addrBook.addrs(id, lid);
|
|
179
|
-
const heads = await this.headBook.heads(id, lid);
|
|
180
|
-
const managed = await this.metadata.getBool(id, lid.toString() + managedSuffix);
|
|
181
|
-
return {
|
|
182
|
-
id: lid,
|
|
183
|
-
pubKey: pk,
|
|
184
|
-
...(sk ? { privKey: sk } : {}),
|
|
185
|
-
addrs,
|
|
186
|
-
...(heads.length > 0 ? { head: heads[0] } : {}),
|
|
187
|
-
managed: managed || false
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// GetManagedLogs returns the logs the host is 'managing' under the given thread.
|
|
192
|
-
async getManagedLogs(id: ThreadID): Promise<IThreadLogInfo[]> {
|
|
193
|
-
const logs = await this.keyBook.logsWithKeys(id);
|
|
194
|
-
const managed: IThreadLogInfo[] = [];
|
|
195
|
-
for (const lid of logs) {
|
|
196
|
-
const lg = await this.getLog(id, lid);
|
|
197
|
-
if (lg.managed || lg.privKey) {
|
|
198
|
-
managed.push(lg);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
return managed;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// DeleteLog deletes a log.
|
|
205
|
-
async deleteLog(id: ThreadID, lid: PeerId): Promise<void> {
|
|
206
|
-
return this.mutex.runExclusive(async () => {
|
|
207
|
-
await this.keyBook.clearLogKeys(id, lid);
|
|
208
|
-
await this.addrBook.clearAddrs(id, lid);
|
|
209
|
-
await this.headBook.clearHeads(id, lid);
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
export default Logstore;
|
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { Key, Query, QueryFilter,Batch, Pair,Datastore } from 'interface-datastore';
|
|
3
|
-
import { BaseDatastore } from 'datastore-core';
|
|
4
|
-
import {
|
|
5
|
-
Transaction,
|
|
6
|
-
QueryExt,
|
|
7
|
-
QueryResult ,
|
|
8
|
-
TxnDatastoreExtended
|
|
9
|
-
} from '../core/db';
|
|
10
|
-
|
|
11
|
-
import {
|
|
12
|
-
AbortOptions,
|
|
13
|
-
} from '../core/core';
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
// ======== 类型扩展声明 ========
|
|
17
|
-
declare module 'interface-datastore' {
|
|
18
|
-
interface Pair {
|
|
19
|
-
size?: number; // 添加扩展属性声明
|
|
20
|
-
}
|
|
21
|
-
interface QueryFilter {
|
|
22
|
-
/** 类型标识字段 */
|
|
23
|
-
$type?: 'key' | 'prefix';
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// 明确导出子类型
|
|
27
|
-
interface KeyFilter extends QueryFilter {
|
|
28
|
-
$type: 'key';
|
|
29
|
-
key: string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
interface PrefixFilter extends QueryFilter {
|
|
33
|
-
$type: 'prefix';
|
|
34
|
-
prefix: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
interface Datastore {
|
|
38
|
-
newTransactionExtended?: ( readOnly: boolean) => Promise<Transaction>;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
// ======== 类型守卫优化 ========
|
|
42
|
-
|
|
43
|
-
function isKeyFilter(filter: QueryFilter): filter is KeyFilter {
|
|
44
|
-
return (filter as KeyFilter).$type === 'key' &&
|
|
45
|
-
typeof (filter as KeyFilter).key === 'string';
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function isPrefixFilter(filter: QueryFilter): filter is PrefixFilter {
|
|
49
|
-
return (filter as PrefixFilter).$type === 'prefix' &&
|
|
50
|
-
typeof (filter as PrefixFilter).prefix === 'string';
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
export interface KeyTransform {
|
|
57
|
-
convert(key: Key): Key;
|
|
58
|
-
invert(key: Key): Key | null;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
// 数据存储扩展接口
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// 组合接口
|
|
66
|
-
export function createTransformedDatastore(
|
|
67
|
-
child: TxnDatastoreExtended,
|
|
68
|
-
transform: KeyTransform
|
|
69
|
-
): TransformedDatastore {
|
|
70
|
-
return new TransformedDatastore(child, transform);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
class TransformedDatastore extends BaseDatastore {
|
|
75
|
-
constructor(
|
|
76
|
-
private readonly child: TxnDatastoreExtended,
|
|
77
|
-
private readonly transform: KeyTransform
|
|
78
|
-
) {
|
|
79
|
-
super();
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// === 基础操作 ===
|
|
83
|
-
async put(key: Key, value: Uint8Array, options?: AbortOptions): Promise<Key> {
|
|
84
|
-
return this.child.put(this.transform.convert(key), value, options);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
async get(key: Key, options?: AbortOptions): Promise<Uint8Array> {
|
|
88
|
-
return this.child.get(this.transform.convert(key));
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
async has(key: Key, options?: AbortOptions): Promise<boolean> {
|
|
92
|
-
return this.child.has(this.transform.convert(key), options)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// 使用 Await<void> 作为返回类型
|
|
96
|
-
async delete(key: Key, options?: AbortOptions): Promise<void> {
|
|
97
|
-
return this.child.delete(this.transform.convert(key), options)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// === 事务管理 ===
|
|
101
|
-
async beginTransaction(): Promise<Transaction> {
|
|
102
|
-
const childTxn = await this.getTransaction();
|
|
103
|
-
return new TransformedTransaction(childTxn, this.transform);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
async newTransactionExtended( readOnly: boolean): Promise<Transaction> {
|
|
107
|
-
const childTxn = await this.getTransaction();
|
|
108
|
-
return new TransformedTransaction(childTxn, this.transform);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
private async getTransaction(): Promise<Transaction> {
|
|
112
|
-
if (typeof (this.child as any).newTransactionExtended === 'function') {
|
|
113
|
-
return (this.child as any).newTransactionExtended(false);
|
|
114
|
-
}
|
|
115
|
-
throw new Error('Transactions not supported by underlying datastore');
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// === 查询处理 ===
|
|
119
|
-
// async *query(query: Query): AsyncIterable<QueryResult> {
|
|
120
|
-
// yield* this.queryExtended({ ...query });
|
|
121
|
-
// }
|
|
122
|
-
|
|
123
|
-
async *query( q: Query): AsyncIterable<Pair> {
|
|
124
|
-
const results = this.queryExtended(q as QueryExt)
|
|
125
|
-
for await (const result of results) {
|
|
126
|
-
yield {key: new Key(result.key), value: result.value}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
async *queryExtended(q: QueryExt): AsyncIterable<QueryResult> {
|
|
132
|
-
const transformedQuery = this.transformQuery(q);
|
|
133
|
-
|
|
134
|
-
for await (const result of this.child.query(transformedQuery)) {
|
|
135
|
-
const originalKey = this.transform.invert(new Key(result.key.toString()));
|
|
136
|
-
if (!originalKey) continue;
|
|
137
|
-
|
|
138
|
-
yield {
|
|
139
|
-
...result,
|
|
140
|
-
key: originalKey.toString()
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
private transformQuery(query: QueryExt): QueryExt {
|
|
146
|
-
return FilterProcessor.process(query, this.transform);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// ======== 事务实现 ========
|
|
151
|
-
class TransformedTransaction implements Transaction {
|
|
152
|
-
constructor(
|
|
153
|
-
private readonly txn: Transaction,
|
|
154
|
-
private readonly transform: KeyTransform
|
|
155
|
-
) {}
|
|
156
|
-
|
|
157
|
-
// === 核心操作 ===
|
|
158
|
-
async put( key: Key, value: Uint8Array): Promise<Key> {
|
|
159
|
-
return this.txn.put(this.transform.convert(key), value);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
async delete( key: Key): Promise<void> {
|
|
163
|
-
return this.txn.delete(this.transform.convert(key));
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
async get( key: Key): Promise<Uint8Array|undefined > {
|
|
167
|
-
return this.txn.get(this.transform.convert(key));
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
async has( key: Key): Promise<boolean> {
|
|
171
|
-
return this.txn.has(this.transform.convert(key));
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
async commit(): Promise<void> {
|
|
175
|
-
return this.txn.commit();
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
discard(): void {
|
|
179
|
-
this.txn.discard();
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// === 查询操作 ===
|
|
183
|
-
async *query( q: Query): AsyncIterable<QueryResult> {
|
|
184
|
-
yield* this.queryExtended(q as QueryExt);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
async *queryExtended( q: QueryExt): AsyncIterable<QueryResult> {
|
|
188
|
-
const processedQuery = FilterProcessor.process(q, this.transform);
|
|
189
|
-
|
|
190
|
-
for await (const result of this.txn.queryExtended(processedQuery)) {
|
|
191
|
-
const originalKey = this.transform.invert(new Key(result.key));
|
|
192
|
-
if (!originalKey) continue;
|
|
193
|
-
|
|
194
|
-
yield {
|
|
195
|
-
...result,
|
|
196
|
-
key: originalKey.toString()
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// ======== 过滤器处理器 ========
|
|
203
|
-
class FilterProcessor {
|
|
204
|
-
static process(input: QueryExt, transform: KeyTransform): QueryExt {
|
|
205
|
-
const query = structuredClone(input);
|
|
206
|
-
|
|
207
|
-
// 前缀转换
|
|
208
|
-
if (query.prefix) {
|
|
209
|
-
query.prefix = transform.convert(new Key(query.prefix)).toString();
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// 过滤器转换
|
|
213
|
-
if (query.filters) {
|
|
214
|
-
query.filters = query.filters.map(filter =>
|
|
215
|
-
this.transformFilter(filter, transform)
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
return query;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// 改进后的转换方法
|
|
223
|
-
private static transformFilter(filter: QueryFilter, transform: KeyTransform): QueryFilter {
|
|
224
|
-
if (isKeyFilter(filter)) {
|
|
225
|
-
const transformedKey = transform.convert(new Key(filter.key)).toString();
|
|
226
|
-
|
|
227
|
-
// 创建一个函数对象
|
|
228
|
-
const keyFilter = function(item: Pair): boolean {
|
|
229
|
-
return item.key.toString() === transformedKey;
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
// 添加属性到函数对象
|
|
233
|
-
Object.assign(keyFilter, {
|
|
234
|
-
key: transformedKey,
|
|
235
|
-
$type: 'key' as const
|
|
236
|
-
});
|
|
237
|
-
return keyFilter ;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (isPrefixFilter(filter)) {
|
|
241
|
-
const transformedPrefix = transform.convert(new Key(filter.prefix)).toString();
|
|
242
|
-
|
|
243
|
-
// 创建一个函数对象
|
|
244
|
-
const prefixFilter = function(item: Pair): boolean {
|
|
245
|
-
return item.key.toString().startsWith(transformedPrefix);
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
// 添加属性到函数对象
|
|
249
|
-
Object.assign(prefixFilter, {
|
|
250
|
-
prefix: transformedPrefix,
|
|
251
|
-
$type: 'prefix' as const
|
|
252
|
-
});
|
|
253
|
-
return prefixFilter;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
throw new Error('Unsupported filter type');
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
private static createKeyFilter(originalKey: string): (entry: Pair) => boolean {
|
|
260
|
-
return (entry) => entry.key.toString() === originalKey;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
private static createPrefixFilter(originalPrefix: string): (entry: Pair) => boolean {
|
|
264
|
-
return (entry) => entry.key.toString().startsWith(originalPrefix);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
// ======== 辅助类型定义 ========
|
|
271
|
-
interface KeyFilter extends QueryFilter {
|
|
272
|
-
key: string;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
interface PrefixFilter extends QueryFilter {
|
|
276
|
-
prefix: string;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// 前缀转换实现
|
|
280
|
-
class PrefixTransform implements KeyTransform {
|
|
281
|
-
private prefix: Key
|
|
282
|
-
|
|
283
|
-
constructor(prefix: string) {
|
|
284
|
-
this.prefix = new Key(prefix)
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
convert(key: Key): Key {
|
|
288
|
-
return new Key(this.prefix.toString() + key.toString())
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
invert(key: Key): Key {
|
|
292
|
-
const keyStr = key.toString()
|
|
293
|
-
const prefixStr = this.prefix.toString()
|
|
294
|
-
if (!keyStr.startsWith(prefixStr)) {
|
|
295
|
-
throw new Error('Invalid prefix')
|
|
296
|
-
}
|
|
297
|
-
return new Key(keyStr.slice(prefixStr.length))
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// 导出
|
|
302
|
-
export {
|
|
303
|
-
TransformedDatastore,
|
|
304
|
-
PrefixTransform,
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
// Add a default export
|
|
308
|
-
export default TransformedDatastore;
|