@quilibrium/quorum-shared 2.1.0-1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +1 -49
- package/dist/index.d.ts +1 -49
- package/dist/index.js +30 -125
- package/dist/index.mjs +30 -125
- package/package.json +3 -7
- package/src/sync/service.ts +37 -312
- package/src/types/conversation.ts +0 -9
- package/src/types/index.ts +1 -1
- package/src/sync/service.test.ts +0 -822
package/dist/index.d.mts
CHANGED
|
@@ -217,7 +217,6 @@ type Message = {
|
|
|
217
217
|
/**
|
|
218
218
|
* Conversation (DM) types for Quorum
|
|
219
219
|
*/
|
|
220
|
-
type ConversationSource = 'quorum' | 'farcaster';
|
|
221
220
|
type Conversation = {
|
|
222
221
|
conversationId: string;
|
|
223
222
|
type: 'direct' | 'group';
|
|
@@ -229,12 +228,6 @@ type Conversation = {
|
|
|
229
228
|
isRepudiable?: boolean;
|
|
230
229
|
saveEditHistory?: boolean;
|
|
231
230
|
lastMessageId?: string;
|
|
232
|
-
source?: ConversationSource;
|
|
233
|
-
farcasterConversationId?: string;
|
|
234
|
-
farcasterFid?: number;
|
|
235
|
-
farcasterUsername?: string;
|
|
236
|
-
farcasterParticipantFids?: number[];
|
|
237
|
-
unreadCount?: number;
|
|
238
231
|
};
|
|
239
232
|
|
|
240
233
|
/**
|
|
@@ -2258,8 +2251,6 @@ interface SyncServiceConfig {
|
|
|
2258
2251
|
requestExpiry?: number;
|
|
2259
2252
|
/** Callback when sync should be initiated */
|
|
2260
2253
|
onInitiateSync?: (spaceId: string, target: string) => void;
|
|
2261
|
-
/** Cache TTL in ms (default: 5000) */
|
|
2262
|
-
cacheTtl?: number;
|
|
2263
2254
|
}
|
|
2264
2255
|
declare class SyncService {
|
|
2265
2256
|
private storage;
|
|
@@ -2270,46 +2261,7 @@ declare class SyncService {
|
|
|
2270
2261
|
private sessions;
|
|
2271
2262
|
/** Deleted message tombstones (caller must persist these) */
|
|
2272
2263
|
private tombstones;
|
|
2273
|
-
/** Pre-computed sync payload cache per space:channel - always ready to use */
|
|
2274
|
-
private payloadCache;
|
|
2275
2264
|
constructor(config: SyncServiceConfig);
|
|
2276
|
-
/**
|
|
2277
|
-
* Get cache key for space/channel
|
|
2278
|
-
*/
|
|
2279
|
-
private getCacheKey;
|
|
2280
|
-
/**
|
|
2281
|
-
* Get or initialize the payload cache for a space/channel.
|
|
2282
|
-
* If not cached, loads from storage and builds the payload once.
|
|
2283
|
-
*/
|
|
2284
|
-
private getPayloadCache;
|
|
2285
|
-
/**
|
|
2286
|
-
* Build the payload cache from messages and members
|
|
2287
|
-
*/
|
|
2288
|
-
private buildPayloadCache;
|
|
2289
|
-
/**
|
|
2290
|
-
* Rebuild derived fields (manifest, digests, summary) from the maps
|
|
2291
|
-
*/
|
|
2292
|
-
private rebuildPayloadCache;
|
|
2293
|
-
/**
|
|
2294
|
-
* Invalidate cache for a space/channel (forces reload from storage on next access)
|
|
2295
|
-
*/
|
|
2296
|
-
invalidateCache(spaceId: string, channelId?: string): void;
|
|
2297
|
-
/**
|
|
2298
|
-
* Update cache with a new/updated message (incremental update - no storage query)
|
|
2299
|
-
*/
|
|
2300
|
-
updateCacheWithMessage(spaceId: string, channelId: string, message: Message): void;
|
|
2301
|
-
/**
|
|
2302
|
-
* Remove a message from cache (incremental update - no storage query)
|
|
2303
|
-
*/
|
|
2304
|
-
removeCacheMessage(spaceId: string, channelId: string, messageId: string): void;
|
|
2305
|
-
/**
|
|
2306
|
-
* Update cache with a new/updated member (incremental update - no storage query)
|
|
2307
|
-
*/
|
|
2308
|
-
updateCacheWithMember(spaceId: string, channelId: string, member: SpaceMember): void;
|
|
2309
|
-
/**
|
|
2310
|
-
* Check if cache exists for a space/channel
|
|
2311
|
-
*/
|
|
2312
|
-
hasCachedPayload(spaceId: string, channelId: string): boolean;
|
|
2313
2265
|
/**
|
|
2314
2266
|
* Check if a sync session is active for a space
|
|
2315
2267
|
*/
|
|
@@ -2411,4 +2363,4 @@ declare class SyncService {
|
|
|
2411
2363
|
cancelSync(spaceId: string): void;
|
|
2412
2364
|
}
|
|
2413
2365
|
|
|
2414
|
-
export { AGGRESSIVE_SYNC_TIMEOUT_MS, type AddReactionParams, type ApiConfig, ApiError, ApiErrorCode, type ApiErrorDetails, BOOKMARKS_CONFIG, type Bookmark, BrowserWebSocketClient, type Channel, type ChannelWasmModule, type ChannelsKey, type Conversation, type ConversationInboxKeypair, type
|
|
2366
|
+
export { AGGRESSIVE_SYNC_TIMEOUT_MS, type AddReactionParams, type ApiConfig, ApiError, ApiErrorCode, type ApiErrorDetails, BOOKMARKS_CONFIG, type Bookmark, BrowserWebSocketClient, type Channel, type ChannelWasmModule, type ChannelsKey, type Conversation, type ConversationInboxKeypair, type CreateWebSocketClient, type CryptoProvider, DEFAULT_SYNC_EXPIRY_MS, type DeleteConversationMessage, type DeleteMessageParams, type DeletedMessageTombstone, type DeviceKeys, type DoubleRatchetStateAndEnvelope, type DoubleRatchetStateAndMessage, ENCRYPTION_STORAGE_KEYS, type Ed448Keypair, type EditMessage, type EditMessageParams, type EmbedMessage, type Emoji, type EncryptedEnvelope, type EncryptedWebSocketMessage, type EncryptionState, type EncryptionStateStorageInterface, type ErrorHandler, type EventMessage, type FolderColor, type GetMessagesParams, type GetMessagesResult, type Group, type HttpMethod, type InboxMapping, type InboxMessageDecryptRequest, type InboxMessageEncryptRequest, type InitializationEnvelope, type JoinMessage, type KeyValueStorageProvider, type Keypair, type KickMessage, type LatestState, type LeaveMessage, type ListenMessage, MAX_CHUNK_SIZE, MAX_MENTIONS, MAX_MESSAGE_LENGTH, MENTION_PATTERNS, type MemberDelta, type MemberDiffResult, type MemberDigest, type Mentions, type Message, type MessageCiphertext, type MessageContent, type MessageDelta, type MessageDiffResult, type MessageDigest, type MessageHandler, type MessageListParams, type MessageSendStatus, type MessagesInfiniteKey, type MuteMessage, type NavItem, type NewDoubleRatchetParams, type NewTripleRatchetParams, type NotificationSettings, type OutboundWebSocketMessage, type P2PChannelEnvelope, type PaginationParams, type ParsedMention, type PeerDiffResult, type PeerEntry, type PeerInfo, type PeerMapDelta, type Permission, type PinMessage, type PostMessage, type QuorumApiClient, RNWebSocketClient, type Reaction, type ReactionDelta, type ReactionDiffResult, type ReactionDigest, type ReactionMessage, type ReceiverX3DHParams, type ReceivingInbox, type RecipientInfo, type RemoveMessage, type RemoveReactionMessage, type RemoveReactionParams, type RequestOptions, type Role, type SealedMessage, type SendDirectMessageParams, type SendMessageParams, type SenderX3DHParams, type SendingInbox, type SignedMessage, type SigningProvider, type Space, type SpaceDetailKey, type SpaceMember, type SpacesKey, type StateChangeHandler, type Sticker, type StickerMessage, type StorageAdapter, type SyncCandidate, type SyncControlPayload, type SyncDeltaPayload, type SyncInfoPayload, type SyncInitiatePayload, type SyncManifest, type SyncManifestPayload, type SyncRequestPayload, SyncService, type SyncServiceConfig, type SyncSession, type SyncSummary, type TransportClient, type TransportConfig, type TransportRequestOptions, type TransportResponse, type TripleRatchetStateAndEnvelope, type TripleRatchetStateAndMessage, type TripleRatchetStateAndMetadata, type UnlistenMessage, type UnsealedEnvelope, type UpdateProfileMessage, type UseChannelsOptions, type UseDeleteMessageOptions, type UseEditMessageOptions, type UseMessagesOptions, type UseReactionOptions, type UseSendMessageOptions, type UseSpaceOptions, type UseSpacesOptions, type UserConfig, type UserProfile, type ValidationResult, WasmCryptoProvider, WasmSigningProvider, type WebSocketClient, type WebSocketClientOptions, type WebSocketConnectionState, type X448Keypair, base64ToBytes, buildMemberDelta, buildMessageDelta, buildReactionDelta, bytesToBase64, bytesToHex, bytesToString, chunkMembers, chunkMessages, computeContentHash, computeHash, computeManifestHash, computeMemberDiff, computeMemberHash, computeMessageDiff, computePeerDiff, computeReactionDiff, computeReactionHash, createApiError, createBrowserWebSocketClient, createManifest, createMemberDigest, createMessageDigest, createNetworkError, createRNWebSocketClient, createReactionDigest, createSignedMessage, createSyncSummary, endpoints, extractMentions, findChannel, flattenChannels, flattenMessages, formatDate, formatDateTime, formatFileSize, formatMemberCount, formatMention, formatMessageDate, formatRelativeTime, formatTime, hexToBytes, int64ToBytes, isSameDay, isSyncDelta, isSyncInfo, isSyncInitiate, isSyncManifest, isSyncRequest, logger, parseMentions, queryKeys, sanitizeContent, stringToBytes, truncateText, useAddReaction, useChannels, useDeleteMessage, useEditMessage, useInvalidateMessages, useMessages, useRemoveReaction, useSendMessage, useSpace, useSpaceMembers, useSpaces, validateMessage, validateMessageContent, verifySignedMessage };
|
package/dist/index.d.ts
CHANGED
|
@@ -217,7 +217,6 @@ type Message = {
|
|
|
217
217
|
/**
|
|
218
218
|
* Conversation (DM) types for Quorum
|
|
219
219
|
*/
|
|
220
|
-
type ConversationSource = 'quorum' | 'farcaster';
|
|
221
220
|
type Conversation = {
|
|
222
221
|
conversationId: string;
|
|
223
222
|
type: 'direct' | 'group';
|
|
@@ -229,12 +228,6 @@ type Conversation = {
|
|
|
229
228
|
isRepudiable?: boolean;
|
|
230
229
|
saveEditHistory?: boolean;
|
|
231
230
|
lastMessageId?: string;
|
|
232
|
-
source?: ConversationSource;
|
|
233
|
-
farcasterConversationId?: string;
|
|
234
|
-
farcasterFid?: number;
|
|
235
|
-
farcasterUsername?: string;
|
|
236
|
-
farcasterParticipantFids?: number[];
|
|
237
|
-
unreadCount?: number;
|
|
238
231
|
};
|
|
239
232
|
|
|
240
233
|
/**
|
|
@@ -2258,8 +2251,6 @@ interface SyncServiceConfig {
|
|
|
2258
2251
|
requestExpiry?: number;
|
|
2259
2252
|
/** Callback when sync should be initiated */
|
|
2260
2253
|
onInitiateSync?: (spaceId: string, target: string) => void;
|
|
2261
|
-
/** Cache TTL in ms (default: 5000) */
|
|
2262
|
-
cacheTtl?: number;
|
|
2263
2254
|
}
|
|
2264
2255
|
declare class SyncService {
|
|
2265
2256
|
private storage;
|
|
@@ -2270,46 +2261,7 @@ declare class SyncService {
|
|
|
2270
2261
|
private sessions;
|
|
2271
2262
|
/** Deleted message tombstones (caller must persist these) */
|
|
2272
2263
|
private tombstones;
|
|
2273
|
-
/** Pre-computed sync payload cache per space:channel - always ready to use */
|
|
2274
|
-
private payloadCache;
|
|
2275
2264
|
constructor(config: SyncServiceConfig);
|
|
2276
|
-
/**
|
|
2277
|
-
* Get cache key for space/channel
|
|
2278
|
-
*/
|
|
2279
|
-
private getCacheKey;
|
|
2280
|
-
/**
|
|
2281
|
-
* Get or initialize the payload cache for a space/channel.
|
|
2282
|
-
* If not cached, loads from storage and builds the payload once.
|
|
2283
|
-
*/
|
|
2284
|
-
private getPayloadCache;
|
|
2285
|
-
/**
|
|
2286
|
-
* Build the payload cache from messages and members
|
|
2287
|
-
*/
|
|
2288
|
-
private buildPayloadCache;
|
|
2289
|
-
/**
|
|
2290
|
-
* Rebuild derived fields (manifest, digests, summary) from the maps
|
|
2291
|
-
*/
|
|
2292
|
-
private rebuildPayloadCache;
|
|
2293
|
-
/**
|
|
2294
|
-
* Invalidate cache for a space/channel (forces reload from storage on next access)
|
|
2295
|
-
*/
|
|
2296
|
-
invalidateCache(spaceId: string, channelId?: string): void;
|
|
2297
|
-
/**
|
|
2298
|
-
* Update cache with a new/updated message (incremental update - no storage query)
|
|
2299
|
-
*/
|
|
2300
|
-
updateCacheWithMessage(spaceId: string, channelId: string, message: Message): void;
|
|
2301
|
-
/**
|
|
2302
|
-
* Remove a message from cache (incremental update - no storage query)
|
|
2303
|
-
*/
|
|
2304
|
-
removeCacheMessage(spaceId: string, channelId: string, messageId: string): void;
|
|
2305
|
-
/**
|
|
2306
|
-
* Update cache with a new/updated member (incremental update - no storage query)
|
|
2307
|
-
*/
|
|
2308
|
-
updateCacheWithMember(spaceId: string, channelId: string, member: SpaceMember): void;
|
|
2309
|
-
/**
|
|
2310
|
-
* Check if cache exists for a space/channel
|
|
2311
|
-
*/
|
|
2312
|
-
hasCachedPayload(spaceId: string, channelId: string): boolean;
|
|
2313
2265
|
/**
|
|
2314
2266
|
* Check if a sync session is active for a space
|
|
2315
2267
|
*/
|
|
@@ -2411,4 +2363,4 @@ declare class SyncService {
|
|
|
2411
2363
|
cancelSync(spaceId: string): void;
|
|
2412
2364
|
}
|
|
2413
2365
|
|
|
2414
|
-
export { AGGRESSIVE_SYNC_TIMEOUT_MS, type AddReactionParams, type ApiConfig, ApiError, ApiErrorCode, type ApiErrorDetails, BOOKMARKS_CONFIG, type Bookmark, BrowserWebSocketClient, type Channel, type ChannelWasmModule, type ChannelsKey, type Conversation, type ConversationInboxKeypair, type
|
|
2366
|
+
export { AGGRESSIVE_SYNC_TIMEOUT_MS, type AddReactionParams, type ApiConfig, ApiError, ApiErrorCode, type ApiErrorDetails, BOOKMARKS_CONFIG, type Bookmark, BrowserWebSocketClient, type Channel, type ChannelWasmModule, type ChannelsKey, type Conversation, type ConversationInboxKeypair, type CreateWebSocketClient, type CryptoProvider, DEFAULT_SYNC_EXPIRY_MS, type DeleteConversationMessage, type DeleteMessageParams, type DeletedMessageTombstone, type DeviceKeys, type DoubleRatchetStateAndEnvelope, type DoubleRatchetStateAndMessage, ENCRYPTION_STORAGE_KEYS, type Ed448Keypair, type EditMessage, type EditMessageParams, type EmbedMessage, type Emoji, type EncryptedEnvelope, type EncryptedWebSocketMessage, type EncryptionState, type EncryptionStateStorageInterface, type ErrorHandler, type EventMessage, type FolderColor, type GetMessagesParams, type GetMessagesResult, type Group, type HttpMethod, type InboxMapping, type InboxMessageDecryptRequest, type InboxMessageEncryptRequest, type InitializationEnvelope, type JoinMessage, type KeyValueStorageProvider, type Keypair, type KickMessage, type LatestState, type LeaveMessage, type ListenMessage, MAX_CHUNK_SIZE, MAX_MENTIONS, MAX_MESSAGE_LENGTH, MENTION_PATTERNS, type MemberDelta, type MemberDiffResult, type MemberDigest, type Mentions, type Message, type MessageCiphertext, type MessageContent, type MessageDelta, type MessageDiffResult, type MessageDigest, type MessageHandler, type MessageListParams, type MessageSendStatus, type MessagesInfiniteKey, type MuteMessage, type NavItem, type NewDoubleRatchetParams, type NewTripleRatchetParams, type NotificationSettings, type OutboundWebSocketMessage, type P2PChannelEnvelope, type PaginationParams, type ParsedMention, type PeerDiffResult, type PeerEntry, type PeerInfo, type PeerMapDelta, type Permission, type PinMessage, type PostMessage, type QuorumApiClient, RNWebSocketClient, type Reaction, type ReactionDelta, type ReactionDiffResult, type ReactionDigest, type ReactionMessage, type ReceiverX3DHParams, type ReceivingInbox, type RecipientInfo, type RemoveMessage, type RemoveReactionMessage, type RemoveReactionParams, type RequestOptions, type Role, type SealedMessage, type SendDirectMessageParams, type SendMessageParams, type SenderX3DHParams, type SendingInbox, type SignedMessage, type SigningProvider, type Space, type SpaceDetailKey, type SpaceMember, type SpacesKey, type StateChangeHandler, type Sticker, type StickerMessage, type StorageAdapter, type SyncCandidate, type SyncControlPayload, type SyncDeltaPayload, type SyncInfoPayload, type SyncInitiatePayload, type SyncManifest, type SyncManifestPayload, type SyncRequestPayload, SyncService, type SyncServiceConfig, type SyncSession, type SyncSummary, type TransportClient, type TransportConfig, type TransportRequestOptions, type TransportResponse, type TripleRatchetStateAndEnvelope, type TripleRatchetStateAndMessage, type TripleRatchetStateAndMetadata, type UnlistenMessage, type UnsealedEnvelope, type UpdateProfileMessage, type UseChannelsOptions, type UseDeleteMessageOptions, type UseEditMessageOptions, type UseMessagesOptions, type UseReactionOptions, type UseSendMessageOptions, type UseSpaceOptions, type UseSpacesOptions, type UserConfig, type UserProfile, type ValidationResult, WasmCryptoProvider, WasmSigningProvider, type WebSocketClient, type WebSocketClientOptions, type WebSocketConnectionState, type X448Keypair, base64ToBytes, buildMemberDelta, buildMessageDelta, buildReactionDelta, bytesToBase64, bytesToHex, bytesToString, chunkMembers, chunkMessages, computeContentHash, computeHash, computeManifestHash, computeMemberDiff, computeMemberHash, computeMessageDiff, computePeerDiff, computeReactionDiff, computeReactionHash, createApiError, createBrowserWebSocketClient, createManifest, createMemberDigest, createMessageDigest, createNetworkError, createRNWebSocketClient, createReactionDigest, createSignedMessage, createSyncSummary, endpoints, extractMentions, findChannel, flattenChannels, flattenMessages, formatDate, formatDateTime, formatFileSize, formatMemberCount, formatMention, formatMessageDate, formatRelativeTime, formatTime, hexToBytes, int64ToBytes, isSameDay, isSyncDelta, isSyncInfo, isSyncInitiate, isSyncManifest, isSyncRequest, logger, parseMentions, queryKeys, sanitizeContent, stringToBytes, truncateText, useAddReaction, useChannels, useDeleteMessage, useEditMessage, useInvalidateMessages, useMessages, useRemoveReaction, useSendMessage, useSpace, useSpaceMembers, useSpaces, validateMessage, validateMessageContent, verifySignedMessage };
|
package/dist/index.js
CHANGED
|
@@ -2159,118 +2159,11 @@ var SyncService = class {
|
|
|
2159
2159
|
this.sessions = /* @__PURE__ */ new Map();
|
|
2160
2160
|
/** Deleted message tombstones (caller must persist these) */
|
|
2161
2161
|
this.tombstones = [];
|
|
2162
|
-
/** Pre-computed sync payload cache per space:channel - always ready to use */
|
|
2163
|
-
this.payloadCache = /* @__PURE__ */ new Map();
|
|
2164
2162
|
this.storage = config2.storage;
|
|
2165
2163
|
this.maxMessages = config2.maxMessages ?? 1e3;
|
|
2166
2164
|
this.requestExpiry = config2.requestExpiry ?? DEFAULT_SYNC_EXPIRY_MS;
|
|
2167
2165
|
this.onInitiateSync = config2.onInitiateSync;
|
|
2168
2166
|
}
|
|
2169
|
-
// ============ Payload Cache Management ============
|
|
2170
|
-
/**
|
|
2171
|
-
* Get cache key for space/channel
|
|
2172
|
-
*/
|
|
2173
|
-
getCacheKey(spaceId, channelId) {
|
|
2174
|
-
return `${spaceId}:${channelId}`;
|
|
2175
|
-
}
|
|
2176
|
-
/**
|
|
2177
|
-
* Get or initialize the payload cache for a space/channel.
|
|
2178
|
-
* If not cached, loads from storage and builds the payload once.
|
|
2179
|
-
*/
|
|
2180
|
-
async getPayloadCache(spaceId, channelId) {
|
|
2181
|
-
const key = this.getCacheKey(spaceId, channelId);
|
|
2182
|
-
const cached = this.payloadCache.get(key);
|
|
2183
|
-
if (cached) {
|
|
2184
|
-
logger.log(`[SyncService] Using cached payload for ${spaceId.substring(0, 12)}:${channelId.substring(0, 12)}`);
|
|
2185
|
-
return cached;
|
|
2186
|
-
}
|
|
2187
|
-
logger.log(`[SyncService] Building initial payload cache for ${spaceId.substring(0, 12)}:${channelId.substring(0, 12)}`);
|
|
2188
|
-
const messages = await this.getChannelMessages(spaceId, channelId);
|
|
2189
|
-
const members = await this.storage.getSpaceMembers(spaceId);
|
|
2190
|
-
const payload = this.buildPayloadCache(spaceId, channelId, messages, members);
|
|
2191
|
-
this.payloadCache.set(key, payload);
|
|
2192
|
-
return payload;
|
|
2193
|
-
}
|
|
2194
|
-
/**
|
|
2195
|
-
* Build the payload cache from messages and members
|
|
2196
|
-
*/
|
|
2197
|
-
buildPayloadCache(spaceId, channelId, messages, members) {
|
|
2198
|
-
const messageMap = new Map(messages.map((m) => [m.messageId, m]));
|
|
2199
|
-
const memberMap = new Map(members.map((m) => [m.address, m]));
|
|
2200
|
-
const manifest = createManifest(spaceId, channelId, messages);
|
|
2201
|
-
const memberDigests = members.map(createMemberDigest);
|
|
2202
|
-
const summary = createSyncSummary(messages, members.length);
|
|
2203
|
-
return { manifest, memberDigests, summary, messageMap, memberMap };
|
|
2204
|
-
}
|
|
2205
|
-
/**
|
|
2206
|
-
* Rebuild derived fields (manifest, digests, summary) from the maps
|
|
2207
|
-
*/
|
|
2208
|
-
rebuildPayloadCache(spaceId, channelId, cache) {
|
|
2209
|
-
const messages = [...cache.messageMap.values()];
|
|
2210
|
-
const members = [...cache.memberMap.values()];
|
|
2211
|
-
cache.manifest = createManifest(spaceId, channelId, messages);
|
|
2212
|
-
cache.memberDigests = members.map(createMemberDigest);
|
|
2213
|
-
cache.summary = createSyncSummary(messages, members.length);
|
|
2214
|
-
}
|
|
2215
|
-
/**
|
|
2216
|
-
* Invalidate cache for a space/channel (forces reload from storage on next access)
|
|
2217
|
-
*/
|
|
2218
|
-
invalidateCache(spaceId, channelId) {
|
|
2219
|
-
if (channelId) {
|
|
2220
|
-
const key = this.getCacheKey(spaceId, channelId);
|
|
2221
|
-
this.payloadCache.delete(key);
|
|
2222
|
-
logger.log(`[SyncService] Invalidated cache for ${spaceId.substring(0, 12)}:${channelId.substring(0, 12)}`);
|
|
2223
|
-
} else {
|
|
2224
|
-
for (const key of this.payloadCache.keys()) {
|
|
2225
|
-
if (key.startsWith(`${spaceId}:`)) {
|
|
2226
|
-
this.payloadCache.delete(key);
|
|
2227
|
-
}
|
|
2228
|
-
}
|
|
2229
|
-
logger.log(`[SyncService] Invalidated all caches for space ${spaceId.substring(0, 12)}`);
|
|
2230
|
-
}
|
|
2231
|
-
}
|
|
2232
|
-
/**
|
|
2233
|
-
* Update cache with a new/updated message (incremental update - no storage query)
|
|
2234
|
-
*/
|
|
2235
|
-
updateCacheWithMessage(spaceId, channelId, message) {
|
|
2236
|
-
const key = this.getCacheKey(spaceId, channelId);
|
|
2237
|
-
const cached = this.payloadCache.get(key);
|
|
2238
|
-
if (cached) {
|
|
2239
|
-
cached.messageMap.set(message.messageId, message);
|
|
2240
|
-
this.rebuildPayloadCache(spaceId, channelId, cached);
|
|
2241
|
-
logger.log(`[SyncService] Updated cache with message ${message.messageId.substring(0, 12)}`);
|
|
2242
|
-
}
|
|
2243
|
-
}
|
|
2244
|
-
/**
|
|
2245
|
-
* Remove a message from cache (incremental update - no storage query)
|
|
2246
|
-
*/
|
|
2247
|
-
removeCacheMessage(spaceId, channelId, messageId) {
|
|
2248
|
-
const key = this.getCacheKey(spaceId, channelId);
|
|
2249
|
-
const cached = this.payloadCache.get(key);
|
|
2250
|
-
if (cached) {
|
|
2251
|
-
cached.messageMap.delete(messageId);
|
|
2252
|
-
this.rebuildPayloadCache(spaceId, channelId, cached);
|
|
2253
|
-
logger.log(`[SyncService] Removed message ${messageId.substring(0, 12)} from cache`);
|
|
2254
|
-
}
|
|
2255
|
-
}
|
|
2256
|
-
/**
|
|
2257
|
-
* Update cache with a new/updated member (incremental update - no storage query)
|
|
2258
|
-
*/
|
|
2259
|
-
updateCacheWithMember(spaceId, channelId, member) {
|
|
2260
|
-
const key = this.getCacheKey(spaceId, channelId);
|
|
2261
|
-
const cached = this.payloadCache.get(key);
|
|
2262
|
-
if (cached) {
|
|
2263
|
-
cached.memberMap.set(member.address, member);
|
|
2264
|
-
this.rebuildPayloadCache(spaceId, channelId, cached);
|
|
2265
|
-
logger.log(`[SyncService] Updated cache with member ${member.address.substring(0, 12)}`);
|
|
2266
|
-
}
|
|
2267
|
-
}
|
|
2268
|
-
/**
|
|
2269
|
-
* Check if cache exists for a space/channel
|
|
2270
|
-
*/
|
|
2271
|
-
hasCachedPayload(spaceId, channelId) {
|
|
2272
|
-
return this.payloadCache.has(this.getCacheKey(spaceId, channelId));
|
|
2273
|
-
}
|
|
2274
2167
|
// ============ Session Management ============
|
|
2275
2168
|
/**
|
|
2276
2169
|
* Check if a sync session is active for a space
|
|
@@ -2321,7 +2214,9 @@ var SyncService = class {
|
|
|
2321
2214
|
* Build sync-request payload to broadcast via hub
|
|
2322
2215
|
*/
|
|
2323
2216
|
async buildSyncRequest(spaceId, channelId, inboxAddress) {
|
|
2324
|
-
const
|
|
2217
|
+
const messages = await this.getChannelMessages(spaceId, channelId);
|
|
2218
|
+
const members = await this.storage.getSpaceMembers(spaceId);
|
|
2219
|
+
const summary = createSyncSummary(messages, members.length);
|
|
2325
2220
|
const expiry = Date.now() + this.requestExpiry;
|
|
2326
2221
|
this.sessions.set(spaceId, {
|
|
2327
2222
|
spaceId,
|
|
@@ -2334,7 +2229,7 @@ var SyncService = class {
|
|
|
2334
2229
|
type: "sync-request",
|
|
2335
2230
|
inboxAddress,
|
|
2336
2231
|
expiry,
|
|
2337
|
-
summary
|
|
2232
|
+
summary
|
|
2338
2233
|
};
|
|
2339
2234
|
}
|
|
2340
2235
|
/**
|
|
@@ -2357,14 +2252,15 @@ var SyncService = class {
|
|
|
2357
2252
|
*/
|
|
2358
2253
|
async buildSyncInfo(spaceId, channelId, inboxAddress, theirSummary) {
|
|
2359
2254
|
logger.log(`[SyncService] buildSyncInfo called for space=${spaceId.substring(0, 12)}, channel=${channelId.substring(0, 12)}`);
|
|
2360
|
-
const
|
|
2361
|
-
const
|
|
2362
|
-
logger.log(`[SyncService] buildSyncInfo: our data - ${
|
|
2255
|
+
const messages = await this.getChannelMessages(spaceId, channelId);
|
|
2256
|
+
const members = await this.storage.getSpaceMembers(spaceId);
|
|
2257
|
+
logger.log(`[SyncService] buildSyncInfo: our data - ${messages.length} messages, ${members.length} members`);
|
|
2363
2258
|
logger.log(`[SyncService] buildSyncInfo: their summary:`, theirSummary);
|
|
2364
|
-
if (
|
|
2259
|
+
if (messages.length === 0 && members.length === 0) {
|
|
2365
2260
|
logger.log(`[SyncService] buildSyncInfo: returning null - we have no data`);
|
|
2366
2261
|
return null;
|
|
2367
2262
|
}
|
|
2263
|
+
const ourSummary = createSyncSummary(messages, members.length);
|
|
2368
2264
|
logger.log(`[SyncService] buildSyncInfo: our summary:`, ourSummary);
|
|
2369
2265
|
if (ourSummary.manifestHash === theirSummary.manifestHash && ourSummary.memberCount === theirSummary.memberCount) {
|
|
2370
2266
|
logger.log(`[SyncService] buildSyncInfo: returning null - hashes and member counts match`);
|
|
@@ -2443,7 +2339,10 @@ var SyncService = class {
|
|
|
2443
2339
|
this.sessions.delete(spaceId);
|
|
2444
2340
|
return null;
|
|
2445
2341
|
}
|
|
2446
|
-
const
|
|
2342
|
+
const messages = await this.getChannelMessages(spaceId, channelId);
|
|
2343
|
+
const members = await this.storage.getSpaceMembers(spaceId);
|
|
2344
|
+
const manifest = createManifest(spaceId, channelId, messages);
|
|
2345
|
+
const memberDigests = members.map(createMemberDigest);
|
|
2447
2346
|
this.setSyncInProgress(spaceId, true);
|
|
2448
2347
|
this.setSyncTarget(spaceId, candidate.inboxAddress);
|
|
2449
2348
|
return {
|
|
@@ -2451,8 +2350,8 @@ var SyncService = class {
|
|
|
2451
2350
|
payload: {
|
|
2452
2351
|
type: "sync-initiate",
|
|
2453
2352
|
inboxAddress,
|
|
2454
|
-
manifest
|
|
2455
|
-
memberDigests
|
|
2353
|
+
manifest,
|
|
2354
|
+
memberDigests,
|
|
2456
2355
|
peerIds
|
|
2457
2356
|
}
|
|
2458
2357
|
};
|
|
@@ -2462,12 +2361,13 @@ var SyncService = class {
|
|
|
2462
2361
|
* Build sync-manifest response to sync-initiate
|
|
2463
2362
|
*/
|
|
2464
2363
|
async buildSyncManifest(spaceId, channelId, peerIds, inboxAddress) {
|
|
2465
|
-
const
|
|
2364
|
+
const messages = await this.getChannelMessages(spaceId, channelId);
|
|
2365
|
+
const members = await this.storage.getSpaceMembers(spaceId);
|
|
2466
2366
|
return {
|
|
2467
2367
|
type: "sync-manifest",
|
|
2468
2368
|
inboxAddress,
|
|
2469
|
-
manifest:
|
|
2470
|
-
memberDigests:
|
|
2369
|
+
manifest: createManifest(spaceId, channelId, messages),
|
|
2370
|
+
memberDigests: members.map(createMemberDigest),
|
|
2471
2371
|
peerIds
|
|
2472
2372
|
};
|
|
2473
2373
|
}
|
|
@@ -2477,21 +2377,26 @@ var SyncService = class {
|
|
|
2477
2377
|
* May return multiple payloads for chunking.
|
|
2478
2378
|
*/
|
|
2479
2379
|
async buildSyncDelta(spaceId, channelId, theirManifest, theirMemberDigests, theirPeerIds, ourPeerEntries) {
|
|
2480
|
-
const
|
|
2380
|
+
const messages = await this.getChannelMessages(spaceId, channelId);
|
|
2381
|
+
const members = await this.storage.getSpaceMembers(spaceId);
|
|
2382
|
+
const ourManifest = createManifest(spaceId, channelId, messages);
|
|
2383
|
+
const ourMemberDigests = members.map(createMemberDigest);
|
|
2481
2384
|
const ourPeerIds = [...ourPeerEntries.keys()];
|
|
2482
|
-
const messageDiff = computeMessageDiff(
|
|
2483
|
-
const memberDiff = computeMemberDiff(theirMemberDigests,
|
|
2385
|
+
const messageDiff = computeMessageDiff(ourManifest, theirManifest);
|
|
2386
|
+
const memberDiff = computeMemberDiff(theirMemberDigests, ourMemberDigests);
|
|
2484
2387
|
const peerDiff = computePeerDiff(theirPeerIds, ourPeerIds);
|
|
2388
|
+
const messageMap = new Map(messages.map((m) => [m.messageId, m]));
|
|
2389
|
+
const memberMap = new Map(members.map((m) => [m.address, m]));
|
|
2485
2390
|
const messageDelta = buildMessageDelta(
|
|
2486
2391
|
spaceId,
|
|
2487
2392
|
channelId,
|
|
2488
2393
|
messageDiff,
|
|
2489
|
-
|
|
2394
|
+
messageMap,
|
|
2490
2395
|
this.tombstones
|
|
2491
2396
|
);
|
|
2492
2397
|
const reactionMessageIds = [...messageDiff.extraIds, ...messageDiff.outdatedIds];
|
|
2493
|
-
const reactionDelta = buildReactionDelta(spaceId, channelId,
|
|
2494
|
-
const memberDelta = buildMemberDelta(spaceId, memberDiff,
|
|
2398
|
+
const reactionDelta = buildReactionDelta(spaceId, channelId, messageMap, reactionMessageIds);
|
|
2399
|
+
const memberDelta = buildMemberDelta(spaceId, memberDiff, memberMap);
|
|
2495
2400
|
const peerMapDelta = {
|
|
2496
2401
|
spaceId,
|
|
2497
2402
|
added: peerDiff.extraPeerIds.map((id) => ourPeerEntries.get(id)).filter((e) => e !== void 0),
|
package/dist/index.mjs
CHANGED
|
@@ -2050,118 +2050,11 @@ var SyncService = class {
|
|
|
2050
2050
|
this.sessions = /* @__PURE__ */ new Map();
|
|
2051
2051
|
/** Deleted message tombstones (caller must persist these) */
|
|
2052
2052
|
this.tombstones = [];
|
|
2053
|
-
/** Pre-computed sync payload cache per space:channel - always ready to use */
|
|
2054
|
-
this.payloadCache = /* @__PURE__ */ new Map();
|
|
2055
2053
|
this.storage = config2.storage;
|
|
2056
2054
|
this.maxMessages = config2.maxMessages ?? 1e3;
|
|
2057
2055
|
this.requestExpiry = config2.requestExpiry ?? DEFAULT_SYNC_EXPIRY_MS;
|
|
2058
2056
|
this.onInitiateSync = config2.onInitiateSync;
|
|
2059
2057
|
}
|
|
2060
|
-
// ============ Payload Cache Management ============
|
|
2061
|
-
/**
|
|
2062
|
-
* Get cache key for space/channel
|
|
2063
|
-
*/
|
|
2064
|
-
getCacheKey(spaceId, channelId) {
|
|
2065
|
-
return `${spaceId}:${channelId}`;
|
|
2066
|
-
}
|
|
2067
|
-
/**
|
|
2068
|
-
* Get or initialize the payload cache for a space/channel.
|
|
2069
|
-
* If not cached, loads from storage and builds the payload once.
|
|
2070
|
-
*/
|
|
2071
|
-
async getPayloadCache(spaceId, channelId) {
|
|
2072
|
-
const key = this.getCacheKey(spaceId, channelId);
|
|
2073
|
-
const cached = this.payloadCache.get(key);
|
|
2074
|
-
if (cached) {
|
|
2075
|
-
logger.log(`[SyncService] Using cached payload for ${spaceId.substring(0, 12)}:${channelId.substring(0, 12)}`);
|
|
2076
|
-
return cached;
|
|
2077
|
-
}
|
|
2078
|
-
logger.log(`[SyncService] Building initial payload cache for ${spaceId.substring(0, 12)}:${channelId.substring(0, 12)}`);
|
|
2079
|
-
const messages = await this.getChannelMessages(spaceId, channelId);
|
|
2080
|
-
const members = await this.storage.getSpaceMembers(spaceId);
|
|
2081
|
-
const payload = this.buildPayloadCache(spaceId, channelId, messages, members);
|
|
2082
|
-
this.payloadCache.set(key, payload);
|
|
2083
|
-
return payload;
|
|
2084
|
-
}
|
|
2085
|
-
/**
|
|
2086
|
-
* Build the payload cache from messages and members
|
|
2087
|
-
*/
|
|
2088
|
-
buildPayloadCache(spaceId, channelId, messages, members) {
|
|
2089
|
-
const messageMap = new Map(messages.map((m) => [m.messageId, m]));
|
|
2090
|
-
const memberMap = new Map(members.map((m) => [m.address, m]));
|
|
2091
|
-
const manifest = createManifest(spaceId, channelId, messages);
|
|
2092
|
-
const memberDigests = members.map(createMemberDigest);
|
|
2093
|
-
const summary = createSyncSummary(messages, members.length);
|
|
2094
|
-
return { manifest, memberDigests, summary, messageMap, memberMap };
|
|
2095
|
-
}
|
|
2096
|
-
/**
|
|
2097
|
-
* Rebuild derived fields (manifest, digests, summary) from the maps
|
|
2098
|
-
*/
|
|
2099
|
-
rebuildPayloadCache(spaceId, channelId, cache) {
|
|
2100
|
-
const messages = [...cache.messageMap.values()];
|
|
2101
|
-
const members = [...cache.memberMap.values()];
|
|
2102
|
-
cache.manifest = createManifest(spaceId, channelId, messages);
|
|
2103
|
-
cache.memberDigests = members.map(createMemberDigest);
|
|
2104
|
-
cache.summary = createSyncSummary(messages, members.length);
|
|
2105
|
-
}
|
|
2106
|
-
/**
|
|
2107
|
-
* Invalidate cache for a space/channel (forces reload from storage on next access)
|
|
2108
|
-
*/
|
|
2109
|
-
invalidateCache(spaceId, channelId) {
|
|
2110
|
-
if (channelId) {
|
|
2111
|
-
const key = this.getCacheKey(spaceId, channelId);
|
|
2112
|
-
this.payloadCache.delete(key);
|
|
2113
|
-
logger.log(`[SyncService] Invalidated cache for ${spaceId.substring(0, 12)}:${channelId.substring(0, 12)}`);
|
|
2114
|
-
} else {
|
|
2115
|
-
for (const key of this.payloadCache.keys()) {
|
|
2116
|
-
if (key.startsWith(`${spaceId}:`)) {
|
|
2117
|
-
this.payloadCache.delete(key);
|
|
2118
|
-
}
|
|
2119
|
-
}
|
|
2120
|
-
logger.log(`[SyncService] Invalidated all caches for space ${spaceId.substring(0, 12)}`);
|
|
2121
|
-
}
|
|
2122
|
-
}
|
|
2123
|
-
/**
|
|
2124
|
-
* Update cache with a new/updated message (incremental update - no storage query)
|
|
2125
|
-
*/
|
|
2126
|
-
updateCacheWithMessage(spaceId, channelId, message) {
|
|
2127
|
-
const key = this.getCacheKey(spaceId, channelId);
|
|
2128
|
-
const cached = this.payloadCache.get(key);
|
|
2129
|
-
if (cached) {
|
|
2130
|
-
cached.messageMap.set(message.messageId, message);
|
|
2131
|
-
this.rebuildPayloadCache(spaceId, channelId, cached);
|
|
2132
|
-
logger.log(`[SyncService] Updated cache with message ${message.messageId.substring(0, 12)}`);
|
|
2133
|
-
}
|
|
2134
|
-
}
|
|
2135
|
-
/**
|
|
2136
|
-
* Remove a message from cache (incremental update - no storage query)
|
|
2137
|
-
*/
|
|
2138
|
-
removeCacheMessage(spaceId, channelId, messageId) {
|
|
2139
|
-
const key = this.getCacheKey(spaceId, channelId);
|
|
2140
|
-
const cached = this.payloadCache.get(key);
|
|
2141
|
-
if (cached) {
|
|
2142
|
-
cached.messageMap.delete(messageId);
|
|
2143
|
-
this.rebuildPayloadCache(spaceId, channelId, cached);
|
|
2144
|
-
logger.log(`[SyncService] Removed message ${messageId.substring(0, 12)} from cache`);
|
|
2145
|
-
}
|
|
2146
|
-
}
|
|
2147
|
-
/**
|
|
2148
|
-
* Update cache with a new/updated member (incremental update - no storage query)
|
|
2149
|
-
*/
|
|
2150
|
-
updateCacheWithMember(spaceId, channelId, member) {
|
|
2151
|
-
const key = this.getCacheKey(spaceId, channelId);
|
|
2152
|
-
const cached = this.payloadCache.get(key);
|
|
2153
|
-
if (cached) {
|
|
2154
|
-
cached.memberMap.set(member.address, member);
|
|
2155
|
-
this.rebuildPayloadCache(spaceId, channelId, cached);
|
|
2156
|
-
logger.log(`[SyncService] Updated cache with member ${member.address.substring(0, 12)}`);
|
|
2157
|
-
}
|
|
2158
|
-
}
|
|
2159
|
-
/**
|
|
2160
|
-
* Check if cache exists for a space/channel
|
|
2161
|
-
*/
|
|
2162
|
-
hasCachedPayload(spaceId, channelId) {
|
|
2163
|
-
return this.payloadCache.has(this.getCacheKey(spaceId, channelId));
|
|
2164
|
-
}
|
|
2165
2058
|
// ============ Session Management ============
|
|
2166
2059
|
/**
|
|
2167
2060
|
* Check if a sync session is active for a space
|
|
@@ -2212,7 +2105,9 @@ var SyncService = class {
|
|
|
2212
2105
|
* Build sync-request payload to broadcast via hub
|
|
2213
2106
|
*/
|
|
2214
2107
|
async buildSyncRequest(spaceId, channelId, inboxAddress) {
|
|
2215
|
-
const
|
|
2108
|
+
const messages = await this.getChannelMessages(spaceId, channelId);
|
|
2109
|
+
const members = await this.storage.getSpaceMembers(spaceId);
|
|
2110
|
+
const summary = createSyncSummary(messages, members.length);
|
|
2216
2111
|
const expiry = Date.now() + this.requestExpiry;
|
|
2217
2112
|
this.sessions.set(spaceId, {
|
|
2218
2113
|
spaceId,
|
|
@@ -2225,7 +2120,7 @@ var SyncService = class {
|
|
|
2225
2120
|
type: "sync-request",
|
|
2226
2121
|
inboxAddress,
|
|
2227
2122
|
expiry,
|
|
2228
|
-
summary
|
|
2123
|
+
summary
|
|
2229
2124
|
};
|
|
2230
2125
|
}
|
|
2231
2126
|
/**
|
|
@@ -2248,14 +2143,15 @@ var SyncService = class {
|
|
|
2248
2143
|
*/
|
|
2249
2144
|
async buildSyncInfo(spaceId, channelId, inboxAddress, theirSummary) {
|
|
2250
2145
|
logger.log(`[SyncService] buildSyncInfo called for space=${spaceId.substring(0, 12)}, channel=${channelId.substring(0, 12)}`);
|
|
2251
|
-
const
|
|
2252
|
-
const
|
|
2253
|
-
logger.log(`[SyncService] buildSyncInfo: our data - ${
|
|
2146
|
+
const messages = await this.getChannelMessages(spaceId, channelId);
|
|
2147
|
+
const members = await this.storage.getSpaceMembers(spaceId);
|
|
2148
|
+
logger.log(`[SyncService] buildSyncInfo: our data - ${messages.length} messages, ${members.length} members`);
|
|
2254
2149
|
logger.log(`[SyncService] buildSyncInfo: their summary:`, theirSummary);
|
|
2255
|
-
if (
|
|
2150
|
+
if (messages.length === 0 && members.length === 0) {
|
|
2256
2151
|
logger.log(`[SyncService] buildSyncInfo: returning null - we have no data`);
|
|
2257
2152
|
return null;
|
|
2258
2153
|
}
|
|
2154
|
+
const ourSummary = createSyncSummary(messages, members.length);
|
|
2259
2155
|
logger.log(`[SyncService] buildSyncInfo: our summary:`, ourSummary);
|
|
2260
2156
|
if (ourSummary.manifestHash === theirSummary.manifestHash && ourSummary.memberCount === theirSummary.memberCount) {
|
|
2261
2157
|
logger.log(`[SyncService] buildSyncInfo: returning null - hashes and member counts match`);
|
|
@@ -2334,7 +2230,10 @@ var SyncService = class {
|
|
|
2334
2230
|
this.sessions.delete(spaceId);
|
|
2335
2231
|
return null;
|
|
2336
2232
|
}
|
|
2337
|
-
const
|
|
2233
|
+
const messages = await this.getChannelMessages(spaceId, channelId);
|
|
2234
|
+
const members = await this.storage.getSpaceMembers(spaceId);
|
|
2235
|
+
const manifest = createManifest(spaceId, channelId, messages);
|
|
2236
|
+
const memberDigests = members.map(createMemberDigest);
|
|
2338
2237
|
this.setSyncInProgress(spaceId, true);
|
|
2339
2238
|
this.setSyncTarget(spaceId, candidate.inboxAddress);
|
|
2340
2239
|
return {
|
|
@@ -2342,8 +2241,8 @@ var SyncService = class {
|
|
|
2342
2241
|
payload: {
|
|
2343
2242
|
type: "sync-initiate",
|
|
2344
2243
|
inboxAddress,
|
|
2345
|
-
manifest
|
|
2346
|
-
memberDigests
|
|
2244
|
+
manifest,
|
|
2245
|
+
memberDigests,
|
|
2347
2246
|
peerIds
|
|
2348
2247
|
}
|
|
2349
2248
|
};
|
|
@@ -2353,12 +2252,13 @@ var SyncService = class {
|
|
|
2353
2252
|
* Build sync-manifest response to sync-initiate
|
|
2354
2253
|
*/
|
|
2355
2254
|
async buildSyncManifest(spaceId, channelId, peerIds, inboxAddress) {
|
|
2356
|
-
const
|
|
2255
|
+
const messages = await this.getChannelMessages(spaceId, channelId);
|
|
2256
|
+
const members = await this.storage.getSpaceMembers(spaceId);
|
|
2357
2257
|
return {
|
|
2358
2258
|
type: "sync-manifest",
|
|
2359
2259
|
inboxAddress,
|
|
2360
|
-
manifest:
|
|
2361
|
-
memberDigests:
|
|
2260
|
+
manifest: createManifest(spaceId, channelId, messages),
|
|
2261
|
+
memberDigests: members.map(createMemberDigest),
|
|
2362
2262
|
peerIds
|
|
2363
2263
|
};
|
|
2364
2264
|
}
|
|
@@ -2368,21 +2268,26 @@ var SyncService = class {
|
|
|
2368
2268
|
* May return multiple payloads for chunking.
|
|
2369
2269
|
*/
|
|
2370
2270
|
async buildSyncDelta(spaceId, channelId, theirManifest, theirMemberDigests, theirPeerIds, ourPeerEntries) {
|
|
2371
|
-
const
|
|
2271
|
+
const messages = await this.getChannelMessages(spaceId, channelId);
|
|
2272
|
+
const members = await this.storage.getSpaceMembers(spaceId);
|
|
2273
|
+
const ourManifest = createManifest(spaceId, channelId, messages);
|
|
2274
|
+
const ourMemberDigests = members.map(createMemberDigest);
|
|
2372
2275
|
const ourPeerIds = [...ourPeerEntries.keys()];
|
|
2373
|
-
const messageDiff = computeMessageDiff(
|
|
2374
|
-
const memberDiff = computeMemberDiff(theirMemberDigests,
|
|
2276
|
+
const messageDiff = computeMessageDiff(ourManifest, theirManifest);
|
|
2277
|
+
const memberDiff = computeMemberDiff(theirMemberDigests, ourMemberDigests);
|
|
2375
2278
|
const peerDiff = computePeerDiff(theirPeerIds, ourPeerIds);
|
|
2279
|
+
const messageMap = new Map(messages.map((m) => [m.messageId, m]));
|
|
2280
|
+
const memberMap = new Map(members.map((m) => [m.address, m]));
|
|
2376
2281
|
const messageDelta = buildMessageDelta(
|
|
2377
2282
|
spaceId,
|
|
2378
2283
|
channelId,
|
|
2379
2284
|
messageDiff,
|
|
2380
|
-
|
|
2285
|
+
messageMap,
|
|
2381
2286
|
this.tombstones
|
|
2382
2287
|
);
|
|
2383
2288
|
const reactionMessageIds = [...messageDiff.extraIds, ...messageDiff.outdatedIds];
|
|
2384
|
-
const reactionDelta = buildReactionDelta(spaceId, channelId,
|
|
2385
|
-
const memberDelta = buildMemberDelta(spaceId, memberDiff,
|
|
2289
|
+
const reactionDelta = buildReactionDelta(spaceId, channelId, messageMap, reactionMessageIds);
|
|
2290
|
+
const memberDelta = buildMemberDelta(spaceId, memberDiff, memberMap);
|
|
2386
2291
|
const peerMapDelta = {
|
|
2387
2292
|
spaceId,
|
|
2388
2293
|
added: peerDiff.extraPeerIds.map((id) => ourPeerEntries.get(id)).filter((e) => e !== void 0),
|