@peerbit/shared-log 16.0.3 → 16.0.4

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": "16.0.3",
3
+ "version": "16.0.4",
4
4
  "description": "Shared log",
5
5
  "sideEffects": false,
6
6
  "type": "module",
@@ -62,27 +62,27 @@
62
62
  "pidusage": "^4.0.1",
63
63
  "pino": "^9.4.0",
64
64
  "uint8arrays": "^5.1.0",
65
- "@peerbit/any-store": "2.2.14",
66
65
  "@peerbit/blocks": "4.2.10",
67
- "@peerbit/blocks-interface": "2.1.5",
68
66
  "@peerbit/cache": "3.1.1",
69
67
  "@peerbit/crypto": "3.1.5",
68
+ "@peerbit/blocks-interface": "2.1.5",
69
+ "@peerbit/any-store": "2.2.14",
70
+ "@peerbit/diagnostics": "0.0.1",
70
71
  "@peerbit/indexer-interface": "3.0.9",
71
- "@peerbit/logger": "2.0.1",
72
72
  "@peerbit/indexer-sqlite3": "3.0.14",
73
- "@peerbit/diagnostics": "0.0.1",
73
+ "@peerbit/logger": "2.0.1",
74
74
  "@peerbit/log": "6.2.17",
75
- "@peerbit/pubsub": "5.4.1",
76
75
  "@peerbit/program": "6.0.49",
76
+ "@peerbit/pubsub": "5.4.1",
77
77
  "@peerbit/pubsub-interface": "5.2.1",
78
- "@peerbit/riblt": "1.2.0",
79
- "@peerbit/stream-interface": "6.0.15",
80
78
  "@peerbit/rpc": "6.1.17",
81
- "@peerbit/time": "3.0.1"
79
+ "@peerbit/stream-interface": "6.0.15",
80
+ "@peerbit/time": "3.0.1",
81
+ "@peerbit/riblt": "1.2.0"
82
82
  },
83
83
  "optionalDependencies": {
84
- "@peerbit/native-backbone": "0.2.5",
85
- "@peerbit/shared-log-rust": "0.1.4"
84
+ "@peerbit/shared-log-rust": "0.1.4",
85
+ "@peerbit/native-backbone": "0.2.5"
86
86
  },
87
87
  "devDependencies": {
88
88
  "@types/libsodium-wrappers": "^0.7.14",
@@ -90,8 +90,8 @@
90
90
  "uuid": "^11.1.1",
91
91
  "@peerbit/any-store-rust": "0.1.4",
92
92
  "@peerbit/indexer-rust": "1.0.7",
93
- "peerbit": "5.3.23",
94
- "@peerbit/test-utils": "3.1.23"
93
+ "@peerbit/test-utils": "3.1.23",
94
+ "peerbit": "5.3.23"
95
95
  },
96
96
  "repository": {
97
97
  "type": "git",
package/src/index.ts CHANGED
@@ -2038,7 +2038,58 @@ export class SharedLog<
2038
2038
 
2039
2039
  /* private _totalParticipation!: number; */
2040
2040
 
2041
- // gid -> coordinate -> publicKeyHash list (of owners)
2041
+ // gid -> set of publicKeyHashes known to hold that gid's entries.
2042
+ //
2043
+ // This is a suppression memo, not a source of truth. A present row lets the
2044
+ // rebalance and repair paths skip re-sending an entry to a peer that already
2045
+ // has it. Every read is `?.has(peer)` guarded, and a MISSING row always
2046
+ // means "assume nothing is known", which produces strictly MORE work --
2047
+ // redundant unchecked delivery in the rebalance loop, redundant queueing in
2048
+ // the repair planner -- and never a wrong prune, a wrong quorum, or data
2049
+ // loss. Losing a row costs bandwidth; keeping a stale row costs a little
2050
+ // memory. That asymmetry is what the rest of this note turns on.
2051
+ //
2052
+ // GROWTH SHAPE. Rows are released by `deleteGidPeerHistory` on the two prune
2053
+ // paths, by `removePeerFromGidPeerHistory` once a gid's last peer drops (the
2054
+ // routine disconnect outcome), by `rebalanceAll({ clearCache: true })`, and
2055
+ // wholesale on close/reset. Nothing on the TRIM path releases a row, so a
2056
+ // node that bounds its log with trim rather than prune accumulates one row
2057
+ // per distinct gid it has ever held. A gid names a graph, not an entry: an
2058
+ // entry with `meta.next` inherits `min(next.meta.gid)` (see
2059
+ // packages/log/src/entry-v0.ts), so document updates fold into the gid of
2060
+ // the first put and the row count tracks distinct chain roots -- distinct
2061
+ // document ids -- rather than entry count. Insert-only workloads mint a
2062
+ // fresh gid per append and so do grow one row per entry. Merges are a
2063
+ // smaller second source: when a join links two graphs the losing entries
2064
+ // keep their own `meta.gid` on disk, and shared-log does not subscribe to
2065
+ // the log's `onGidRemoved`, so the shadowed gid's row lingers too.
2066
+ //
2067
+ // WHY TRIM DOES NOT SIMPLY CALL `deleteGidPeerHistory` AS WELL. Both prune
2068
+ // callers delete a whole row from a single entry's gid, and under the
2069
+ // default hash domain that is correct by construction: the coordinate is a
2070
+ // pure function of the gid (replication-domain-hash.ts sha256s
2071
+ // `entry.meta.gid`), so identical gid => identical coordinates => identical
2072
+ // leader set => every local sibling of that gid is prune-eligible in the
2073
+ // same batch. The gid really is finished locally. Trim offers no such
2074
+ // guarantee. It walks oldest-first against a length/bytelength/age bound and
2075
+ // stops the instant the bound is met (packages/log/src/trim.ts); its only
2076
+ // use of gid is memoizing the caller's `canTrim` verdict, never grouping
2077
+ // deletes. So trim routinely removes the OLDEST entry of a gid while newer
2078
+ // siblings -- same gid, same coordinates, still local, still replicated --
2079
+ // remain. Copying the prune call onto trim would therefore delete a LIVE row
2080
+ // on the common path, paying for the freed memory in repeated re-delivery of
2081
+ // entries that are still here. That trade is not worth it.
2082
+ //
2083
+ // Bounding this correctly requires a per-gid count of locally held entries,
2084
+ // dropping the row only when it reaches zero -- a real reverse index, not a
2085
+ // one-line delete. Deliberately not built: the growth is bounded by distinct
2086
+ // gids, and the cheap version is a bandwidth regression.
2087
+ //
2088
+ // Existing, deliberate imprecision: under the time domain the coordinate is
2089
+ // `meta.clock.timestamp.wallTime` (replication-domain-time.ts) and is
2090
+ // gid-independent, so siblings of one gid can carry different leader sets
2091
+ // and prune's whole-row delete is already over-eager there. The cost is the
2092
+ // same bounded extra traffic, never a wrong prune.
2042
2093
  _gidPeersHistory!: Map<string, Set<string>>;
2043
2094
 
2044
2095
  private _onSubscriptionFn!: (arg: any) => any;