@peerbit/shared-log 13.2.31 → 13.2.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/src/exchange-heads.d.ts +13 -2
  2. package/dist/src/exchange-heads.d.ts.map +1 -1
  3. package/dist/src/exchange-heads.js +13 -2
  4. package/dist/src/exchange-heads.js.map +1 -1
  5. package/dist/src/index.d.ts +11 -0
  6. package/dist/src/index.d.ts.map +1 -1
  7. package/dist/src/index.js +727 -85
  8. package/dist/src/index.js.map +1 -1
  9. package/dist/src/replication-announcement.d.ts +3 -1
  10. package/dist/src/replication-announcement.d.ts.map +1 -1
  11. package/dist/src/replication-announcement.js +1 -0
  12. package/dist/src/replication-announcement.js.map +1 -1
  13. package/dist/src/replication-info-v2-binding.d.ts +16 -0
  14. package/dist/src/replication-info-v2-binding.d.ts.map +1 -0
  15. package/dist/src/replication-info-v2-binding.js +30 -0
  16. package/dist/src/replication-info-v2-binding.js.map +1 -0
  17. package/dist/src/replication-info-v2-receive.d.ts +181 -0
  18. package/dist/src/replication-info-v2-receive.d.ts.map +1 -0
  19. package/dist/src/replication-info-v2-receive.js +725 -0
  20. package/dist/src/replication-info-v2-receive.js.map +1 -0
  21. package/dist/src/replication-info-v2-send.d.ts +95 -0
  22. package/dist/src/replication-info-v2-send.d.ts.map +1 -0
  23. package/dist/src/replication-info-v2-send.js +398 -0
  24. package/dist/src/replication-info-v2-send.js.map +1 -0
  25. package/dist/src/replication.d.ts +26 -4
  26. package/dist/src/replication.d.ts.map +1 -1
  27. package/dist/src/replication.js +60 -5
  28. package/dist/src/replication.js.map +1 -1
  29. package/package.json +11 -11
  30. package/src/exchange-heads.ts +15 -2
  31. package/src/index.ts +1040 -201
  32. package/src/replication-announcement.ts +10 -4
  33. package/src/replication-info-v2-binding.ts +44 -0
  34. package/src/replication-info-v2-receive.ts +1045 -0
  35. package/src/replication-info-v2-send.ts +540 -0
  36. package/src/replication.ts +39 -5
@@ -204,8 +204,16 @@ export type ReplicationAnnouncementDeps<R extends "u32" | "u64"> = {
204
204
  // Owner-routed so coordinator spies keep observing re-entrant queueing.
205
205
  queueCurrentReplicationStateAnnouncementRepair: () => void;
206
206
  queueCurrentReplicationStateAnnouncementRetry: (error: unknown) => boolean;
207
+ // Best-effort sidecar. The legacy publish remains the primary operation and
208
+ // retains its exact rejection/retry semantics during mixed-version rollout.
209
+ enqueueReplicationInfoV2: (message: LegacyReplicationInfoMessage) => void;
207
210
  };
208
211
 
212
+ type LegacyReplicationInfoMessage =
213
+ | AllReplicatingSegmentsMessage
214
+ | AddedReplicationSegmentMessage
215
+ | StoppedReplicating;
216
+
209
217
  export class ReplicationAnnouncementCoordinator<R extends "u32" | "u64"> {
210
218
  replicationAnnouncementRetryDebounced:
211
219
  | ReturnType<typeof debounceFixedInterval>
@@ -611,10 +619,7 @@ export class ReplicationAnnouncementCoordinator<R extends "u32" | "u64"> {
611
619
  }
612
620
 
613
621
  async sendReplicationAnnouncement(
614
- message:
615
- | AllReplicatingSegmentsMessage
616
- | AddedReplicationSegmentMessage
617
- | StoppedReplicating,
622
+ message: LegacyReplicationInfoMessage,
618
623
  ownershipLifecycleController = this.deps.captureReplicationOwnershipLifecycle(),
619
624
  options?: { shouldSend?: () => boolean },
620
625
  ): Promise<void> {
@@ -639,6 +644,7 @@ export class ReplicationAnnouncementCoordinator<R extends "u32" | "u64"> {
639
644
  // after that stale send settles.
640
645
  this.rotateAnnouncementSession();
641
646
  this.advanceCurrentReplicationStateAnnouncementRepairGeneration();
647
+ this.deps.enqueueReplicationInfoV2(message);
642
648
  try {
643
649
  await this.deps.getRpc().send(message, {
644
650
  priority: CONVERGENCE_MESSAGE_PRIORITY,
@@ -0,0 +1,44 @@
1
+ import { serialize } from "@dao-xyz/borsh";
2
+ import { type PublicSignKey, sha256Sync } from "@peerbit/crypto";
3
+ import { concat, fromString } from "uint8arrays";
4
+
5
+ const RECEIVER_BINDING_DOMAIN = fromString(
6
+ "peerbit/shared-log/replication-info-v2/receiver-binding/v1",
7
+ );
8
+
9
+ const lengthPrefixed = (bytes: Uint8Array): Uint8Array => {
10
+ const length = new Uint8Array(4);
11
+ new DataView(length.buffer).setUint32(0, bytes.byteLength, true);
12
+ return concat([length, bytes]);
13
+ };
14
+
15
+ const u64LittleEndian = (value: bigint): Uint8Array => {
16
+ const bytes = new Uint8Array(8);
17
+ new DataView(bytes.buffer).setBigUint64(0, value, true);
18
+ return bytes;
19
+ };
20
+
21
+ /**
22
+ * Derive the token echoed by V2 data frames. Delivery recipients are unsigned,
23
+ * so the receiver's nonce alone is not a destination binding. Folding both
24
+ * authenticated identities and signed transport sessions into the 32-byte
25
+ * field prevents a copied request nonce from creating an interchangeable
26
+ * stream for another receiver.
27
+ */
28
+ export const deriveReplicationInfoV2ReceiverBinding = (properties: {
29
+ receiverChallenge: Uint8Array;
30
+ receiver: PublicSignKey;
31
+ receiverTransportSession: bigint;
32
+ sender: PublicSignKey;
33
+ senderTransportSession: bigint;
34
+ }): Uint8Array =>
35
+ sha256Sync(
36
+ concat([
37
+ lengthPrefixed(RECEIVER_BINDING_DOMAIN),
38
+ lengthPrefixed(properties.receiverChallenge),
39
+ lengthPrefixed(serialize(properties.receiver)),
40
+ u64LittleEndian(properties.receiverTransportSession),
41
+ lengthPrefixed(serialize(properties.sender)),
42
+ u64LittleEndian(properties.senderTransportSession),
43
+ ]),
44
+ );