@peerbit/shared-log 11.4.3 → 11.5.1-0fddff8

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,72 +1,72 @@
1
1
  {
2
- "name": "@peerbit/shared-log",
3
- "version": "11.4.3",
4
- "description": "Shared log",
5
- "sideEffects": false,
6
- "type": "module",
7
- "types": "./dist/src/index.d.ts",
8
- "typesVersions": {
9
- "*": {
10
- "*": [
11
- "*",
12
- "dist/*",
13
- "dist/src/*",
14
- "dist/src/*/index"
15
- ],
16
- "src/*": [
17
- "*",
18
- "dist/*",
19
- "dist/src/*",
20
- "dist/src/*/index"
21
- ]
22
- }
23
- },
24
- "files": [
25
- "src",
26
- "dist",
27
- "!dist/e2e",
28
- "!dist/test",
29
- "!**/*.tsbuildinfo"
30
- ],
31
- "exports": {
32
- ".": {
33
- "types": "./dist/src/index.d.ts",
34
- "import": "./dist/src/index.js"
35
- }
36
- },
37
- "eslintConfig": {
38
- "extends": "peerbit",
39
- "parserOptions": {
40
- "project": true,
41
- "sourceType": "module"
42
- },
43
- "ignorePatterns": [
44
- "!.aegir.js",
45
- "test/ts-use",
46
- "*.d.ts"
47
- ]
48
- },
49
- "publishConfig": {
50
- "access": "public"
51
- },
52
- "scripts": {
53
- "clean": "aegir clean",
54
- "build": "aegir build --no-bundle",
55
- "test": "aegir test --target node",
56
- "lint": "aegir lint"
57
- },
58
- "author": "dao.xyz",
59
- "license": "MIT",
60
- "dependencies": {
61
- "@dao-xyz/borsh": "^5.2.3",
62
- "@peerbit/logger": "1.0.4",
63
- "@peerbit/program": "5.3.0",
64
- "@peerbit/log": "4.1.3",
65
- "@peerbit/rpc": "5.3.21",
66
- "@peerbit/time": "2.2.0",
67
- "@peerbit/riblt": "1.0.6"
68
- },
69
- "devDependencies": {
70
- "@peerbit/test-utils": "^2.2.3"
71
- }
2
+ "name": "@peerbit/shared-log",
3
+ "version": "11.5.1-0fddff8",
4
+ "description": "Shared log",
5
+ "sideEffects": false,
6
+ "type": "module",
7
+ "types": "./dist/src/index.d.ts",
8
+ "typesVersions": {
9
+ "*": {
10
+ "*": [
11
+ "*",
12
+ "dist/*",
13
+ "dist/src/*",
14
+ "dist/src/*/index"
15
+ ],
16
+ "src/*": [
17
+ "*",
18
+ "dist/*",
19
+ "dist/src/*",
20
+ "dist/src/*/index"
21
+ ]
22
+ }
23
+ },
24
+ "files": [
25
+ "src",
26
+ "dist",
27
+ "!dist/e2e",
28
+ "!dist/test",
29
+ "!**/*.tsbuildinfo"
30
+ ],
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/src/index.d.ts",
34
+ "import": "./dist/src/index.js"
35
+ }
36
+ },
37
+ "eslintConfig": {
38
+ "extends": "peerbit",
39
+ "parserOptions": {
40
+ "project": true,
41
+ "sourceType": "module"
42
+ },
43
+ "ignorePatterns": [
44
+ "!.aegir.js",
45
+ "test/ts-use",
46
+ "*.d.ts"
47
+ ]
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ },
52
+ "scripts": {
53
+ "clean": "aegir clean",
54
+ "build": "aegir build --no-bundle",
55
+ "test": "aegir test --target node",
56
+ "lint": "aegir lint"
57
+ },
58
+ "author": "dao.xyz",
59
+ "license": "MIT",
60
+ "dependencies": {
61
+ "@dao-xyz/borsh": "^5.2.3",
62
+ "@peerbit/logger": "1.0.4-0fddff8",
63
+ "@peerbit/program": "5.3.2-0fddff8",
64
+ "@peerbit/log": "4.1.5-0fddff8",
65
+ "@peerbit/rpc": "5.3.23-0fddff8",
66
+ "@peerbit/time": "2.2.0-0fddff8",
67
+ "@peerbit/riblt": "1.0.6-0fddff8"
68
+ },
69
+ "devDependencies": {
70
+ "@peerbit/test-utils": "2.2.5-0fddff8"
71
+ }
72
72
  }
package/src/index.ts CHANGED
@@ -2964,57 +2964,90 @@ export class SharedLog<
2964
2964
 
2965
2965
  async waitForReplicator(
2966
2966
  key: PublicSignKey,
2967
- options?: { signal?: AbortSignal },
2967
+ options?: {
2968
+ signal?: AbortSignal;
2969
+ eager?: boolean;
2970
+ roleAge?: number;
2971
+ timeout?: number;
2972
+ },
2968
2973
  ) {
2969
- let deferred = pDefer<void>();
2970
-
2971
- let timeout = setTimeout(() => {
2972
- clear();
2973
- deferred.reject(
2974
- new TimeoutError(`Timeout waiting for replicator ${key.hashcode()}`),
2975
- );
2976
- }, this.waitForReplicatorTimeout);
2974
+ const deferred = pDefer<void>();
2975
+ const timeoutMs = options?.timeout ?? this.waitForReplicatorTimeout;
2976
+ const resolvedRoleAge = options?.eager
2977
+ ? undefined
2978
+ : (options?.roleAge ?? (await this.getDefaultMinRoleAge()));
2977
2979
 
2978
- if (options?.signal) {
2979
- options.signal.addEventListener("abort", () => {
2980
- clear();
2981
- deferred.reject(new AbortError());
2982
- });
2983
- }
2980
+ let settled = false;
2981
+ let timer: ReturnType<typeof setTimeout> | undefined;
2984
2982
 
2985
2983
  const clear = () => {
2986
2984
  this.events.removeEventListener("replicator:mature", check);
2987
2985
  this.events.removeEventListener("replication:change", check);
2988
- if (options?.signal) {
2989
- options.signal.removeEventListener("abort", clear);
2986
+ options?.signal?.removeEventListener("abort", onAbort);
2987
+ if (timer != null) {
2988
+ clearTimeout(timer);
2989
+ timer = undefined;
2990
2990
  }
2991
- clearTimeout(timeout);
2992
2991
  };
2993
2992
 
2994
- deferred.promise.finally(() => {
2993
+ const resolve = () => {
2994
+ if (settled) {
2995
+ return;
2996
+ }
2997
+ settled = true;
2995
2998
  clear();
2996
- });
2999
+ deferred.resolve();
3000
+ };
3001
+
3002
+ const reject = (error: Error) => {
3003
+ if (settled) {
3004
+ return;
3005
+ }
3006
+ settled = true;
3007
+ clear();
3008
+ deferred.reject(error);
3009
+ };
3010
+
3011
+ const onAbort = () => reject(new AbortError());
3012
+ if (options?.signal) {
3013
+ options.signal.addEventListener("abort", onAbort);
3014
+ }
3015
+
3016
+ timer = setTimeout(() => {
3017
+ reject(
3018
+ new TimeoutError(`Timeout waiting for replicator ${key.hashcode()}`),
3019
+ );
3020
+ }, timeoutMs);
2997
3021
 
2998
3022
  const check = async () => {
2999
3023
  const iterator = this.replicationIndex?.iterate(
3000
3024
  { query: new StringMatch({ key: "hash", value: key.hashcode() }) },
3001
3025
  { reference: true },
3002
3026
  );
3003
- const rects = await iterator?.next(1);
3004
- await iterator.close();
3005
- const rect = rects[0]?.value;
3006
- if (
3007
- !rect ||
3008
- !isMatured(rect, +new Date(), await this.getDefaultMinRoleAge())
3009
- ) {
3010
- return;
3027
+ try {
3028
+ const rects = await iterator?.next(1);
3029
+ const rect = rects?.[0]?.value;
3030
+ if (!rect) {
3031
+ return;
3032
+ }
3033
+ if (!options?.eager && resolvedRoleAge != null) {
3034
+ if (!isMatured(rect, +new Date(), resolvedRoleAge)) {
3035
+ return;
3036
+ }
3037
+ }
3038
+ resolve();
3039
+ } catch (error) {
3040
+ reject(error instanceof Error ? error : new Error(String(error)));
3041
+ } finally {
3042
+ await iterator?.close();
3011
3043
  }
3012
- return deferred.resolve();
3013
3044
  };
3045
+
3014
3046
  check();
3015
3047
  this.events.addEventListener("replicator:mature", check);
3016
3048
  this.events.addEventListener("replication:change", check);
3017
- return deferred.promise;
3049
+
3050
+ return deferred.promise.finally(clear);
3018
3051
  }
3019
3052
 
3020
3053
  async waitForReplicators(options?: {
package/src/ranges.ts CHANGED
@@ -2394,6 +2394,15 @@ export const getCoverSet = async <R extends "u32" | "u64">(properties: {
2394
2394
  ? properties.numbers.min(startForNext, endLocation)
2395
2395
  : startForNext
2396
2396
  : properties.numbers.min(startForNext, endLocation);
2397
+
2398
+ if (
2399
+ (typeof nextLocation === "bigint" &&
2400
+ nextLocation === (endLocation as bigint)) ||
2401
+ (typeof nextLocation === "number" &&
2402
+ nextLocation === (endLocation as number))
2403
+ ) {
2404
+ break;
2405
+ }
2397
2406
  }
2398
2407
 
2399
2408
  start instanceof PublicSignKey && ret.add(start.hashcode());
@@ -420,8 +420,6 @@ export class RatelessIBLTSynchronizer<D extends "u32" | "u64">
420
420
  }, 2e4); // TODO arg
421
421
  };
422
422
 
423
- let count = 0;
424
- /* let t0 = +new Date(); */
425
423
  let messageQueue: {
426
424
  seqNo: bigint;
427
425
  symbols: (SSymbol | SymbolSerialized)[];
@@ -452,47 +450,13 @@ export class RatelessIBLTSynchronizer<D extends "u32" | "u64">
452
450
  if (messageQueue[0].seqNo !== lastSeqNo + 1n) {
453
451
  return;
454
452
  }
455
- lastSeqNo++;
456
453
 
457
- const symbolMessage = messageQueue.shift();
458
- if (!symbolMessage) {
459
- return;
460
- }
461
-
462
- for (const symbol of symbolMessage.symbols) {
463
- decoder.add_coded_symbol(symbol);
464
- }
465
- try {
466
- decoder.try_decode();
467
- } catch (error: any) {
468
- if (
469
- error?.message === "Invalid degree" ||
470
- error === "Invalid degree"
471
- ) {
472
- // TODO in some way test this code path
473
- logger.error(error?.message ?? error);
474
- obj.free();
475
- await this.simple.rpc.send(
476
- new RequestAll({
477
- syncId: message.syncId,
478
- }),
479
- {
480
- mode: new SilentDelivery({
481
- to: [context.from!],
482
- redundancy: 1,
483
- }),
484
- priority: 1,
485
- },
486
- );
487
- return true;
488
- } else {
489
- throw error;
454
+ const finalizeIfDecoded = (): boolean => {
455
+ if (!decoder.decoded()) {
456
+ return false;
490
457
  }
491
- }
492
- count += symbolMessage.symbols.length;
493
458
 
494
- if (decoder.decoded()) {
495
- let allMissingSymbolsInRemote: bigint[] = [];
459
+ const allMissingSymbolsInRemote: bigint[] = [];
496
460
  for (const missingSymbol of decoder.get_remote_symbols()) {
497
461
  allMissingSymbolsInRemote.push(missingSymbol);
498
462
  }
@@ -502,6 +466,48 @@ export class RatelessIBLTSynchronizer<D extends "u32" | "u64">
502
466
  });
503
467
  obj.free();
504
468
  return true;
469
+ };
470
+
471
+ while (
472
+ messageQueue.length > 0 &&
473
+ messageQueue[0].seqNo === lastSeqNo + 1n
474
+ ) {
475
+ const symbolMessage = messageQueue.shift();
476
+ if (!symbolMessage) {
477
+ break;
478
+ }
479
+
480
+ lastSeqNo = symbolMessage.seqNo;
481
+
482
+ for (const symbol of symbolMessage.symbols) {
483
+ const normalizedSymbol =
484
+ symbol instanceof SymbolSerialized
485
+ ? symbol
486
+ : new SymbolSerialized({
487
+ count: symbol.count,
488
+ hash: symbol.hash,
489
+ symbol: symbol.symbol,
490
+ });
491
+
492
+ decoder.add_coded_symbol(normalizedSymbol);
493
+ try {
494
+ decoder.try_decode();
495
+ if (finalizeIfDecoded()) {
496
+ return true;
497
+ }
498
+ } catch (error: any) {
499
+ if (
500
+ error?.message === "Invalid degree" ||
501
+ error === "Invalid degree"
502
+ ) {
503
+ logger.debug(
504
+ "Decoder reported invalid degree; waiting for more symbols",
505
+ );
506
+ continue;
507
+ }
508
+ throw error;
509
+ }
510
+ }
505
511
  }
506
512
  return false;
507
513
  },