@peerbit/shared-log 13.2.14 → 13.2.16

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peerbit/shared-log",
3
- "version": "13.2.14",
3
+ "version": "13.2.16",
4
4
  "description": "Shared log",
5
5
  "sideEffects": false,
6
6
  "type": "module",
@@ -61,27 +61,27 @@
61
61
  "pidusage": "^4.0.1",
62
62
  "pino": "^9.4.0",
63
63
  "uint8arrays": "^5.1.0",
64
+ "@peerbit/any-store": "2.2.13",
64
65
  "@peerbit/blocks": "4.2.7",
65
- "@peerbit/blocks-interface": "2.1.3",
66
66
  "@peerbit/crypto": "3.1.4",
67
- "@peerbit/cache": "3.1.1",
68
- "@peerbit/any-store": "2.2.13",
69
67
  "@peerbit/diagnostics": "0.0.1",
70
- "@peerbit/indexer-sqlite3": "3.0.11",
68
+ "@peerbit/cache": "3.1.1",
71
69
  "@peerbit/indexer-interface": "3.0.8",
72
- "@peerbit/logger": "2.0.1",
70
+ "@peerbit/blocks-interface": "2.1.3",
71
+ "@peerbit/indexer-sqlite3": "3.0.11",
73
72
  "@peerbit/log": "6.2.10",
74
- "@peerbit/program": "6.0.40",
73
+ "@peerbit/logger": "2.0.1",
74
+ "@peerbit/rpc": "6.1.9",
75
75
  "@peerbit/pubsub-interface": "5.1.7",
76
76
  "@peerbit/riblt": "1.2.0",
77
- "@peerbit/pubsub": "5.3.5",
78
- "@peerbit/rpc": "6.1.8",
77
+ "@peerbit/program": "6.0.41",
78
+ "@peerbit/time": "3.0.1",
79
79
  "@peerbit/stream-interface": "6.0.13",
80
- "@peerbit/time": "3.0.1"
80
+ "@peerbit/pubsub": "5.3.6"
81
81
  },
82
82
  "optionalDependencies": {
83
- "@peerbit/shared-log-rust": "0.1.3",
84
- "@peerbit/native-backbone": "0.2.3"
83
+ "@peerbit/native-backbone": "0.2.3",
84
+ "@peerbit/shared-log-rust": "0.1.3"
85
85
  },
86
86
  "devDependencies": {
87
87
  "@types/libsodium-wrappers": "^0.7.14",
@@ -89,8 +89,8 @@
89
89
  "uuid": "^11.1.1",
90
90
  "@peerbit/any-store-rust": "0.1.3",
91
91
  "@peerbit/indexer-rust": "1.0.6",
92
- "@peerbit/test-utils": "3.1.12",
93
- "peerbit": "5.3.12"
92
+ "@peerbit/test-utils": "3.1.13",
93
+ "peerbit": "5.3.13"
94
94
  },
95
95
  "repository": {
96
96
  "type": "git",
@@ -1160,26 +1160,32 @@ export class ResponseIPruneV2 extends TransportMessage {
1160
1160
 
1161
1161
  const MAX_EXCHANGE_MESSAGE_SIZE = 1e5; // 100kb. Too large size might not be faster (even if we can do 5mb)
1162
1162
  export const MAX_RAW_EXCHANGE_MESSAGE_SIZE = 512 * 1024;
1163
+ // Hash-resolved full entries and raw JS blocks remain reachable while a yielded
1164
+ // message is being sent, so bound their count-based lookahead. Caller-owned
1165
+ // Entry[] values and an individual entry's bytes are not byte-bounded here;
1166
+ // native metadata-only planning can retain its larger batch.
1167
+ const EXCHANGE_HEADS_PAYLOAD_RESOLVE_BATCH_SIZE = 16;
1163
1168
  export const EXCHANGE_HEADS_RESOLVE_BATCH_SIZE = 256;
1164
1169
 
1165
- export const createExchangeHeadsMessages = async function* (
1170
+ const createExchangeHeadsMessagesWithVisited = async function* (
1166
1171
  log: Log<any>,
1167
1172
  heads: Entry<any>[] | string[] | Set<string>,
1173
+ visitedHeads: Set<string>,
1168
1174
  ): AsyncGenerator<ExchangeHeadsMessage<any>, void, void> {
1169
1175
  let size = 0;
1170
1176
  let current: EntryWithRefs<any>[] = [];
1171
- const visitedHeads = new Set<string>();
1172
1177
  const headArray = Array.isArray(heads) ? heads : [...heads];
1173
- const canUseNativeReferenceGids = headArray.length === 1;
1178
+ const canUseNativeReferenceGids =
1179
+ headArray.length === 1 && visitedHeads.size === 0;
1174
1180
 
1175
1181
  for (
1176
1182
  let offset = 0;
1177
1183
  offset < headArray.length;
1178
- offset += EXCHANGE_HEADS_RESOLVE_BATCH_SIZE
1184
+ offset += EXCHANGE_HEADS_PAYLOAD_RESOLVE_BATCH_SIZE
1179
1185
  ) {
1180
1186
  const headBatch = headArray.slice(
1181
1187
  offset,
1182
- offset + EXCHANGE_HEADS_RESOLVE_BATCH_SIZE,
1188
+ offset + EXCHANGE_HEADS_PAYLOAD_RESOLVE_BATCH_SIZE,
1183
1189
  );
1184
1190
  const nativeReferenceRowsByPosition =
1185
1191
  canUseNativeReferenceGids === false
@@ -1192,6 +1198,7 @@ export const createExchangeHeadsMessages = async function* (
1192
1198
  );
1193
1199
  for (let i = 0; i < resolvedHeads.length; i++) {
1194
1200
  const entry = resolvedHeads[i];
1201
+ resolvedHeads[i] = undefined;
1195
1202
  if (!entry) {
1196
1203
  continue; // missing this entry, could be deleted while iterating
1197
1204
  }
@@ -1290,6 +1297,13 @@ export const createExchangeHeadsMessages = async function* (
1290
1297
  }
1291
1298
  };
1292
1299
 
1300
+ export const createExchangeHeadsMessages = async function* (
1301
+ log: Log<any>,
1302
+ heads: Entry<any>[] | string[] | Set<string>,
1303
+ ): AsyncGenerator<ExchangeHeadsMessage<any>, void, void> {
1304
+ yield* createExchangeHeadsMessagesWithVisited(log, heads, new Set<string>());
1305
+ };
1306
+
1293
1307
  export const createRawExchangeHeadsMessages = async function* (
1294
1308
  log: Log<any>,
1295
1309
  heads: string[] | Set<string>,
@@ -1313,30 +1327,44 @@ export const createRawExchangeHeadsMessages = async function* (
1313
1327
  });
1314
1328
  }
1315
1329
  };
1330
+ const flushCurrent = () => {
1331
+ if (current.length === 0) {
1332
+ return undefined;
1333
+ }
1334
+ emitJsBlockBytes(current, size);
1335
+ const message = new RawExchangeHeadsMessage({ heads: current });
1336
+ size = 0;
1337
+ current = [];
1338
+ return message;
1339
+ };
1316
1340
 
1317
- for (let offset = 0; offset < headArray.length; offset += EXCHANGE_HEADS_RESOLVE_BATCH_SIZE) {
1341
+ for (
1342
+ let offset = 0;
1343
+ offset < headArray.length;
1344
+ offset += EXCHANGE_HEADS_PAYLOAD_RESOLVE_BATCH_SIZE
1345
+ ) {
1318
1346
  const headBatch = headArray.slice(
1319
1347
  offset,
1320
- offset + EXCHANGE_HEADS_RESOLVE_BATCH_SIZE,
1348
+ offset + EXCHANGE_HEADS_PAYLOAD_RESOLVE_BATCH_SIZE,
1321
1349
  );
1322
1350
  const nativeReferenceRowsByPosition = getNativeReferenceRowsByHeadInput(
1323
1351
  log,
1324
1352
  headBatch,
1325
1353
  visitedHeads,
1326
1354
  );
1327
- if (!nativeReferenceRowsByPosition) {
1328
- for await (const message of createExchangeHeadsMessages(log, headBatch)) {
1329
- yield message;
1355
+ const blockRows = nativeReferenceRowsByPosition
1356
+ ? await resolveExchangeHeadBlocks(log, headBatch, visitedHeads)
1357
+ : undefined;
1358
+ if (!nativeReferenceRowsByPosition || !blockRows) {
1359
+ const pending = flushCurrent();
1360
+ if (pending) {
1361
+ yield pending;
1330
1362
  }
1331
- continue;
1332
- }
1333
- const blockRows = await resolveExchangeHeadBlocks(
1334
- log,
1335
- headBatch,
1336
- visitedHeads,
1337
- );
1338
- if (!blockRows) {
1339
- for await (const message of createExchangeHeadsMessages(log, headBatch)) {
1363
+ for await (const message of createExchangeHeadsMessagesWithVisited(
1364
+ log,
1365
+ headBatch,
1366
+ visitedHeads,
1367
+ )) {
1340
1368
  yield message;
1341
1369
  }
1342
1370
  continue;
@@ -1344,6 +1372,7 @@ export const createRawExchangeHeadsMessages = async function* (
1344
1372
 
1345
1373
  for (let i = 0; i < blockRows.length; i++) {
1346
1374
  const block = blockRows[i];
1375
+ blockRows[i] = undefined;
1347
1376
  if (!block) {
1348
1377
  continue;
1349
1378
  }
@@ -1376,16 +1405,16 @@ export const createRawExchangeHeadsMessages = async function* (
1376
1405
  );
1377
1406
  size += block.bytes.byteLength;
1378
1407
  if (size > MAX_RAW_EXCHANGE_MESSAGE_SIZE) {
1379
- emitJsBlockBytes(current, size);
1380
- size = 0;
1381
- yield new RawExchangeHeadsMessage({ heads: current });
1382
- current = [];
1408
+ const pending = flushCurrent();
1409
+ if (pending) {
1410
+ yield pending;
1411
+ }
1383
1412
  }
1384
1413
  }
1385
1414
  }
1386
- if (current.length > 0) {
1387
- emitJsBlockBytes(current, size);
1388
- yield new RawExchangeHeadsMessage({ heads: current });
1415
+ const pending = flushCurrent();
1416
+ if (pending) {
1417
+ yield pending;
1389
1418
  }
1390
1419
  };
1391
1420
 
package/src/index.ts CHANGED
@@ -16342,6 +16342,8 @@ export class SharedLog<
16342
16342
  sync: options?.sync,
16343
16343
  isEntryRecentlyKnownByPeer: (hash, peer, maxAgeMs) =>
16344
16344
  this.isEntryRecentlyKnownByPeer(hash, peer, maxAgeMs),
16345
+ peerSupportsRawExchangeHeads: (peer) =>
16346
+ this.peerSupportsRawExchangeHeads(peer),
16345
16347
  sendRawExchangeHeads,
16346
16348
  });
16347
16349
  } else {
@@ -16359,6 +16361,8 @@ export class SharedLog<
16359
16361
  sync: options?.sync,
16360
16362
  isEntryRecentlyKnownByPeer: (hash, peer, maxAgeMs) =>
16361
16363
  this.isEntryRecentlyKnownByPeer(hash, peer, maxAgeMs),
16364
+ peerSupportsRawExchangeHeads: (peer) =>
16365
+ this.peerSupportsRawExchangeHeads(peer),
16362
16366
  sendRawExchangeHeads,
16363
16367
  });
16364
16368
  } else {
@@ -16381,6 +16385,8 @@ export class SharedLog<
16381
16385
  sync: options?.sync,
16382
16386
  isEntryRecentlyKnownByPeer: (hash, peer, maxAgeMs) =>
16383
16387
  this.isEntryRecentlyKnownByPeer(hash, peer, maxAgeMs),
16388
+ peerSupportsRawExchangeHeads: (peer) =>
16389
+ this.peerSupportsRawExchangeHeads(peer),
16384
16390
  sendRawExchangeHeads,
16385
16391
  }) as Syncronizer<R>;
16386
16392
  }
package/src/sync/index.ts CHANGED
@@ -172,6 +172,7 @@ export type SynchronizerComponents<R extends "u32" | "u64"> = {
172
172
  peer: string,
173
173
  maxAgeMs: number,
174
174
  ) => boolean;
175
+ peerSupportsRawExchangeHeads?: (peer: string) => boolean;
175
176
  sendRawExchangeHeads?: RawExchangeHeadsSender;
176
177
  };
177
178
  export type SynchronizerConstructor<R extends "u32" | "u64"> = new (
@@ -558,6 +558,7 @@ export class SimpleSyncronizer<R extends "u32" | "u64">
558
558
  peer: string,
559
559
  maxAgeMs: number,
560
560
  ) => boolean;
561
+ private peerSupportsRawExchangeHeads?: (peer: string) => boolean;
561
562
  private sendRawExchangeHeads?: RawExchangeHeadsSender;
562
563
  private recentlySentExchangeHeads: Map<string, Map<string, number>>;
563
564
  private pendingMaybeSyncResponses: Map<
@@ -602,6 +603,7 @@ export class SimpleSyncronizer<R extends "u32" | "u64">
602
603
  peer: string,
603
604
  maxAgeMs: number,
604
605
  ) => boolean;
606
+ peerSupportsRawExchangeHeads?: (peer: string) => boolean;
605
607
  sendRawExchangeHeads?: RawExchangeHeadsSender;
606
608
  }) {
607
609
  this.syncInFlightQueue = new Map();
@@ -638,6 +640,7 @@ export class SimpleSyncronizer<R extends "u32" | "u64">
638
640
  this.resolveHashListForSymbols = properties.resolveHashListForSymbols;
639
641
  this.syncOptions = properties.sync;
640
642
  this.isEntryRecentlyKnownByPeer = properties.isEntryRecentlyKnownByPeer;
643
+ this.peerSupportsRawExchangeHeads = properties.peerSupportsRawExchangeHeads;
641
644
  this.sendRawExchangeHeads = properties.sendRawExchangeHeads;
642
645
  this.recentlySentExchangeHeads = new Map();
643
646
  this.pendingMaybeSyncResponses = new Map();
@@ -3958,13 +3961,16 @@ export class SimpleSyncronizer<R extends "u32" | "u64">
3958
3961
  this.maxCoordinatesPerMessage,
3959
3962
  );
3960
3963
  for (const target of targets) {
3964
+ const requestRawExchangeHeads =
3965
+ this.syncOptions?.rawExchangeHeads === true &&
3966
+ this.peerSupportsRawExchangeHeads?.(target) === true;
3961
3967
  for (const chunk of chunks) {
3962
3968
  if (!this.isSyncDispatchLifecycleActive(lifecycle, target)) {
3963
3969
  break;
3964
3970
  }
3965
3971
  try {
3966
3972
  await this.rpc.send(
3967
- this.syncOptions?.rawExchangeHeads
3973
+ requestRawExchangeHeads
3968
3974
  ? new RequestMaybeSyncCoordinateCapabilities({
3969
3975
  hashNumbers: chunk,
3970
3976
  })
@@ -3993,13 +3999,16 @@ export class SimpleSyncronizer<R extends "u32" | "u64">
3993
3999
  if (stringHashes.length > 0) {
3994
4000
  const chunks = this.chunk(stringHashes, this.maxHashesPerMessage);
3995
4001
  for (const target of targets) {
4002
+ const requestRawExchangeHeads =
4003
+ this.syncOptions?.rawExchangeHeads === true &&
4004
+ this.peerSupportsRawExchangeHeads?.(target) === true;
3996
4005
  for (const chunk of chunks) {
3997
4006
  if (!this.isSyncDispatchLifecycleActive(lifecycle, target)) {
3998
4007
  break;
3999
4008
  }
4000
4009
  try {
4001
4010
  await this.rpc.send(
4002
- this.syncOptions?.rawExchangeHeads
4011
+ requestRawExchangeHeads
4003
4012
  ? new ResponseMaybeSyncCapabilities({
4004
4013
  hashes: chunk,
4005
4014
  })