| … | … | @@ -406,6 +406,16 @@ export class StateBaseV3 { |
| 406 | 406 | this.base = new Autobase(this.store, bootstrapKey, baseOpts) |
| 407 | 407 | await this.base.ready() |
| 408 | 408 | |
| 409 | // Fire the watcher fan-out on EVERY autobase view advance — crucially including the BACKGROUND |
| 410 | // apply-completion of THIS node's OWN optimistic write. Without this, a solo write (e.g. a direct |
| 411 | // apply-write on the notary) appends but the sb.watch -> tick -> sign() chain never re-fires: the |
| 412 | // apply-path _fireWatchers() only runs on an explicit base.update() drain with new nodes, and the |
| 413 | // autoUpdate view advance does not go through _apply. So the write would finalize only when some |
| 414 | // OTHER event (a co-owner's replication, another write, a presence change) happens to drive an apply |
| 415 | // — the "direct notary write never finalizes" lag. See test/finalization-lag.repro.test.js. sign() is |
| 416 | // idempotent (no-ops on an unchanged data root) and the tick coalesces, so extra fires are cheap. |
| 417 | this.base.on('update', () => this._fireWatchers()) |
| 418 | |
| 409 | 419 | if (this._network) { |
| 410 | 420 | if (!this.swarm) { |
| 411 | 421 | this.swarm = new Hyperswarm(this._swarmOpts || undefined) |