@peerbit/shared-log 10.0.4 → 10.0.5-8abb258

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,75 +1,72 @@
1
1
  {
2
- "name": "@peerbit/shared-log",
3
- "version": "10.0.4",
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
- "browser": {
32
- "./dist/src/sync/wasm-init.js": "./dist/src/sync/wasm-init.browser.js"
33
- },
34
- "exports": {
35
- ".": {
36
- "types": "./dist/src/index.d.ts",
37
- "import": "./dist/src/index.js"
38
- }
39
- },
40
- "eslintConfig": {
41
- "extends": "peerbit",
42
- "parserOptions": {
43
- "project": true,
44
- "sourceType": "module"
45
- },
46
- "ignorePatterns": [
47
- "!.aegir.js",
48
- "test/ts-use",
49
- "*.d.ts"
50
- ]
51
- },
52
- "publishConfig": {
53
- "access": "public"
54
- },
55
- "scripts": {
56
- "clean": "aegir clean",
57
- "build": "aegir build --no-bundle",
58
- "test": "aegir test --target node",
59
- "lint": "aegir lint"
60
- },
61
- "author": "dao.xyz",
62
- "license": "MIT",
63
- "dependencies": {
64
- "@dao-xyz/borsh": "^5.2.3",
65
- "@peerbit/logger": "1.0.3",
66
- "@peerbit/program": "5.1.0",
67
- "@peerbit/log": "4.0.23",
68
- "@peerbit/rpc": "5.0.21",
69
- "@peerbit/time": "2.0.7",
70
- "@peerbit/riblt": "1.0.3"
71
- },
72
- "devDependencies": {
73
- "@peerbit/test-utils": "^2.1.11"
74
- }
2
+ "name": "@peerbit/shared-log",
3
+ "version": "10.0.5-8abb258",
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.3-8abb258",
63
+ "@peerbit/program": "5.1.0-8abb258",
64
+ "@peerbit/log": "4.0.23-8abb258",
65
+ "@peerbit/rpc": "5.0.21-8abb258",
66
+ "@peerbit/time": "2.0.7-8abb258",
67
+ "@peerbit/riblt": "1.0.3-8abb258"
68
+ },
69
+ "devDependencies": {
70
+ "@peerbit/test-utils": "2.1.11-8abb258"
71
+ }
75
72
  }
package/src/index.ts CHANGED
@@ -2037,7 +2037,7 @@ export class SharedLog<
2037
2037
  if (isLeader) {
2038
2038
  for (const entry of entries) {
2039
2039
  this.pruneDebouncedFn.delete(entry.entry.hash);
2040
- this._requestIPruneSent.delete(entry.entry.hash);
2040
+ this.removePruneRequestSent(entry.entry.hash);
2041
2041
  this._requestIPruneResponseReplicatorSet.delete(
2042
2042
  entry.entry.hash,
2043
2043
  );
@@ -2130,13 +2130,17 @@ export class SharedLog<
2130
2130
  }
2131
2131
  } else if (msg instanceof RequestIPrune) {
2132
2132
  const hasAndIsLeader: string[] = [];
2133
+ const from = context.from.hashcode();
2134
+
2133
2135
  for (const hash of msg.hashes) {
2136
+ this.removePruneRequestSent(hash, from);
2137
+
2134
2138
  // if we expect the remote to be owner of this entry because we are to prune ourselves, then we need to remove the remote
2135
2139
  // this is due to that the remote has previously indicated to be a replicator to help us prune but now has changed their mind
2136
2140
  const outGoingPrunes =
2137
2141
  this._requestIPruneResponseReplicatorSet.get(hash);
2138
2142
  if (outGoingPrunes) {
2139
- outGoingPrunes.delete(context.from.hashcode());
2143
+ outGoingPrunes.delete(from);
2140
2144
  }
2141
2145
 
2142
2146
  const indexedEntry = await this.log.entryIndex.getShallow(hash);
@@ -2170,6 +2174,8 @@ export class SharedLog<
2170
2174
  }
2171
2175
 
2172
2176
  if (isLeader) {
2177
+ //console.log("IS LEADER", this.node.identity.publicKey.hashcode(), hash);
2178
+
2173
2179
  hasAndIsLeader.push(hash);
2174
2180
 
2175
2181
  hasAndIsLeader.length > 0 &&
@@ -2205,13 +2211,20 @@ export class SharedLog<
2205
2211
  context.from!.hashcode(),
2206
2212
  entry.meta.gid,
2207
2213
  );
2214
+ this.removePruneRequestSent(entry.hash, from);
2208
2215
  let isLeader = false;
2209
- await this.findLeaders(
2216
+ await this._waitForReplicators(
2210
2217
  await this.createCoordinates(
2211
2218
  entry,
2212
2219
  decodeReplicas(entry).getValue(this),
2213
2220
  ),
2214
2221
  entry,
2222
+ [
2223
+ {
2224
+ key: this.node.identity.publicKey.hashcode(),
2225
+ replicator: true,
2226
+ },
2227
+ ],
2215
2228
  {
2216
2229
  onLeader: (key) => {
2217
2230
  isLeader =
@@ -3171,6 +3184,20 @@ export class SharedLog<
3171
3184
  return new AbsoluteReplicas(maxValue);
3172
3185
  }
3173
3186
 
3187
+ private removePruneRequestSent(hash: string, to?: string) {
3188
+ if (!to) {
3189
+ this._requestIPruneSent.delete(hash);
3190
+ } else {
3191
+ let set = this._requestIPruneSent.get(hash);
3192
+ if (set) {
3193
+ set.delete(to);
3194
+ if (set.size === 0) {
3195
+ this._requestIPruneSent.delete(hash);
3196
+ }
3197
+ }
3198
+ }
3199
+ }
3200
+
3174
3201
  prune(
3175
3202
  entries: Map<
3176
3203
  string,
@@ -3184,7 +3211,7 @@ export class SharedLog<
3184
3211
  if (options?.unchecked) {
3185
3212
  return [...entries.values()].map((x) => {
3186
3213
  this._gidPeersHistory.delete(x.entry.meta.gid);
3187
- this._requestIPruneSent.delete(x.entry.hash);
3214
+ this.removePruneRequestSent(x.entry.hash);
3188
3215
  this._requestIPruneResponseReplicatorSet.delete(x.entry.hash);
3189
3216
  return this.log.remove(x.entry, {
3190
3217
  recursively: true,
@@ -3192,6 +3219,10 @@ export class SharedLog<
3192
3219
  });
3193
3220
  }
3194
3221
 
3222
+ if (this.closed) {
3223
+ return [];
3224
+ }
3225
+
3195
3226
  // ask network if they have they entry,
3196
3227
  // so I can delete it
3197
3228
 
@@ -3227,7 +3258,6 @@ export class SharedLog<
3227
3258
  const deferredPromise: DeferredPromise<void> = pDefer();
3228
3259
 
3229
3260
  const clear = () => {
3230
- //pendingPrev?.clear();
3231
3261
  const pending = this._pendingDeletes.get(entry.hash);
3232
3262
  if (pending?.promise === deferredPromise) {
3233
3263
  this._pendingDeletes.delete(entry.hash);
@@ -3239,6 +3269,10 @@ export class SharedLog<
3239
3269
  clear();
3240
3270
  cleanupTimer.push(
3241
3271
  setTimeout(async () => {
3272
+ this._gidPeersHistory.delete(entry.meta.gid);
3273
+ this.removePruneRequestSent(entry.hash);
3274
+ this._requestIPruneResponseReplicatorSet.delete(entry.hash);
3275
+
3242
3276
  if (
3243
3277
  await this.isLeader({
3244
3278
  entry,
@@ -3251,10 +3285,6 @@ export class SharedLog<
3251
3285
  return;
3252
3286
  }
3253
3287
 
3254
- this._gidPeersHistory.delete(entry.meta.gid);
3255
- this._requestIPruneSent.delete(entry.hash);
3256
- this._requestIPruneResponseReplicatorSet.delete(entry.hash);
3257
-
3258
3288
  return this.log
3259
3289
  .remove(entry, {
3260
3290
  recursively: true,
@@ -3267,7 +3297,7 @@ export class SharedLog<
3267
3297
  })
3268
3298
  .finally(async () => {
3269
3299
  this._gidPeersHistory.delete(entry.meta.gid);
3270
- this._requestIPruneSent.delete(entry.hash);
3300
+ this.removePruneRequestSent(entry.hash);
3271
3301
  this._requestIPruneResponseReplicatorSet.delete(entry.hash);
3272
3302
  // TODO in the case we become leader again here we need to re-add the entry
3273
3303
 
@@ -3286,7 +3316,7 @@ export class SharedLog<
3286
3316
 
3287
3317
  const reject = (e: any) => {
3288
3318
  clear();
3289
- this._requestIPruneSent.delete(entry.hash);
3319
+ this.removePruneRequestSent(entry.hash);
3290
3320
  this._requestIPruneResponseReplicatorSet.delete(entry.hash);
3291
3321
  deferredPromise.reject(e);
3292
3322
  };
@@ -3301,9 +3331,7 @@ export class SharedLog<
3301
3331
 
3302
3332
  this._pendingDeletes.set(entry.hash, {
3303
3333
  promise: deferredPromise,
3304
- clear: () => {
3305
- clear();
3306
- },
3334
+ clear,
3307
3335
  reject,
3308
3336
  resolve: async (publicKeyHash: string) => {
3309
3337
  const minReplicasObj = this.getClampedReplicas(minReplicas);
@@ -3363,8 +3391,8 @@ export class SharedLog<
3363
3391
  set = new Set();
3364
3392
  this._requestIPruneSent.set(entry, set);
3365
3393
  }
3366
-
3367
- /* if (set.has(to)) {
3394
+ /* TODO why can we not have this statement?
3395
+ if (set.has(to)) {
3368
3396
  continue;
3369
3397
  } */
3370
3398
  set.add(to);
@@ -3390,64 +3418,10 @@ export class SharedLog<
3390
3418
  emitMessages(v, k);
3391
3419
  }
3392
3420
 
3393
- /* const fn = async () => {
3394
- this.rpc.send(
3395
- new RequestIPrune({
3396
- hashes: filteredEntries.map(x => x.hash),
3397
- }),
3398
- {
3399
- mode: new SilentDelivery({
3400
- to: [...await this.getReplicators()],
3401
- redundancy: 1,
3402
- }),
3403
- priority: 1,
3404
- },
3405
- )
3406
- };
3407
- fn() */
3408
-
3409
- /* const onPeersChange = async (
3410
- e?: CustomEvent<ReplicatorJoinEvent>,
3411
- reason?: string,
3412
- ) => {
3413
- if (
3414
- true // e.detail.publicKey.equals(this.node.identity.publicKey) === false // TODO proper condition
3415
- ) {
3416
-
3417
- const peerToEntryMap = await this.groupByLeaders(
3418
- filteredEntries
3419
- .filter((x) => !readyToDelete.has(x.hash))
3420
- .map((x) => {
3421
- return { entry: x, replicas: maxReplicasValue }; // TODO choose right maxReplicasValue, should it really be for all entries combined?
3422
- }),
3423
- );
3424
- for (const receiver of peerToEntryMap.keys()) {
3425
- if (receiver === this.node.identity.publicKey.hashcode()) {
3426
- continue;
3427
- }
3428
- const peerEntries = peerToEntryMap.get(receiver);
3429
- if (peerEntries && peerEntries.length > 0) {
3430
- emitMessages(
3431
- peerEntries.map((x) => filteredEntries[x].hash),
3432
- receiver,
3433
- );
3434
- }
3435
- }
3436
- }
3437
- }; */
3438
-
3439
- // check joining peers
3440
- /* this.events.addEventListener("replication:change", onPeersChange);
3441
- this.events.addEventListener("replicator:mature", onPeersChange);
3442
- this.events.addEventListener("replicator:join", onPeersChange); */
3443
-
3444
3421
  let cleanup = () => {
3445
3422
  for (const timer of cleanupTimer) {
3446
3423
  clearTimeout(timer);
3447
3424
  }
3448
- /* this.events.removeEventListener("replication:change", onPeersChange);
3449
- this.events.removeEventListener("replicator:mature", onPeersChange);
3450
- this.events.removeEventListener("replicator:join", onPeersChange); */
3451
3425
  this._closeController.signal.removeEventListener("abort", cleanup);
3452
3426
  };
3453
3427
 
@@ -3565,15 +3539,14 @@ export class SharedLog<
3565
3539
  if (!set.has(entryReplicated.hash)) {
3566
3540
  set.set(entryReplicated.hash, entryReplicated);
3567
3541
  }
3542
+ }
3543
+ }
3568
3544
 
3569
- /* for (const entry of coordinates) {
3570
- let arr = set.get(entry.hash);
3571
- if (!arr) {
3572
- arr = [];
3573
- set.set(entry.hash, arr);
3574
- }
3575
- arr.push(entry);
3576
- } */
3545
+ if (oldPeersSet) {
3546
+ for (const oldPeer of oldPeersSet) {
3547
+ if (!currentPeers.has(oldPeer)) {
3548
+ this.removePruneRequestSent(entryReplicated.hash);
3549
+ }
3577
3550
  }
3578
3551
  }
3579
3552
 
@@ -3591,13 +3564,14 @@ export class SharedLog<
3591
3564
  });
3592
3565
  }
3593
3566
 
3567
+ // console.log("DELETE RESPONSE AS LEADER", this.node.identity.publicKey.hashcode(), entryReplicated.hash)
3594
3568
  this.responseToPruneDebouncedFn.delete(entryReplicated.hash); // don't allow others to prune because of expecting me to replicating this entry
3595
3569
  } else {
3596
3570
  this.pruneDebouncedFn.delete(entryReplicated.hash);
3597
3571
  await this._pendingDeletes
3598
3572
  .get(entryReplicated.hash)
3599
3573
  ?.reject(new Error("Failed to delete, is leader again"));
3600
- this._requestIPruneSent.delete(entryReplicated.hash);
3574
+ this.removePruneRequestSent(entryReplicated.hash);
3601
3575
  }
3602
3576
  }
3603
3577
  for (const [target, entries] of uncheckedDeliver) {
@@ -3,7 +3,7 @@ import { Cache } from "@peerbit/cache";
3
3
  import { type PublicSignKey, randomBytes, toBase64 } from "@peerbit/crypto";
4
4
  import { type Index } from "@peerbit/indexer-interface";
5
5
  import type { Entry, Log } from "@peerbit/log";
6
- import init, { DecoderWrapper, EncoderWrapper } from "@peerbit/riblt";
6
+ import { DecoderWrapper, EncoderWrapper } from "@peerbit/riblt";
7
7
  import type { RPC, RequestContext } from "@peerbit/rpc";
8
8
  import { SilentDelivery } from "@peerbit/stream-interface";
9
9
  import type { SyncableKey, Syncronizer } from ".";
@@ -16,9 +16,6 @@ import {
16
16
  matchEntriesInRangeQuery,
17
17
  } from "../ranges.js";
18
18
  import { SimpleSyncronizer } from "./simple.js";
19
- import "./wasm-init.js";
20
-
21
- await init();
22
19
 
23
20
  type NumberOrBigint = number | bigint;
24
21
 
@@ -178,7 +178,7 @@ export class SimpleSyncronizer<R extends "u32" | "u64">
178
178
  )) {
179
179
  await this.rpc.send(message, {
180
180
  mode: new SilentDelivery({ to: [context.from!], redundancy: 1 }),
181
- priority: 1,
181
+ // dont set priority 1 here because this will block other messages that should higher priority
182
182
  });
183
183
  }
184
184
 
@@ -1 +0,0 @@
1
- //# sourceMappingURL=wasm-init.browser.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wasm-init.browser.d.ts","sourceRoot":"","sources":["../../../src/sync/wasm-init.browser.ts"],"names":[],"mappings":""}
@@ -1,3 +0,0 @@
1
- "use strict";
2
- // nothing to do since 'fetch' works as expected in the browsere
3
- //# sourceMappingURL=wasm-init.browser.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wasm-init.browser.js","sourceRoot":"","sources":["../../../src/sync/wasm-init.browser.ts"],"names":[],"mappings":";AAAA,gEAAgE"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=wasm-init.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wasm-init.d.ts","sourceRoot":"","sources":["../../../src/sync/wasm-init.ts"],"names":[],"mappings":""}
@@ -1,13 +0,0 @@
1
- // Override globalThis.fetch to intercept .wasm requests
2
- import { readFile } from "fs/promises";
3
- const defaultFetch = globalThis.fetch.bind(globalThis);
4
- globalThis.fetch = async (url, options) => {
5
- // If you have multiple wasm files, you might use some logic to handle them.
6
- // Here, we assume any request ending in `.wasm` is local on disk at the same path.
7
- if (url.toString().endsWith(".wasm")) {
8
- // Return a NodeResponse that looks enough like a fetch Response
9
- return readFile(url);
10
- }
11
- return defaultFetch(url, options);
12
- };
13
- //# sourceMappingURL=wasm-init.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wasm-init.js","sourceRoot":"","sources":["../../../src/sync/wasm-init.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AACtD,UAAU,CAAC,KAAa,GAAG,KAAK,EAAE,GAAQ,EAAE,OAAY,EAAE,EAAE;IAC5D,4EAA4E;IAC5E,mFAAmF;IACnF,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,gEAAgE;QAChE,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AACnC,CAAC,CAAC"}
@@ -1 +0,0 @@
1
- // nothing to do since 'fetch' works as expected in the browsere
@@ -1,14 +0,0 @@
1
- // Override globalThis.fetch to intercept .wasm requests
2
- import { readFile } from "fs/promises";
3
-
4
- const defaultFetch = globalThis.fetch.bind(globalThis);
5
- (globalThis.fetch as any) = async (url: any, options: any) => {
6
- // If you have multiple wasm files, you might use some logic to handle them.
7
- // Here, we assume any request ending in `.wasm` is local on disk at the same path.
8
- if (url.toString().endsWith(".wasm")) {
9
- // Return a NodeResponse that looks enough like a fetch Response
10
- return readFile(url);
11
- }
12
-
13
- return defaultFetch(url, options);
14
- };