@brightchain/brightchain-lib 0.29.26 → 0.30.1
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/package.json +10 -4
- package/src/index.d.ts +1 -1
- package/src/index.d.ts.map +1 -1
- package/src/index.js +2 -1
- package/src/index.js.map +1 -1
- package/src/lib/constants.d.ts +3 -26
- package/src/lib/constants.d.ts.map +1 -1
- package/src/lib/constants.js +2 -1
- package/src/lib/constants.js.map +1 -1
- package/src/lib/db/collection.d.ts +1 -1
- package/src/lib/db/collection.d.ts.map +1 -1
- package/src/lib/db/collection.js +2 -1
- package/src/lib/db/collection.js.map +1 -1
- package/src/lib/enumeration-translations/index.d.ts +2 -0
- package/src/lib/enumeration-translations/index.d.ts.map +1 -1
- package/src/lib/enumeration-translations/index.js +1 -0
- package/src/lib/enumeration-translations/index.js.map +1 -1
- package/src/lib/enumeration-translations/memberStatusType.d.ts +5 -0
- package/src/lib/enumeration-translations/memberStatusType.d.ts.map +1 -0
- package/src/lib/enumeration-translations/memberStatusType.js +58 -0
- package/src/lib/enumeration-translations/memberStatusType.js.map +1 -0
- package/src/lib/enumerations/brightChainStrings.d.ts +61 -0
- package/src/lib/enumerations/brightChainStrings.d.ts.map +1 -1
- package/src/lib/enumerations/brightChainStrings.js +64 -0
- package/src/lib/enumerations/brightChainStrings.js.map +1 -1
- package/src/lib/enumerations/brightchainFeatures.d.ts +1 -0
- package/src/lib/enumerations/brightchainFeatures.d.ts.map +1 -1
- package/src/lib/enumerations/brightchainFeatures.js +1 -0
- package/src/lib/enumerations/brightchainFeatures.js.map +1 -1
- package/src/lib/enumerations/communication.d.ts +7 -1
- package/src/lib/enumerations/communication.d.ts.map +1 -1
- package/src/lib/enumerations/communication.js +6 -0
- package/src/lib/enumerations/communication.js.map +1 -1
- package/src/lib/enumerations/friendRequestStatus.d.ts +7 -0
- package/src/lib/enumerations/friendRequestStatus.d.ts.map +1 -0
- package/src/lib/enumerations/friendRequestStatus.js +11 -0
- package/src/lib/enumerations/friendRequestStatus.js.map +1 -0
- package/src/lib/enumerations/friendsErrorCode.d.ts +10 -0
- package/src/lib/enumerations/friendsErrorCode.d.ts.map +1 -0
- package/src/lib/enumerations/friendsErrorCode.js +14 -0
- package/src/lib/enumerations/friendsErrorCode.js.map +1 -0
- package/src/lib/enumerations/friendshipStatus.d.ts +7 -0
- package/src/lib/enumerations/friendshipStatus.d.ts.map +1 -0
- package/src/lib/enumerations/friendshipStatus.js +11 -0
- package/src/lib/enumerations/friendshipStatus.js.map +1 -0
- package/src/lib/enumerations/index.d.ts +3 -0
- package/src/lib/enumerations/index.d.ts.map +1 -1
- package/src/lib/enumerations/index.js +4 -0
- package/src/lib/enumerations/index.js.map +1 -1
- package/src/lib/enumerations/messaging/emailErrorType.d.ts +15 -2
- package/src/lib/enumerations/messaging/emailErrorType.d.ts.map +1 -1
- package/src/lib/enumerations/messaging/emailErrorType.js +17 -1
- package/src/lib/enumerations/messaging/emailErrorType.js.map +1 -1
- package/src/lib/enumerations/messaging/messageEncryptionScheme.d.ts +4 -2
- package/src/lib/enumerations/messaging/messageEncryptionScheme.d.ts.map +1 -1
- package/src/lib/enumerations/messaging/messageEncryptionScheme.js +3 -1
- package/src/lib/enumerations/messaging/messageEncryptionScheme.js.map +1 -1
- package/src/lib/errors/encryptionErrors.d.ts +71 -0
- package/src/lib/errors/encryptionErrors.d.ts.map +1 -0
- package/src/lib/errors/encryptionErrors.js +112 -0
- package/src/lib/errors/encryptionErrors.js.map +1 -0
- package/src/lib/errors/friendsServiceError.d.ts +20 -0
- package/src/lib/errors/friendsServiceError.d.ts.map +1 -0
- package/src/lib/errors/friendsServiceError.js +48 -0
- package/src/lib/errors/friendsServiceError.js.map +1 -0
- package/src/lib/errors/index.d.ts +15 -0
- package/src/lib/errors/index.d.ts.map +1 -1
- package/src/lib/errors/index.js +21 -0
- package/src/lib/errors/index.js.map +1 -1
- package/src/lib/i18n/i18n-setup.d.ts +2 -2
- package/src/lib/i18n/i18n-setup.d.ts.map +1 -1
- package/src/lib/i18n/strings/englishUK.d.ts +2 -2
- package/src/lib/i18n/strings/englishUK.d.ts.map +1 -1
- package/src/lib/i18n/strings/englishUK.js.map +1 -1
- package/src/lib/i18n/strings/englishUs.d.ts +2 -2
- package/src/lib/i18n/strings/englishUs.d.ts.map +1 -1
- package/src/lib/i18n/strings/englishUs.js +65 -1
- package/src/lib/i18n/strings/englishUs.js.map +1 -1
- package/src/lib/i18n/strings/french.d.ts +2 -2
- package/src/lib/i18n/strings/french.d.ts.map +1 -1
- package/src/lib/i18n/strings/french.js +78 -13
- package/src/lib/i18n/strings/french.js.map +1 -1
- package/src/lib/i18n/strings/german.d.ts +2 -2
- package/src/lib/i18n/strings/german.d.ts.map +1 -1
- package/src/lib/i18n/strings/german.js +77 -12
- package/src/lib/i18n/strings/german.js.map +1 -1
- package/src/lib/i18n/strings/japanese.d.ts +2 -2
- package/src/lib/i18n/strings/japanese.d.ts.map +1 -1
- package/src/lib/i18n/strings/japanese.js +77 -12
- package/src/lib/i18n/strings/japanese.js.map +1 -1
- package/src/lib/i18n/strings/mandarin.d.ts +2 -2
- package/src/lib/i18n/strings/mandarin.d.ts.map +1 -1
- package/src/lib/i18n/strings/mandarin.js +77 -12
- package/src/lib/i18n/strings/mandarin.js.map +1 -1
- package/src/lib/i18n/strings/spanish.d.ts +2 -2
- package/src/lib/i18n/strings/spanish.d.ts.map +1 -1
- package/src/lib/i18n/strings/spanish.js +77 -12
- package/src/lib/i18n/strings/spanish.js.map +1 -1
- package/src/lib/i18n/strings/ukrainian.d.ts +2 -2
- package/src/lib/i18n/strings/ukrainian.d.ts.map +1 -1
- package/src/lib/i18n/strings/ukrainian.js +77 -12
- package/src/lib/i18n/strings/ukrainian.js.map +1 -1
- package/src/lib/index.d.ts +31 -0
- package/src/lib/index.d.ts.map +1 -1
- package/src/lib/index.js +29 -1
- package/src/lib/index.js.map +1 -1
- package/src/lib/interfaces/appSubsystemPlugin.d.ts +69 -0
- package/src/lib/interfaces/appSubsystemPlugin.d.ts.map +1 -0
- package/src/lib/interfaces/appSubsystemPlugin.js +3 -0
- package/src/lib/interfaces/appSubsystemPlugin.js.map +1 -0
- package/src/lib/interfaces/auth/writeProof.d.ts +2 -0
- package/src/lib/interfaces/auth/writeProof.d.ts.map +1 -1
- package/src/lib/interfaces/auth/writeProofUtils.d.ts +1 -1
- package/src/lib/interfaces/auth/writeProofUtils.d.ts.map +1 -1
- package/src/lib/interfaces/auth/writeProofUtils.js +2 -2
- package/src/lib/interfaces/auth/writeProofUtils.js.map +1 -1
- package/src/lib/interfaces/availability/gossipService.d.ts +99 -1
- package/src/lib/interfaces/availability/gossipService.d.ts.map +1 -1
- package/src/lib/interfaces/availability/gossipService.js +4 -0
- package/src/lib/interfaces/availability/gossipService.js.map +1 -1
- package/src/lib/interfaces/communication/blockContentStore.d.ts +57 -0
- package/src/lib/interfaces/communication/blockContentStore.d.ts.map +1 -0
- package/src/lib/interfaces/communication/blockContentStore.js +21 -0
- package/src/lib/interfaces/communication/blockContentStore.js.map +1 -0
- package/src/lib/interfaces/communication/chatStorageProvider.d.ts +77 -0
- package/src/lib/interfaces/communication/chatStorageProvider.d.ts.map +1 -0
- package/src/lib/interfaces/communication/chatStorageProvider.js +25 -0
- package/src/lib/interfaces/communication/chatStorageProvider.js.map +1 -0
- package/src/lib/interfaces/communication/index.d.ts +4 -0
- package/src/lib/interfaces/communication/index.d.ts.map +1 -0
- package/src/lib/interfaces/communication/index.js +3 -0
- package/src/lib/interfaces/communication/index.js.map +1 -0
- package/src/lib/interfaces/communication/server.d.ts +57 -0
- package/src/lib/interfaces/communication/server.d.ts.map +1 -0
- package/src/lib/interfaces/communication/server.js +14 -0
- package/src/lib/interfaces/communication/server.js.map +1 -0
- package/src/lib/interfaces/communication.d.ts +62 -5
- package/src/lib/interfaces/communication.d.ts.map +1 -1
- package/src/lib/interfaces/communication.js +8 -0
- package/src/lib/interfaces/communication.js.map +1 -1
- package/src/lib/interfaces/communicationEvents.d.ts +59 -1
- package/src/lib/interfaces/communicationEvents.d.ts.map +1 -1
- package/src/lib/interfaces/constants.d.ts +2 -0
- package/src/lib/interfaces/constants.d.ts.map +1 -1
- package/src/lib/interfaces/events/communicationEventEmitter.d.ts +9 -0
- package/src/lib/interfaces/events/communicationEventEmitter.d.ts.map +1 -1
- package/src/lib/interfaces/events/communicationEventEmitter.js +9 -0
- package/src/lib/interfaces/events/communicationEventEmitter.js.map +1 -1
- package/src/lib/interfaces/friends/baseFriendRequest.d.ts +13 -0
- package/src/lib/interfaces/friends/baseFriendRequest.d.ts.map +1 -0
- package/src/lib/interfaces/friends/baseFriendRequest.js +3 -0
- package/src/lib/interfaces/friends/baseFriendRequest.js.map +1 -0
- package/src/lib/interfaces/friends/baseFriendship.d.ts +11 -0
- package/src/lib/interfaces/friends/baseFriendship.d.ts.map +1 -0
- package/src/lib/interfaces/friends/baseFriendship.js +3 -0
- package/src/lib/interfaces/friends/baseFriendship.js.map +1 -0
- package/src/lib/interfaces/friends/friendsService.d.ts +32 -0
- package/src/lib/interfaces/friends/friendsService.d.ts.map +1 -0
- package/src/lib/interfaces/friends/friendsService.js +3 -0
- package/src/lib/interfaces/friends/friendsService.js.map +1 -0
- package/src/lib/interfaces/friends/friendsSuggestionProvider.d.ts +17 -0
- package/src/lib/interfaces/friends/friendsSuggestionProvider.d.ts.map +1 -0
- package/src/lib/interfaces/friends/friendsSuggestionProvider.js +3 -0
- package/src/lib/interfaces/friends/friendsSuggestionProvider.js.map +1 -0
- package/src/lib/interfaces/friends/index.d.ts +6 -0
- package/src/lib/interfaces/friends/index.d.ts.map +1 -0
- package/src/lib/interfaces/friends/index.js +3 -0
- package/src/lib/interfaces/friends/index.js.map +1 -0
- package/src/lib/interfaces/friends/pagination.d.ts +11 -0
- package/src/lib/interfaces/friends/pagination.d.ts.map +1 -0
- package/src/lib/interfaces/friends/pagination.js +3 -0
- package/src/lib/interfaces/friends/pagination.js.map +1 -0
- package/src/lib/interfaces/index.d.ts +6 -1
- package/src/lib/interfaces/index.d.ts.map +1 -1
- package/src/lib/interfaces/index.js +3 -0
- package/src/lib/interfaces/index.js.map +1 -1
- package/src/lib/interfaces/messaging/gpgKey.d.ts +93 -0
- package/src/lib/interfaces/messaging/gpgKey.d.ts.map +1 -0
- package/src/lib/interfaces/messaging/gpgKey.js +12 -0
- package/src/lib/interfaces/messaging/gpgKey.js.map +1 -0
- package/src/lib/interfaces/messaging/index.d.ts +4 -0
- package/src/lib/interfaces/messaging/index.d.ts.map +1 -1
- package/src/lib/interfaces/messaging/index.js +4 -0
- package/src/lib/interfaces/messaging/index.js.map +1 -1
- package/src/lib/interfaces/messaging/keyStore.d.ts +100 -0
- package/src/lib/interfaces/messaging/keyStore.d.ts.map +1 -0
- package/src/lib/interfaces/messaging/keyStore.js +13 -0
- package/src/lib/interfaces/messaging/keyStore.js.map +1 -0
- package/src/lib/interfaces/messaging/recipientKeyResolver.d.ts +92 -0
- package/src/lib/interfaces/messaging/recipientKeyResolver.d.ts.map +1 -0
- package/src/lib/interfaces/messaging/recipientKeyResolver.js +13 -0
- package/src/lib/interfaces/messaging/recipientKeyResolver.js.map +1 -0
- package/src/lib/interfaces/messaging/smimeCertificate.d.ts +99 -0
- package/src/lib/interfaces/messaging/smimeCertificate.d.ts.map +1 -0
- package/src/lib/interfaces/messaging/smimeCertificate.js +12 -0
- package/src/lib/interfaces/messaging/smimeCertificate.js.map +1 -0
- package/src/lib/interfaces/responses/adminDashboardResponse.d.ts +8 -0
- package/src/lib/interfaces/responses/adminDashboardResponse.d.ts.map +1 -1
- package/src/lib/interfaces/responses/communicationResponses.d.ts +25 -0
- package/src/lib/interfaces/responses/communicationResponses.d.ts.map +1 -1
- package/src/lib/interfaces/storage/documentTypes.d.ts +4 -0
- package/src/lib/interfaces/storage/documentTypes.d.ts.map +1 -1
- package/src/lib/services/blockService.d.ts +11 -3
- package/src/lib/services/blockService.d.ts.map +1 -1
- package/src/lib/services/blockService.js +22 -2
- package/src/lib/services/blockService.js.map +1 -1
- package/src/lib/services/communication/__tests__/mockChatStorageProvider.d.ts +108 -0
- package/src/lib/services/communication/__tests__/mockChatStorageProvider.d.ts.map +1 -0
- package/src/lib/services/communication/__tests__/mockChatStorageProvider.js +284 -0
- package/src/lib/services/communication/__tests__/mockChatStorageProvider.js.map +1 -0
- package/src/lib/services/communication/attachmentUtils.d.ts +20 -0
- package/src/lib/services/communication/attachmentUtils.d.ts.map +1 -0
- package/src/lib/services/communication/attachmentUtils.js +43 -0
- package/src/lib/services/communication/attachmentUtils.js.map +1 -0
- package/src/lib/services/communication/channelService.d.ts +143 -14
- package/src/lib/services/communication/channelService.d.ts.map +1 -1
- package/src/lib/services/communication/channelService.js +562 -41
- package/src/lib/services/communication/channelService.js.map +1 -1
- package/src/lib/services/communication/conversationService.d.ts +91 -4
- package/src/lib/services/communication/conversationService.d.ts.map +1 -1
- package/src/lib/services/communication/conversationService.js +269 -7
- package/src/lib/services/communication/conversationService.js.map +1 -1
- package/src/lib/services/communication/eciesKeyEncryptionHandler.d.ts +36 -0
- package/src/lib/services/communication/eciesKeyEncryptionHandler.d.ts.map +1 -0
- package/src/lib/services/communication/eciesKeyEncryptionHandler.js +30 -0
- package/src/lib/services/communication/eciesKeyEncryptionHandler.js.map +1 -0
- package/src/lib/services/communication/groupService.d.ts +99 -21
- package/src/lib/services/communication/groupService.d.ts.map +1 -1
- package/src/lib/services/communication/groupService.js +387 -41
- package/src/lib/services/communication/groupService.js.map +1 -1
- package/src/lib/services/communication/index.d.ts +6 -1
- package/src/lib/services/communication/index.d.ts.map +1 -1
- package/src/lib/services/communication/index.js +20 -1
- package/src/lib/services/communication/index.js.map +1 -1
- package/src/lib/services/communication/keyEpochManager.d.ts +41 -0
- package/src/lib/services/communication/keyEpochManager.d.ts.map +1 -0
- package/src/lib/services/communication/keyEpochManager.js +59 -0
- package/src/lib/services/communication/keyEpochManager.js.map +1 -0
- package/src/lib/services/communication/rehydrationHelpers.d.ts +32 -0
- package/src/lib/services/communication/rehydrationHelpers.d.ts.map +1 -0
- package/src/lib/services/communication/rehydrationHelpers.js +58 -0
- package/src/lib/services/communication/rehydrationHelpers.js.map +1 -0
- package/src/lib/services/communication/serverService.d.ts +193 -0
- package/src/lib/services/communication/serverService.d.ts.map +1 -0
- package/src/lib/services/communication/serverService.js +495 -0
- package/src/lib/services/communication/serverService.js.map +1 -0
- package/src/lib/services/copyOnWrite.service.d.ts +110 -0
- package/src/lib/services/copyOnWrite.service.d.ts.map +1 -0
- package/src/lib/services/copyOnWrite.service.js +256 -0
- package/src/lib/services/copyOnWrite.service.js.map +1 -0
- package/src/lib/services/index.d.ts +1 -0
- package/src/lib/services/index.d.ts.map +1 -1
- package/src/lib/services/index.js +1 -0
- package/src/lib/services/index.js.map +1 -1
- package/src/lib/services/memberStore.d.ts +17 -1
- package/src/lib/services/memberStore.d.ts.map +1 -1
- package/src/lib/services/memberStore.js +98 -17
- package/src/lib/services/memberStore.js.map +1 -1
- package/src/lib/services/messaging/emailEncryptionService.d.ts +162 -0
- package/src/lib/services/messaging/emailEncryptionService.d.ts.map +1 -1
- package/src/lib/services/messaging/emailEncryptionService.js +293 -0
- package/src/lib/services/messaging/emailEncryptionService.js.map +1 -1
- package/src/lib/services/messaging/emailMessageService.d.ts +64 -0
- package/src/lib/services/messaging/emailMessageService.d.ts.map +1 -1
- package/src/lib/services/messaging/emailMessageService.js +142 -13
- package/src/lib/services/messaging/emailMessageService.js.map +1 -1
- package/src/lib/services/messaging/gpgKeyManager.d.ts +130 -0
- package/src/lib/services/messaging/gpgKeyManager.d.ts.map +1 -0
- package/src/lib/services/messaging/gpgKeyManager.js +381 -0
- package/src/lib/services/messaging/gpgKeyManager.js.map +1 -0
- package/src/lib/services/messaging/index.d.ts +3 -0
- package/src/lib/services/messaging/index.d.ts.map +1 -1
- package/src/lib/services/messaging/index.js +3 -0
- package/src/lib/services/messaging/index.js.map +1 -1
- package/src/lib/services/messaging/recipientKeyResolver.d.ts +47 -0
- package/src/lib/services/messaging/recipientKeyResolver.d.ts.map +1 -0
- package/src/lib/services/messaging/recipientKeyResolver.js +132 -0
- package/src/lib/services/messaging/recipientKeyResolver.js.map +1 -0
- package/src/lib/services/messaging/smimeCertificateManager.d.ts +207 -0
- package/src/lib/services/messaging/smimeCertificateManager.d.ts.map +1 -0
- package/src/lib/services/messaging/smimeCertificateManager.js +696 -0
- package/src/lib/services/messaging/smimeCertificateManager.js.map +1 -0
- package/src/lib/utils/index.d.ts +6 -0
- package/src/lib/utils/index.d.ts.map +1 -1
- package/src/lib/utils/index.js +9 -0
- package/src/lib/utils/index.js.map +1 -1
- package/src/lib/utils/sortPair.d.ts +6 -0
- package/src/lib/utils/sortPair.d.ts.map +1 -0
- package/src/lib/utils/sortPair.js +11 -0
- package/src/lib/utils/sortPair.js.map +1 -0
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ServerService — manages server lifecycle, membership, and channel organization.
|
|
4
|
+
*
|
|
5
|
+
* Maintains in-memory stores for servers. When an IChatStorageProvider is
|
|
6
|
+
* injected, servers are also persisted to the provider's collections (write-through).
|
|
7
|
+
* Without a provider (e.g. in unit tests), services fall back to in-memory Maps.
|
|
8
|
+
*
|
|
9
|
+
* Requirements: 1.1, 1.3, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ServerService = exports.ServerInviteExpiredError = exports.ServerInviteNotFoundError = exports.MemberAlreadyInServerError = exports.ServerNameValidationError = exports.NotServerMemberError = exports.ServerPermissionError = exports.ServerNotFoundError = void 0;
|
|
13
|
+
const uuid_1 = require("uuid");
|
|
14
|
+
const communication_1 = require("../../enumerations/communication");
|
|
15
|
+
const events_1 = require("../../interfaces/events");
|
|
16
|
+
const pagination_1 = require("../../utils/pagination");
|
|
17
|
+
// ─── Error classes ──────────────────────────────────────────────────────────
|
|
18
|
+
class ServerNotFoundError extends Error {
|
|
19
|
+
constructor(serverId) {
|
|
20
|
+
super(`Server ${serverId} not found`);
|
|
21
|
+
this.name = 'ServerNotFoundError';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.ServerNotFoundError = ServerNotFoundError;
|
|
25
|
+
class ServerPermissionError extends Error {
|
|
26
|
+
constructor(message = 'You do not have permission to perform this action') {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = 'ServerPermissionError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.ServerPermissionError = ServerPermissionError;
|
|
32
|
+
class NotServerMemberError extends Error {
|
|
33
|
+
constructor() {
|
|
34
|
+
super('You are not a member of this server');
|
|
35
|
+
this.name = 'NotServerMemberError';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.NotServerMemberError = NotServerMemberError;
|
|
39
|
+
class ServerNameValidationError extends Error {
|
|
40
|
+
constructor(message = 'Server name must be between 1 and 100 characters') {
|
|
41
|
+
super(message);
|
|
42
|
+
this.name = 'ServerNameValidationError';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.ServerNameValidationError = ServerNameValidationError;
|
|
46
|
+
class MemberAlreadyInServerError extends Error {
|
|
47
|
+
constructor(memberId) {
|
|
48
|
+
super(`Member ${memberId} is already in this server`);
|
|
49
|
+
this.name = 'MemberAlreadyInServerError';
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.MemberAlreadyInServerError = MemberAlreadyInServerError;
|
|
53
|
+
class ServerInviteNotFoundError extends Error {
|
|
54
|
+
constructor(token) {
|
|
55
|
+
super(`Server invite token ${token} not found`);
|
|
56
|
+
this.name = 'ServerInviteNotFoundError';
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.ServerInviteNotFoundError = ServerInviteNotFoundError;
|
|
60
|
+
class ServerInviteExpiredError extends Error {
|
|
61
|
+
constructor() {
|
|
62
|
+
super('Server invite token has expired or exceeded max uses');
|
|
63
|
+
this.name = 'ServerInviteExpiredError';
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.ServerInviteExpiredError = ServerInviteExpiredError;
|
|
67
|
+
// ─── Service ────────────────────────────────────────────────────────────────
|
|
68
|
+
class ServerService {
|
|
69
|
+
/** serverId → IServer */
|
|
70
|
+
servers = new Map();
|
|
71
|
+
/** token → IServerInviteToken */
|
|
72
|
+
serverInviteTokens = new Map();
|
|
73
|
+
channelService;
|
|
74
|
+
eventEmitter;
|
|
75
|
+
/** Optional persistent collection for servers (write-through). */
|
|
76
|
+
serverCollection;
|
|
77
|
+
/** Optional persistent collection for server invite tokens (write-through). */
|
|
78
|
+
serverInviteCollection;
|
|
79
|
+
/** Whether init() has already been called. */
|
|
80
|
+
initialized = false;
|
|
81
|
+
constructor(options) {
|
|
82
|
+
this.channelService = options.channelService;
|
|
83
|
+
this.eventEmitter = options.eventEmitter ?? new events_1.NullEventEmitter();
|
|
84
|
+
if (options.storageProvider) {
|
|
85
|
+
this.serverCollection = options.storageProvider.servers;
|
|
86
|
+
this.serverInviteCollection = options.storageProvider.serverInvites;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// ─── Rehydration ──────────────────────────────────────────────────────
|
|
90
|
+
/**
|
|
91
|
+
* Load persisted servers and server invite tokens back into in-memory Maps.
|
|
92
|
+
*
|
|
93
|
+
* Idempotent: only the first call performs rehydration. No-op when no
|
|
94
|
+
* storage provider was supplied at construction time.
|
|
95
|
+
*
|
|
96
|
+
* Requirements: 1.4, 1.5, 1.6, 5.1, 5.2, 8.1, 8.2, 9.1
|
|
97
|
+
*/
|
|
98
|
+
async init() {
|
|
99
|
+
if (this.initialized)
|
|
100
|
+
return;
|
|
101
|
+
if (!this.serverCollection)
|
|
102
|
+
return;
|
|
103
|
+
this.initialized = true;
|
|
104
|
+
// ── Load servers ──────────────────────────────────────────────────
|
|
105
|
+
let loadedServers;
|
|
106
|
+
try {
|
|
107
|
+
loadedServers = await this.serverCollection.findMany();
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
console.error('[ServerService] Failed to load from servers collection:', error);
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
for (const server of loadedServers) {
|
|
114
|
+
this.servers.set(server.id, server);
|
|
115
|
+
}
|
|
116
|
+
// ── Load server invite tokens ───────────────────────────────────
|
|
117
|
+
let loadedInvites;
|
|
118
|
+
try {
|
|
119
|
+
loadedInvites = await this.serverInviteCollection.findMany();
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
console.error('[ServerService] Failed to load from serverInvites collection:', error);
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
for (const invite of loadedInvites) {
|
|
126
|
+
this.serverInviteTokens.set(invite.token, invite);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// ─── Helpers ──────────────────────────────────────────────────────────
|
|
130
|
+
validateServerName(name) {
|
|
131
|
+
if (!name || name.length === 0 || name.length > 100) {
|
|
132
|
+
throw new ServerNameValidationError();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
assertServerExists(serverId) {
|
|
136
|
+
const server = this.servers.get(serverId);
|
|
137
|
+
if (!server)
|
|
138
|
+
throw new ServerNotFoundError(serverId);
|
|
139
|
+
return server;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Returns the role of a member within a server.
|
|
143
|
+
* The server owner always has OWNER role; all other members have MEMBER role.
|
|
144
|
+
* Returns null if the user is not a member.
|
|
145
|
+
*/
|
|
146
|
+
getMemberRole(serverId, memberId) {
|
|
147
|
+
const server = this.servers.get(serverId);
|
|
148
|
+
if (!server)
|
|
149
|
+
return null;
|
|
150
|
+
if (!server.memberIds.includes(memberId))
|
|
151
|
+
return null;
|
|
152
|
+
if (server.ownerId === memberId)
|
|
153
|
+
return communication_1.DefaultRole.OWNER;
|
|
154
|
+
return communication_1.DefaultRole.MEMBER;
|
|
155
|
+
}
|
|
156
|
+
assertCanUpdate(server, userId) {
|
|
157
|
+
const role = this.getMemberRole(server.id, userId);
|
|
158
|
+
if (role !== communication_1.DefaultRole.OWNER && role !== communication_1.DefaultRole.ADMIN) {
|
|
159
|
+
throw new ServerPermissionError('Only the server owner or admin can update this server');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
assertCanDelete(server, userId) {
|
|
163
|
+
if (server.ownerId !== userId) {
|
|
164
|
+
throw new ServerPermissionError('Only the server owner can delete this server');
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// ─── CRUD ─────────────────────────────────────────────────────────────
|
|
168
|
+
/**
|
|
169
|
+
* Create a new server with a default "General" category and "general" channel.
|
|
170
|
+
* The owner is added as the first member.
|
|
171
|
+
*
|
|
172
|
+
* Requirements: 1.1, 1.3, 2.1
|
|
173
|
+
*/
|
|
174
|
+
async createServer(ownerId, params) {
|
|
175
|
+
this.validateServerName(params.name);
|
|
176
|
+
const now = new Date();
|
|
177
|
+
const serverId = (0, uuid_1.v4)();
|
|
178
|
+
const categoryId = (0, uuid_1.v4)();
|
|
179
|
+
// Create the default "general" channel via ChannelService
|
|
180
|
+
const generalChannel = await this.channelService.createChannel('general', ownerId, communication_1.ChannelVisibility.PUBLIC, '', serverId);
|
|
181
|
+
// serverId is already set by createChannel above
|
|
182
|
+
// Build the default "General" category
|
|
183
|
+
const defaultCategory = {
|
|
184
|
+
id: categoryId,
|
|
185
|
+
name: 'General',
|
|
186
|
+
position: 0,
|
|
187
|
+
channelIds: [generalChannel.id],
|
|
188
|
+
};
|
|
189
|
+
const server = {
|
|
190
|
+
id: serverId,
|
|
191
|
+
name: params.name,
|
|
192
|
+
iconUrl: params.iconUrl,
|
|
193
|
+
ownerId,
|
|
194
|
+
memberIds: [ownerId],
|
|
195
|
+
channelIds: [generalChannel.id],
|
|
196
|
+
categories: [defaultCategory],
|
|
197
|
+
createdAt: now,
|
|
198
|
+
updatedAt: now,
|
|
199
|
+
};
|
|
200
|
+
this.servers.set(serverId, server);
|
|
201
|
+
// Persist to storage provider if available
|
|
202
|
+
if (this.serverCollection) {
|
|
203
|
+
await this.serverCollection.create(server);
|
|
204
|
+
}
|
|
205
|
+
return server;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Get a server by ID.
|
|
209
|
+
* Throws ServerNotFoundError if the server does not exist.
|
|
210
|
+
*
|
|
211
|
+
* Requirement: 2.3
|
|
212
|
+
*/
|
|
213
|
+
async getServer(serverId) {
|
|
214
|
+
return this.assertServerExists(serverId);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Update server settings (name, iconUrl, categories).
|
|
218
|
+
* Only the owner or admin can update.
|
|
219
|
+
*
|
|
220
|
+
* Requirements: 2.4, 2.5
|
|
221
|
+
*/
|
|
222
|
+
async updateServer(serverId, userId, update) {
|
|
223
|
+
const server = this.assertServerExists(serverId);
|
|
224
|
+
this.assertCanUpdate(server, userId);
|
|
225
|
+
if (update.name !== undefined) {
|
|
226
|
+
this.validateServerName(update.name);
|
|
227
|
+
server.name = update.name;
|
|
228
|
+
}
|
|
229
|
+
if (update.iconUrl !== undefined) {
|
|
230
|
+
server.iconUrl = update.iconUrl;
|
|
231
|
+
}
|
|
232
|
+
if (update.categories !== undefined) {
|
|
233
|
+
server.categories = update.categories;
|
|
234
|
+
}
|
|
235
|
+
server.updatedAt = new Date();
|
|
236
|
+
// Persist to storage provider if available
|
|
237
|
+
if (this.serverCollection) {
|
|
238
|
+
await this.serverCollection.update(serverId, server);
|
|
239
|
+
}
|
|
240
|
+
return server;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Delete a server and cascade-delete all its channels.
|
|
244
|
+
* Only the owner can delete.
|
|
245
|
+
*
|
|
246
|
+
* Requirements: 2.5, 2.6
|
|
247
|
+
*/
|
|
248
|
+
async deleteServer(serverId, userId) {
|
|
249
|
+
const server = this.assertServerExists(serverId);
|
|
250
|
+
this.assertCanDelete(server, userId);
|
|
251
|
+
// Cascade delete all channels belonging to this server
|
|
252
|
+
for (const channelId of server.channelIds) {
|
|
253
|
+
try {
|
|
254
|
+
await this.channelService.deleteChannel(channelId, server.ownerId);
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
// Channel may already be deleted; continue cleanup
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
this.servers.delete(serverId);
|
|
261
|
+
// Persist deletion to storage provider if available
|
|
262
|
+
if (this.serverCollection) {
|
|
263
|
+
await this.serverCollection.delete(serverId);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* List all servers where the given member is a member.
|
|
268
|
+
* Supports cursor-based pagination.
|
|
269
|
+
*
|
|
270
|
+
* Requirement: 2.2
|
|
271
|
+
*/
|
|
272
|
+
async listServersForMember(memberId, pagination) {
|
|
273
|
+
const memberServers = Array.from(this.servers.values()).filter((s) => s.memberIds.includes(memberId));
|
|
274
|
+
// Sort by creation date descending (newest first)
|
|
275
|
+
memberServers.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
276
|
+
return (0, pagination_1.paginateItems)(memberServers, pagination?.cursor, pagination?.limit ?? 50);
|
|
277
|
+
}
|
|
278
|
+
// ─── Membership ────────────────────────────────────────────────────────
|
|
279
|
+
/**
|
|
280
|
+
* Add members to a server. Only owner or admin can add members.
|
|
281
|
+
* Skips members who are already in the server. Returns the list of
|
|
282
|
+
* actually added member IDs.
|
|
283
|
+
*
|
|
284
|
+
* After adding, distributes channel keys for all server channels
|
|
285
|
+
* to each new member via ChannelService.addMemberToChannel().
|
|
286
|
+
*
|
|
287
|
+
* Requirements: 2.7, 6.1, 6.2, 6.3
|
|
288
|
+
*/
|
|
289
|
+
async addMembers(serverId, userId, memberIds) {
|
|
290
|
+
const server = this.assertServerExists(serverId);
|
|
291
|
+
this.assertCanUpdate(server, userId);
|
|
292
|
+
const added = [];
|
|
293
|
+
for (const memberId of memberIds) {
|
|
294
|
+
if (!server.memberIds.includes(memberId)) {
|
|
295
|
+
server.memberIds.push(memberId);
|
|
296
|
+
added.push(memberId);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
if (added.length > 0) {
|
|
300
|
+
// Distribute channel keys for all server channels to each new member
|
|
301
|
+
for (const memberId of added) {
|
|
302
|
+
for (const channelId of server.channelIds) {
|
|
303
|
+
await this.channelService.addMemberToChannel(channelId, memberId);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
server.updatedAt = new Date();
|
|
307
|
+
// Persist to storage provider if available
|
|
308
|
+
if (this.serverCollection) {
|
|
309
|
+
await this.serverCollection.update(serverId, server);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return added;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Remove a member from a server and all of its channels.
|
|
316
|
+
* Only owner or admin can remove members. Emits SERVER_MEMBER_REMOVED event.
|
|
317
|
+
*
|
|
318
|
+
* Delegates to ChannelService.removeMemberFromChannel() for each channel,
|
|
319
|
+
* which performs epoch-aware key rotation and removes the member's wrapped
|
|
320
|
+
* key entries from all epochs.
|
|
321
|
+
*
|
|
322
|
+
* Requirements: 2.8, 7.1, 7.2, 7.3
|
|
323
|
+
*/
|
|
324
|
+
async removeMember(serverId, userId, memberId) {
|
|
325
|
+
const server = this.assertServerExists(serverId);
|
|
326
|
+
this.assertCanUpdate(server, userId);
|
|
327
|
+
// Remove from server memberIds
|
|
328
|
+
server.memberIds = server.memberIds.filter((id) => id !== memberId);
|
|
329
|
+
// Remove from all server channels via ChannelService (triggers key rotation)
|
|
330
|
+
for (const channelId of server.channelIds) {
|
|
331
|
+
await this.channelService.removeMemberFromChannel(channelId, memberId);
|
|
332
|
+
}
|
|
333
|
+
server.updatedAt = new Date();
|
|
334
|
+
// Persist to storage provider if available
|
|
335
|
+
if (this.serverCollection) {
|
|
336
|
+
await this.serverCollection.update(serverId, server);
|
|
337
|
+
}
|
|
338
|
+
this.eventEmitter.emitServerMemberRemoved(serverId, memberId);
|
|
339
|
+
}
|
|
340
|
+
// ─── Invites ──────────────────────────────────────────────────────────
|
|
341
|
+
/**
|
|
342
|
+
* Create an invite token for a server.
|
|
343
|
+
* Only members of the server can create invites.
|
|
344
|
+
* Generates a unique token with optional expiration and max-use limits.
|
|
345
|
+
*
|
|
346
|
+
* Requirements: 3.1
|
|
347
|
+
*/
|
|
348
|
+
async createInvite(serverId, userId, params) {
|
|
349
|
+
const server = this.assertServerExists(serverId);
|
|
350
|
+
// Caller must be a member of the server
|
|
351
|
+
if (!server.memberIds.includes(userId)) {
|
|
352
|
+
throw new NotServerMemberError();
|
|
353
|
+
}
|
|
354
|
+
const now = new Date();
|
|
355
|
+
const invite = {
|
|
356
|
+
token: (0, uuid_1.v4)(),
|
|
357
|
+
serverId,
|
|
358
|
+
createdBy: userId,
|
|
359
|
+
createdAt: now,
|
|
360
|
+
expiresAt: params.expiresInMs
|
|
361
|
+
? new Date(now.getTime() + params.expiresInMs)
|
|
362
|
+
: undefined,
|
|
363
|
+
maxUses: params.maxUses,
|
|
364
|
+
currentUses: 0,
|
|
365
|
+
};
|
|
366
|
+
this.serverInviteTokens.set(invite.token, invite);
|
|
367
|
+
// Persist to storage provider if available
|
|
368
|
+
if (this.serverInviteCollection) {
|
|
369
|
+
await this.serverInviteCollection.create(invite);
|
|
370
|
+
}
|
|
371
|
+
return invite;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Redeem an invite token to join a server.
|
|
375
|
+
* Validates the token belongs to the specified server, checks expiration
|
|
376
|
+
* and max-use limits, increments currentUses, and adds the user to the server.
|
|
377
|
+
*
|
|
378
|
+
* After joining, distributes channel keys for all server channels
|
|
379
|
+
* to the new member via ChannelService.addMemberToChannel().
|
|
380
|
+
*
|
|
381
|
+
* Requirements: 3.2, 3.3, 3.4, 6.1, 6.2, 6.3
|
|
382
|
+
*/
|
|
383
|
+
async redeemInvite(serverId, token, userId) {
|
|
384
|
+
const invite = this.serverInviteTokens.get(token);
|
|
385
|
+
if (!invite) {
|
|
386
|
+
throw new ServerInviteNotFoundError(token);
|
|
387
|
+
}
|
|
388
|
+
// Validate the token belongs to the specified server
|
|
389
|
+
if (invite.serverId !== serverId) {
|
|
390
|
+
throw new ServerInviteNotFoundError(token);
|
|
391
|
+
}
|
|
392
|
+
// Check expiration
|
|
393
|
+
if (invite.expiresAt && new Date() >= invite.expiresAt) {
|
|
394
|
+
throw new ServerInviteExpiredError();
|
|
395
|
+
}
|
|
396
|
+
// Check max uses
|
|
397
|
+
if (invite.maxUses !== undefined && invite.currentUses >= invite.maxUses) {
|
|
398
|
+
throw new ServerInviteExpiredError();
|
|
399
|
+
}
|
|
400
|
+
const server = this.assertServerExists(serverId);
|
|
401
|
+
// Skip if already a member
|
|
402
|
+
if (server.memberIds.includes(userId)) {
|
|
403
|
+
throw new MemberAlreadyInServerError(userId);
|
|
404
|
+
}
|
|
405
|
+
// Add user to server
|
|
406
|
+
server.memberIds.push(userId);
|
|
407
|
+
server.updatedAt = new Date();
|
|
408
|
+
// Distribute channel keys for all server channels to the new member
|
|
409
|
+
for (const channelId of server.channelIds) {
|
|
410
|
+
await this.channelService.addMemberToChannel(channelId, userId);
|
|
411
|
+
}
|
|
412
|
+
// Increment usage
|
|
413
|
+
invite.currentUses++;
|
|
414
|
+
// Persist changes to storage provider if available
|
|
415
|
+
if (this.serverCollection) {
|
|
416
|
+
await this.serverCollection.update(serverId, server);
|
|
417
|
+
}
|
|
418
|
+
if (this.serverInviteCollection) {
|
|
419
|
+
await this.serverInviteCollection.update(invite.token, invite);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
// ─── Channel management within server ────────────────────────────────
|
|
423
|
+
/**
|
|
424
|
+
* Create a channel within a server.
|
|
425
|
+
* Validates caller has owner/admin role, creates the channel via ChannelService,
|
|
426
|
+
* sets serverId on the channel, adds channelId to server.channelIds,
|
|
427
|
+
* adds to specified category (or first category if not specified),
|
|
428
|
+
* and emits SERVER_CHANNEL_CREATED event.
|
|
429
|
+
*
|
|
430
|
+
* Requirements: 1.3, 1.4, 7.2
|
|
431
|
+
*/
|
|
432
|
+
async createChannelInServer(serverId, userId, params, categoryId) {
|
|
433
|
+
const server = this.assertServerExists(serverId);
|
|
434
|
+
this.assertCanUpdate(server, userId);
|
|
435
|
+
// Create the channel via ChannelService
|
|
436
|
+
const channel = await this.channelService.createChannel(params.name, userId, params.visibility, params.topic ?? '', serverId);
|
|
437
|
+
// serverId is already set by createChannel above
|
|
438
|
+
// Add channelId to server's channelIds
|
|
439
|
+
server.channelIds.push(channel.id);
|
|
440
|
+
// Determine target category
|
|
441
|
+
let targetCategory;
|
|
442
|
+
if (categoryId) {
|
|
443
|
+
targetCategory = server.categories.find((c) => c.id === categoryId);
|
|
444
|
+
}
|
|
445
|
+
if (!targetCategory && server.categories.length > 0) {
|
|
446
|
+
targetCategory = server.categories[0];
|
|
447
|
+
}
|
|
448
|
+
const resolvedCategoryId = targetCategory?.id ?? '';
|
|
449
|
+
if (targetCategory) {
|
|
450
|
+
targetCategory.channelIds.push(channel.id);
|
|
451
|
+
}
|
|
452
|
+
server.updatedAt = new Date();
|
|
453
|
+
// Persist to storage provider if available
|
|
454
|
+
if (this.serverCollection) {
|
|
455
|
+
await this.serverCollection.update(serverId, server);
|
|
456
|
+
}
|
|
457
|
+
this.eventEmitter.emitServerChannelCreated(serverId, channel.id, channel.name, resolvedCategoryId);
|
|
458
|
+
return channel;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Remove a channel from a server.
|
|
462
|
+
* Validates caller has owner/admin role, deletes the channel via ChannelService,
|
|
463
|
+
* removes channelId from server.channelIds and from category.channelIds,
|
|
464
|
+
* and emits SERVER_CHANNEL_DELETED event.
|
|
465
|
+
*
|
|
466
|
+
* Requirements: 1.3, 1.4, 7.2
|
|
467
|
+
*/
|
|
468
|
+
async removeChannelFromServer(serverId, channelId, userId) {
|
|
469
|
+
const server = this.assertServerExists(serverId);
|
|
470
|
+
this.assertCanUpdate(server, userId);
|
|
471
|
+
// Delete the channel via ChannelService
|
|
472
|
+
await this.channelService.deleteChannel(channelId, userId);
|
|
473
|
+
// Remove channelId from server's channelIds
|
|
474
|
+
server.channelIds = server.channelIds.filter((id) => id !== channelId);
|
|
475
|
+
// Remove from any category that contains it
|
|
476
|
+
for (const category of server.categories) {
|
|
477
|
+
category.channelIds = category.channelIds.filter((id) => id !== channelId);
|
|
478
|
+
}
|
|
479
|
+
server.updatedAt = new Date();
|
|
480
|
+
// Persist to storage provider if available
|
|
481
|
+
if (this.serverCollection) {
|
|
482
|
+
await this.serverCollection.update(serverId, server);
|
|
483
|
+
}
|
|
484
|
+
this.eventEmitter.emitServerChannelDeleted(serverId, channelId);
|
|
485
|
+
}
|
|
486
|
+
// ─── Accessors (for testing / internal use) ───────────────────────────
|
|
487
|
+
getServerById(serverId) {
|
|
488
|
+
return this.servers.get(serverId);
|
|
489
|
+
}
|
|
490
|
+
getInviteToken(token) {
|
|
491
|
+
return this.serverInviteTokens.get(token);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
exports.ServerService = ServerService;
|
|
495
|
+
//# sourceMappingURL=serverService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverService.js","sourceRoot":"","sources":["../../../../../../brightchain-lib/src/lib/services/communication/serverService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Member, type PlatformID } from '@digitaldefiance/ecies-lib';
|
|
2
|
+
import { ConstituentBlockListBlock } from '../blocks/cbl';
|
|
3
|
+
import { ExtendedCBL } from '../blocks/extendedCbl';
|
|
4
|
+
import { InMemoryBlockTuple } from '../blocks/memoryTuple';
|
|
5
|
+
import { RandomBlock } from '../blocks/random';
|
|
6
|
+
import { WhitenedBlock } from '../blocks/whitened';
|
|
7
|
+
import { BlockSize } from '../enumerations/blockSize';
|
|
8
|
+
import { Checksum } from '../types/checksum';
|
|
9
|
+
import type { CBLService } from './cblService';
|
|
10
|
+
import type { ChecksumService } from './checksum.service';
|
|
11
|
+
/**
|
|
12
|
+
* Result of a CopyOnWrite operation.
|
|
13
|
+
* Contains the new CBL and metadata about what changed.
|
|
14
|
+
*/
|
|
15
|
+
export interface CopyOnWriteResult<TID extends PlatformID = Uint8Array> {
|
|
16
|
+
/** The new CBL referencing both reused and new blocks */
|
|
17
|
+
cbl: ConstituentBlockListBlock<TID> | ExtendedCBL<TID>;
|
|
18
|
+
/** Number of tuples reused from the original CBL */
|
|
19
|
+
reusedTupleCount: number;
|
|
20
|
+
/** Number of new tuples created for changed data */
|
|
21
|
+
newTupleCount: number;
|
|
22
|
+
/** Total number of tuples in the new CBL */
|
|
23
|
+
totalTupleCount: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Options for the CopyOnWrite operation.
|
|
27
|
+
*/
|
|
28
|
+
export interface CopyOnWriteOptions {
|
|
29
|
+
/** If true, create an ExtendedCBL with file metadata */
|
|
30
|
+
createExtendedCbl?: boolean;
|
|
31
|
+
/** File name for ExtendedCBL */
|
|
32
|
+
fileName?: string;
|
|
33
|
+
/** MIME type for ExtendedCBL */
|
|
34
|
+
mimeType?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* CopyOnWriteService provides efficient versioning for CBL-based data.
|
|
38
|
+
*
|
|
39
|
+
* When data changes, instead of re-creating all blocks from scratch, this service:
|
|
40
|
+
* 1. Reads the new data in block-sized chunks
|
|
41
|
+
* 2. Compares each chunk against the corresponding original block data
|
|
42
|
+
* (recovered by XORing the tuple's constituent blocks)
|
|
43
|
+
* 3. Reuses the original tuple addresses for unchanged blocks
|
|
44
|
+
* 4. Creates new tuples only for blocks whose data has changed
|
|
45
|
+
* 5. Produces a new CBL that references both old (reused) and new block addresses
|
|
46
|
+
*
|
|
47
|
+
* This is analogous to copy-on-write in operating systems: we share unchanged
|
|
48
|
+
* pages and only allocate new storage for modified pages.
|
|
49
|
+
*
|
|
50
|
+
* The tuple size (typically 3) means each "logical block" in the CBL is
|
|
51
|
+
* represented by `tupleSize` addresses. When we say "reuse a tuple," we
|
|
52
|
+
* mean we copy all `tupleSize` addresses from the old CBL into the new one.
|
|
53
|
+
*
|
|
54
|
+
* @typeParam TID - The platform ID type (defaults to Uint8Array)
|
|
55
|
+
*/
|
|
56
|
+
export declare class CopyOnWriteService<TID extends PlatformID = Uint8Array> {
|
|
57
|
+
private readonly checksumService;
|
|
58
|
+
private readonly cblService;
|
|
59
|
+
constructor(checksumService?: ChecksumService, cblService?: CBLService<TID>);
|
|
60
|
+
/**
|
|
61
|
+
* Create a new version of a CBL by applying changes from new data,
|
|
62
|
+
* reusing unchanged blocks from the original CBL.
|
|
63
|
+
*
|
|
64
|
+
* @param originalCbl - The existing CBL to base the new version on
|
|
65
|
+
* @param newData - The complete new data as a Uint8Array
|
|
66
|
+
* @param creator - The member creating the new version
|
|
67
|
+
* @param blockSize - The block size to use (must match the original CBL's block size)
|
|
68
|
+
* @param getBlockData - Function to retrieve raw block data by checksum from the store
|
|
69
|
+
* @param whitenedBlockSource - Function to get whitened blocks for new tuples
|
|
70
|
+
* @param randomBlockSource - Function to get random blocks for new tuples
|
|
71
|
+
* @param persistTuple - Function to persist newly created tuples
|
|
72
|
+
* @param options - Optional settings for extended CBL creation
|
|
73
|
+
* @returns The new CBL and statistics about reuse
|
|
74
|
+
*/
|
|
75
|
+
newVersion(originalCbl: ConstituentBlockListBlock<TID>, newData: Uint8Array, creator: Member<TID>, blockSize: BlockSize, getBlockData: (checksum: Checksum) => Promise<Uint8Array>, whitenedBlockSource: () => WhitenedBlock | undefined, randomBlockSource: () => RandomBlock, persistTuple: (tuple: InMemoryBlockTuple) => Promise<void>, options?: CopyOnWriteOptions): Promise<CopyOnWriteResult<TID>>;
|
|
76
|
+
/**
|
|
77
|
+
* Recover the original plaintext data from a tuple by XORing all
|
|
78
|
+
* constituent blocks together.
|
|
79
|
+
*
|
|
80
|
+
* In the OFF system, a tuple of `tupleSize` blocks is stored such that
|
|
81
|
+
* XORing all blocks together recovers the original data:
|
|
82
|
+
* plaintext = block[0] XOR block[1] XOR ... XOR block[tupleSize-1]
|
|
83
|
+
*
|
|
84
|
+
* @param tupleAddresses - The checksums of the blocks in the tuple
|
|
85
|
+
* @param getBlockData - Function to retrieve raw block data by checksum
|
|
86
|
+
* @returns The recovered plaintext data
|
|
87
|
+
*/
|
|
88
|
+
private recoverTupleData;
|
|
89
|
+
/**
|
|
90
|
+
* Compare two block-sized byte arrays for equality.
|
|
91
|
+
* Uses constant-length comparison (always checks all bytes).
|
|
92
|
+
*/
|
|
93
|
+
private blocksEqual;
|
|
94
|
+
/**
|
|
95
|
+
* Create a new tuple for a data block by XORing it with whitener/random blocks,
|
|
96
|
+
* then persist the tuple.
|
|
97
|
+
*
|
|
98
|
+
* @returns The checksums of all blocks in the new tuple (in order)
|
|
99
|
+
*/
|
|
100
|
+
private createNewTuple;
|
|
101
|
+
/**
|
|
102
|
+
* Convert an array of Checksums to a concatenated Uint8Array buffer.
|
|
103
|
+
*/
|
|
104
|
+
private addressesToBuffer;
|
|
105
|
+
/**
|
|
106
|
+
* Helper to convert a Readable stream to Uint8Array.
|
|
107
|
+
*/
|
|
108
|
+
private streamToUint8Array;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=copyOnWrite.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copyOnWrite.service.d.ts","sourceRoot":"","sources":["../../../../../brightchain-lib/src/lib/services/copyOnWrite.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAInD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1D;;;GAGG;AACH,MAAM,WAAW,iBAAiB,CAAC,GAAG,SAAS,UAAU,GAAG,UAAU;IACpE,yDAAyD;IACzD,GAAG,EAAE,yBAAyB,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IACvD,oDAAoD;IACpD,gBAAgB,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,kBAAkB,CAAC,GAAG,SAAS,UAAU,GAAG,UAAU;IACjE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;gBAG3C,eAAe,CAAC,EAAE,eAAe,EACjC,UAAU,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC;IAQ9B;;;;;;;;;;;;;;OAcG;IACU,UAAU,CACrB,WAAW,EAAE,yBAAyB,CAAC,GAAG,CAAC,EAC3C,OAAO,EAAE,UAAU,EACnB,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,EACpB,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,UAAU,CAAC,EACzD,mBAAmB,EAAE,MAAM,aAAa,GAAG,SAAS,EACpD,iBAAiB,EAAE,MAAM,WAAW,EACpC,YAAY,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,EAC1D,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;IA0HlC;;;;;;;;;;;OAWG;YACW,gBAAgB;IA2B9B;;;OAGG;IACH,OAAO,CAAC,WAAW;IAgBnB;;;;;OAKG;YACW,cAAc;IAkD5B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAYzB;;OAEG;YACW,kBAAkB;CAcjC"}
|