@peerbit/shared-log 15.0.0 → 16.0.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.
Files changed (53) hide show
  1. package/dist/src/checked-prune.d.ts.map +1 -1
  2. package/dist/src/checked-prune.js +12 -0
  3. package/dist/src/checked-prune.js.map +1 -1
  4. package/dist/src/index.d.ts +7 -13
  5. package/dist/src/index.d.ts.map +1 -1
  6. package/dist/src/index.js +81 -598
  7. package/dist/src/index.js.map +1 -1
  8. package/dist/src/instance-lifecycle.d.ts.map +1 -1
  9. package/dist/src/instance-lifecycle.js +9 -0
  10. package/dist/src/instance-lifecycle.js.map +1 -1
  11. package/dist/src/peer-session.d.ts.map +1 -1
  12. package/dist/src/peer-session.js +9 -0
  13. package/dist/src/peer-session.js.map +1 -1
  14. package/dist/src/pid.d.ts +0 -2
  15. package/dist/src/pid.d.ts.map +1 -1
  16. package/dist/src/pid.js +0 -5
  17. package/dist/src/pid.js.map +1 -1
  18. package/dist/src/replication-announcement.d.ts +3 -106
  19. package/dist/src/replication-announcement.d.ts.map +1 -1
  20. package/dist/src/replication-announcement.js +0 -521
  21. package/dist/src/replication-announcement.js.map +1 -1
  22. package/dist/src/replication-info-v2-receive.d.ts +14 -43
  23. package/dist/src/replication-info-v2-receive.d.ts.map +1 -1
  24. package/dist/src/replication-info-v2-receive.js +24 -199
  25. package/dist/src/replication-info-v2-receive.js.map +1 -1
  26. package/dist/src/replication-info-v2-send.d.ts +0 -1
  27. package/dist/src/replication-info-v2-send.d.ts.map +1 -1
  28. package/dist/src/replication-info-v2-send.js +0 -6
  29. package/dist/src/replication-info-v2-send.js.map +1 -1
  30. package/dist/src/replication.d.ts +0 -1
  31. package/dist/src/replication.d.ts.map +1 -1
  32. package/dist/src/replication.js +2 -17
  33. package/dist/src/replication.js.map +1 -1
  34. package/dist/src/role.d.ts +0 -4
  35. package/dist/src/role.d.ts.map +1 -1
  36. package/dist/src/role.js +0 -9
  37. package/dist/src/role.js.map +1 -1
  38. package/dist/src/sync/factory.d.ts +0 -1
  39. package/dist/src/sync/factory.d.ts.map +1 -1
  40. package/dist/src/sync/factory.js +20 -36
  41. package/dist/src/sync/factory.js.map +1 -1
  42. package/package.json +8 -8
  43. package/src/checked-prune.ts +12 -0
  44. package/src/index.ts +104 -817
  45. package/src/instance-lifecycle.ts +9 -0
  46. package/src/peer-session.ts +9 -0
  47. package/src/pid.ts +0 -6
  48. package/src/replication-announcement.ts +8 -739
  49. package/src/replication-info-v2-receive.ts +25 -271
  50. package/src/replication-info-v2-send.ts +0 -7
  51. package/src/replication.ts +1 -20
  52. package/src/role.ts +0 -13
  53. package/src/sync/factory.ts +24 -38
@@ -23,7 +23,6 @@ const REQUIRED_SENDER_CAPABILITIES =
23
23
  const DEFAULT_REQUEST_RETRY_MS = 1_000;
24
24
  const DEFAULT_MAX_REQUEST_RETRY_MS = 30_000;
25
25
  const DEFAULT_REQUEST_MAX_ATTEMPTS = 7;
26
- const DEFAULT_LEGACY_FALLBACK_DELAY_MS = 5_000;
27
26
  const MAX_U64 = (1n << 64n) - 1n;
28
27
  const MAX_BACKOFF_EXPONENT = 20;
29
28
 
@@ -39,13 +38,12 @@ const bytesEqual = (left: Uint8Array, right: Uint8Array): boolean => {
39
38
  return true;
40
39
  };
41
40
 
42
- type LegacyReplicationInfoMessage =
43
- | AllReplicatingSegmentsMessage
44
- | AddedReplicationSegmentMessage
45
- | StoppedReplicating;
46
-
41
+ // Q4 (B12): fingerprints keep constructing the legacy-class canonical forms.
42
+ // They are byte-stable local-only hash inputs, never sent; these are the only
43
+ // sanctioned legacy-frame construction sites in src (see the no-legacy-
44
+ // machinery source ratchet's narrowed whitelist).
47
45
  const replicationInfoPayloadFingerprint = (
48
- message: ReplicationInfoV2Message | LegacyReplicationInfoMessage,
46
+ message: ReplicationInfoV2Message,
49
47
  ): Uint8Array => {
50
48
  const canonical =
51
49
  message instanceof FullReplicationInfoV2Message
@@ -86,14 +84,12 @@ type LocalCapabilityReadyProperties = {
86
84
 
87
85
  export type ReplicationInfoV2LocalCapabilityAdvertisementHandle = {
88
86
  firstAttempt: Promise<void>;
89
- releaseLegacyBarrier(): void;
90
87
  };
91
88
 
92
89
  export type ReplicationInfoV2LocalCapabilityContext = {
93
90
  peerHash: string;
94
91
  target: PublicSignKey;
95
92
  lifecycleSignal: AbortSignal;
96
- legacyBarrierReleased: boolean;
97
93
  };
98
94
 
99
95
  export type ReplicationInfoV2LocalCapabilityAdvertisement = {
@@ -141,18 +137,6 @@ export type ReplicationInfoV2ReceiveState = {
141
137
  requestsSinceCapabilityRefresh: number;
142
138
  requestParked: boolean;
143
139
  capabilityRefreshRequired: boolean;
144
- legacyFallbackTimer?: ReturnType<typeof setTimeout>;
145
- legacyFallbackFingerprint?: Uint8Array;
146
- legacyFallbackTimestamp?: bigint;
147
- legacyFallbackAmbiguous: boolean;
148
- lastCommittedTransportTimestamp?: bigint;
149
- recentCommittedPayloads: Array<{
150
- fingerprint: Uint8Array;
151
- transportTimestamp: bigint;
152
- }>;
153
- lastLegacyObservationTimestamp?: bigint;
154
- lastLegacyObservationFingerprint?: Uint8Array;
155
- lastLegacyObservationAmbiguous: boolean;
156
140
  reservedAdmission?: ReplicationInfoV2ReceiveAdmission;
157
141
  };
158
142
 
@@ -204,7 +188,6 @@ export type ReplicationInfoV2ReceiveDeps = {
204
188
  requestRetryMs?: number;
205
189
  maxRequestRetryMs?: number;
206
190
  requestMaxAttempts?: number;
207
- legacyFallbackDelayMs?: number;
208
191
  };
209
192
 
210
193
  /**
@@ -214,6 +197,14 @@ export type ReplicationInfoV2ReceiveDeps = {
214
197
  */
215
198
  export class ReplicationInfoV2ReceiveCoordinator {
216
199
  _receiveStates!: Map<string, ReplicationInfoV2ReceiveState>;
200
+ /**
201
+ * Post-B12 V2 resync memory: sessions that have already taken one full
202
+ * replication-info snapshot. Two load-bearing reads, both in
203
+ * observeCapability: phase selection (a remembered session opens in
204
+ * "resync" instead of "awaiting-full"), and capability refresh (the
205
+ * preserveCutover decision, which keeps the memory only when a re-advert
206
+ * arrives under the same session with a ready sender).
207
+ */
217
208
  _cutoverPeerSessions!: WeakSet<object>;
218
209
  _localCapabilityReadyBySession!: WeakMap<object, LocalCapabilityReady>;
219
210
  _localCapabilityContextBySession!: WeakMap<
@@ -230,7 +221,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
230
221
  private readonly requestRetryMs: number;
231
222
  private readonly maxRequestRetryMs: number;
232
223
  private readonly requestMaxAttempts: number;
233
- private readonly legacyFallbackDelayMs: number;
234
224
 
235
225
  constructor(private readonly deps: ReplicationInfoV2ReceiveDeps) {
236
226
  this.now = deps.now ?? Date.now;
@@ -246,10 +236,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
246
236
  1,
247
237
  Math.floor(deps.requestMaxAttempts ?? DEFAULT_REQUEST_MAX_ATTEMPTS),
248
238
  );
249
- this.legacyFallbackDelayMs = Math.max(
250
- this.requestRetryMs,
251
- deps.legacyFallbackDelayMs ?? DEFAULT_LEGACY_FALLBACK_DELAY_MS,
252
- );
253
239
  this._receiveStates = new Map();
254
240
  this._cutoverPeerSessions = new WeakSet();
255
241
  this._localCapabilityReadyBySession = new WeakMap();
@@ -308,15 +294,17 @@ export class ReplicationInfoV2ReceiveCoordinator {
308
294
  }
309
295
 
310
296
  /** Revoke an unauthenticated or downgraded capability generation. */
311
- revokePeerCapability(peerHash: string, reopenLegacy = true): void {
297
+ revokePeerCapability(peerHash: string): void {
312
298
  const state = this._receiveStates.get(peerHash);
313
299
  if (!state) {
314
300
  return;
315
301
  }
316
302
  this.clearState(state);
317
- if (reopenLegacy) {
318
- this._cutoverPeerSessions.delete(state.peerSession);
319
- }
303
+ // Unconditional: the revoked session must lose its resync memory so a
304
+ // re-advert starts from the first phase again. (This used to sit behind
305
+ // an opt-out parameter that defaulted to true, had no else-arm, and that
306
+ // no caller ever overrode.)
307
+ this._cutoverPeerSessions.delete(state.peerSession);
320
308
  }
321
309
 
322
310
  private clearState(state: ReplicationInfoV2ReceiveState): void {
@@ -324,10 +312,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
324
312
  clearTimeout(state.requestTimer);
325
313
  state.requestTimer = undefined;
326
314
  }
327
- if (state.legacyFallbackTimer) {
328
- clearTimeout(state.legacyFallbackTimer);
329
- state.legacyFallbackTimer = undefined;
330
- }
331
315
  state.controller.abort();
332
316
  state.version++;
333
317
  if (this._receiveStates.get(state.peerHash) === state) {
@@ -422,9 +406,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
422
406
  if (state.timer || state.inFlight || state.ready) {
423
407
  return;
424
408
  }
425
- if (state.acknowledgedReady && !state.context.legacyBarrierReleased) {
426
- return;
427
- }
428
409
  if (!this.isLocalCapabilityAdvertisementOwnerCurrent(state)) {
429
410
  this.clearLocalCapabilityAdvertisement(state);
430
411
  return;
@@ -468,9 +449,7 @@ export class ReplicationInfoV2ReceiveCoordinator {
468
449
  return;
469
450
  }
470
451
  if (state.acknowledgedReady) {
471
- if (state.context.legacyBarrierReleased) {
472
- this.promoteLocalCapabilityAdvertisement(state);
473
- }
452
+ this.promoteLocalCapabilityAdvertisement(state);
474
453
  return;
475
454
  }
476
455
  if (!this.isLocalCapabilityAdvertisementReadyOpen(state)) {
@@ -528,9 +507,7 @@ export class ReplicationInfoV2ReceiveCoordinator {
528
507
  this.isLocalCapabilityAdvertisementGenerationCurrent(state) &&
529
508
  !state.ready
530
509
  ) {
531
- if (!state.acknowledgedReady || state.context.legacyBarrierReleased) {
532
- this.armLocalCapabilityAdvertisement(state);
533
- }
510
+ this.armLocalCapabilityAdvertisement(state);
534
511
  }
535
512
  });
536
513
  state.inFlight = operation;
@@ -538,10 +515,9 @@ export class ReplicationInfoV2ReceiveCoordinator {
538
515
  }
539
516
 
540
517
  /**
541
- * Start local authenticated-apply advertisement independently of the legacy
542
- * join path. ACK and legacy publication are a two-phase barrier: the first
543
- * attempt always settles independently, while readiness is promoted only
544
- * after the host releases the legacy barrier. Failed attempts leave one
518
+ * Start local authenticated-apply advertisement. Readiness is promoted as
519
+ * soon as the ACK lands (B12: the legacy publication this once ordered
520
+ * behind a two-phase barrier is retired). Failed attempts leave one
545
521
  * exact-session worker retrying with capped exponential backoff.
546
522
  */
547
523
  advertiseLocalCapability(properties: {
@@ -559,7 +535,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
559
535
  ) {
560
536
  return {
561
537
  firstAttempt: Promise.resolve(),
562
- releaseLegacyBarrier: () => {},
563
538
  };
564
539
  }
565
540
  let context = this._localCapabilityContextBySession.get(
@@ -573,7 +548,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
573
548
  ) {
574
549
  return {
575
550
  firstAttempt: Promise.resolve(),
576
- releaseLegacyBarrier: () => {},
577
551
  };
578
552
  }
579
553
  if (!context) {
@@ -581,7 +555,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
581
555
  peerHash,
582
556
  target: properties.target,
583
557
  lifecycleSignal: properties.signal,
584
- legacyBarrierReleased: false,
585
558
  };
586
559
  this._localCapabilityContextBySession.set(
587
560
  properties.peerSession,
@@ -613,7 +586,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
613
586
  ) {
614
587
  return {
615
588
  firstAttempt: Promise.resolve(),
616
- releaseLegacyBarrier: () => {},
617
589
  };
618
590
  }
619
591
  if (!state) {
@@ -646,52 +618,17 @@ export class ReplicationInfoV2ReceiveCoordinator {
646
618
  const firstAttempt =
647
619
  state.firstAttempt ??
648
620
  (state.firstAttempt = this.runLocalCapabilityAdvertisement(state));
649
- const advertisement = state;
650
621
  return {
651
622
  firstAttempt,
652
- releaseLegacyBarrier: () =>
653
- this.releaseLocalCapabilityLegacyBarrier(
654
- advertisement.peerSession,
655
- context,
656
- ),
657
623
  };
658
624
  }
659
625
 
660
- private releaseLocalCapabilityLegacyBarrier(
661
- peerSession: object,
662
- context: ReplicationInfoV2LocalCapabilityContext,
663
- ): void {
664
- if (context.legacyBarrierReleased) {
665
- return;
666
- }
667
- if (
668
- this._localCapabilityContextBySession.get(peerSession) !== context ||
669
- context.lifecycleSignal.aborted ||
670
- this.deps.isClosed() ||
671
- !this.deps.isPeerSessionCurrent(context.peerHash, peerSession)
672
- ) {
673
- return;
674
- }
675
- context.legacyBarrierReleased = true;
676
- const state = this._localCapabilityAdvertisementsByPeer.get(
677
- context.peerHash,
678
- );
679
- if (state?.peerSession === peerSession && state.context === context) {
680
- if (!this.isLocalCapabilityAdvertisementOwnerCurrent(state)) {
681
- this.clearLocalCapabilityAdvertisement(state);
682
- return;
683
- }
684
- this.promoteLocalCapabilityAdvertisement(state);
685
- }
686
- }
687
-
688
626
  private promoteLocalCapabilityAdvertisement(
689
627
  state: ReplicationInfoV2LocalCapabilityAdvertisement,
690
628
  ): boolean {
691
629
  const ready = state.acknowledgedReady;
692
630
  if (
693
631
  state.ready ||
694
- !state.context.legacyBarrierReleased ||
695
632
  !ready ||
696
633
  ready.receiveEpoch !== state.receiveEpoch ||
697
634
  ready.advertisement !== state ||
@@ -725,9 +662,7 @@ export class ReplicationInfoV2ReceiveCoordinator {
725
662
 
726
663
  /**
727
664
  * Re-advertise one exact current recovery epoch from the stable membership
728
- * context captured during opening. The opening handle owns barrier release;
729
- * recovery never bypasses a legacy snapshot or role publication still in
730
- * progress.
665
+ * context captured during opening.
731
666
  */
732
667
  reAdvertiseLocalCapabilityForRecovery(properties: {
733
668
  peerHash: string;
@@ -946,9 +881,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
946
881
  requestsSinceCapabilityRefresh: 0,
947
882
  requestParked: false,
948
883
  capabilityRefreshRequired: retainedCutover,
949
- legacyFallbackAmbiguous: false,
950
- recentCommittedPayloads: [],
951
- lastLegacyObservationAmbiguous: false,
952
884
  };
953
885
  this._receiveStates.set(peerHash, state);
954
886
  const ready = this._localCapabilityReadyBySession.get(peerSession);
@@ -1090,10 +1022,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
1090
1022
  }
1091
1023
  }
1092
1024
 
1093
- isLegacyCutover(peerSession: object | null): boolean {
1094
- return peerSession !== null && this._cutoverPeerSessions.has(peerSession);
1095
- }
1096
-
1097
1025
  prepare(
1098
1026
  message: ReplicationInfoV2Message,
1099
1027
  properties: {
@@ -1235,10 +1163,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
1235
1163
  clearTimeout(state.requestTimer);
1236
1164
  state.requestTimer = undefined;
1237
1165
  }
1238
- if (state.legacyFallbackTimer) {
1239
- clearTimeout(state.legacyFallbackTimer);
1240
- state.legacyFallbackTimer = undefined;
1241
- }
1242
1166
  return admission;
1243
1167
  }
1244
1168
 
@@ -1273,156 +1197,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
1273
1197
  // worker so the exact current generation cannot become stranded.
1274
1198
  this.armRequest(state, 0);
1275
1199
  }
1276
- if (
1277
- currentState === state &&
1278
- this.isStateCurrent(state) &&
1279
- state.phase === "active" &&
1280
- state.legacyFallbackFingerprint !== undefined
1281
- ) {
1282
- // A reservation also pauses compat sidecar recovery. Matching commits
1283
- // clear the evidence; an uncommitted or non-matching frame restores its
1284
- // bounded fallback without invalidating work in the host apply lane.
1285
- this.armLegacyFallback(state);
1286
- }
1287
- }
1288
-
1289
- /**
1290
- * B9 can lose its sender grant while keeping the topic session open. Its
1291
- * unmatched legacy sidecar is the compatibility signal to re-handshake; a
1292
- * matching V2 payload before or after the legacy copy suppresses the timer.
1293
- */
1294
- noteLegacyAnnouncement(properties: {
1295
- peerHash: string;
1296
- peerSession: object;
1297
- receiveEpoch: object | null;
1298
- senderTransportSession: bigint;
1299
- transportTimestamp: bigint;
1300
- message: LegacyReplicationInfoMessage;
1301
- }): boolean {
1302
- const state = this._receiveStates.get(properties.peerHash);
1303
- if (
1304
- !state ||
1305
- state.peerSession !== properties.peerSession ||
1306
- state.receiveEpoch !== properties.receiveEpoch ||
1307
- state.senderTransportSession !== properties.senderTransportSession ||
1308
- !this._cutoverPeerSessions.has(properties.peerSession) ||
1309
- !this.isStateCurrent(state)
1310
- ) {
1311
- return false;
1312
- }
1313
- const fingerprint = replicationInfoPayloadFingerprint(properties.message);
1314
- if (
1315
- state.lastCommittedTransportTimestamp !== undefined &&
1316
- properties.transportTimestamp < state.lastCommittedTransportTimestamp
1317
- ) {
1318
- return true;
1319
- }
1320
- if (
1321
- state.recentCommittedPayloads.some(
1322
- (committed) =>
1323
- properties.transportTimestamp <= committed.transportTimestamp &&
1324
- bytesEqual(committed.fingerprint, fingerprint),
1325
- )
1326
- ) {
1327
- return true;
1328
- }
1329
- if (state.lastLegacyObservationTimestamp !== undefined) {
1330
- if (
1331
- properties.transportTimestamp < state.lastLegacyObservationTimestamp
1332
- ) {
1333
- return true;
1334
- }
1335
- if (
1336
- properties.transportTimestamp === state.lastLegacyObservationTimestamp
1337
- ) {
1338
- if (
1339
- state.lastLegacyObservationAmbiguous ||
1340
- (state.lastLegacyObservationFingerprint !== undefined &&
1341
- bytesEqual(state.lastLegacyObservationFingerprint, fingerprint))
1342
- ) {
1343
- return true;
1344
- }
1345
- state.lastLegacyObservationAmbiguous = true;
1346
- } else {
1347
- state.lastLegacyObservationTimestamp = properties.transportTimestamp;
1348
- state.lastLegacyObservationFingerprint = fingerprint.slice();
1349
- state.lastLegacyObservationAmbiguous = false;
1350
- }
1351
- } else {
1352
- state.lastLegacyObservationTimestamp = properties.transportTimestamp;
1353
- state.lastLegacyObservationFingerprint = fingerprint.slice();
1354
- state.lastLegacyObservationAmbiguous = false;
1355
- }
1356
- const reserved = this._reservedAdmissionsByPeer.get(properties.peerHash);
1357
- if (
1358
- reserved?.state === state &&
1359
- !bytesEqual(reserved.payloadFingerprint, fingerprint)
1360
- ) {
1361
- // A legacy sidecar observed while a different V2 payload is applying
1362
- // cannot be erased by that commit. The transport has already ACKed the
1363
- // sidecar, so require one authoritative successor after release.
1364
- reserved.resyncAfterRelease = true;
1365
- }
1366
- if (!state.legacyFallbackFingerprint) {
1367
- state.legacyFallbackFingerprint = fingerprint;
1368
- state.legacyFallbackTimestamp = properties.transportTimestamp;
1369
- state.legacyFallbackAmbiguous = false;
1370
- } else {
1371
- if (!bytesEqual(state.legacyFallbackFingerprint, fingerprint)) {
1372
- state.legacyFallbackAmbiguous = true;
1373
- }
1374
- if (
1375
- state.legacyFallbackTimestamp === undefined ||
1376
- properties.transportTimestamp > state.legacyFallbackTimestamp
1377
- ) {
1378
- state.legacyFallbackTimestamp = properties.transportTimestamp;
1379
- }
1380
- }
1381
- if (state.phase !== "active") {
1382
- if (state.requestParked) {
1383
- this.transitionToResync(state, {
1384
- force: true,
1385
- refreshCapability: true,
1386
- });
1387
- }
1388
- return true;
1389
- }
1390
- if (state.legacyFallbackTimer) {
1391
- return true;
1392
- }
1393
- this.armLegacyFallback(state);
1394
- return true;
1395
- }
1396
-
1397
- private armLegacyFallback(state: ReplicationInfoV2ReceiveState): void {
1398
- if (
1399
- state.legacyFallbackTimer ||
1400
- state.phase !== "active" ||
1401
- state.legacyFallbackFingerprint === undefined ||
1402
- this._reservedAdmissionsByPeer.has(state.peerHash)
1403
- ) {
1404
- return;
1405
- }
1406
- state.legacyFallbackTimer = setTimeout(() => {
1407
- state.legacyFallbackTimer = undefined;
1408
- if (this.isStateCurrent(state) && state.phase === "active") {
1409
- this.transitionToResync(state, {
1410
- force: true,
1411
- refreshCapability: true,
1412
- });
1413
- }
1414
- }, this.legacyFallbackDelayMs);
1415
- state.legacyFallbackTimer.unref?.();
1416
- }
1417
-
1418
- private clearLegacyFallback(state: ReplicationInfoV2ReceiveState): void {
1419
- if (state.legacyFallbackTimer) {
1420
- clearTimeout(state.legacyFallbackTimer);
1421
- state.legacyFallbackTimer = undefined;
1422
- }
1423
- state.legacyFallbackFingerprint = undefined;
1424
- state.legacyFallbackTimestamp = undefined;
1425
- state.legacyFallbackAmbiguous = false;
1426
1200
  }
1427
1201
 
1428
1202
  isAdmissionCurrent(admission: ReplicationInfoV2ReceiveAdmission): boolean {
@@ -1464,26 +1238,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
1464
1238
  state.requestsSinceCapabilityRefresh = 0;
1465
1239
  state.requestParked = false;
1466
1240
  state.capabilityRefreshRequired = false;
1467
- state.lastCommittedTransportTimestamp = admission.transportTimestamp;
1468
- state.recentCommittedPayloads.push({
1469
- fingerprint: admission.payloadFingerprint.slice(),
1470
- transportTimestamp: admission.transportTimestamp,
1471
- });
1472
- if (state.recentCommittedPayloads.length > 8) {
1473
- state.recentCommittedPayloads.shift();
1474
- }
1475
- if (
1476
- (state.legacyFallbackTimestamp !== undefined &&
1477
- admission.transportTimestamp > state.legacyFallbackTimestamp) ||
1478
- (!state.legacyFallbackAmbiguous &&
1479
- state.legacyFallbackFingerprint !== undefined &&
1480
- bytesEqual(
1481
- state.legacyFallbackFingerprint,
1482
- admission.payloadFingerprint,
1483
- ))
1484
- ) {
1485
- this.clearLegacyFallback(state);
1486
- }
1487
1241
  if (state.requestTimer) {
1488
1242
  clearTimeout(state.requestTimer);
1489
1243
  state.requestTimer = undefined;
@@ -392,13 +392,6 @@ export class ReplicationInfoV2SendCoordinator<R extends "u32" | "u64"> {
392
392
  }
393
393
  }
394
394
 
395
- enqueueSnapshotForPeer(peerHash: string): void {
396
- const state = this._sendStates.get(peerHash);
397
- if (state) {
398
- this.enqueueState(state, { kind: "snapshot" });
399
- }
400
- }
401
-
402
395
  private enqueueState(
403
396
  state: ReplicationInfoV2SendState,
404
397
  request: SendRequest,
@@ -7,14 +7,12 @@ import {
7
7
  variant,
8
8
  vec,
9
9
  } from "@dao-xyz/borsh";
10
- import { PublicSignKey, randomBytes } from "@peerbit/crypto";
10
+ import { PublicSignKey } from "@peerbit/crypto";
11
11
  import { type Index } from "@peerbit/indexer-interface";
12
12
  import { TransportMessage } from "./message.js";
13
13
  import {
14
- ReplicationIntent,
15
14
  type ReplicationRangeIndexable,
16
15
  ReplicationRangeMessage,
17
- ReplicationRangeMessageU32,
18
16
  } from "./ranges.js";
19
17
  import { Observer, Replicator, Role } from "./role.js";
20
18
 
@@ -63,23 +61,6 @@ export class ResponseRoleMessage extends TransportMessage {
63
61
  super();
64
62
  this.role = properties.role;
65
63
  }
66
-
67
- toReplicationInfoMessage(): AllReplicatingSegmentsMessage {
68
- return new AllReplicatingSegmentsMessage({
69
- segments:
70
- this.role instanceof Replicator
71
- ? this.role.segments.map((x) => {
72
- return new ReplicationRangeMessageU32({
73
- id: randomBytes(32),
74
- offset: x.offset,
75
- factor: x.factor,
76
- timestamp: x.timestamp,
77
- mode: ReplicationIntent.NonStrict,
78
- });
79
- })
80
- : [],
81
- });
82
- }
83
64
  }
84
65
 
85
66
  @variant([1, 2])
package/src/role.ts CHANGED
@@ -6,19 +6,10 @@
6
6
  import { field, variant, vec } from "@dao-xyz/borsh";
7
7
  import { MAX_U32, denormalizer } from "./integers.js";
8
8
 
9
- export const overlaps = (x1: number, x2: number, y1: number, y2: number) => {
10
- if (x1 <= y2 && y1 <= x2) {
11
- return true;
12
- }
13
- return false;
14
- };
15
-
16
9
  export abstract class Role {
17
10
  abstract equals(other: Role): boolean;
18
11
  }
19
12
 
20
- export const NO_TYPE_VARIANT = new Uint8Array([0]);
21
-
22
13
  @variant(0)
23
14
  export class NoType extends Role {
24
15
  equals(other: Role) {
@@ -26,8 +17,6 @@ export class NoType extends Role {
26
17
  }
27
18
  }
28
19
 
29
- export const OBSERVER_TYPE_VARIANT = new Uint8Array([1]);
30
-
31
20
  @variant(1)
32
21
  export class Observer extends Role {
33
22
  equals(other: Role) {
@@ -35,8 +24,6 @@ export class Observer extends Role {
35
24
  }
36
25
  }
37
26
 
38
- export const REPLICATOR_TYPE_VARIANT = new Uint8Array([2]);
39
-
40
27
  const denormalizeru32 = denormalizer("u32");
41
28
  export class RoleReplicationSegment {
42
29
  @field({ type: "u64" })
@@ -14,7 +14,6 @@ import type {
14
14
  Syncronizer,
15
15
  } from "./index.js";
16
16
  import { RatelessIBLTSynchronizer } from "./rateless-iblt.js";
17
- import { SimpleSyncronizer } from "./simple.js";
18
17
 
19
18
  export type CreateSyncronizerProps<R extends "u32" | "u64"> = {
20
19
  // pass-through refs (snapshotted at open() time; stable post-open)
@@ -39,7 +38,6 @@ export type CreateSyncronizerProps<R extends "u32" | "u64"> = {
39
38
  sendRawExchangeHeads: RawExchangeHeadsSender;
40
39
  warn: (message: string) => void;
41
40
  // construction-time scalars
42
- compatibility?: number;
43
41
  resolution: R;
44
42
  sync?: SyncOptions<R>;
45
43
  syncronizer?: SynchronizerConstructor<R>;
@@ -113,42 +111,30 @@ export function createSyncronizer<R extends "u32" | "u64">(
113
111
  peerSupportsRawExchangeHeads: props.peerSupportsRawExchangeHeads,
114
112
  sendRawExchangeHeads: props.sendRawExchangeHeads,
115
113
  });
116
- } else {
117
- if (props.compatibility !== undefined && props.compatibility < 10) {
118
- return new SimpleSyncronizer({
119
- log: props.log,
120
- rpc: props.rpc,
121
- entryIndex: props.entryIndex,
122
- coordinateToHash: props.coordinateToHash,
123
- resolveHashesForSymbols,
124
- resolveHashListForSymbols,
125
- sync: props.sync,
126
- isEntryRecentlyKnownByPeer: props.isEntryRecentlyKnownByPeer,
127
- peerSupportsRawExchangeHeads: props.peerSupportsRawExchangeHeads,
128
- sendRawExchangeHeads: props.sendRawExchangeHeads,
129
- });
130
- } else {
131
- if (props.resolution === "u32") {
132
- props.warn(
133
- "u32 resolution is not recommended for RatelessIBLTSynchronizer",
134
- );
135
- }
114
+ }
136
115
 
137
- return new RatelessIBLTSynchronizer<R>({
138
- numbers: props.numbers,
139
- entryIndex: props.entryIndex,
140
- log: props.log,
141
- rangeIndex: props.rangeIndex,
142
- rpc: props.rpc,
143
- coordinateToHash: props.coordinateToHash,
144
- resolveHashesForSymbols,
145
- resolveHashListForSymbols,
146
- resolveHashNumbersInRange,
147
- sync: props.sync,
148
- isEntryRecentlyKnownByPeer: props.isEntryRecentlyKnownByPeer,
149
- peerSupportsRawExchangeHeads: props.peerSupportsRawExchangeHeads,
150
- sendRawExchangeHeads: props.sendRawExchangeHeads,
151
- }) as Syncronizer<R>;
152
- }
116
+ // Default synchronizer. SimpleSyncronizer stays a first-class explicit
117
+ // choice via the `syncronizer` option above; only the retired
118
+ // compatibility-coupled defaulting arm that once selected it is gone (B12).
119
+ if (props.resolution === "u32") {
120
+ props.warn(
121
+ "u32 resolution is not recommended for RatelessIBLTSynchronizer",
122
+ );
153
123
  }
124
+
125
+ return new RatelessIBLTSynchronizer<R>({
126
+ numbers: props.numbers,
127
+ entryIndex: props.entryIndex,
128
+ log: props.log,
129
+ rangeIndex: props.rangeIndex,
130
+ rpc: props.rpc,
131
+ coordinateToHash: props.coordinateToHash,
132
+ resolveHashesForSymbols,
133
+ resolveHashListForSymbols,
134
+ resolveHashNumbersInRange,
135
+ sync: props.sync,
136
+ isEntryRecentlyKnownByPeer: props.isEntryRecentlyKnownByPeer,
137
+ peerSupportsRawExchangeHeads: props.peerSupportsRawExchangeHeads,
138
+ sendRawExchangeHeads: props.sendRawExchangeHeads,
139
+ }) as Syncronizer<R>;
154
140
  }