@cero-base/core 1.11.0 → 1.12.0

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": "@cero-base/core",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
4
4
  "description": "cero p2p primitives — identity, storage, network, database, blobs, rpc, pairing.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -144,7 +144,7 @@
144
144
  },
145
145
  "dependencies": {
146
146
  "@hyperswarm/secret-stream": "^6.9.1",
147
- "autobee": "2.0.0-rc.14",
147
+ "autobee": "2.0.0-rc.19",
148
148
  "autobee-encryption": "0.1.3",
149
149
  "b4a": "^1.8.1",
150
150
  "bare-crypto": "^1.15.3",
@@ -152,18 +152,18 @@
152
152
  "bare-path": "^3.1.1",
153
153
  "bip39-mnemonic": "^2.5.0",
154
154
  "blind-pairing": "^2.3.1",
155
- "blind-peering": "^2.6.1",
156
- "compact-encoding": "^3.3.0",
155
+ "blind-peering": "^2.6.3",
156
+ "compact-encoding": "^3.3.2",
157
157
  "corestore": "^7.12.0",
158
158
  "framed-stream": "^1.0.1",
159
- "hrpc": "^4.3.0",
159
+ "hrpc": "^4.3.1",
160
160
  "hyperblobs": "^2.12.1",
161
- "hypercore": "^11.35.1",
161
+ "hypercore": "^11.35.2",
162
162
  "hypercore-blob-server": "^1.15.0",
163
163
  "hypercore-crypto": "^3.7.0",
164
164
  "hypercore-id-encoding": "^1.3.0",
165
- "hypercore-storage": "^3.2.0",
166
- "hyperdb": "^6.8.0",
165
+ "hypercore-storage": "^3.2.1",
166
+ "hyperdb": "^6.9.0",
167
167
  "hyperdispatch": "^1.6.0",
168
168
  "hyperschema": "^1.22.0",
169
169
  "hyperswarm": "^4.17.0",
@@ -182,7 +182,7 @@
182
182
  "bare-fetch": "^3.2.0",
183
183
  "bare-process": "^4.5.1",
184
184
  "bare-url": "^2.5.2",
185
- "blind-peer": "^3.13.2",
185
+ "blind-peer": "^3.13.3",
186
186
  "brittle": "^4.1.0",
187
187
  "typescript": "^5.9.3",
188
188
  "which-runtime": "^1.4.0"
@@ -114,7 +114,11 @@ export function makeDispatcher(
114
114
  if (!isKey(op.master) || !isKey(op.writer) || !isSig(op.sig)) return
115
115
  if (!Identity.verify(op.master, addWriterPayload(ctx.dbKey, op.writer, ctx.key), op.sig)) return
116
116
  if (!(await isGenesis(ctx.view)) && !can(await getRole(ctx.view, op.master), INVITE)) return
117
- await ctx.host.addWriter(op.writer, { isIndexer: op.isIndexer !== false })
117
+ // always an indexer, like claim-writer below. The op's optional isIndexer
118
+ // bool decodes to false when absent (nothing sets it), which silently made
119
+ // every device a weight-1 writer — autobee 2.0 gc's caught-up non-indexer
120
+ // sessions, and a gc'd writer misses later appends until a wakeup revives it
121
+ await ctx.host.addWriter(op.writer, { isIndexer: true })
118
122
  const ts = op.ts || 0
119
123
  await insert(ctx.view, 'devices', `@${ns}/devices`, {
120
124
  id: toId(op.writer),
@@ -230,54 +230,36 @@ export class EpochAutobee extends Autobee {
230
230
  await primeKeyring(this.keyring, this.local)
231
231
  }
232
232
 
233
- // Upstream's drain body with one change: a writer whose next block sits at
234
- // an epoch we haven't learned yet parks (stays pending, so every later
235
- // bump re-examines it) instead of aborting the whole drain — the
236
- // announcement carrying that epoch lives in another writer's core and
237
- // applies on this or a later bump. The catch wraps the whole per-writer
238
- // step so an UNKNOWN_EPOCH surfacing from batch processing parks too
239
- // instead of crashing the bee.
233
+ // A writer whose next blocks sit at an epoch we haven't learned yet parks:
234
+ // its next() reports "nothing to offer" instead of throwing, so upstream's
235
+ // drain keeps selecting among the other writers — the announcement carrying
236
+ // the missing epoch lives in one of THEIR cores and unlocks the parked
237
+ // writer on a later bump (the scheduled retry pokes the drain). The outer
238
+ // catch backstops an UNKNOWN_EPOCH surfacing from batch processing itself.
240
239
  async _bumpPendingWriters() {
241
- if (this._catchupMigratedNodes !== null) {
242
- await this._bumpMigratedWriters()
243
- this._catchupMigratedNodes = null
240
+ for (const w of this.writers.pending) this._parkOnUnknownEpoch(w)
241
+ try {
242
+ return await super._bumpPendingWriters()
243
+ } catch (err) {
244
+ if (err?.code !== 'UNKNOWN_EPOCH') throw err
245
+ this._scheduleEpochRetry()
246
+ return false
244
247
  }
248
+ }
245
249
 
246
- let updated = false
247
-
248
- const pending = this.writers.pending.slice()
249
-
250
- for (let i = pending.length - 1; i >= 0; i--) {
251
- const w = pending[i]
252
-
250
+ _parkOnUnknownEpoch(w) {
251
+ if (w._epochParking) return
252
+ w._epochParking = true
253
+ const next = w.next.bind(w)
254
+ w.next = async () => {
253
255
  try {
254
- const batch = await w.next()
255
- if (batch === null) continue
256
-
257
- if (w.isAdded || (w.isRemoved && w.hasReferrals())) {
258
- await this._processBatch(batch)
259
- w.notify(batch)
260
- updated = true
261
- continue
262
- }
263
-
264
- if (this.optimistic && !w.isRemoved && batch[0].optimistic) {
265
- if (!(await this._optimisticBatch(batch))) {
266
- w.removePending()
267
- continue
268
- }
269
- w.notify(batch)
270
- updated = true
271
- continue
272
- }
256
+ return await next()
273
257
  } catch (err) {
274
258
  if (err?.code !== 'UNKNOWN_EPOCH') throw err
275
259
  this._scheduleEpochRetry()
276
- continue
260
+ return null
277
261
  }
278
262
  }
279
-
280
- return updated
281
263
  }
282
264
 
283
265
  // a parked writer produces no wake-up of its own — poke the bee until the
@@ -11,13 +11,20 @@ export function blobEpochKey(entropy: Uint8Array): Uint8Array;
11
11
  * Wire codec for a rotation announcement's envelope list — one sealed box
12
12
  * per remaining member, addressed by member id.
13
13
  */
14
- export const wraps: any;
14
+ export const wraps: c.Encoder<any[], {
15
+ id: string;
16
+ box: Uint8Array<ArrayBufferLike>;
17
+ }[]>;
15
18
  /**
16
19
  * Wire codec for locally persisted / pairing-delivered epoch secrets.
17
20
  * `epoch` is the apply-order sequence; `stamp` is the content-addressed
18
21
  * uint32 written into block headers.
19
22
  */
20
- export const epochEntries: any;
23
+ export const epochEntries: c.Encoder<any[], {
24
+ epoch: number;
25
+ stamp: number;
26
+ entropy: Uint8Array<ArrayBufferLike>;
27
+ }[]>;
21
28
  /**
22
29
  * Per-database registry of rotation epochs. Stamp 0 is the base key era
23
30
  * (no entry needed — it derives from the upstream GENESIS_ENTROPY path).
@@ -83,8 +90,9 @@ export class EpochAutobee {
83
90
  _epochRetryDelay: number;
84
91
  _epochRetrySeen: number;
85
92
  _bootState(): Promise<void>;
86
- _bumpPendingWriters(): Promise<boolean>;
87
- _catchupMigratedNodes: any;
93
+ _bumpPendingWriters(): Promise<any>;
94
+ _parkOnUnknownEpoch(w: any): void;
88
95
  _scheduleEpochRetry(): void;
89
96
  _close(): Promise<any>;
90
97
  }
98
+ import c from 'compact-encoding';
@@ -56,7 +56,7 @@ export class Database extends ReadyResource {
56
56
  verb?: string;
57
57
  }>;
58
58
  version: any;
59
- behind: any;
59
+ behind: number;
60
60
  routes: Record<string, Function>;
61
61
  namespace: string;
62
62
  encryptionKey: Uint8Array<ArrayBufferLike>;